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 (conf, G_OBJECT (header_view),
2712 MODEST_CONF_HEADER_VIEW_KEY);
2714 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2718 /* Update dimming state */
2719 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2720 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2724 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2731 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2733 online = tny_device_is_online (modest_runtime_get_device());
2736 /* already online -- the item is simply not there... */
2737 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2739 GTK_MESSAGE_WARNING,
2741 _("The %s you selected cannot be found"),
2743 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2744 gtk_dialog_run (GTK_DIALOG(dialog));
2746 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2749 _("mcen_bd_dialog_cancel"),
2750 GTK_RESPONSE_REJECT,
2751 _("mcen_bd_dialog_ok"),
2752 GTK_RESPONSE_ACCEPT,
2754 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2755 "Do you want to get online?"), item);
2756 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2757 gtk_label_new (txt), FALSE, FALSE, 0);
2758 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2761 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2762 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2763 /* TODO: Comment about why is this commented out: */
2764 /* modest_platform_connect_and_wait (); */
2767 gtk_widget_destroy (dialog);
2771 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2774 /* g_message ("%s %s", __FUNCTION__, link); */
2779 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2782 modest_platform_activate_uri (link);
2786 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2789 modest_platform_show_uri_popup (link);
2793 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2796 /* we check for low-mem; in that case, show a warning, and don't allow
2797 * viewing attachments
2799 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2802 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2806 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2807 const gchar *address,
2810 /* g_message ("%s %s", __FUNCTION__, address); */
2814 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2815 TnyMsg *saved_draft,
2818 ModestMsgEditWindow *edit_window;
2820 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2821 #ifndef MODEST_TOOLKIT_HILDON2
2822 ModestMainWindow *win;
2824 /* FIXME. Make the header view sensitive again. This is a
2825 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2827 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2828 modest_runtime_get_window_mgr(), FALSE));
2830 GtkWidget *hdrview = modest_main_window_get_child_widget(
2831 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2832 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2836 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2838 /* Set draft is there was no error */
2839 if (!modest_mail_operation_get_error (mail_op))
2840 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2842 g_object_unref(edit_window);
2846 enough_space_for_message (ModestMsgEditWindow *edit_window,
2849 guint64 available_disk, expected_size;
2854 available_disk = modest_utils_get_available_space (NULL);
2855 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2856 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2861 /* Double check: memory full condition or message too big */
2862 if (available_disk < MIN_FREE_SPACE ||
2863 expected_size > available_disk) {
2864 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
2865 modest_platform_information_banner (NULL, NULL, msg);
2872 * djcb: if we're in low-memory state, we only allow for
2873 * saving messages smaller than
2874 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2875 * should still allow for sending anything critical...
2877 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2878 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2882 * djcb: we also make sure that the attachments are smaller than the max size
2883 * this is for the case where we'd try to forward a message with attachments
2884 * bigger than our max allowed size, or sending an message from drafts which
2885 * somehow got past our checks when attaching.
2887 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2888 modest_platform_run_information_dialog (
2889 GTK_WINDOW(edit_window),
2890 _KR("memr_ib_operation_disabled"),
2899 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2901 TnyTransportAccount *transport_account;
2902 ModestMailOperation *mail_operation;
2904 gchar *account_name;
2905 ModestAccountMgr *account_mgr;
2906 gboolean had_error = FALSE;
2907 ModestMainWindow *win = NULL;
2909 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2911 data = modest_msg_edit_window_get_msg_data (edit_window);
2914 if (!enough_space_for_message (edit_window, data)) {
2915 modest_msg_edit_window_free_msg_data (edit_window, data);
2919 account_name = g_strdup (data->account_name);
2920 account_mgr = modest_runtime_get_account_mgr();
2922 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2924 account_name = modest_account_mgr_get_default_account (account_mgr);
2925 if (!account_name) {
2926 g_printerr ("modest: no account found\n");
2927 modest_msg_edit_window_free_msg_data (edit_window, data);
2931 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2932 account_name = g_strdup (data->account_name);
2936 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2937 (modest_runtime_get_account_store (),
2939 TNY_ACCOUNT_TYPE_TRANSPORT));
2940 if (!transport_account) {
2941 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2942 g_free (account_name);
2943 modest_msg_edit_window_free_msg_data (edit_window, data);
2947 /* Create the mail operation */
2948 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
2950 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2952 modest_mail_operation_save_to_drafts (mail_operation,
2964 data->priority_flags,
2967 on_save_to_drafts_cb,
2968 g_object_ref(edit_window));
2970 #ifdef MODEST_TOOLKIT_HILDON2
2971 /* In hildon2 we always show the information banner on saving to drafts.
2972 * It will be a system information banner in this case.
2974 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2975 modest_platform_information_banner (NULL, NULL, text);
2978 /* Use the main window as the parent of the banner, if the
2979 main window does not exist it won't be shown, if the parent
2980 window exists then it's properly shown. We don't use the
2981 editor window because it could be closed (save to drafts
2982 could happen after closing the window */
2983 win = (ModestMainWindow *)
2984 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
2986 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2987 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
2991 modest_msg_edit_window_set_modified (edit_window, FALSE);
2994 g_free (account_name);
2995 g_object_unref (G_OBJECT (transport_account));
2996 g_object_unref (G_OBJECT (mail_operation));
2998 modest_msg_edit_window_free_msg_data (edit_window, data);
3001 * If the drafts folder is selected then make the header view
3002 * insensitive while the message is being saved to drafts
3003 * (it'll be sensitive again in on_save_to_drafts_cb()). This
3004 * is not very clean but it avoids letting the drafts folder
3005 * in an inconsistent state: the user could edit the message
3006 * being saved and undesirable things would happen.
3007 * In the average case the user won't notice anything at
3008 * all. In the worst case (the user is editing a really big
3009 * file from Drafts) the header view will be insensitive
3010 * during the saving process (10 or 20 seconds, depending on
3011 * the message). Anyway this is just a quick workaround: once
3012 * we find a better solution it should be removed
3013 * See NB#65125 (commend #18) for details.
3015 if (!had_error && win != NULL) {
3016 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
3017 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
3019 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
3021 if (modest_tny_folder_is_local_folder(folder)) {
3022 TnyFolderType folder_type;
3023 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
3024 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
3025 GtkWidget *hdrview = modest_main_window_get_child_widget(
3026 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3027 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
3031 if (folder != NULL) g_object_unref(folder);
3038 /* For instance, when clicking the Send toolbar button when editing a message: */
3040 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3042 TnyTransportAccount *transport_account = NULL;
3043 gboolean had_error = FALSE;
3045 ModestAccountMgr *account_mgr;
3046 gchar *account_name;
3047 ModestMailOperation *mail_operation;
3049 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
3051 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
3054 data = modest_msg_edit_window_get_msg_data (edit_window);
3057 if (!enough_space_for_message (edit_window, data)) {
3058 modest_msg_edit_window_free_msg_data (edit_window, data);
3062 account_mgr = modest_runtime_get_account_mgr();
3063 account_name = g_strdup (data->account_name);
3065 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3068 account_name = modest_account_mgr_get_default_account (account_mgr);
3070 if (!account_name) {
3071 modest_msg_edit_window_free_msg_data (edit_window, data);
3072 /* Run account setup wizard */
3073 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
3078 /* Get the currently-active transport account for this modest account: */
3079 if (strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
3081 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3082 (modest_runtime_get_account_store (),
3083 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
3086 if (!transport_account) {
3087 modest_msg_edit_window_free_msg_data (edit_window, data);
3088 /* Run account setup wizard */
3089 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
3094 /* Create the mail operation */
3095 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
3096 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3098 modest_mail_operation_send_new_mail (mail_operation,
3112 data->priority_flags);
3114 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3115 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
3117 if (modest_mail_operation_get_error (mail_operation) != NULL) {
3118 const GError *error = modest_mail_operation_get_error (mail_operation);
3119 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3120 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3121 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3122 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3128 g_free (account_name);
3129 g_object_unref (G_OBJECT (transport_account));
3130 g_object_unref (G_OBJECT (mail_operation));
3132 modest_msg_edit_window_free_msg_data (edit_window, data);
3135 modest_msg_edit_window_set_sent (edit_window, TRUE);
3137 /* Save settings and close the window: */
3138 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3145 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3146 ModestMsgEditWindow *window)
3148 ModestMsgEditFormatState *format_state = NULL;
3150 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3151 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3153 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3156 format_state = modest_msg_edit_window_get_format_state (window);
3157 g_return_if_fail (format_state != NULL);
3159 format_state->bold = gtk_toggle_action_get_active (action);
3160 modest_msg_edit_window_set_format_state (window, format_state);
3161 g_free (format_state);
3166 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3167 ModestMsgEditWindow *window)
3169 ModestMsgEditFormatState *format_state = NULL;
3171 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3172 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3174 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3177 format_state = modest_msg_edit_window_get_format_state (window);
3178 g_return_if_fail (format_state != NULL);
3180 format_state->italics = gtk_toggle_action_get_active (action);
3181 modest_msg_edit_window_set_format_state (window, format_state);
3182 g_free (format_state);
3187 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3188 ModestMsgEditWindow *window)
3190 ModestMsgEditFormatState *format_state = NULL;
3192 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3193 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3195 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3198 format_state = modest_msg_edit_window_get_format_state (window);
3199 g_return_if_fail (format_state != NULL);
3201 format_state->bullet = gtk_toggle_action_get_active (action);
3202 modest_msg_edit_window_set_format_state (window, format_state);
3203 g_free (format_state);
3208 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3209 GtkRadioAction *selected,
3210 ModestMsgEditWindow *window)
3212 ModestMsgEditFormatState *format_state = NULL;
3213 GtkJustification value;
3215 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3217 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3220 value = gtk_radio_action_get_current_value (selected);
3222 format_state = modest_msg_edit_window_get_format_state (window);
3223 g_return_if_fail (format_state != NULL);
3225 format_state->justification = value;
3226 modest_msg_edit_window_set_format_state (window, format_state);
3227 g_free (format_state);
3231 modest_ui_actions_on_select_editor_color (GtkAction *action,
3232 ModestMsgEditWindow *window)
3234 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3235 g_return_if_fail (GTK_IS_ACTION (action));
3237 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3240 modest_msg_edit_window_select_color (window);
3244 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3245 ModestMsgEditWindow *window)
3247 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3248 g_return_if_fail (GTK_IS_ACTION (action));
3250 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3253 modest_msg_edit_window_select_background_color (window);
3257 modest_ui_actions_on_insert_image (GObject *object,
3258 ModestMsgEditWindow *window)
3260 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3263 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3266 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3269 modest_msg_edit_window_insert_image (window);
3273 modest_ui_actions_on_attach_file (GtkAction *action,
3274 ModestMsgEditWindow *window)
3276 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3277 g_return_if_fail (GTK_IS_ACTION (action));
3279 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3282 modest_msg_edit_window_offer_attach_file (window);
3286 modest_ui_actions_on_remove_attachments (GtkAction *action,
3287 ModestMsgEditWindow *window)
3289 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3291 modest_msg_edit_window_remove_attachments (window, NULL);
3295 do_create_folder_cb (ModestMailOperation *mail_op,
3296 TnyFolderStore *parent_folder,
3297 TnyFolder *new_folder,
3300 gchar *suggested_name = (gchar *) user_data;
3301 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3302 const GError *error;
3304 error = modest_mail_operation_get_error (mail_op);
3307 /* Show an error. If there was some problem writing to
3308 disk, show it, otherwise show the generic folder
3309 create error. We do it here and not in an error
3310 handler because the call to do_create_folder will
3311 stop the main loop in a gtk_dialog_run and then,
3312 the message won't be shown until that dialog is
3314 modest_ui_actions_disk_operations_error_handler (mail_op,
3315 _("mail_in_ui_folder_create_error"));
3317 if (!is_memory_full_error ((GError *) error, mail_op)) {
3318 /* Try again if there is no full memory condition */
3319 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3322 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3323 * FIXME: any other? */
3324 GtkWidget *folder_view;
3326 if (MODEST_IS_MAIN_WINDOW(source_win))
3328 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3329 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3331 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3332 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3334 /* Select the newly created folder. It could happen
3335 that the widget is no longer there (i.e. the window
3336 has been destroyed, so we need to check this */
3338 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3340 g_object_unref (new_folder);
3342 /* Free. Note that the first time it'll be NULL so noop */
3343 g_free (suggested_name);
3344 g_object_unref (source_win);
3349 TnyFolderStore *parent;
3350 } CreateFolderConnect;
3353 do_create_folder_performer (gboolean canceled,
3355 GtkWindow *parent_window,
3356 TnyAccount *account,
3359 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3360 ModestMailOperation *mail_op;
3362 if (canceled || err) {
3363 /* In memory full conditions we could get this error here */
3364 check_memory_full_error ((GtkWidget *) parent_window, err);
3366 /* This happens if we have selected the outbox folder
3368 if (err->code == TNY_SERVICE_ERROR_UNKNOWN &&
3369 TNY_IS_MERGE_FOLDER (helper->parent)) {
3370 /* Show an error and retry */
3371 modest_platform_information_banner ((GtkWidget *) parent_window,
3373 _("mail_in_ui_folder_create_error"));
3375 do_create_folder (parent_window, helper->parent, helper->folder_name);
3381 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3382 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3384 modest_mail_operation_create_folder (mail_op,
3386 (const gchar *) helper->folder_name,
3387 do_create_folder_cb,
3388 g_strdup (helper->folder_name));
3389 g_object_unref (mail_op);
3393 g_object_unref (helper->parent);
3394 if (helper->folder_name)
3395 g_free (helper->folder_name);
3396 g_slice_free (CreateFolderConnect, helper);
3401 do_create_folder (GtkWindow *parent_window,
3402 TnyFolderStore *suggested_parent,
3403 const gchar *suggested_name)
3406 gchar *folder_name = NULL;
3407 TnyFolderStore *parent_folder = NULL;
3409 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3411 (gchar *) suggested_name,
3415 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3416 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3417 helper->folder_name = g_strdup (folder_name);
3418 helper->parent = g_object_ref (parent_folder);
3420 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3423 do_create_folder_performer,
3428 g_free (folder_name);
3430 g_object_unref (parent_folder);
3434 modest_ui_actions_create_folder(GtkWidget *parent_window,
3435 GtkWidget *folder_view,
3436 TnyFolderStore *parent_folder)
3438 if (!parent_folder) {
3439 #ifdef MODEST_TOOLKIT_HILDON2
3440 ModestTnyAccountStore *acc_store;
3442 acc_store = modest_runtime_get_account_store ();
3444 parent_folder = (TnyFolderStore *)
3445 modest_tny_account_store_get_local_folders_account (acc_store);
3447 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3451 if (parent_folder) {
3452 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3453 g_object_unref (parent_folder);
3458 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3461 g_return_if_fail (MODEST_IS_WINDOW(window));
3463 if (MODEST_IS_MAIN_WINDOW (window)) {
3464 GtkWidget *folder_view;
3466 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3467 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3471 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3472 #ifdef MODEST_TOOLKIT_HILDON2
3473 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3474 GtkWidget *folder_view;
3476 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3477 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3480 g_assert_not_reached ();
3485 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3488 const GError *error = NULL;
3489 gchar *message = NULL;
3492 /* Get error message */
3493 error = modest_mail_operation_get_error (mail_op);
3495 g_return_if_reached ();
3497 mem_full = is_memory_full_error ((GError *) error, mail_op);
3499 message = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3500 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3501 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3502 message = _CS("ckdg_ib_folder_already_exists");
3503 } else if (error->domain == TNY_ERROR_DOMAIN &&
3504 error->code == TNY_SERVICE_ERROR_STATE) {
3505 /* This means that the folder is already in use (a
3506 message is opened for example */
3507 message = _("emev_ni_internal_error");
3509 message = _CS("ckdg_ib_unable_to_rename");
3512 /* We don't set a parent for the dialog because the dialog
3513 will be destroyed so the banner won't appear */
3514 modest_platform_information_banner (NULL, NULL, message);
3521 TnyFolderStore *folder;
3526 on_rename_folder_cb (ModestMailOperation *mail_op,
3527 TnyFolder *new_folder,
3530 ModestFolderView *folder_view;
3532 /* If the window was closed when renaming a folder, or if
3533 * it's not a main window this will happen */
3534 if (!MODEST_IS_FOLDER_VIEW (user_data))
3537 folder_view = MODEST_FOLDER_VIEW (user_data);
3538 /* Note that if the rename fails new_folder will be NULL */
3540 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3542 modest_folder_view_select_first_inbox_or_local (folder_view);
3544 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3548 on_rename_folder_performer (gboolean canceled,
3550 GtkWindow *parent_window,
3551 TnyAccount *account,
3554 ModestMailOperation *mail_op = NULL;
3555 GtkTreeSelection *sel = NULL;
3556 GtkWidget *folder_view = NULL;
3557 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3559 if (canceled || err) {
3560 /* In memory full conditions we could get this error here */
3561 check_memory_full_error ((GtkWidget *) parent_window, err);
3565 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3566 modest_ui_actions_rename_folder_error_handler,
3567 parent_window, NULL);
3569 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3572 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3574 folder_view = modest_main_window_get_child_widget (
3575 MODEST_MAIN_WINDOW (parent_window),
3576 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3578 #ifdef MODEST_TOOLKIT_HILDON2
3579 else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3580 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3581 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3585 /* Clear the folders view */
3586 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3587 gtk_tree_selection_unselect_all (sel);
3589 /* Actually rename the folder */
3590 modest_mail_operation_rename_folder (mail_op,
3591 TNY_FOLDER (data->folder),
3592 (const gchar *) (data->new_name),
3593 on_rename_folder_cb,
3595 g_object_unref (mail_op);
3598 g_object_unref (data->folder);
3599 g_free (data->new_name);
3604 modest_ui_actions_on_rename_folder (GtkAction *action,
3605 ModestWindow *window)
3607 modest_ui_actions_on_edit_mode_rename_folder (window);
3611 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3613 TnyFolderStore *folder;
3614 GtkWidget *folder_view;
3615 gboolean do_rename = TRUE;
3617 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3619 if (MODEST_IS_MAIN_WINDOW (window)) {
3620 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3621 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3625 #ifdef MODEST_TOOLKIT_HILDON2
3626 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3627 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3633 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3638 if (TNY_IS_FOLDER (folder)) {
3639 gchar *folder_name = NULL;
3641 const gchar *current_name;
3642 TnyFolderStore *parent;
3644 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3645 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3646 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
3647 parent, current_name,
3649 g_object_unref (parent);
3651 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3654 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3655 rename_folder_data->folder = g_object_ref (folder);
3656 rename_folder_data->new_name = folder_name;
3657 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
3658 folder, on_rename_folder_performer, rename_folder_data);
3661 g_object_unref (folder);
3666 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3669 GObject *win = modest_mail_operation_get_source (mail_op);
3671 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3672 _("mail_in_ui_folder_delete_error"),
3674 g_object_unref (win);
3678 TnyFolderStore *folder;
3679 gboolean move_to_trash;
3683 on_delete_folder_cb (gboolean canceled,
3685 GtkWindow *parent_window,
3686 TnyAccount *account,
3689 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3690 GtkWidget *folder_view;
3691 ModestMailOperation *mail_op;
3692 GtkTreeSelection *sel;
3694 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
3695 g_object_unref (G_OBJECT (info->folder));
3700 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
3701 folder_view = modest_main_window_get_child_widget (
3702 MODEST_MAIN_WINDOW (parent_window),
3703 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3704 #ifdef MODEST_TOOLKIT_HILDON2
3705 } else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3706 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
3709 g_object_unref (G_OBJECT (info->folder));
3714 /* Unselect the folder before deleting it to free the headers */
3715 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3716 gtk_tree_selection_unselect_all (sel);
3718 /* Create the mail operation */
3720 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3721 modest_ui_actions_delete_folder_error_handler,
3724 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3726 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3728 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3730 g_object_unref (G_OBJECT (mail_op));
3731 g_object_unref (G_OBJECT (info->folder));
3736 delete_folder (ModestWindow *window, gboolean move_to_trash)
3738 TnyFolderStore *folder;
3739 GtkWidget *folder_view;
3743 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3745 if (MODEST_IS_MAIN_WINDOW (window)) {
3747 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3748 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3749 #ifdef MODEST_TOOLKIT_HILDON2
3750 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3751 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3759 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3764 /* Show an error if it's an account */
3765 if (!TNY_IS_FOLDER (folder)) {
3766 modest_platform_run_information_dialog (GTK_WINDOW (window),
3767 _("mail_in_ui_folder_delete_error"),
3769 g_object_unref (G_OBJECT (folder));
3774 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3775 tny_folder_get_name (TNY_FOLDER (folder)));
3776 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
3777 (const gchar *) message);
3780 if (response == GTK_RESPONSE_OK) {
3781 DeleteFolderInfo *info;
3782 info = g_new0(DeleteFolderInfo, 1);
3783 info->folder = folder;
3784 info->move_to_trash = move_to_trash;
3785 g_object_ref (G_OBJECT (info->folder));
3786 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder));
3787 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
3789 TNY_FOLDER_STORE (account),
3790 on_delete_folder_cb, info);
3791 g_object_unref (account);
3796 g_object_unref (G_OBJECT (folder));
3800 modest_ui_actions_on_delete_folder (GtkAction *action,
3801 ModestWindow *window)
3803 modest_ui_actions_on_edit_mode_delete_folder (window);
3807 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
3809 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
3811 return delete_folder (window, FALSE);
3815 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3817 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3819 delete_folder (MODEST_WINDOW (main_window), TRUE);
3823 typedef struct _PasswordDialogFields {
3824 GtkWidget *username;
3825 GtkWidget *password;
3827 } PasswordDialogFields;
3830 password_dialog_check_field (GtkEditable *editable,
3831 PasswordDialogFields *fields)
3834 gboolean any_value_empty = FALSE;
3836 #ifdef MODEST_TOOLKIT_HILDON2
3837 value = hildon_entry_get_text (HILDON_ENTRY (fields->username));
3839 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
3841 if ((value == NULL) || value[0] == '\0') {
3842 any_value_empty = TRUE;
3844 #ifdef MODEST_TOOLKIT_HILDON2
3845 value = hildon_entry_get_text (HILDON_ENTRY (fields->password));
3847 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
3849 if ((value == NULL) || value[0] == '\0') {
3850 any_value_empty = TRUE;
3852 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3856 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3857 const gchar* server_account_name,
3862 ModestMainWindow *main_window)
3864 g_return_if_fail(server_account_name);
3865 gboolean completed = FALSE;
3866 PasswordDialogFields *fields = NULL;
3868 /* Initalize output parameters: */
3875 #ifndef MODEST_TOOLKIT_GTK
3876 /* Maemo uses a different (awkward) button order,
3877 * It should probably just use gtk_alternative_dialog_button_order ().
3879 #ifdef MODEST_TOOLKIT_HILDON2
3881 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3884 _HL("wdgt_bd_done"),
3885 GTK_RESPONSE_ACCEPT,
3887 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
3888 HILDON_MARGIN_DOUBLE);
3891 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3894 _("mcen_bd_dialog_ok"),
3895 GTK_RESPONSE_ACCEPT,
3896 _("mcen_bd_dialog_cancel"),
3897 GTK_RESPONSE_REJECT,
3899 #endif /* MODEST_TOOLKIT_HILDON2 */
3902 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3906 GTK_RESPONSE_REJECT,
3908 GTK_RESPONSE_ACCEPT,
3910 #endif /* MODEST_TOOLKIT_GTK */
3912 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3914 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3915 modest_runtime_get_account_mgr(), server_account_name);
3916 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3917 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3920 gtk_widget_destroy (dialog);
3924 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3925 GtkWidget *label = gtk_label_new (txt);
3926 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
3928 g_free (server_name);
3929 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
3934 gchar *initial_username = modest_account_mgr_get_server_account_username (
3935 modest_runtime_get_account_mgr(), server_account_name);
3937 #ifdef MODEST_TOOLKIT_HILDON2
3938 GtkWidget *entry_username = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
3939 if (initial_username)
3940 hildon_entry_set_text (HILDON_ENTRY (entry_username), initial_username);
3942 GtkWidget *entry_username = gtk_entry_new ();
3943 if (initial_username)
3944 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
3946 /* Dim this if a connection has ever succeeded with this username,
3947 * as per the UI spec: */
3948 /* const gboolean username_known = */
3949 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3950 /* modest_runtime_get_account_mgr(), server_account_name); */
3951 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3953 /* We drop the username sensitive code and disallow changing it here
3954 * as tinymail does not support really changing the username in the callback
3956 gtk_widget_set_sensitive (entry_username, FALSE);
3958 #ifndef MODEST_TOOLKIT_GTK
3959 /* Auto-capitalization is the default, so let's turn it off: */
3960 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3962 /* Create a size group to be used by all captions.
3963 * Note that HildonCaption does not create a default size group if we do not specify one.
3964 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3965 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3967 #ifdef MODEST_TOOLKIT_HILDON2
3968 GtkWidget *caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
3969 _("mail_fi_username"), FALSE,
3972 GtkWidget *caption = hildon_caption_new (sizegroup,
3973 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
3975 gtk_widget_show (entry_username);
3976 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3977 FALSE, FALSE, MODEST_MARGIN_HALF);
3978 gtk_widget_show (caption);
3980 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
3982 #endif /* !MODEST_TOOLKIT_GTK */
3985 #ifdef MODEST_TOOLKIT_HILDON2
3986 GtkWidget *entry_password = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
3988 GtkWidget *entry_password = gtk_entry_new ();
3990 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3991 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3993 #ifndef MODEST_TOOLKIT_GTK
3994 /* Auto-capitalization is the default, so let's turn it off: */
3995 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3996 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3998 #ifdef MODEST_TOOLKIT_HILDON2
3999 caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4000 _("mail_fi_password"), FALSE,
4003 caption = hildon_caption_new (sizegroup,
4004 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
4006 gtk_widget_show (entry_password);
4007 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4008 FALSE, FALSE, MODEST_MARGIN_HALF);
4009 gtk_widget_show (caption);
4010 g_object_unref (sizegroup);
4012 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
4014 #endif /* !MODEST_TOOLKIT_GTK */
4016 if (initial_username != NULL)
4017 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
4019 /* This is not in the Maemo UI spec:
4020 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
4021 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
4025 fields = g_slice_new0 (PasswordDialogFields);
4026 fields->username = entry_username;
4027 fields->password = entry_password;
4028 fields->dialog = dialog;
4030 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
4031 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
4032 password_dialog_check_field (NULL, fields);
4034 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4036 while (!completed) {
4038 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
4040 #ifdef MODEST_TOOLKIT_HILDON2
4041 *username = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_username)));
4043 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
4046 /* Note that an empty field becomes the "" string */
4047 if (*username && strlen (*username) > 0) {
4048 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
4049 server_account_name,
4053 const gboolean username_was_changed =
4054 (strcmp (*username, initial_username) != 0);
4055 if (username_was_changed) {
4056 g_warning ("%s: tinymail does not yet support changing the "
4057 "username in the get_password() callback.\n", __FUNCTION__);
4063 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
4064 _("mcen_ib_username_pw_incorrect"));
4070 #ifdef MODEST_TOOLKIT_HILDON2
4071 *password = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_password)));
4073 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
4076 /* We do not save the password in the configuration,
4077 * because this function is only called for passwords that should
4078 * not be remembered:
4079 modest_server_account_set_password (
4080 modest_runtime_get_account_mgr(), server_account_name,
4087 #ifndef MODEST_TOOLKIT_HILDON2
4088 /* Set parent to NULL or the banner will disappear with its parent dialog */
4089 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
4101 /* This is not in the Maemo UI spec:
4102 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
4108 g_free (initial_username);
4109 gtk_widget_destroy (dialog);
4110 g_slice_free (PasswordDialogFields, fields);
4112 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
4116 modest_ui_actions_on_cut (GtkAction *action,
4117 ModestWindow *window)
4119 GtkWidget *focused_widget;
4120 GtkClipboard *clipboard;
4122 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4123 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4124 if (GTK_IS_EDITABLE (focused_widget)) {
4125 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
4126 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4127 gtk_clipboard_store (clipboard);
4128 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4129 GtkTextBuffer *buffer;
4131 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4132 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4133 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
4134 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4135 gtk_clipboard_store (clipboard);
4137 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4138 TnyList *header_list = modest_header_view_get_selected_headers (
4139 MODEST_HEADER_VIEW (focused_widget));
4140 gboolean continue_download = FALSE;
4141 gint num_of_unc_msgs;
4143 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4145 if (num_of_unc_msgs) {
4146 TnyAccount *account = get_account_from_header_list (header_list);
4148 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4149 g_object_unref (account);
4153 if (num_of_unc_msgs == 0 || continue_download) {
4154 /* modest_platform_information_banner (
4155 NULL, NULL, _CS("mcen_ib_getting_items"));*/
4156 modest_header_view_cut_selection (
4157 MODEST_HEADER_VIEW (focused_widget));
4160 g_object_unref (header_list);
4161 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4162 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4167 modest_ui_actions_on_copy (GtkAction *action,
4168 ModestWindow *window)
4170 GtkClipboard *clipboard;
4171 GtkWidget *focused_widget;
4172 gboolean copied = TRUE;
4174 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4175 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4177 if (GTK_IS_LABEL (focused_widget)) {
4179 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4180 gtk_clipboard_set_text (clipboard, selection, -1);
4182 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4183 gtk_clipboard_store (clipboard);
4184 } else if (GTK_IS_EDITABLE (focused_widget)) {
4185 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4186 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4187 gtk_clipboard_store (clipboard);
4188 } else if (GTK_IS_HTML (focused_widget)) {
4191 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4192 if ((sel == NULL) || (sel[0] == '\0')) {
4195 gtk_html_copy (GTK_HTML (focused_widget));
4196 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4197 gtk_clipboard_store (clipboard);
4199 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4200 GtkTextBuffer *buffer;
4201 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4202 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4203 gtk_text_buffer_copy_clipboard (buffer, clipboard);
4204 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4205 gtk_clipboard_store (clipboard);
4207 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4208 TnyList *header_list = modest_header_view_get_selected_headers (
4209 MODEST_HEADER_VIEW (focused_widget));
4210 gboolean continue_download = FALSE;
4211 gint num_of_unc_msgs;
4213 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4215 if (num_of_unc_msgs) {
4216 TnyAccount *account = get_account_from_header_list (header_list);
4218 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4219 g_object_unref (account);
4223 if (num_of_unc_msgs == 0 || continue_download) {
4224 modest_platform_information_banner (
4225 NULL, NULL, _CS("mcen_ib_getting_items"));
4226 modest_header_view_copy_selection (
4227 MODEST_HEADER_VIEW (focused_widget));
4231 g_object_unref (header_list);
4233 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4234 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4237 /* Show information banner if there was a copy to clipboard */
4239 modest_platform_information_banner (
4240 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4244 modest_ui_actions_on_undo (GtkAction *action,
4245 ModestWindow *window)
4247 ModestEmailClipboard *clipboard = NULL;
4249 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4250 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4251 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4252 /* Clear clipboard source */
4253 clipboard = modest_runtime_get_email_clipboard ();
4254 modest_email_clipboard_clear (clipboard);
4257 g_return_if_reached ();
4262 modest_ui_actions_on_redo (GtkAction *action,
4263 ModestWindow *window)
4265 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4266 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4269 g_return_if_reached ();
4275 destroy_information_note (ModestMailOperation *mail_op,
4278 /* destroy information note */
4279 gtk_widget_destroy (GTK_WIDGET(user_data));
4283 destroy_folder_information_note (ModestMailOperation *mail_op,
4284 TnyFolder *new_folder,
4287 /* destroy information note */
4288 gtk_widget_destroy (GTK_WIDGET(user_data));
4293 paste_as_attachment_free (gpointer data)
4295 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4297 if (helper->banner) {
4298 gtk_widget_destroy (helper->banner);
4299 g_object_unref (helper->banner);
4305 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4310 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4311 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4316 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4321 modest_ui_actions_on_paste (GtkAction *action,
4322 ModestWindow *window)
4324 GtkWidget *focused_widget = NULL;
4325 GtkWidget *inf_note = NULL;
4326 ModestMailOperation *mail_op = NULL;
4328 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4329 if (GTK_IS_EDITABLE (focused_widget)) {
4330 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4331 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4332 ModestEmailClipboard *e_clipboard = NULL;
4333 e_clipboard = modest_runtime_get_email_clipboard ();
4334 if (modest_email_clipboard_cleared (e_clipboard)) {
4335 GtkTextBuffer *buffer;
4336 GtkClipboard *clipboard;
4338 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4339 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4340 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4341 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4342 ModestMailOperation *mail_op;
4343 TnyFolder *src_folder = NULL;
4344 TnyList *data = NULL;
4346 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4347 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4348 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4349 _CS("ckct_nw_pasting"));
4350 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4351 mail_op = modest_mail_operation_new (G_OBJECT (window));
4352 if (helper->banner != NULL) {
4353 g_object_ref (G_OBJECT (helper->banner));
4354 gtk_widget_show (GTK_WIDGET (helper->banner));
4358 modest_mail_operation_get_msgs_full (mail_op,
4360 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4362 paste_as_attachment_free);
4366 g_object_unref (data);
4368 g_object_unref (src_folder);
4371 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4372 ModestEmailClipboard *clipboard = NULL;
4373 TnyFolder *src_folder = NULL;
4374 TnyFolderStore *folder_store = NULL;
4375 TnyList *data = NULL;
4376 gboolean delete = FALSE;
4378 /* Check clipboard source */
4379 clipboard = modest_runtime_get_email_clipboard ();
4380 if (modest_email_clipboard_cleared (clipboard))
4383 /* Get elements to paste */
4384 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4386 /* Create a new mail operation */
4387 mail_op = modest_mail_operation_new (G_OBJECT(window));
4389 /* Get destination folder */
4390 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4392 /* transfer messages */
4396 /* Ask for user confirmation */
4398 modest_ui_actions_msgs_move_to_confirmation (window,
4399 TNY_FOLDER (folder_store),
4403 if (response == GTK_RESPONSE_OK) {
4404 /* Launch notification */
4405 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4406 _CS("ckct_nw_pasting"));
4407 if (inf_note != NULL) {
4408 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4409 gtk_widget_show (GTK_WIDGET(inf_note));
4412 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4413 modest_mail_operation_xfer_msgs (mail_op,
4415 TNY_FOLDER (folder_store),
4417 destroy_information_note,
4420 g_object_unref (mail_op);
4423 } else if (src_folder != NULL) {
4424 /* Launch notification */
4425 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4426 _CS("ckct_nw_pasting"));
4427 if (inf_note != NULL) {
4428 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4429 gtk_widget_show (GTK_WIDGET(inf_note));
4432 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4433 modest_mail_operation_xfer_folder (mail_op,
4437 destroy_folder_information_note,
4443 g_object_unref (data);
4444 if (src_folder != NULL)
4445 g_object_unref (src_folder);
4446 if (folder_store != NULL)
4447 g_object_unref (folder_store);
4453 modest_ui_actions_on_select_all (GtkAction *action,
4454 ModestWindow *window)
4456 GtkWidget *focused_widget;
4458 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4459 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4460 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4461 } else if (GTK_IS_LABEL (focused_widget)) {
4462 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4463 } else if (GTK_IS_EDITABLE (focused_widget)) {
4464 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4465 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4466 GtkTextBuffer *buffer;
4467 GtkTextIter start, end;
4469 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4470 gtk_text_buffer_get_start_iter (buffer, &start);
4471 gtk_text_buffer_get_end_iter (buffer, &end);
4472 gtk_text_buffer_select_range (buffer, &start, &end);
4473 } else if (GTK_IS_HTML (focused_widget)) {
4474 gtk_html_select_all (GTK_HTML (focused_widget));
4475 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4476 GtkWidget *header_view = focused_widget;
4477 GtkTreeSelection *selection = NULL;
4479 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4480 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4481 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4484 /* Disable window dimming management */
4485 modest_window_disable_dimming (MODEST_WINDOW(window));
4487 /* Select all messages */
4488 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4489 gtk_tree_selection_select_all (selection);
4491 /* Set focuse on header view */
4492 gtk_widget_grab_focus (header_view);
4494 /* Enable window dimming management */
4495 modest_window_enable_dimming (MODEST_WINDOW(window));
4496 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4497 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4503 modest_ui_actions_on_mark_as_read (GtkAction *action,
4504 ModestWindow *window)
4506 g_return_if_fail (MODEST_IS_WINDOW(window));
4508 /* Mark each header as read */
4509 do_headers_action (window, headers_action_mark_as_read, NULL);
4513 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4514 ModestWindow *window)
4516 g_return_if_fail (MODEST_IS_WINDOW(window));
4518 /* Mark each header as read */
4519 do_headers_action (window, headers_action_mark_as_unread, NULL);
4523 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4524 GtkRadioAction *selected,
4525 ModestWindow *window)
4529 value = gtk_radio_action_get_current_value (selected);
4530 if (MODEST_IS_WINDOW (window)) {
4531 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4536 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4537 GtkRadioAction *selected,
4538 ModestWindow *window)
4540 TnyHeaderFlags flags;
4541 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4543 flags = gtk_radio_action_get_current_value (selected);
4544 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4548 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4549 GtkRadioAction *selected,
4550 ModestWindow *window)
4554 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4556 file_format = gtk_radio_action_get_current_value (selected);
4557 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4562 modest_ui_actions_on_zoom_plus (GtkAction *action,
4563 ModestWindow *window)
4565 g_return_if_fail (MODEST_IS_WINDOW (window));
4567 modest_window_zoom_plus (MODEST_WINDOW (window));
4571 modest_ui_actions_on_zoom_minus (GtkAction *action,
4572 ModestWindow *window)
4574 g_return_if_fail (MODEST_IS_WINDOW (window));
4576 modest_window_zoom_minus (MODEST_WINDOW (window));
4580 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4581 ModestWindow *window)
4583 ModestWindowMgr *mgr;
4584 gboolean fullscreen, active;
4585 g_return_if_fail (MODEST_IS_WINDOW (window));
4587 mgr = modest_runtime_get_window_mgr ();
4589 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4590 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4592 if (active != fullscreen) {
4593 modest_window_mgr_set_fullscreen_mode (mgr, active);
4594 #ifndef MODEST_TOOLKIT_HILDON2
4595 gtk_window_present (GTK_WINDOW (window));
4601 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4602 ModestWindow *window)
4604 ModestWindowMgr *mgr;
4605 gboolean fullscreen;
4607 g_return_if_fail (MODEST_IS_WINDOW (window));
4609 mgr = modest_runtime_get_window_mgr ();
4610 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4611 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4613 #ifndef MODEST_TOOLKIT_HILDON2
4614 gtk_window_present (GTK_WINDOW (window));
4619 * Used by modest_ui_actions_on_details to call do_headers_action
4622 headers_action_show_details (TnyHeader *header,
4623 ModestWindow *window,
4627 gboolean async_retrieval;
4630 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4631 async_retrieval = TRUE;
4632 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
4634 async_retrieval = FALSE;
4636 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header, async_retrieval, msg);
4638 g_object_unref (msg);
4642 * Show the header details in a ModestDetailsDialog widget
4645 modest_ui_actions_on_details (GtkAction *action,
4648 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4652 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4656 header = tny_msg_get_header (msg);
4658 headers_action_show_details (header, win, NULL);
4659 g_object_unref (header);
4661 g_object_unref (msg);
4663 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4664 GtkWidget *folder_view, *header_view;
4666 /* Check which widget has the focus */
4667 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4668 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4669 if (gtk_widget_is_focus (folder_view)) {
4670 TnyFolderStore *folder_store
4671 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4672 if (!folder_store) {
4673 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4676 /* Show only when it's a folder */
4677 /* This function should not be called for account items,
4678 * because we dim the menu item for them. */
4679 if (TNY_IS_FOLDER (folder_store)) {
4680 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4681 TNY_FOLDER (folder_store));
4684 g_object_unref (folder_store);
4687 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4688 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4689 /* Show details of each header */
4690 do_headers_action (win, headers_action_show_details, header_view);
4692 #ifdef MODEST_TOOLKIT_HILDON2
4693 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4695 GtkWidget *header_view;
4697 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4698 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4700 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4702 g_object_unref (folder);
4709 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4710 ModestMsgEditWindow *window)
4712 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4714 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4718 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4719 ModestMsgEditWindow *window)
4721 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4723 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4727 modest_ui_actions_toggle_folders_view (GtkAction *action,
4728 ModestMainWindow *main_window)
4730 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4732 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4733 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4735 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4739 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4740 ModestWindow *window)
4742 gboolean active, fullscreen = FALSE;
4743 ModestWindowMgr *mgr;
4745 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4747 /* Check if we want to toggle the toolbar view in fullscreen
4749 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4750 "ViewShowToolbarFullScreen")) {
4754 /* Toggle toolbar */
4755 mgr = modest_runtime_get_window_mgr ();
4756 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4760 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4761 ModestMsgEditWindow *window)
4763 modest_msg_edit_window_select_font (window);
4768 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4769 const gchar *display_name,
4772 /* don't update the display name if it was already set;
4773 * updating the display name apparently is expensive */
4774 const gchar* old_name = gtk_window_get_title (window);
4776 if (display_name == NULL)
4779 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4780 return; /* don't do anything */
4782 /* This is usually used to change the title of the main window, which
4783 * is the one that holds the folder view. Note that this change can
4784 * happen even when the widget doesn't have the focus. */
4785 gtk_window_set_title (window, display_name);
4790 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4792 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4793 modest_msg_edit_window_select_contacts (window);
4797 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4799 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4800 modest_msg_edit_window_check_names (window, FALSE);
4803 #ifndef MODEST_TOOLKIT_HILDON2
4805 * This function is used to track changes in the selection of the
4806 * folder view that is inside the "move to" dialog to enable/disable
4807 * the OK button because we do not want the user to select a disallowed
4808 * destination for a folder.
4809 * The user also not desired to be able to use NEW button on items where
4810 * folder creation is not possibel.
4813 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4814 TnyFolderStore *folder_store,
4818 GtkWidget *dialog = NULL;
4819 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4820 gboolean moving_folder = FALSE;
4821 gboolean is_local_account = TRUE;
4822 GtkWidget *folder_view = NULL;
4823 ModestTnyFolderRules rules;
4825 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
4830 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
4834 /* check if folder_store is an remote account */
4835 if (TNY_IS_ACCOUNT (folder_store)) {
4836 TnyAccount *local_account = NULL;
4837 TnyAccount *mmc_account = NULL;
4838 ModestTnyAccountStore *account_store = NULL;
4840 account_store = modest_runtime_get_account_store ();
4841 local_account = modest_tny_account_store_get_local_folders_account (account_store);
4842 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
4844 if ((gpointer) local_account != (gpointer) folder_store &&
4845 (gpointer) mmc_account != (gpointer) folder_store) {
4846 ModestProtocolType proto;
4847 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
4848 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
4849 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
4851 is_local_account = FALSE;
4852 /* New button should be dimmed on remote
4854 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4856 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
4858 g_object_unref (local_account);
4860 /* It could not exist */
4862 g_object_unref (mmc_account);
4865 /* Check the target folder rules */
4866 if (TNY_IS_FOLDER (folder_store)) {
4867 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
4868 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
4869 ok_sensitive = FALSE;
4870 new_sensitive = FALSE;
4875 /* Check if we're moving a folder */
4876 if (MODEST_IS_MAIN_WINDOW (user_data)) {
4877 /* Get the widgets */
4878 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
4879 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4880 if (gtk_widget_is_focus (folder_view))
4881 moving_folder = TRUE;
4884 if (moving_folder) {
4885 TnyFolderStore *moved_folder = NULL, *parent = NULL;
4887 /* Get the folder to move */
4888 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4890 /* Check that we're not moving to the same folder */
4891 if (TNY_IS_FOLDER (moved_folder)) {
4892 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
4893 if (parent == folder_store)
4894 ok_sensitive = FALSE;
4895 g_object_unref (parent);
4898 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
4899 /* Do not allow to move to an account unless it's the
4900 local folders account */
4901 if (!is_local_account)
4902 ok_sensitive = FALSE;
4905 if (ok_sensitive && (moved_folder == folder_store)) {
4906 /* Do not allow to move to itself */
4907 ok_sensitive = FALSE;
4909 g_object_unref (moved_folder);
4911 TnyFolder *src_folder = NULL;
4913 /* Moving a message */
4914 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
4916 TnyHeader *header = NULL;
4917 header = modest_msg_view_window_get_header
4918 (MODEST_MSG_VIEW_WINDOW (user_data));
4919 if (!TNY_IS_HEADER(header))
4920 g_warning ("%s: could not get source header", __FUNCTION__);
4922 src_folder = tny_header_get_folder (header);
4925 g_object_unref (header);
4928 TNY_FOLDER (modest_folder_view_get_selected
4929 (MODEST_FOLDER_VIEW (folder_view)));
4932 if (TNY_IS_FOLDER(src_folder)) {
4933 /* Do not allow to move the msg to the same folder */
4934 /* Do not allow to move the msg to an account */
4935 if ((gpointer) src_folder == (gpointer) folder_store ||
4936 TNY_IS_ACCOUNT (folder_store))
4937 ok_sensitive = FALSE;
4938 g_object_unref (src_folder);
4940 g_warning ("%s: could not get source folder", __FUNCTION__);
4944 /* Set sensitivity of the OK and NEW button */
4945 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
4946 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
4951 on_move_to_dialog_response (GtkDialog *dialog,
4955 GtkWidget *parent_win;
4956 MoveToInfo *helper = NULL;
4957 ModestFolderView *folder_view;
4959 helper = (MoveToInfo *) user_data;
4961 parent_win = (GtkWidget *) helper->win;
4962 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
4963 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4966 TnyFolderStore *dst_folder;
4967 TnyFolderStore *selected;
4969 case MODEST_GTK_RESPONSE_NEW_FOLDER:
4970 selected = modest_folder_view_get_selected (folder_view);
4971 modest_ui_actions_create_folder (GTK_WIDGET (dialog), GTK_WIDGET (folder_view), selected);
4972 g_object_unref (selected);
4974 case GTK_RESPONSE_NONE:
4975 case GTK_RESPONSE_CANCEL:
4976 case GTK_RESPONSE_DELETE_EVENT:
4978 case GTK_RESPONSE_OK:
4979 dst_folder = modest_folder_view_get_selected (folder_view);
4981 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
4982 /* Clean list to move used for filtering */
4983 modest_folder_view_set_list_to_move (folder_view, NULL);
4985 modest_ui_actions_on_main_window_move_to (NULL,
4986 GTK_WIDGET (folder_view),
4988 MODEST_MAIN_WINDOW (parent_win));
4989 #ifdef MODEST_TOOLKIT_HILDON2
4990 } else if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
4991 /* Clean list to move used for filtering */
4992 modest_folder_view_set_list_to_move (folder_view, NULL);
4994 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
4997 GTK_WINDOW (parent_win));
5000 /* if the user selected a root folder
5001 (account) then do not perform any action */
5002 if (TNY_IS_ACCOUNT (dst_folder)) {
5003 g_signal_stop_emission_by_name (dialog, "response");
5007 /* Clean list to move used for filtering */
5008 modest_folder_view_set_list_to_move (folder_view, NULL);
5010 /* Moving from headers window in edit mode */
5011 modest_ui_actions_on_window_move_to (NULL, helper->list,
5013 MODEST_WINDOW (parent_win));
5017 g_object_unref (dst_folder);
5021 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
5024 /* Free the helper and exit */
5026 g_object_unref (helper->list);
5027 g_slice_free (MoveToInfo, helper);
5028 gtk_widget_destroy (GTK_WIDGET (dialog));
5032 create_move_to_dialog (GtkWindow *win,
5033 GtkWidget *folder_view,
5034 TnyList *list_to_move)
5036 GtkWidget *dialog, *tree_view = NULL;
5038 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
5040 #ifndef MODEST_TOOLKIT_HILDON2
5041 /* Track changes in the selection to
5042 * disable the OK button whenever "Move to" is not possible
5043 * disbale NEW button whenever New is not possible */
5044 g_signal_connect (tree_view,
5045 "folder_selection_changed",
5046 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
5050 /* It could happen that we're trying to move a message from a
5051 window (msg window for example) after the main window was
5052 closed, so we can not just get the model of the folder
5054 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
5055 const gchar *visible_id = NULL;
5057 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5058 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5059 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
5060 MODEST_FOLDER_VIEW(tree_view));
5063 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
5065 /* Show the same account than the one that is shown in the main window */
5066 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
5069 const gchar *active_account_name = NULL;
5070 ModestAccountMgr *mgr = NULL;
5071 ModestAccountSettings *settings = NULL;
5072 ModestServerAccountSettings *store_settings = NULL;
5074 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5075 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5076 modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view),
5077 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
5079 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
5080 mgr = modest_runtime_get_account_mgr ();
5081 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
5084 const gchar *store_account_name;
5085 store_settings = modest_account_settings_get_store_settings (settings);
5086 store_account_name = modest_server_account_settings_get_account_name (store_settings);
5088 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
5089 store_account_name);
5090 g_object_unref (store_settings);
5091 g_object_unref (settings);
5095 /* we keep a pointer to the embedded folder view, so we can
5096 * retrieve it with get_folder_view_from_move_to_dialog (see
5097 * above) later (needed for focus handling)
5099 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
5101 /* Hide special folders */
5102 #ifndef MODEST_TOOLKIT_HILDON2
5103 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
5106 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
5107 #ifndef MODEST_TOOLKIT_HILDON2
5108 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5111 gtk_widget_show (GTK_WIDGET (tree_view));
5117 * Shows a confirmation dialog to the user when we're moving messages
5118 * from a remote server to the local storage. Returns the dialog
5119 * response. If it's other kind of movement then it always returns
5122 * This one is used by the next functions:
5123 * modest_ui_actions_on_paste - commented out
5124 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
5127 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
5128 TnyFolder *dest_folder,
5132 gint response = GTK_RESPONSE_OK;
5133 TnyAccount *account = NULL;
5134 TnyFolder *src_folder = NULL;
5135 TnyIterator *iter = NULL;
5136 TnyHeader *header = NULL;
5138 /* return with OK if the destination is a remote folder */
5139 if (modest_tny_folder_is_remote_folder (dest_folder))
5140 return GTK_RESPONSE_OK;
5142 /* Get source folder */
5143 iter = tny_list_create_iterator (headers);
5144 header = TNY_HEADER (tny_iterator_get_current (iter));
5146 src_folder = tny_header_get_folder (header);
5147 g_object_unref (header);
5149 g_object_unref (iter);
5151 /* if no src_folder, message may be an attahcment */
5152 if (src_folder == NULL)
5153 return GTK_RESPONSE_CANCEL;
5155 /* If the source is a local or MMC folder */
5156 if (!modest_tny_folder_is_remote_folder (src_folder)) {
5157 g_object_unref (src_folder);
5158 return GTK_RESPONSE_OK;
5161 /* Get the account */
5162 account = tny_folder_get_account (src_folder);
5164 /* now if offline we ask the user */
5165 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
5166 response = GTK_RESPONSE_OK;
5168 response = GTK_RESPONSE_CANCEL;
5171 g_object_unref (src_folder);
5172 g_object_unref (account);
5178 move_to_helper_destroyer (gpointer user_data)
5180 MoveToHelper *helper = (MoveToHelper *) user_data;
5182 /* Close the "Pasting" information banner */
5183 if (helper->banner) {
5184 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5185 g_object_unref (helper->banner);
5187 if (gtk_tree_row_reference_valid (helper->reference)) {
5188 gtk_tree_row_reference_free (helper->reference);
5189 helper->reference = NULL;
5195 move_to_cb (ModestMailOperation *mail_op,
5198 MoveToHelper *helper = (MoveToHelper *) user_data;
5199 GObject *object = modest_mail_operation_get_source (mail_op);
5201 /* Note that the operation could have failed, in that case do
5203 if (modest_mail_operation_get_status (mail_op) !=
5204 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5207 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5208 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5210 if (!modest_msg_view_window_select_next_message (self) &&
5211 !modest_msg_view_window_select_previous_message (self)) {
5212 /* No more messages to view, so close this window */
5213 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5215 } else if (MODEST_IS_MAIN_WINDOW (object) &&
5216 gtk_tree_row_reference_valid (helper->reference)) {
5217 GtkWidget *header_view;
5219 GtkTreeSelection *sel;
5221 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5222 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5223 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5224 path = gtk_tree_row_reference_get_path (helper->reference);
5225 /* We need to unselect the previous one
5226 because we could be copying instead of
5228 gtk_tree_selection_unselect_all (sel);
5229 gtk_tree_selection_select_path (sel, path);
5230 gtk_tree_path_free (path);
5232 g_object_unref (object);
5235 /* Destroy the helper */
5236 move_to_helper_destroyer (helper);
5240 folder_move_to_cb (ModestMailOperation *mail_op,
5241 TnyFolder *new_folder,
5244 GtkWidget *folder_view;
5247 object = modest_mail_operation_get_source (mail_op);
5248 if (MODEST_IS_MAIN_WINDOW (object)) {
5249 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5250 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5251 g_object_ref (folder_view);
5252 g_object_unref (object);
5253 move_to_cb (mail_op, user_data);
5254 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5255 g_object_unref (folder_view);
5257 move_to_cb (mail_op, user_data);
5262 msgs_move_to_cb (ModestMailOperation *mail_op,
5265 move_to_cb (mail_op, user_data);
5269 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5272 GObject *win = NULL;
5274 #ifndef MODEST_TOOLKIT_HILDON2
5275 ModestWindow *main_window = NULL;
5277 /* Disable next automatic folder selection */
5278 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5279 FALSE); /* don't create */
5281 GtkWidget *folder_view = NULL;
5283 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5284 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5285 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5287 if (user_data && TNY_IS_FOLDER (user_data)) {
5288 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5289 TNY_FOLDER (user_data), FALSE);
5293 /* Show notification dialog only if the main window exists */
5294 win = modest_mail_operation_get_source (mail_op);
5295 modest_platform_run_information_dialog ((GtkWindow *) win,
5296 _("mail_in_ui_folder_move_target_error"),
5299 g_object_unref (win);
5303 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5312 gint pending_purges = 0;
5313 gboolean some_purged = FALSE;
5314 ModestWindow *win = MODEST_WINDOW (user_data);
5315 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5317 /* If there was any error */
5318 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5319 modest_window_mgr_unregister_header (mgr, header);
5323 /* Once the message has been retrieved for purging, we check if
5324 * it's all ok for purging */
5326 parts = tny_simple_list_new ();
5327 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5328 iter = tny_list_create_iterator (parts);
5330 while (!tny_iterator_is_done (iter)) {
5332 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5333 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5334 if (tny_mime_part_is_purged (part))
5341 g_object_unref (part);
5343 tny_iterator_next (iter);
5345 g_object_unref (iter);
5348 if (pending_purges>0) {
5350 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5352 if (response == GTK_RESPONSE_OK) {
5355 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5356 iter = tny_list_create_iterator (parts);
5357 while (!tny_iterator_is_done (iter)) {
5360 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5361 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5362 tny_mime_part_set_purged (part);
5365 g_object_unref (part);
5367 tny_iterator_next (iter);
5369 g_object_unref (iter);
5371 tny_msg_rewrite_cache (msg);
5373 gtk_widget_destroy (info);
5377 modest_window_mgr_unregister_header (mgr, header);
5379 g_object_unref (parts);
5383 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5384 ModestMainWindow *win)
5386 GtkWidget *header_view;
5387 TnyList *header_list;
5389 TnyHeaderFlags flags;
5390 ModestWindow *msg_view_window = NULL;
5393 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5395 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5396 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5398 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5400 g_warning ("%s: no header selected", __FUNCTION__);
5404 if (tny_list_get_length (header_list) == 1) {
5405 TnyIterator *iter = tny_list_create_iterator (header_list);
5406 header = TNY_HEADER (tny_iterator_get_current (iter));
5407 g_object_unref (iter);
5411 if (!header || !TNY_IS_HEADER(header)) {
5412 g_warning ("%s: header is not valid", __FUNCTION__);
5416 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5417 header, &msg_view_window);
5418 flags = tny_header_get_flags (header);
5419 if (!(flags & TNY_HEADER_FLAG_CACHED))
5422 if (msg_view_window != NULL)
5423 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5425 /* do nothing; uid was registered before, so window is probably on it's way */
5426 g_warning ("debug: header %p has already been registered", header);
5429 ModestMailOperation *mail_op = NULL;
5430 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5431 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5432 modest_ui_actions_disk_operations_error_handler,
5434 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5435 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5437 g_object_unref (mail_op);
5440 g_object_unref (header);
5442 g_object_unref (header_list);
5446 * Checks if we need a connection to do the transfer and if the user
5447 * wants to connect to complete it
5450 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5451 TnyFolderStore *src_folder,
5453 TnyFolder *dst_folder,
5454 gboolean delete_originals,
5455 gboolean *need_connection,
5458 TnyAccount *src_account;
5459 gint uncached_msgs = 0;
5461 /* We don't need any further check if
5463 * 1- the source folder is local OR
5464 * 2- the device is already online
5466 if (!modest_tny_folder_store_is_remote (src_folder) ||
5467 tny_device_is_online (modest_runtime_get_device())) {
5468 *need_connection = FALSE;
5473 /* We must ask for a connection when
5475 * - the message(s) is not already cached OR
5476 * - the message(s) is cached but the leave_on_server setting
5477 * is FALSE (because we need to sync the source folder to
5478 * delete the message from the server (for IMAP we could do it
5479 * offline, it'll take place the next time we get a
5482 uncached_msgs = header_list_count_uncached_msgs (headers);
5483 src_account = get_account_from_folder_store (src_folder);
5484 if (uncached_msgs > 0) {
5488 *need_connection = TRUE;
5489 num_headers = tny_list_get_length (headers);
5490 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5492 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5493 GTK_RESPONSE_CANCEL) {
5499 /* The transfer is possible and the user wants to */
5502 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5503 const gchar *account_name;
5504 gboolean leave_on_server;
5506 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5507 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5510 if (leave_on_server == TRUE) {
5511 *need_connection = FALSE;
5513 *need_connection = TRUE;
5516 *need_connection = FALSE;
5521 g_object_unref (src_account);
5525 xfer_messages_error_handler (ModestMailOperation *mail_op,
5529 const GError *error;
5531 win = modest_mail_operation_get_source (mail_op);
5532 error = modest_mail_operation_get_error (mail_op);
5534 if (error && is_memory_full_error ((GError *) error, mail_op)) {
5535 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
5536 modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
5539 modest_platform_run_information_dialog ((GtkWindow *) win,
5540 _("mail_in_ui_folder_move_target_error"),
5544 g_object_unref (win);
5548 TnyFolderStore *dst_folder;
5553 * Utility function that transfer messages from both the main window
5554 * and the msg view window when using the "Move to" dialog
5557 xfer_messages_performer (gboolean canceled,
5559 GtkWindow *parent_window,
5560 TnyAccount *account,
5563 ModestWindow *win = MODEST_WINDOW (parent_window);
5564 TnyAccount *dst_account = NULL;
5565 gboolean dst_forbids_message_add = FALSE;
5566 XferMsgsHelper *helper;
5567 MoveToHelper *movehelper;
5568 ModestMailOperation *mail_op;
5570 helper = (XferMsgsHelper *) user_data;
5572 if (canceled || err) {
5573 if (!check_memory_full_error ((GtkWidget *) parent_window, err)) {
5574 /* Show the proper error message */
5575 modest_ui_actions_on_account_connection_error (parent_window, account);
5580 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5582 /* tinymail will return NULL for local folders it seems */
5583 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5584 modest_tny_account_get_protocol_type (dst_account),
5585 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_MESSAGE_ADD);
5586 g_object_unref (dst_account);
5588 if (dst_forbids_message_add) {
5589 modest_platform_information_banner (GTK_WIDGET (win),
5591 ngettext("mail_in_ui_folder_move_target_error",
5592 "mail_in_ui_folder_move_targets_error",
5593 tny_list_get_length (helper->headers)));
5597 movehelper = g_new0 (MoveToHelper, 1);
5599 #ifndef MODEST_TOOLKIT_HILDON2
5600 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5601 _CS("ckct_nw_pasting"));
5602 if (movehelper->banner != NULL) {
5603 g_object_ref (movehelper->banner);
5604 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5608 if (MODEST_IS_MAIN_WINDOW (win)) {
5609 GtkWidget *header_view =
5610 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5611 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5612 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5615 /* Perform the mail operation */
5616 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5617 xfer_messages_error_handler,
5619 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5622 modest_mail_operation_xfer_msgs (mail_op,
5624 TNY_FOLDER (helper->dst_folder),
5629 g_object_unref (G_OBJECT (mail_op));
5631 g_object_unref (helper->dst_folder);
5632 g_object_unref (helper->headers);
5633 g_slice_free (XferMsgsHelper, helper);
5637 TnyFolder *src_folder;
5638 TnyFolderStore *dst_folder;
5639 gboolean delete_original;
5640 GtkWidget *folder_view;
5644 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
5645 TnyAccount *account, gpointer user_data)
5647 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5648 GtkTreeSelection *sel;
5649 ModestMailOperation *mail_op = NULL;
5651 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
5652 g_object_unref (G_OBJECT (info->src_folder));
5653 g_object_unref (G_OBJECT (info->dst_folder));
5658 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5659 #ifndef MODEST_TOOLKIT_HILDON2
5660 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5661 _CS("ckct_nw_pasting"));
5662 if (helper->banner != NULL) {
5663 g_object_ref (helper->banner);
5664 gtk_widget_show (GTK_WIDGET(helper->banner));
5667 /* Clean folder on header view before moving it */
5668 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5669 gtk_tree_selection_unselect_all (sel);
5671 /* Let gtk events run. We need that the folder
5672 view frees its reference to the source
5673 folder *before* issuing the mail operation
5674 so we need the signal handler of selection
5675 changed to happen before the mail
5677 while (gtk_events_pending ())
5678 gtk_main_iteration (); */
5681 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5682 modest_ui_actions_move_folder_error_handler,
5683 info->src_folder, NULL);
5684 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5687 /* Select *after* the changes */
5688 /* TODO: this function hangs UI after transfer */
5689 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
5690 /* TNY_FOLDER (src_folder), TRUE); */
5692 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
5693 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5694 TNY_FOLDER (info->dst_folder), TRUE);
5696 modest_mail_operation_xfer_folder (mail_op,
5697 TNY_FOLDER (info->src_folder),
5699 info->delete_original,
5702 g_object_unref (G_OBJECT (info->src_folder));
5704 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5707 /* Unref mail operation */
5708 g_object_unref (G_OBJECT (mail_op));
5709 g_object_unref (G_OBJECT (info->dst_folder));
5714 get_account_from_folder_store (TnyFolderStore *folder_store)
5716 if (TNY_IS_ACCOUNT (folder_store))
5717 return g_object_ref (folder_store);
5719 return tny_folder_get_account (TNY_FOLDER (folder_store));
5723 * UI handler for the "Move to" action when invoked from the
5727 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5728 GtkWidget *folder_view,
5729 TnyFolderStore *dst_folder,
5730 ModestMainWindow *win)
5732 ModestHeaderView *header_view = NULL;
5733 TnyFolderStore *src_folder = NULL;
5735 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5737 /* Get the source folder */
5738 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5740 /* Get header view */
5741 header_view = (ModestHeaderView *)
5742 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5744 /* Get folder or messages to transfer */
5745 if (gtk_widget_is_focus (folder_view)) {
5746 gboolean do_xfer = TRUE;
5748 /* Allow only to transfer folders to the local root folder */
5749 if (TNY_IS_ACCOUNT (dst_folder) &&
5750 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5751 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5753 } else if (!TNY_IS_FOLDER (src_folder)) {
5754 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5759 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5760 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5762 info->src_folder = g_object_ref (src_folder);
5763 info->dst_folder = g_object_ref (dst_folder);
5764 info->delete_original = TRUE;
5765 info->folder_view = folder_view;
5767 connect_info->callback = on_move_folder_cb;
5768 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5769 connect_info->data = info;
5771 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5772 TNY_FOLDER_STORE (src_folder),
5775 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5778 headers = modest_header_view_get_selected_headers(header_view);
5780 /* Transfer the messages */
5781 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
5782 headers, TNY_FOLDER (dst_folder));
5784 g_object_unref (headers);
5788 g_object_unref (src_folder);
5791 #ifdef MODEST_TOOLKIT_HILDON2
5793 * UI handler for the "Move to" action when invoked from the
5794 * ModestFolderWindow
5797 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
5798 TnyFolderStore *dst_folder,
5802 TnyFolderStore *src_folder = NULL;
5803 TnyIterator *iterator;
5805 if (tny_list_get_length (selection) != 1)
5808 iterator = tny_list_create_iterator (selection);
5809 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
5810 g_object_unref (iterator);
5813 gboolean do_xfer = TRUE;
5815 /* Allow only to transfer folders to the local root folder */
5816 if (TNY_IS_ACCOUNT (dst_folder) &&
5817 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5818 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5821 modest_platform_run_information_dialog (win,
5822 _("mail_in_ui_folder_move_target_error"),
5824 } else if (!TNY_IS_FOLDER (src_folder)) {
5825 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5830 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5831 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5833 info->src_folder = g_object_ref (src_folder);
5834 info->dst_folder = g_object_ref (dst_folder);
5835 info->delete_original = TRUE;
5836 info->folder_view = folder_view;
5838 connect_info->callback = on_move_folder_cb;
5839 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5840 connect_info->data = info;
5842 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5843 TNY_FOLDER_STORE (src_folder),
5848 g_object_unref (src_folder);
5854 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
5855 TnyFolder *src_folder,
5857 TnyFolder *dst_folder)
5859 gboolean need_connection = TRUE;
5860 gboolean do_xfer = TRUE;
5861 XferMsgsHelper *helper;
5863 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5864 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5865 g_return_if_fail (TNY_IS_LIST (headers));
5867 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5868 headers, TNY_FOLDER (dst_folder),
5869 TRUE, &need_connection,
5872 /* If we don't want to transfer just return */
5876 /* Create the helper */
5877 helper = g_slice_new (XferMsgsHelper);
5878 helper->dst_folder = g_object_ref (dst_folder);
5879 helper->headers = g_object_ref (headers);
5881 if (need_connection) {
5882 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5883 connect_info->callback = xfer_messages_performer;
5884 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5885 connect_info->data = helper;
5887 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5888 TNY_FOLDER_STORE (src_folder),
5891 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5892 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
5893 src_account, helper);
5894 g_object_unref (src_account);
5899 * UI handler for the "Move to" action when invoked from the
5900 * ModestMsgViewWindow
5903 modest_ui_actions_on_window_move_to (GtkAction *action,
5905 TnyFolderStore *dst_folder,
5908 TnyFolder *src_folder = NULL;
5910 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5913 TnyHeader *header = NULL;
5916 iter = tny_list_create_iterator (headers);
5917 header = (TnyHeader *) tny_iterator_get_current (iter);
5918 src_folder = tny_header_get_folder (header);
5920 /* Transfer the messages */
5921 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
5923 TNY_FOLDER (dst_folder));
5926 g_object_unref (header);
5927 g_object_unref (iter);
5928 g_object_unref (src_folder);
5933 modest_ui_actions_on_move_to (GtkAction *action,
5936 modest_ui_actions_on_edit_mode_move_to (win);
5940 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
5942 GtkWidget *dialog = NULL;
5943 MoveToInfo *helper = NULL;
5944 TnyList *list_to_move;
5946 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
5948 #ifndef MODEST_TOOLKIT_HILDON2
5949 /* Get the main window if exists */
5950 ModestMainWindow *main_window;
5951 if (MODEST_IS_MAIN_WINDOW (win))
5952 main_window = MODEST_MAIN_WINDOW (win);
5955 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5956 FALSE)); /* don't create */
5959 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
5964 if (tny_list_get_length (list_to_move) < 1) {
5965 g_object_unref (list_to_move);
5969 /* Create and run the dialog */
5970 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
5971 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
5972 GTK_WINDOW (dialog),
5976 helper = g_slice_new0 (MoveToInfo);
5977 helper->list = list_to_move;
5980 /* Listen to response signal */
5981 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
5983 /* Show the dialog */
5984 gtk_widget_show (dialog);
5990 * Calls #HeadersFunc for each header already selected in the main
5991 * window or the message currently being shown in the msg view window
5994 do_headers_action (ModestWindow *win,
5998 TnyList *headers_list = NULL;
5999 TnyIterator *iter = NULL;
6000 TnyHeader *header = NULL;
6001 TnyFolder *folder = NULL;
6004 headers_list = get_selected_headers (win);
6008 /* Get the folder */
6009 iter = tny_list_create_iterator (headers_list);
6010 header = TNY_HEADER (tny_iterator_get_current (iter));
6012 folder = tny_header_get_folder (header);
6013 g_object_unref (header);
6016 /* Call the function for each header */
6017 while (!tny_iterator_is_done (iter)) {
6018 header = TNY_HEADER (tny_iterator_get_current (iter));
6019 func (header, win, user_data);
6020 g_object_unref (header);
6021 tny_iterator_next (iter);
6024 /* Trick: do a poke status in order to speed up the signaling
6027 tny_folder_poke_status (folder);
6028 g_object_unref (folder);
6032 g_object_unref (iter);
6033 g_object_unref (headers_list);
6037 modest_ui_actions_view_attachment (GtkAction *action,
6038 ModestWindow *window)
6040 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6041 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
6043 /* not supported window for this action */
6044 g_return_if_reached ();
6049 modest_ui_actions_save_attachments (GtkAction *action,
6050 ModestWindow *window)
6052 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6054 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
6057 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
6059 /* not supported window for this action */
6060 g_return_if_reached ();
6065 modest_ui_actions_remove_attachments (GtkAction *action,
6066 ModestWindow *window)
6068 if (MODEST_IS_MAIN_WINDOW (window)) {
6069 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
6070 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6071 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
6073 /* not supported window for this action */
6074 g_return_if_reached ();
6079 modest_ui_actions_on_settings (GtkAction *action,
6084 dialog = modest_platform_get_global_settings_dialog ();
6085 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
6086 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
6087 gtk_widget_show_all (dialog);
6089 gtk_dialog_run (GTK_DIALOG (dialog));
6091 gtk_widget_destroy (dialog);
6095 modest_ui_actions_on_help (GtkAction *action,
6098 /* Help app is not available at all in fremantle */
6099 #ifndef MODEST_TOOLKIT_HILDON2
6100 const gchar *help_id;
6102 g_return_if_fail (win && GTK_IS_WINDOW(win));
6104 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
6107 modest_platform_show_help (GTK_WINDOW (win), help_id);
6112 modest_ui_actions_on_csm_help (GtkAction *action,
6115 /* Help app is not available at all in fremantle */
6116 #ifndef MODEST_TOOLKIT_HILDON2
6118 const gchar* help_id = NULL;
6119 GtkWidget *folder_view;
6120 TnyFolderStore *folder_store;
6122 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
6124 /* Get selected folder */
6125 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
6126 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6127 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6129 /* Switch help_id */
6130 if (folder_store && TNY_IS_FOLDER (folder_store))
6131 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
6134 g_object_unref (folder_store);
6137 modest_platform_show_help (GTK_WINDOW (win), help_id);
6139 modest_ui_actions_on_help (action, win);
6144 retrieve_contents_cb (ModestMailOperation *mail_op,
6151 /* We only need this callback to show an error in case of
6152 memory low condition */
6153 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
6154 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
6159 retrieve_msg_contents_performer (gboolean canceled,
6161 GtkWindow *parent_window,
6162 TnyAccount *account,
6165 ModestMailOperation *mail_op;
6166 TnyList *headers = TNY_LIST (user_data);
6168 if (err || canceled) {
6169 check_memory_full_error ((GtkWidget *) parent_window, err);
6173 /* Create mail operation */
6174 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
6175 modest_ui_actions_disk_operations_error_handler,
6177 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
6178 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
6181 g_object_unref (mail_op);
6183 g_object_unref (headers);
6184 g_object_unref (account);
6188 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
6189 ModestWindow *window)
6191 TnyList *headers = NULL;
6192 TnyAccount *account = NULL;
6193 TnyIterator *iter = NULL;
6194 TnyHeader *header = NULL;
6195 TnyFolder *folder = NULL;
6198 headers = get_selected_headers (window);
6202 /* Pick the account */
6203 iter = tny_list_create_iterator (headers);
6204 header = TNY_HEADER (tny_iterator_get_current (iter));
6205 folder = tny_header_get_folder (header);
6206 account = tny_folder_get_account (folder);
6207 g_object_unref (folder);
6208 g_object_unref (header);
6209 g_object_unref (iter);
6211 /* Connect and perform the message retrieval */
6212 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6213 g_object_ref (account),
6214 retrieve_msg_contents_performer,
6215 g_object_ref (headers));
6218 g_object_unref (account);
6219 g_object_unref (headers);
6223 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6225 g_return_if_fail (MODEST_IS_WINDOW (window));
6228 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6232 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6234 g_return_if_fail (MODEST_IS_WINDOW (window));
6237 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6241 modest_ui_actions_on_email_menu_activated (GtkAction *action,
6242 ModestWindow *window)
6244 g_return_if_fail (MODEST_IS_WINDOW (window));
6247 modest_ui_actions_check_menu_dimming_rules (window);
6251 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
6252 ModestWindow *window)
6254 g_return_if_fail (MODEST_IS_WINDOW (window));
6257 modest_ui_actions_check_menu_dimming_rules (window);
6261 modest_ui_actions_on_view_menu_activated (GtkAction *action,
6262 ModestWindow *window)
6264 g_return_if_fail (MODEST_IS_WINDOW (window));
6267 modest_ui_actions_check_menu_dimming_rules (window);
6271 modest_ui_actions_on_format_menu_activated (GtkAction *action,
6272 ModestWindow *window)
6274 g_return_if_fail (MODEST_IS_WINDOW (window));
6277 modest_ui_actions_check_menu_dimming_rules (window);
6281 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
6282 ModestWindow *window)
6284 g_return_if_fail (MODEST_IS_WINDOW (window));
6287 modest_ui_actions_check_menu_dimming_rules (window);
6291 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
6292 ModestWindow *window)
6294 g_return_if_fail (MODEST_IS_WINDOW (window));
6297 modest_ui_actions_check_menu_dimming_rules (window);
6301 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
6302 ModestWindow *window)
6304 g_return_if_fail (MODEST_IS_WINDOW (window));
6307 modest_ui_actions_check_menu_dimming_rules (window);
6311 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
6312 ModestWindow *window)
6314 g_return_if_fail (MODEST_IS_WINDOW (window));
6317 modest_ui_actions_check_menu_dimming_rules (window);
6321 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
6322 ModestWindow *window)
6324 g_return_if_fail (MODEST_IS_WINDOW (window));
6327 modest_ui_actions_check_menu_dimming_rules (window);
6331 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6333 g_return_if_fail (MODEST_IS_WINDOW (window));
6335 /* we check for low-mem; in that case, show a warning, and don't allow
6338 if (modest_platform_check_memory_low (window, TRUE))
6341 modest_platform_show_search_messages (GTK_WINDOW (window));
6345 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6347 g_return_if_fail (MODEST_IS_WINDOW (win));
6350 /* we check for low-mem; in that case, show a warning, and don't allow
6351 * for the addressbook
6353 if (modest_platform_check_memory_low (win, TRUE))
6357 modest_platform_show_addressbook (GTK_WINDOW (win));
6362 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6363 ModestWindow *window)
6366 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6368 if (GTK_IS_TOGGLE_ACTION (action))
6369 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6373 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window),
6378 on_send_receive_finished (ModestMailOperation *mail_op,
6381 GtkWidget *header_view, *folder_view;
6382 TnyFolderStore *folder_store;
6383 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6385 /* Set send/receive operation finished */
6386 modest_main_window_notify_send_receive_completed (main_win);
6388 /* Don't refresh the current folder if there were any errors */
6389 if (modest_mail_operation_get_status (mail_op) !=
6390 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6393 /* Refresh the current folder if we're viewing a window. We do
6394 this because the user won't be able to see the new mails in
6395 the selected folder after a Send&Receive because it only
6396 performs a poke_status, i.e, only the number of read/unread
6397 messages is updated, but the new headers are not
6399 folder_view = modest_main_window_get_child_widget (main_win,
6400 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6404 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6406 /* Do not need to refresh INBOX again because the
6407 update_account does it always automatically */
6408 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6409 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6410 ModestMailOperation *refresh_op;
6412 header_view = modest_main_window_get_child_widget (main_win,
6413 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6415 /* We do not need to set the contents style
6416 because it hasn't changed. We also do not
6417 need to save the widget status. Just force
6419 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6420 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6421 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6422 folder_refreshed_cb, main_win);
6423 g_object_unref (refresh_op);
6427 g_object_unref (folder_store);
6432 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6438 const gchar* server_name = NULL;
6439 TnyTransportAccount *transport;
6440 gchar *message = NULL;
6441 ModestProtocol *protocol;
6443 /* Don't show anything if the user cancelled something or the
6444 * send receive request is not interactive. Authentication
6445 * errors are managed by the account store so no need to show
6446 * a dialog here again */
6447 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6448 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6449 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6453 /* Get the server name. Note that we could be using a
6454 connection specific transport account */
6455 transport = (TnyTransportAccount *)
6456 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
6458 ModestTnyAccountStore *acc_store;
6459 const gchar *acc_name;
6460 TnyTransportAccount *conn_specific;
6462 acc_store = modest_runtime_get_account_store();
6463 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
6464 conn_specific = (TnyTransportAccount *)
6465 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
6466 if (conn_specific) {
6467 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
6468 g_object_unref (conn_specific);
6470 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
6472 g_object_unref (transport);
6476 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
6477 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
6478 tny_account_get_proto (TNY_ACCOUNT (transport)));
6480 g_warning ("%s: Account with no proto", __FUNCTION__);
6484 /* Show the appropriate message text for the GError: */
6485 switch (err->code) {
6486 case TNY_SERVICE_ERROR_CONNECT:
6487 message = modest_protocol_get_translation (protocol,
6488 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
6491 case TNY_SERVICE_ERROR_SEND:
6492 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6494 case TNY_SERVICE_ERROR_UNAVAILABLE:
6495 message = modest_protocol_get_translation (protocol,
6496 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
6500 g_warning ("%s: unexpected ERROR %d",
6501 __FUNCTION__, err->code);
6502 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6506 modest_platform_run_information_dialog (NULL, message, FALSE);
6511 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6516 ModestWindow *top_window = NULL;
6517 ModestWindowMgr *mgr = NULL;
6518 GtkWidget *header_view = NULL;
6519 TnyFolder *selected_folder = NULL;
6520 TnyFolderType folder_type;
6522 mgr = modest_runtime_get_window_mgr ();
6523 top_window = modest_window_mgr_get_current_top (mgr);
6528 #ifndef MODEST_TOOLKIT_HILDON2
6529 if (MODEST_IS_MAIN_WINDOW (top_window)) {
6530 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (top_window),
6531 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6534 if (MODEST_IS_HEADER_WINDOW (top_window)) {
6535 header_view = (GtkWidget *)
6536 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
6540 /* Get selected folder */
6542 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
6543 if (!selected_folder)
6546 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6547 #if GTK_CHECK_VERSION(2, 8, 0)
6548 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
6549 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6550 GtkTreeViewColumn *tree_column;
6552 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6553 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6555 gtk_tree_view_column_queue_resize (tree_column);
6557 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
6558 gtk_widget_queue_draw (header_view);
6561 #ifndef MODEST_TOOLKIT_HILDON2
6562 /* Rerun dimming rules, because the message could become deletable for example */
6563 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6564 MODEST_DIMMING_RULES_TOOLBAR);
6565 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6566 MODEST_DIMMING_RULES_MENU);
6570 g_object_unref (selected_folder);
6574 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6575 TnyAccount *account)
6577 ModestProtocolType protocol_type;
6578 ModestProtocol *protocol;
6579 gchar *error_note = NULL;
6581 protocol_type = modest_tny_account_get_protocol_type (account);
6582 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6585 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6586 if (error_note == NULL) {
6587 g_warning ("%s: This should not be reached", __FUNCTION__);
6589 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6590 g_free (error_note);
6595 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6599 TnyFolderStore *folder = NULL;
6600 TnyAccount *account = NULL;
6601 ModestProtocolType proto;
6602 ModestProtocol *protocol;
6603 TnyHeader *header = NULL;
6605 if (MODEST_IS_MAIN_WINDOW (win)) {
6606 GtkWidget *header_view;
6607 TnyList* headers = NULL;
6609 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6610 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6611 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6612 if (!headers || tny_list_get_length (headers) == 0) {
6614 g_object_unref (headers);
6617 iter = tny_list_create_iterator (headers);
6618 header = TNY_HEADER (tny_iterator_get_current (iter));
6619 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6620 g_object_unref (iter);
6621 g_object_unref (headers);
6622 #ifdef MODEST_TOOLKIT_HILDON2
6623 } else if (MODEST_IS_HEADER_WINDOW (win)) {
6624 GtkWidget *header_view;
6625 TnyList* headers = NULL;
6627 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
6628 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6629 if (!headers || tny_list_get_length (headers) == 0) {
6631 g_object_unref (headers);
6634 iter = tny_list_create_iterator (headers);
6635 header = TNY_HEADER (tny_iterator_get_current (iter));
6637 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6639 g_warning ("List should contain headers");
6641 g_object_unref (iter);
6642 g_object_unref (headers);
6644 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6645 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6647 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6650 if (!header || !folder)
6653 /* Get the account type */
6654 account = tny_folder_get_account (TNY_FOLDER (folder));
6655 proto = modest_tny_account_get_protocol_type (account);
6656 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6659 subject = tny_header_dup_subject (header);
6660 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6664 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6670 g_object_unref (account);
6672 g_object_unref (folder);
6674 g_object_unref (header);
6680 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6681 const gchar *account_name,
6682 const gchar *account_title)
6684 ModestAccountMgr *account_mgr;
6687 ModestProtocol *protocol;
6688 gboolean removed = FALSE;
6690 g_return_val_if_fail (account_name, FALSE);
6691 g_return_val_if_fail (account_title, FALSE);
6693 account_mgr = modest_runtime_get_account_mgr();
6695 /* The warning text depends on the account type: */
6696 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6697 modest_account_mgr_get_store_protocol (account_mgr,
6699 txt = modest_protocol_get_translation (protocol,
6700 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6703 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6705 response = modest_platform_run_confirmation_dialog (parent_window, txt);
6709 if (response == GTK_RESPONSE_OK) {
6710 /* Remove account. If it succeeds then it also removes
6711 the account from the ModestAccountView: */
6712 gboolean is_default = FALSE;
6713 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6714 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6716 g_free (default_account_name);
6718 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6720 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
6726 modest_ui_actions_on_fetch_images (GtkAction *action,
6727 ModestWindow *window)
6729 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
6731 modest_msg_view_window_fetch_images (MODEST_MSG_VIEW_WINDOW (window));
6736 modest_ui_actions_on_reload_message (const gchar *msg_id)
6738 ModestWindow *window = NULL;
6740 g_return_if_fail (msg_id && msg_id[0] != '\0');
6741 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
6747 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
6750 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));