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-camel-folder.h>
50 #include <tny-camel-imap-folder.h>
51 #include <tny-camel-pop-folder.h>
52 #ifdef MODEST_TOOLKIT_HILDON2
53 #include <modest-accounts-window.h>
54 #include <hildon/hildon-pannable-area.h>
55 #include <hildon/hildon-gtk.h>
56 #include <modest-header-window.h>
57 #include <modest-folder-window.h>
58 #include <modest-maemo-utils.h>
61 #ifdef MODEST_PLATFORM_MAEMO
62 #include "maemo/modest-osso-state-saving.h"
63 #endif /* MODEST_PLATFORM_MAEMO */
64 #ifndef MODEST_TOOLKIT_GTK
65 #include "maemo/modest-hildon-includes.h"
66 #include "maemo/modest-connection-specific-smtp-window.h"
67 #endif /* !MODEST_TOOLKIT_GTK */
68 #include <modest-utils.h>
70 #include "widgets/modest-ui-constants.h"
71 #include <widgets/modest-main-window.h>
72 #include <widgets/modest-msg-view-window.h>
73 #include <widgets/modest-account-view-window.h>
74 #include <widgets/modest-details-dialog.h>
75 #include <widgets/modest-attachments-view.h>
76 #include "widgets/modest-folder-view.h"
77 #include "widgets/modest-global-settings-dialog.h"
78 #include "modest-account-mgr-helpers.h"
79 #include "modest-mail-operation.h"
80 #include "modest-text-utils.h"
81 #include <modest-widget-memory.h>
82 #include <tny-error.h>
83 #include <tny-simple-list.h>
84 #include <tny-msg-view.h>
85 #include <tny-device.h>
86 #include <tny-merge-folder.h>
88 #include <gtkhtml/gtkhtml.h>
90 #define MIN_FREE_SPACE 5 * 1024 * 1024
91 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
93 typedef struct _GetMsgAsyncHelper {
95 ModestMailOperation *mail_op;
102 typedef enum _ReplyForwardAction {
106 } ReplyForwardAction;
108 typedef struct _ReplyForwardHelper {
109 guint reply_forward_type;
110 ReplyForwardAction action;
113 GtkWidget *parent_window;
115 } ReplyForwardHelper;
117 typedef struct _MoveToHelper {
118 GtkTreeRowReference *reference;
122 typedef struct _PasteAsAttachmentHelper {
123 ModestMsgEditWindow *window;
125 } PasteAsAttachmentHelper;
133 * The do_headers_action uses this kind of functions to perform some
134 * action to each member of a list of headers
136 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
138 static void do_headers_action (ModestWindow *win,
142 static void open_msg_cb (ModestMailOperation *mail_op,
149 static void reply_forward_cb (ModestMailOperation *mail_op,
156 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
158 static void folder_refreshed_cb (ModestMailOperation *mail_op,
162 static void on_send_receive_finished (ModestMailOperation *mail_op,
165 static gint header_list_count_uncached_msgs (TnyList *header_list);
167 static gboolean connect_to_get_msg (ModestWindow *win,
168 gint num_of_uncached_msgs,
169 TnyAccount *account);
171 static gboolean remote_folder_has_leave_on_server (TnyFolderStore *folder);
173 static void do_create_folder (GtkWindow *window,
174 TnyFolderStore *parent_folder,
175 const gchar *suggested_name);
177 static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store);
179 static void modest_ui_actions_on_main_window_move_to (GtkAction *action,
180 GtkWidget *folder_view,
181 TnyFolderStore *dst_folder,
182 ModestMainWindow *win);
183 #ifdef MODEST_TOOLKIT_HILDON2
184 static void modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
185 TnyFolderStore *dst_folder,
190 static void modest_ui_actions_on_window_move_to (GtkAction *action,
191 TnyList *list_to_move,
192 TnyFolderStore *dst_folder,
196 * This function checks whether a TnyFolderStore is a pop account
199 remote_folder_has_leave_on_server (TnyFolderStore *folder)
204 g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
206 account = get_account_from_folder_store (folder);
207 result = (modest_protocol_registry_protocol_type_has_leave_on_server (modest_runtime_get_protocol_registry (),
208 modest_tny_account_get_protocol_type (account)));
209 g_object_unref (account);
214 /* FIXME: this should be merged with the similar code in modest-account-view-window */
215 /* Show the account creation wizard dialog.
216 * returns: TRUE if an account was created. FALSE if the user cancelled.
219 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
221 gboolean result = FALSE;
223 gint dialog_response;
225 /* there is no such wizard yet */
226 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
227 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (wizard), (GtkWindow *) win);
229 #ifndef MODEST_TOOLKIT_HILDON2
230 /* always present a main window in the background
231 * we do it here, so we cannot end up with two wizards (as this
232 * function might be called in modest_window_mgr_get_main_window as well */
234 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
235 TRUE); /* create if not existent */
239 ModestWindowMgr *mgr;
241 mgr = modest_runtime_get_window_mgr ();
243 window_list = modest_window_mgr_get_window_list (mgr);
244 if (window_list == NULL) {
245 win = MODEST_WINDOW (modest_accounts_window_new ());
246 if (modest_window_mgr_register_window (mgr, win, NULL)) {
247 gtk_widget_show_all (GTK_WIDGET (win));
249 gtk_widget_destroy (GTK_WIDGET (win));
254 g_list_free (window_list);
260 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
262 /* make sure the mainwindow is visible. We need to present the
263 wizard again to give it the focus back. show_all are needed
264 in order to get the widgets properly drawn (MainWindow main
265 paned won't be in its right position and the dialog will be
267 #ifndef MODEST_TOOLKIT_HILDON2
268 gtk_widget_show_all (GTK_WIDGET (win));
269 gtk_widget_show_all (GTK_WIDGET (wizard));
270 gtk_window_present (GTK_WINDOW (win));
271 gtk_window_present (GTK_WINDOW (wizard));
274 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
275 gtk_widget_destroy (GTK_WIDGET (wizard));
276 if (gtk_events_pending ())
277 gtk_main_iteration ();
279 if (dialog_response == GTK_RESPONSE_CANCEL) {
282 /* Check whether an account was created: */
283 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
290 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
293 const gchar *authors[] = {
294 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
297 about = gtk_about_dialog_new ();
298 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
299 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
300 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
301 _("Copyright (c) 2006, Nokia Corporation\n"
302 "All rights reserved."));
303 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
304 _("a modest e-mail client\n\n"
305 "design and implementation: Dirk-Jan C. Binnema\n"
306 "contributions from the fine people at KC and Ig\n"
307 "uses the tinymail email framework written by Philip van Hoof"));
308 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
309 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
310 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
311 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
313 gtk_dialog_run (GTK_DIALOG (about));
314 gtk_widget_destroy(about);
318 * Gets the list of currently selected messages. If the win is the
319 * main window, then it returns a newly allocated list of the headers
320 * selected in the header view. If win is the msg view window, then
321 * the value returned is a list with just a single header.
323 * The caller of this funcion must free the list.
326 get_selected_headers (ModestWindow *win)
328 if (MODEST_IS_MAIN_WINDOW(win)) {
329 GtkWidget *header_view;
331 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
332 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
333 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
335 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
336 /* for MsgViewWindows, we simply return a list with one element */
338 TnyList *list = NULL;
340 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
341 if (header != NULL) {
342 list = tny_simple_list_new ();
343 tny_list_prepend (list, G_OBJECT(header));
344 g_object_unref (G_OBJECT(header));
349 #ifdef MODEST_TOOLKIT_HILDON2
350 } else if (MODEST_IS_HEADER_WINDOW (win)) {
351 GtkWidget *header_view;
353 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
354 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
360 static GtkTreeRowReference *
361 get_next_after_selected_headers (ModestHeaderView *header_view)
363 GtkTreeSelection *sel;
364 GList *selected_rows, *node;
366 GtkTreeRowReference *result;
369 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
370 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
371 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
373 if (selected_rows == NULL)
376 node = g_list_last (selected_rows);
377 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
378 gtk_tree_path_next (path);
380 result = gtk_tree_row_reference_new (model, path);
382 gtk_tree_path_free (path);
383 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
384 g_list_free (selected_rows);
390 headers_action_mark_as_read (TnyHeader *header,
394 TnyHeaderFlags flags;
396 g_return_if_fail (TNY_IS_HEADER(header));
398 flags = tny_header_get_flags (header);
399 if (flags & TNY_HEADER_FLAG_SEEN) return;
400 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
404 headers_action_mark_as_unread (TnyHeader *header,
408 TnyHeaderFlags flags;
410 g_return_if_fail (TNY_IS_HEADER(header));
412 flags = tny_header_get_flags (header);
413 if (flags & TNY_HEADER_FLAG_SEEN) {
414 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
418 /** After deleing a message that is currently visible in a window,
419 * show the next message from the list, or close the window if there are no more messages.
422 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
424 /* Close msg view window or select next */
425 if (!modest_msg_view_window_select_next_message (win) &&
426 !modest_msg_view_window_select_previous_message (win)) {
428 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
434 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
436 modest_ui_actions_on_edit_mode_delete_message (win);
440 modest_ui_actions_on_edit_mode_delete_message (ModestWindow *win)
442 TnyList *header_list = NULL;
443 TnyIterator *iter = NULL;
444 TnyHeader *header = NULL;
445 gchar *message = NULL;
448 ModestWindowMgr *mgr;
449 GtkWidget *header_view = NULL;
450 gboolean retval = TRUE;
452 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
454 /* Check first if the header view has the focus */
455 if (MODEST_IS_MAIN_WINDOW (win)) {
457 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
458 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
459 if (!gtk_widget_is_focus (header_view))
463 /* Get the headers, either from the header view (if win is the main window),
464 * or from the message view window: */
465 header_list = get_selected_headers (win);
466 if (!header_list) return FALSE;
468 /* Check if any of the headers are already opened, or in the process of being opened */
469 if (MODEST_IS_MAIN_WINDOW (win)) {
470 gint opened_headers = 0;
472 iter = tny_list_create_iterator (header_list);
473 mgr = modest_runtime_get_window_mgr ();
474 while (!tny_iterator_is_done (iter)) {
475 header = TNY_HEADER (tny_iterator_get_current (iter));
477 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
479 g_object_unref (header);
481 tny_iterator_next (iter);
483 g_object_unref (iter);
485 if (opened_headers > 0) {
488 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
491 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg, FALSE);
494 g_object_unref (header_list);
500 if (tny_list_get_length(header_list) == 1) {
501 iter = tny_list_create_iterator (header_list);
502 header = TNY_HEADER (tny_iterator_get_current (iter));
505 subject = tny_header_dup_subject (header);
507 subject = g_strdup (_("mail_va_no_subject"));
508 desc = g_strdup_printf ("%s", subject);
510 g_object_unref (header);
513 g_object_unref (iter);
515 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
516 tny_list_get_length(header_list)), desc);
518 /* Confirmation dialog */
519 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
523 if (response == GTK_RESPONSE_OK) {
524 ModestWindow *main_window = NULL;
525 ModestWindowMgr *mgr = NULL;
526 GtkTreeModel *model = NULL;
527 GtkTreeSelection *sel = NULL;
528 GList *sel_list = NULL, *tmp = NULL;
529 GtkTreeRowReference *next_row_reference = NULL;
530 GtkTreeRowReference *prev_row_reference = NULL;
531 GtkTreePath *next_path = NULL;
532 GtkTreePath *prev_path = NULL;
533 ModestMailOperation *mail_op = NULL;
535 /* Find last selected row */
536 if (MODEST_IS_MAIN_WINDOW (win)) {
537 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
538 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
539 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
540 for (tmp=sel_list; tmp; tmp=tmp->next) {
541 if (tmp->next == NULL) {
542 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
543 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
545 gtk_tree_path_prev (prev_path);
546 gtk_tree_path_next (next_path);
548 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
549 next_row_reference = gtk_tree_row_reference_new (model, next_path);
554 /* Disable window dimming management */
555 modest_window_disable_dimming (MODEST_WINDOW(win));
557 /* Remove each header. If it's a view window header_view == NULL */
558 mail_op = modest_mail_operation_new ((GObject *) win);
559 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
561 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
562 g_object_unref (mail_op);
564 /* Enable window dimming management */
566 gtk_tree_selection_unselect_all (sel);
568 modest_window_enable_dimming (MODEST_WINDOW(win));
570 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
571 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
573 /* Get main window */
574 mgr = modest_runtime_get_window_mgr ();
575 main_window = modest_window_mgr_get_main_window (mgr, FALSE); /* don't create */
576 } else if (MODEST_IS_MAIN_WINDOW (win)) {
577 /* Move cursor to next row */
580 /* Select next or previous row */
581 if (gtk_tree_row_reference_valid (next_row_reference)) {
582 gtk_tree_selection_select_path (sel, next_path);
584 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
585 gtk_tree_selection_select_path (sel, prev_path);
589 if (gtk_tree_row_reference_valid (next_row_reference))
590 gtk_tree_row_reference_free (next_row_reference);
591 if (next_path != NULL)
592 gtk_tree_path_free (next_path);
593 if (gtk_tree_row_reference_valid (prev_row_reference))
594 gtk_tree_row_reference_free (prev_row_reference);
595 if (prev_path != NULL)
596 gtk_tree_path_free (prev_path);
599 /* Update toolbar dimming state */
601 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
602 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
606 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
607 g_list_free (sel_list);
616 g_object_unref (header_list);
624 /* delete either message or folder, based on where we are */
626 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
628 g_return_if_fail (MODEST_IS_WINDOW(win));
630 /* Check first if the header view has the focus */
631 if (MODEST_IS_MAIN_WINDOW (win)) {
633 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
634 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
635 if (gtk_widget_is_focus (w)) {
636 modest_ui_actions_on_delete_folder (action, MODEST_WINDOW(win));
640 modest_ui_actions_on_delete_message (action, win);
644 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
646 ModestWindowMgr *mgr = NULL;
648 #ifdef MODEST_PLATFORM_MAEMO
649 modest_osso_save_state();
650 #endif /* MODEST_PLATFORM_MAEMO */
652 g_debug ("closing down, clearing %d item(s) from operation queue",
653 modest_mail_operation_queue_num_elements
654 (modest_runtime_get_mail_operation_queue()));
656 /* cancel all outstanding operations */
657 modest_mail_operation_queue_cancel_all
658 (modest_runtime_get_mail_operation_queue());
660 g_debug ("queue has been cleared");
663 /* Check if there are opened editing windows */
664 mgr = modest_runtime_get_window_mgr ();
665 modest_window_mgr_close_all_windows (mgr);
667 /* note: when modest-tny-account-store is finalized,
668 it will automatically set all network connections
671 /* gtk_main_quit (); */
675 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
679 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
681 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
682 /* gtk_widget_destroy (GTK_WIDGET (win)); */
683 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
684 /* gboolean ret_value; */
685 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
686 /* } else if (MODEST_IS_WINDOW (win)) { */
687 /* gtk_widget_destroy (GTK_WIDGET (win)); */
689 /* g_return_if_reached (); */
694 modest_ui_actions_add_to_contacts (GtkAction *action, ModestWindow *win)
696 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
698 modest_msg_view_window_add_to_contacts (MODEST_MSG_VIEW_WINDOW (win));
702 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
704 GtkClipboard *clipboard = NULL;
705 gchar *selection = NULL;
707 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
708 selection = gtk_clipboard_wait_for_text (clipboard);
710 /* Question: why is the clipboard being used here?
711 * It doesn't really make a lot of sense. */
715 modest_address_book_add_address (selection);
721 modest_ui_actions_on_new_account (GtkAction *action,
722 ModestWindow *window)
724 if (!modest_ui_actions_run_account_setup_wizard (window)) {
725 g_debug ("%s: wizard was already running", __FUNCTION__);
730 modest_ui_actions_on_accounts (GtkAction *action,
733 /* This is currently only implemented for Maemo */
734 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
735 if (!modest_ui_actions_run_account_setup_wizard (win))
736 g_debug ("%s: wizard was already running", __FUNCTION__);
740 /* Show the list of accounts */
741 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
743 /* The accounts dialog must be modal */
744 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
745 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
750 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
752 /* This is currently only implemented for Maemo,
753 * because it requires an API (libconic) to detect different connection
756 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
758 /* Create the window if necessary: */
759 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
760 modest_connection_specific_smtp_window_fill_with_connections (
761 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
762 modest_runtime_get_account_mgr());
764 /* Show the window: */
765 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
766 GTK_WINDOW (specific_window), (GtkWindow *) win);
767 gtk_widget_show (specific_window);
768 #endif /* !MODEST_TOOLKIT_GTK */
772 modest_ui_actions_compose_msg(ModestWindow *win,
775 const gchar *bcc_str,
776 const gchar *subject_str,
777 const gchar *body_str,
779 gboolean set_as_modified)
781 gchar *account_name = NULL;
782 const gchar *mailbox;
784 TnyAccount *account = NULL;
785 TnyFolder *folder = NULL;
786 gchar *from_str = NULL, *signature = NULL, *body = NULL;
787 gchar *recipient = NULL;
788 gboolean use_signature = FALSE;
789 ModestWindow *msg_win = NULL;
790 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
791 ModestTnyAccountStore *store = modest_runtime_get_account_store();
792 GnomeVFSFileSize total_size, allowed_size;
794 /* we check for low-mem */
795 if (modest_platform_check_memory_low (win, TRUE))
798 #ifdef MODEST_TOOLKIT_HILDON2
800 account_name = g_strdup (modest_window_get_active_account(win));
803 account_name = modest_account_mgr_get_default_account(mgr);
806 g_printerr ("modest: no account found\n");
811 mailbox = modest_window_get_active_mailbox (win);
814 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
816 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
819 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
821 g_printerr ("modest: failed to find Drafts folder\n");
824 from_str = modest_account_mgr_get_from_string (mgr, account_name, mailbox);
826 g_printerr ("modest: failed get from string for '%s'\n", account_name);
830 recipient = modest_text_utils_get_email_address (from_str);
831 signature = modest_account_mgr_get_signature_from_recipient (mgr, recipient, &use_signature);
833 if (body_str != NULL) {
834 body = use_signature ? g_strconcat(body_str, "\n--\n", signature, NULL) : g_strdup(body_str);
836 body = use_signature ? g_strconcat("\n--\n", signature, NULL) : g_strdup("");
839 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, NULL, NULL, body, NULL, NULL, NULL);
841 g_printerr ("modest: failed to create new msg\n");
845 /* Create and register edit window */
846 /* This is destroyed by TODO. */
848 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
849 msg_win = modest_msg_edit_window_new (msg, account_name, mailbox, FALSE);
851 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, win)) {
852 gtk_widget_destroy (GTK_WIDGET (msg_win));
855 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
856 gtk_widget_show_all (GTK_WIDGET (msg_win));
858 while (attachments) {
860 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
861 attachments->data, allowed_size);
863 if (total_size > allowed_size) {
864 g_warning ("%s: total size: %u",
865 __FUNCTION__, (unsigned int)total_size);
868 allowed_size -= total_size;
870 attachments = g_slist_next(attachments);
877 g_free (account_name);
879 g_object_unref (G_OBJECT(account));
881 g_object_unref (G_OBJECT(folder));
883 g_object_unref (G_OBJECT(msg));
887 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
889 /* if there are no accounts yet, just show the wizard */
890 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
891 if (!modest_ui_actions_run_account_setup_wizard (win))
894 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
899 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
903 ModestMailOperationStatus status;
905 /* If there is no message or the operation was not successful */
906 status = modest_mail_operation_get_status (mail_op);
907 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
910 /* If it's a memory low issue, then show a banner */
911 error = modest_mail_operation_get_error (mail_op);
912 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
913 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
914 GObject *source = modest_mail_operation_get_source (mail_op);
915 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
916 _KR("memr_ib_operation_disabled"),
918 g_object_unref (source);
921 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
922 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
923 gchar *subject, *msg, *format = NULL;
925 subject = tny_header_dup_subject (header);
927 subject = g_strdup (_("mail_va_no_subject"));
929 account = modest_mail_operation_get_account (mail_op);
931 ModestProtocol *protocol;
932 ModestProtocolType proto;
933 proto = modest_tny_account_get_protocol_type (account);
934 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), proto);
936 format = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
937 g_object_unref (account);
941 format = g_strdup (_("emev_ni_ui_imap_message_not_available_in_server"));
943 msg = g_strdup_printf (format, subject);
944 modest_platform_run_information_dialog (NULL, msg, FALSE);
950 /* Remove the header from the preregistered uids */
951 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
969 OpenMsgBannerInfo *banner_info;
970 GtkTreeRowReference *rowref;
974 open_msg_banner_idle (gpointer userdata)
976 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
978 gdk_threads_enter ();
979 banner_info->idle_handler = 0;
980 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
981 if (banner_info->banner)
982 g_object_ref (banner_info->banner);
984 gdk_threads_leave ();
990 get_header_view_from_window (ModestWindow *window)
992 GtkWidget *header_view;
994 if (MODEST_IS_MAIN_WINDOW (window)) {
995 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
996 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
997 #ifdef MODEST_TOOLKIT_HILDON2
998 } else if (MODEST_IS_HEADER_WINDOW (window)){
999 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
1009 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
1012 gchar *account = NULL;
1013 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
1018 folder = tny_header_get_folder (header);
1019 /* Gets folder type (OUTBOX headers will be opened in edit window */
1020 if (modest_tny_folder_is_local_folder (folder)) {
1021 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1022 if (folder_type == TNY_FOLDER_TYPE_INVALID)
1023 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1026 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
1027 TnyTransportAccount *traccount = NULL;
1028 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
1029 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
1031 ModestTnySendQueue *send_queue = NULL;
1032 ModestTnySendQueueStatus status;
1034 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
1035 TNY_ACCOUNT(traccount)));
1036 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
1037 if (TNY_IS_SEND_QUEUE (send_queue)) {
1038 msg_id = modest_tny_send_queue_get_msg_id (header);
1039 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
1041 /* Only open messages in outbox with the editor if they are in Failed state */
1042 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
1045 #ifdef MODEST_TOOLKIT_HILDON2
1047 /* In Fremantle we can not
1048 open any message from
1049 outbox which is not in
1055 g_object_unref(traccount);
1057 g_warning("Cannot get transport account for message in outbox!!");
1059 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
1060 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
1064 TnyAccount *acc = tny_folder_get_account (folder);
1067 g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (acc));
1068 g_object_unref (acc);
1072 g_object_unref (folder);
1078 open_msg_cb (ModestMailOperation *mail_op,
1085 ModestWindowMgr *mgr = NULL;
1086 ModestWindow *parent_win = NULL;
1087 ModestWindow *win = NULL;
1088 gchar *account = NULL;
1089 gboolean open_in_editor = FALSE;
1091 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1093 /* Do nothing if there was any problem with the mail
1094 operation. The error will be shown by the error_handler of
1095 the mail operation */
1096 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1099 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1101 /* Mark header as read */
1102 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1104 account = get_info_from_header (header, &open_in_editor, &can_open);
1108 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1110 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1112 if (open_in_editor) {
1113 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1114 gchar *from_header = NULL, *acc_name;
1115 gchar *mailbox = NULL;
1117 from_header = tny_header_dup_from (header);
1119 /* we cannot edit without a valid account... */
1120 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1121 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1122 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1124 g_free (from_header);
1129 acc_name = modest_utils_get_account_name_from_recipient (from_header, &mailbox);
1130 g_free (from_header);
1136 win = modest_msg_edit_window_new (msg, account, mailbox, TRUE);
1140 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1141 const gchar *mailbox = NULL;
1143 if (parent_win && MODEST_IS_WINDOW (parent_win))
1144 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_win));
1146 if (helper->rowref && helper->model) {
1147 win = modest_msg_view_window_new_with_header_model (msg, account, mailbox, (const gchar*) uid,
1148 helper->model, helper->rowref);
1150 win = modest_msg_view_window_new_for_attachment (msg, account, mailbox, (const gchar*) uid);
1155 /* Register and show new window */
1157 mgr = modest_runtime_get_window_mgr ();
1158 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1159 gtk_widget_destroy (GTK_WIDGET (win));
1162 gtk_widget_show_all (GTK_WIDGET(win));
1165 /* Update toolbar dimming state */
1166 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1167 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1173 g_object_unref (parent_win);
1177 is_memory_full_error (GError *error, ModestMailOperation *mail_op)
1179 gboolean enough_free_space = TRUE;
1180 GnomeVFSURI *cache_dir_uri;
1181 const gchar *cache_dir = NULL;
1182 GnomeVFSFileSize free_space;
1183 TnyAccountStore *acc_store;
1185 acc_store = TNY_ACCOUNT_STORE (modest_runtime_get_account_store ());
1187 /* Cache dir is different in case we're using an external storage (like MMC account) */
1189 TnyAccount *account = modest_mail_operation_get_account (mail_op);
1191 if (modest_tny_account_is_memory_card_account (account)) {
1192 cache_dir = g_getenv (MODEST_MMC1_VOLUMEPATH_ENV);
1194 g_object_unref (account);
1198 /* Get the default local cache dir */
1200 cache_dir = tny_account_store_get_cache_dir (acc_store);
1202 cache_dir_uri = gnome_vfs_uri_new (cache_dir);
1203 if (cache_dir_uri) {
1204 if (gnome_vfs_get_volume_free_space (cache_dir_uri, &free_space) == GNOME_VFS_OK) {
1205 if (free_space < MIN_FREE_SPACE)
1206 enough_free_space = FALSE;
1208 gnome_vfs_uri_unref (cache_dir_uri);
1211 if ((error->code == TNY_SYSTEM_ERROR_MEMORY ||
1212 /* When asking for a mail and no space left on device
1213 tinymail returns this error */
1214 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE ||
1215 /* When the folder summary could not be read or
1217 error->code == TNY_IO_ERROR_WRITE ||
1218 error->code == TNY_IO_ERROR_READ) &&
1219 !enough_free_space) {
1227 check_memory_full_error (GtkWidget *parent_window, GError *err)
1232 if (is_memory_full_error (err, NULL)) {
1233 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
1234 modest_platform_information_banner (parent_window, NULL, msg);
1236 } else if (err->code == TNY_SYSTEM_ERROR_MEMORY)
1237 /* If the account was created in memory full
1238 conditions then tinymail won't be able to
1239 connect so it'll return this error code */
1240 modest_platform_information_banner (parent_window,
1241 NULL, _("emev_ui_imap_inbox_select_error"));
1249 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1252 const GError *error;
1253 GObject *win = NULL;
1254 ModestMailOperationStatus status;
1256 win = modest_mail_operation_get_source (mail_op);
1257 error = modest_mail_operation_get_error (mail_op);
1258 status = modest_mail_operation_get_status (mail_op);
1260 /* If the mail op has been cancelled then it's not an error:
1261 don't show any message */
1262 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1263 if (is_memory_full_error ((GError *) error, mail_op)) {
1264 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
1265 modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
1267 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1268 modest_platform_information_banner ((GtkWidget *) win,
1269 NULL, _("emev_ui_imap_inbox_select_error"));
1270 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1271 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1272 modest_platform_information_banner ((GtkWidget *) win,
1273 NULL, _CS ("sfil_ni_unable_to_open_file_not_found"));
1274 } else if (user_data) {
1275 modest_platform_information_banner ((GtkWidget *) win,
1281 g_object_unref (win);
1285 * Returns the account a list of headers belongs to. It returns a
1286 * *new* reference so don't forget to unref it
1289 get_account_from_header_list (TnyList *headers)
1291 TnyAccount *account = NULL;
1293 if (tny_list_get_length (headers) > 0) {
1294 TnyIterator *iter = tny_list_create_iterator (headers);
1295 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1296 TnyFolder *folder = tny_header_get_folder (header);
1299 g_object_unref (header);
1301 while (!tny_iterator_is_done (iter)) {
1302 header = TNY_HEADER (tny_iterator_get_current (iter));
1303 folder = tny_header_get_folder (header);
1306 g_object_unref (header);
1308 tny_iterator_next (iter);
1313 account = tny_folder_get_account (folder);
1314 g_object_unref (folder);
1318 g_object_unref (header);
1320 g_object_unref (iter);
1326 get_account_from_header (TnyHeader *header)
1328 TnyAccount *account = NULL;
1331 folder = tny_header_get_folder (header);
1334 account = tny_folder_get_account (folder);
1335 g_object_unref (folder);
1341 open_msg_helper_destroyer (gpointer user_data)
1343 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1345 if (helper->banner_info) {
1346 g_free (helper->banner_info->message);
1347 if (helper->banner_info->idle_handler > 0) {
1348 g_source_remove (helper->banner_info->idle_handler);
1349 helper->banner_info->idle_handler = 0;
1351 if (helper->banner_info->banner != NULL) {
1352 gtk_widget_destroy (helper->banner_info->banner);
1353 g_object_unref (helper->banner_info->banner);
1354 helper->banner_info->banner = NULL;
1356 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1357 helper->banner_info = NULL;
1359 g_object_unref (helper->model);
1360 g_object_unref (helper->header);
1361 gtk_tree_row_reference_free (helper->rowref);
1362 g_slice_free (OpenMsgHelper, helper);
1366 open_msg_performer(gboolean canceled,
1368 GtkWindow *parent_window,
1369 TnyAccount *account,
1372 ModestMailOperation *mail_op = NULL;
1373 gchar *error_msg = NULL;
1374 ModestProtocolType proto;
1375 TnyConnectionStatus status;
1376 OpenMsgHelper *helper = NULL;
1377 ModestProtocol *protocol;
1378 ModestProtocolRegistry *protocol_registry;
1381 helper = (OpenMsgHelper *) user_data;
1383 status = tny_account_get_connection_status (account);
1384 if (err || canceled) {
1385 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1386 /* Free the helper */
1387 open_msg_helper_destroyer (helper);
1389 /* In memory full conditions we could get this error here */
1390 check_memory_full_error ((GtkWidget *) parent_window, err);
1395 /* Get the error message depending on the protocol */
1396 proto = modest_tny_account_get_protocol_type (account);
1397 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1398 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1401 protocol_registry = modest_runtime_get_protocol_registry ();
1402 subject = tny_header_dup_subject (helper->header);
1404 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1405 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1409 if (error_msg == NULL) {
1410 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1413 #ifndef MODEST_TOOLKIT_HILDON2
1414 gboolean show_open_draft = FALSE;
1415 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1417 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1419 TnyFolderType folder_type;
1421 folder = tny_header_get_folder (helper->header);
1422 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1423 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1424 g_object_unref (folder);
1428 #ifdef MODEST_TOOLKIT_HILDON2
1431 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1434 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1435 g_free (account_name);
1436 open_msg_helper_destroyer (helper);
1441 ModestWindow *window;
1442 GtkWidget *header_view;
1445 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1446 uid = modest_tny_folder_get_header_unique_id (helper->header);
1448 const gchar *mailbox = NULL;
1449 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_window));
1450 window = modest_msg_view_window_new_from_header_view
1451 (MODEST_HEADER_VIEW (header_view), account_name, mailbox, uid, helper->rowref);
1452 if (window != NULL) {
1453 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1455 gtk_widget_destroy (GTK_WIDGET (window));
1457 gtk_widget_show_all (GTK_WIDGET(window));
1461 g_free (account_name);
1463 open_msg_helper_destroyer (helper);
1466 g_free (account_name);
1468 /* Create the mail operation */
1470 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1471 modest_ui_actions_disk_operations_error_handler,
1472 g_strdup (error_msg), g_free);
1473 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1477 #ifndef MODEST_TOOLKIT_HILDON2
1478 if (show_open_draft) {
1479 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1480 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1481 helper->banner_info->banner = NULL;
1482 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1483 helper->banner_info);
1489 headers = TNY_LIST (tny_simple_list_new ());
1490 tny_list_prepend (headers, G_OBJECT (helper->header));
1491 modest_mail_operation_get_msgs_full (mail_op,
1495 open_msg_helper_destroyer);
1496 g_object_unref (headers);
1503 g_object_unref (mail_op);
1504 g_object_unref (account);
1508 * This function is used by both modest_ui_actions_on_open and
1509 * modest_ui_actions_on_header_activated. This way we always do the
1510 * same when trying to open messages.
1513 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1515 ModestWindowMgr *mgr = NULL;
1516 TnyAccount *account;
1517 gboolean cached = FALSE;
1519 GtkWidget *header_view = NULL;
1520 OpenMsgHelper *helper;
1521 ModestWindow *window;
1523 g_return_if_fail (header != NULL && rowref != NULL);
1525 mgr = modest_runtime_get_window_mgr ();
1528 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1529 if (header_view == NULL)
1532 /* Get the account */
1533 account = get_account_from_header (header);
1538 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1540 /* Do not open again the message and present the
1541 window to the user */
1544 #ifndef MODEST_TOOLKIT_HILDON2
1545 gtk_window_present (GTK_WINDOW (window));
1548 /* the header has been registered already, we don't do
1549 * anything but wait for the window to come up*/
1550 g_debug ("header %p already registered, waiting for window", header);
1555 /* Open each message */
1556 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1558 /* Allways download if we are online. */
1559 if (!tny_device_is_online (modest_runtime_get_device ())) {
1562 /* If ask for user permission to download the messages */
1563 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1564 _("mcen_nc_get_msg"));
1566 /* End if the user does not want to continue */
1567 if (response == GTK_RESPONSE_CANCEL) {
1573 /* We register the window for opening */
1574 modest_window_mgr_register_header (mgr, header, NULL);
1576 /* Create the helper. We need to get a reference to the model
1577 here because it could change while the message is readed
1578 (the user could switch between folders) */
1579 helper = g_slice_new (OpenMsgHelper);
1580 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1581 helper->header = g_object_ref (header);
1582 helper->rowref = gtk_tree_row_reference_copy (rowref);
1583 helper->banner_info = NULL;
1585 /* Connect to the account and perform */
1587 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1588 open_msg_performer, helper);
1590 /* Call directly the performer, do not need to connect */
1591 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1592 g_object_ref (account), helper);
1597 g_object_unref (account);
1601 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1608 /* we check for low-mem; in that case, show a warning, and don't allow
1611 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1615 headers = get_selected_headers (win);
1619 headers_count = tny_list_get_length (headers);
1620 if (headers_count != 1) {
1621 if (headers_count > 1) {
1622 /* Don't allow activation if there are more than one message selected */
1623 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1626 g_object_unref (headers);
1630 iter = tny_list_create_iterator (headers);
1631 header = TNY_HEADER (tny_iterator_get_current (iter));
1632 g_object_unref (iter);
1636 open_msg_from_header (header, NULL, win);
1637 g_object_unref (header);
1640 g_object_unref(headers);
1644 rf_helper_window_closed (gpointer data,
1647 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1649 helper->parent_window = NULL;
1652 static ReplyForwardHelper*
1653 create_reply_forward_helper (ReplyForwardAction action,
1655 guint reply_forward_type,
1658 ReplyForwardHelper *rf_helper = NULL;
1659 const gchar *active_acc = modest_window_get_active_account (win);
1660 const gchar *active_mailbox = modest_window_get_active_mailbox (win);
1662 rf_helper = g_slice_new0 (ReplyForwardHelper);
1663 rf_helper->reply_forward_type = reply_forward_type;
1664 rf_helper->action = action;
1665 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1666 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1667 rf_helper->account_name = (active_acc) ?
1668 g_strdup (active_acc) :
1669 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1670 rf_helper->mailbox = g_strdup (active_mailbox);
1672 /* Note that window could be destroyed just AFTER calling
1673 register_window so we must ensure that this pointer does
1674 not hold invalid references */
1675 if (rf_helper->parent_window)
1676 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1677 rf_helper_window_closed, rf_helper);
1683 free_reply_forward_helper (gpointer data)
1685 ReplyForwardHelper *helper;
1687 helper = (ReplyForwardHelper *) data;
1688 g_free (helper->account_name);
1689 g_free (helper->mailbox);
1691 g_object_unref (helper->header);
1692 if (helper->parent_window)
1693 g_object_weak_unref (G_OBJECT (helper->parent_window),
1694 rf_helper_window_closed, helper);
1695 g_slice_free (ReplyForwardHelper, helper);
1699 reply_forward_cb (ModestMailOperation *mail_op,
1706 TnyMsg *new_msg = NULL;
1707 ReplyForwardHelper *rf_helper;
1708 ModestWindow *msg_win = NULL;
1709 ModestEditType edit_type;
1711 TnyAccount *account = NULL;
1712 ModestWindowMgr *mgr = NULL;
1713 gchar *signature = NULL;
1714 gboolean use_signature;
1717 /* If there was any error. The mail operation could be NULL,
1718 this means that we already have the message downloaded and
1719 that we didn't do a mail operation to retrieve it */
1720 rf_helper = (ReplyForwardHelper *) user_data;
1721 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1724 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1725 rf_helper->account_name, rf_helper->mailbox);
1726 recipient = modest_text_utils_get_email_address (from);
1727 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr(),
1732 /* Create reply mail */
1733 switch (rf_helper->action) {
1736 modest_tny_msg_create_reply_msg (msg, header, from,
1737 (use_signature) ? signature : NULL,
1738 rf_helper->reply_forward_type,
1739 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1741 case ACTION_REPLY_TO_ALL:
1743 modest_tny_msg_create_reply_msg (msg, header, from,
1744 (use_signature) ? signature : NULL,
1745 rf_helper->reply_forward_type,
1746 MODEST_TNY_MSG_REPLY_MODE_ALL);
1747 edit_type = MODEST_EDIT_TYPE_REPLY;
1749 case ACTION_FORWARD:
1751 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1752 rf_helper->reply_forward_type);
1753 edit_type = MODEST_EDIT_TYPE_FORWARD;
1756 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1758 g_return_if_reached ();
1766 g_warning ("%s: failed to create message\n", __FUNCTION__);
1770 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1771 rf_helper->account_name,
1772 TNY_ACCOUNT_TYPE_STORE);
1774 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1778 /* Create and register the windows */
1779 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, rf_helper->mailbox, FALSE);
1780 mgr = modest_runtime_get_window_mgr ();
1781 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1783 /* Note that register_window could have deleted the account */
1784 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1785 gdouble parent_zoom;
1787 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1788 modest_window_set_zoom (msg_win, parent_zoom);
1791 /* Show edit window */
1792 gtk_widget_show_all (GTK_WIDGET (msg_win));
1795 /* We always unregister the header because the message is
1796 forwarded or replied so the original one is no longer
1798 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1801 g_object_unref (G_OBJECT (new_msg));
1803 g_object_unref (G_OBJECT (account));
1804 free_reply_forward_helper (rf_helper);
1807 /* Checks a list of headers. If any of them are not currently
1808 * downloaded (CACHED) then returns TRUE else returns FALSE.
1811 header_list_count_uncached_msgs (TnyList *header_list)
1814 gint uncached_messages = 0;
1816 iter = tny_list_create_iterator (header_list);
1817 while (!tny_iterator_is_done (iter)) {
1820 header = TNY_HEADER (tny_iterator_get_current (iter));
1822 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1823 uncached_messages ++;
1824 g_object_unref (header);
1827 tny_iterator_next (iter);
1829 g_object_unref (iter);
1831 return uncached_messages;
1834 /* Returns FALSE if the user does not want to download the
1835 * messages. Returns TRUE if the user allowed the download.
1838 connect_to_get_msg (ModestWindow *win,
1839 gint num_of_uncached_msgs,
1840 TnyAccount *account)
1842 GtkResponseType response;
1844 /* Allways download if we are online. */
1845 if (tny_device_is_online (modest_runtime_get_device ()))
1848 /* If offline, then ask for user permission to download the messages */
1849 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1850 ngettext("mcen_nc_get_msg",
1852 num_of_uncached_msgs));
1854 if (response == GTK_RESPONSE_CANCEL)
1857 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1861 reply_forward_performer (gboolean canceled,
1863 GtkWindow *parent_window,
1864 TnyAccount *account,
1867 ReplyForwardHelper *rf_helper = NULL;
1868 ModestMailOperation *mail_op;
1870 rf_helper = (ReplyForwardHelper *) user_data;
1872 if (canceled || err) {
1873 free_reply_forward_helper (rf_helper);
1877 /* Retrieve the message */
1878 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1879 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1880 modest_ui_actions_disk_operations_error_handler,
1882 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1883 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1886 g_object_unref(mail_op);
1890 * Common code for the reply and forward actions
1893 reply_forward (ReplyForwardAction action, ModestWindow *win)
1895 ReplyForwardHelper *rf_helper = NULL;
1896 guint reply_forward_type;
1898 g_return_if_fail (MODEST_IS_WINDOW(win));
1900 /* we check for low-mem; in that case, show a warning, and don't allow
1901 * reply/forward (because it could potentially require a lot of memory */
1902 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1906 /* we need an account when editing */
1907 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1908 if (!modest_ui_actions_run_account_setup_wizard (win))
1912 reply_forward_type =
1913 modest_conf_get_int (modest_runtime_get_conf (),
1914 (action == ACTION_FORWARD) ?
1915 MODEST_CONF_FORWARD_TYPE :
1916 MODEST_CONF_REPLY_TYPE,
1919 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1921 TnyHeader *header = NULL;
1922 /* Get header and message. Do not free them here, the
1923 reply_forward_cb must do it */
1924 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1925 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1927 if (msg && header) {
1929 rf_helper = create_reply_forward_helper (action, win,
1930 reply_forward_type, header);
1931 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1933 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1937 g_object_unref (msg);
1939 g_object_unref (header);
1941 TnyHeader *header = NULL;
1943 gboolean do_retrieve = TRUE;
1944 TnyList *header_list = NULL;
1946 header_list = get_selected_headers (win);
1949 /* Check that only one message is selected for replying */
1950 if (tny_list_get_length (header_list) != 1) {
1951 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1952 NULL, _("mcen_ib_select_one_message"));
1953 g_object_unref (header_list);
1957 /* Only reply/forward to one message */
1958 iter = tny_list_create_iterator (header_list);
1959 header = TNY_HEADER (tny_iterator_get_current (iter));
1960 g_object_unref (iter);
1962 /* Retrieve messages */
1963 do_retrieve = (action == ACTION_FORWARD) ||
1964 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1967 TnyAccount *account = NULL;
1968 TnyFolder *folder = NULL;
1969 gdouble download = TRUE;
1970 guint uncached_msgs = 0;
1972 folder = tny_header_get_folder (header);
1974 goto do_retrieve_frees;
1975 account = tny_folder_get_account (folder);
1977 goto do_retrieve_frees;
1979 uncached_msgs = header_list_count_uncached_msgs (header_list);
1981 if (uncached_msgs > 0) {
1982 /* Allways download if we are online. */
1983 if (!tny_device_is_online (modest_runtime_get_device ())) {
1986 /* If ask for user permission to download the messages */
1987 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1988 ngettext("mcen_nc_get_msg",
1992 /* End if the user does not want to continue */
1993 if (response == GTK_RESPONSE_CANCEL)
2000 rf_helper = create_reply_forward_helper (action, win,
2001 reply_forward_type, header);
2002 if (uncached_msgs > 0) {
2003 modest_platform_connect_and_perform (GTK_WINDOW (win),
2005 reply_forward_performer,
2008 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
2009 account, rf_helper);
2014 g_object_unref (account);
2016 g_object_unref (folder);
2018 reply_forward_cb (NULL, header, FALSE, NULL, NULL, rf_helper);
2021 g_object_unref (header_list);
2022 g_object_unref (header);
2027 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
2029 g_return_if_fail (MODEST_IS_WINDOW(win));
2031 reply_forward (ACTION_REPLY, win);
2035 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
2037 g_return_if_fail (MODEST_IS_WINDOW(win));
2039 reply_forward (ACTION_FORWARD, win);
2043 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
2045 g_return_if_fail (MODEST_IS_WINDOW(win));
2047 reply_forward (ACTION_REPLY_TO_ALL, win);
2051 modest_ui_actions_on_next (GtkAction *action,
2052 ModestWindow *window)
2054 if (MODEST_IS_MAIN_WINDOW (window)) {
2055 GtkWidget *header_view;
2057 header_view = modest_main_window_get_child_widget (
2058 MODEST_MAIN_WINDOW(window),
2059 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2063 modest_header_view_select_next (
2064 MODEST_HEADER_VIEW(header_view));
2065 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2066 modest_msg_view_window_select_next_message (
2067 MODEST_MSG_VIEW_WINDOW (window));
2069 g_return_if_reached ();
2074 modest_ui_actions_on_prev (GtkAction *action,
2075 ModestWindow *window)
2077 g_return_if_fail (MODEST_IS_WINDOW(window));
2079 if (MODEST_IS_MAIN_WINDOW (window)) {
2080 GtkWidget *header_view;
2081 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2082 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2086 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
2087 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2088 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
2090 g_return_if_reached ();
2095 modest_ui_actions_on_sort (GtkAction *action,
2096 ModestWindow *window)
2098 GtkWidget *header_view = NULL;
2100 g_return_if_fail (MODEST_IS_WINDOW(window));
2102 if (MODEST_IS_MAIN_WINDOW (window)) {
2103 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2104 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2105 #ifdef MODEST_TOOLKIT_HILDON2
2106 } else if (MODEST_IS_HEADER_WINDOW (window)) {
2107 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2112 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
2117 /* Show sorting dialog */
2118 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
2122 new_messages_arrived (ModestMailOperation *self,
2123 TnyList *new_headers,
2127 gboolean show_visual_notifications;
2129 source = modest_mail_operation_get_source (self);
2130 show_visual_notifications = (source) ? FALSE : TRUE;
2132 g_object_unref (source);
2134 /* Notify new messages have been downloaded. If the
2135 send&receive was invoked by the user then do not show any
2136 visual notification, only play a sound and activate the LED
2137 (for the Maemo version) */
2138 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0) {
2140 /* We only notify about really new messages (not seen) we get */
2141 TnyList *actually_new_list;
2142 TnyIterator *iterator;
2143 actually_new_list = TNY_LIST (tny_simple_list_new ());
2144 for (iterator = tny_list_create_iterator (new_headers);
2145 !tny_iterator_is_done (iterator);
2146 tny_iterator_next (iterator)) {
2148 TnyHeaderFlags flags;
2149 header = TNY_HEADER (tny_iterator_get_current (iterator));
2150 flags = tny_header_get_flags (header);
2152 if (!(flags & TNY_HEADER_FLAG_SEEN)) {
2153 tny_list_append (actually_new_list, G_OBJECT (header));
2155 g_object_unref (header);
2158 g_object_unref (iterator);
2160 if (tny_list_get_length (actually_new_list) > 0) {
2161 modest_platform_on_new_headers_received (actually_new_list,
2162 show_visual_notifications);
2164 g_object_unref (actually_new_list);
2170 retrieve_all_messages_cb (GObject *source,
2172 guint retrieve_limit)
2178 window = GTK_WINDOW (source);
2179 msg = g_strdup_printf (_("mail_nc_msg_count_limit_exceeded"),
2180 num_msgs, retrieve_limit);
2182 /* Ask the user if they want to retrieve all the messages */
2184 modest_platform_run_confirmation_dialog_with_buttons (window, msg,
2185 _("mcen_bd_get_all"),
2186 _("mcen_bd_newest_only"));
2187 /* Free and return */
2189 return (response == GTK_RESPONSE_ACCEPT) ? TRUE : FALSE;
2193 TnyAccount *account;
2195 gchar *account_name;
2196 gboolean poke_status;
2197 gboolean interactive;
2198 ModestMailOperation *mail_op;
2202 do_send_receive_performer (gboolean canceled,
2204 GtkWindow *parent_window,
2205 TnyAccount *account,
2208 SendReceiveInfo *info;
2210 info = (SendReceiveInfo *) user_data;
2212 if (err || canceled) {
2213 /* In memory full conditions we could get this error here */
2214 check_memory_full_error ((GtkWidget *) parent_window, err);
2216 if (info->mail_op) {
2217 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2223 /* Set send/receive operation in progress */
2224 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2225 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2228 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2229 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2230 G_CALLBACK (on_send_receive_finished),
2233 /* Send & receive. */
2234 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2235 (info->win) ? retrieve_all_messages_cb : NULL,
2236 new_messages_arrived, info->win);
2241 g_object_unref (G_OBJECT (info->mail_op));
2242 if (info->account_name)
2243 g_free (info->account_name);
2245 g_object_unref (info->win);
2247 g_object_unref (info->account);
2248 g_slice_free (SendReceiveInfo, info);
2252 * This function performs the send & receive required actions. The
2253 * window is used to create the mail operation. Typically it should
2254 * always be the main window, but we pass it as argument in order to
2258 modest_ui_actions_do_send_receive (const gchar *account_name,
2259 gboolean force_connection,
2260 gboolean poke_status,
2261 gboolean interactive,
2264 gchar *acc_name = NULL;
2265 SendReceiveInfo *info;
2266 ModestTnyAccountStore *acc_store;
2268 /* If no account name was provided then get the current account, and if
2269 there is no current account then pick the default one: */
2270 if (!account_name) {
2272 acc_name = g_strdup (modest_window_get_active_account (win));
2274 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2276 g_printerr ("modest: cannot get default account\n");
2280 acc_name = g_strdup (account_name);
2283 acc_store = modest_runtime_get_account_store ();
2285 /* Create the info for the connect and perform */
2286 info = g_slice_new (SendReceiveInfo);
2287 info->account_name = acc_name;
2288 info->win = (win) ? g_object_ref (win) : NULL;
2289 info->poke_status = poke_status;
2290 info->interactive = interactive;
2291 info->account = modest_tny_account_store_get_server_account (acc_store, acc_name,
2292 TNY_ACCOUNT_TYPE_STORE);
2293 /* We need to create the operation here, because otherwise it
2294 could happen that the queue emits the queue-empty signal
2295 while we're trying to connect the account */
2296 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2297 modest_ui_actions_disk_operations_error_handler,
2299 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2301 /* Invoke the connect and perform */
2302 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2303 force_connection, info->account,
2304 do_send_receive_performer, info);
2309 modest_ui_actions_do_cancel_send (const gchar *account_name,
2312 TnyTransportAccount *transport_account;
2313 TnySendQueue *send_queue = NULL;
2314 GError *error = NULL;
2316 /* Get transport account */
2318 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2319 (modest_runtime_get_account_store(),
2321 TNY_ACCOUNT_TYPE_TRANSPORT));
2322 if (!transport_account) {
2323 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2328 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2329 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2330 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2331 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2332 "modest: could not find send queue for account\n");
2334 /* Cancel the current send */
2335 tny_account_cancel (TNY_ACCOUNT (transport_account));
2337 /* Suspend all pending messages */
2338 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2342 if (transport_account != NULL)
2343 g_object_unref (G_OBJECT (transport_account));
2347 modest_ui_actions_cancel_send_all (ModestWindow *win)
2349 GSList *account_names, *iter;
2351 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2354 iter = account_names;
2356 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2357 iter = g_slist_next (iter);
2360 modest_account_mgr_free_account_names (account_names);
2361 account_names = NULL;
2365 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2368 /* Check if accounts exist */
2369 gboolean accounts_exist =
2370 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2372 /* If not, allow the user to create an account before trying to send/receive. */
2373 if (!accounts_exist)
2374 modest_ui_actions_on_accounts (NULL, win);
2376 /* Cancel all sending operaitons */
2377 modest_ui_actions_cancel_send_all (win);
2381 * Refreshes all accounts. This function will be used by automatic
2385 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2386 gboolean force_connection,
2387 gboolean poke_status,
2388 gboolean interactive)
2390 GSList *account_names, *iter;
2392 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2395 iter = account_names;
2397 modest_ui_actions_do_send_receive ((const char*) iter->data,
2399 poke_status, interactive, win);
2400 iter = g_slist_next (iter);
2403 modest_account_mgr_free_account_names (account_names);
2404 account_names = NULL;
2408 * Handler of the click on Send&Receive button in the main toolbar
2411 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2413 /* Check if accounts exist */
2414 gboolean accounts_exist;
2417 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2419 /* If not, allow the user to create an account before trying to send/receive. */
2420 if (!accounts_exist)
2421 modest_ui_actions_on_accounts (NULL, win);
2423 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2424 if (MODEST_IS_MAIN_WINDOW (win)) {
2425 GtkWidget *folder_view;
2426 TnyFolderStore *folder_store;
2429 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2430 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2434 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2437 g_object_unref (folder_store);
2438 /* Refresh the active account. Force the connection if needed
2439 and poke the status of all folders */
2440 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2441 #ifdef MODEST_TOOLKIT_HILDON2
2442 } else if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2443 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2446 const gchar *active_account;
2447 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2449 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2456 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2459 GtkWidget *header_view;
2461 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2463 header_view = modest_main_window_get_child_widget (main_window,
2464 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2468 conf = modest_runtime_get_conf ();
2470 /* what is saved/restored is depending on the style; thus; we save with
2471 * old style, then update the style, and restore for this new style
2473 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2475 if (modest_header_view_get_style
2476 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2477 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2478 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2480 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2481 MODEST_HEADER_VIEW_STYLE_DETAILS);
2483 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2484 MODEST_CONF_HEADER_VIEW_KEY);
2489 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2491 ModestMainWindow *main_window)
2493 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2494 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2496 /* in the case the folder is empty, show the empty folder message and focus
2498 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2499 if (modest_header_view_is_empty (header_view)) {
2500 TnyFolder *folder = modest_header_view_get_folder (header_view);
2501 GtkWidget *folder_view =
2502 modest_main_window_get_child_widget (main_window,
2503 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2504 if (folder != NULL) {
2505 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2506 g_object_unref (folder);
2508 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2512 /* If no header has been selected then exit */
2517 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2518 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2520 /* Update toolbar dimming state */
2521 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2522 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2526 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2529 ModestWindow *window)
2531 GtkWidget *open_widget;
2532 GtkTreeRowReference *rowref;
2534 g_return_if_fail (MODEST_IS_WINDOW(window));
2535 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2536 g_return_if_fail (TNY_IS_HEADER (header));
2538 if (modest_header_view_count_selected_headers (header_view) > 1) {
2539 /* Don't allow activation if there are more than one message selected */
2540 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2544 /* we check for low-mem; in that case, show a warning, and don't allow
2545 * activating headers
2547 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2550 if (MODEST_IS_MAIN_WINDOW (window)) {
2551 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2552 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2553 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2557 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2558 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2559 gtk_tree_row_reference_free (rowref);
2563 set_active_account_from_tny_account (TnyAccount *account,
2564 ModestWindow *window)
2566 const gchar *server_acc_name = tny_account_get_id (account);
2568 /* We need the TnyAccount provided by the
2569 account store because that is the one that
2570 knows the name of the Modest account */
2571 TnyAccount *modest_server_account =
2572 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2573 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2575 if (!modest_server_account) {
2576 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2580 /* Update active account, but only if it's not a pseudo-account */
2581 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2582 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2583 const gchar *modest_acc_name =
2584 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2585 if (modest_acc_name)
2586 modest_window_set_active_account (window, modest_acc_name);
2589 g_object_unref (modest_server_account);
2594 folder_refreshed_cb (ModestMailOperation *mail_op,
2598 ModestMainWindow *win = NULL;
2599 GtkWidget *folder_view, *header_view;
2600 const GError *error;
2602 g_return_if_fail (TNY_IS_FOLDER (folder));
2604 win = MODEST_MAIN_WINDOW (user_data);
2606 /* Check if the operation failed due to memory low conditions */
2607 error = modest_mail_operation_get_error (mail_op);
2608 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2609 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2610 modest_platform_run_information_dialog (GTK_WINDOW (win),
2611 _KR("memr_ib_operation_disabled"),
2617 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2619 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2622 TnyFolderStore *current_folder;
2624 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2625 if (current_folder) {
2626 gboolean different = ((TnyFolderStore *) folder != current_folder);
2627 g_object_unref (current_folder);
2633 /* Check if folder is empty and set headers view contents style */
2634 if ((tny_folder_get_all_count (folder) == 0) ||
2635 modest_header_view_is_empty (MODEST_HEADER_VIEW (header_view)))
2636 modest_main_window_set_contents_style (win,
2637 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2641 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2642 TnyFolderStore *folder_store,
2644 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);
2656 conf = modest_runtime_get_conf ();
2658 if (TNY_IS_ACCOUNT (folder_store)) {
2660 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2662 /* Show account details */
2663 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2666 if (TNY_IS_FOLDER (folder_store) && selected) {
2667 TnyAccount *account;
2668 const gchar *account_name = NULL;
2670 /* Update the active account */
2671 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2673 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2675 modest_tny_account_get_parent_modest_account_name_for_server_account (account);
2676 g_object_unref (account);
2680 /* Set the header style by default, it could
2681 be changed later by the refresh callback to
2683 modest_main_window_set_contents_style (main_window,
2684 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2686 /* Set folder on header view. This function
2687 will call tny_folder_refresh_async so we
2688 pass a callback that will be called when
2689 finished. We use that callback to set the
2690 empty view if there are no messages */
2691 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2692 TNY_FOLDER (folder_store),
2694 MODEST_WINDOW (main_window),
2695 folder_refreshed_cb,
2698 /* Restore configuration. We need to do this
2699 *after* the set_folder because the widget
2700 memory asks the header view about its
2702 modest_widget_memory_restore (modest_runtime_get_conf (),
2703 G_OBJECT(header_view),
2704 MODEST_CONF_HEADER_VIEW_KEY);
2706 /* No need to save the header view
2707 configuration for Maemo because it only
2708 saves the sorting stuff and that it's
2709 already being done by the sort
2710 dialog. Remove it when the GNOME version
2711 has the same behaviour */
2712 #ifdef MODEST_TOOLKIT_GTK
2713 if (modest_main_window_get_contents_style (main_window) ==
2714 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2715 modest_widget_memory_save (conf, G_OBJECT (header_view),
2716 MODEST_CONF_HEADER_VIEW_KEY);
2718 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2722 /* Update dimming state */
2723 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2724 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2728 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2735 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2737 online = tny_device_is_online (modest_runtime_get_device());
2740 /* already online -- the item is simply not there... */
2741 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2743 GTK_MESSAGE_WARNING,
2745 _("The %s you selected cannot be found"),
2747 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2748 gtk_dialog_run (GTK_DIALOG(dialog));
2750 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2753 _("mcen_bd_dialog_cancel"),
2754 GTK_RESPONSE_REJECT,
2755 _("mcen_bd_dialog_ok"),
2756 GTK_RESPONSE_ACCEPT,
2758 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2759 "Do you want to get online?"), item);
2760 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2761 gtk_label_new (txt), FALSE, FALSE, 0);
2762 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2765 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2766 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2767 /* TODO: Comment about why is this commented out: */
2768 /* modest_platform_connect_and_wait (); */
2771 gtk_widget_destroy (dialog);
2775 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2778 /* g_message ("%s %s", __FUNCTION__, link); */
2783 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2786 modest_platform_activate_uri (link);
2790 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2793 modest_platform_show_uri_popup (link);
2797 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2800 /* we check for low-mem; in that case, show a warning, and don't allow
2801 * viewing attachments
2803 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2806 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2810 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2811 const gchar *address,
2814 /* g_message ("%s %s", __FUNCTION__, address); */
2818 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2819 TnyMsg *saved_draft,
2822 ModestMsgEditWindow *edit_window;
2824 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2825 #ifndef MODEST_TOOLKIT_HILDON2
2826 ModestMainWindow *win;
2828 /* FIXME. Make the header view sensitive again. This is a
2829 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2831 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2832 modest_runtime_get_window_mgr(), FALSE));
2834 GtkWidget *hdrview = modest_main_window_get_child_widget(
2835 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2836 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2840 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2842 /* Set draft is there was no error */
2843 if (!modest_mail_operation_get_error (mail_op))
2844 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2846 g_object_unref(edit_window);
2850 enough_space_for_message (ModestMsgEditWindow *edit_window,
2853 TnyAccountStore *acc_store;
2854 guint64 available_disk, expected_size;
2859 acc_store = TNY_ACCOUNT_STORE (modest_runtime_get_account_store());
2860 available_disk = modest_utils_get_available_space (NULL);
2861 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2862 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2867 /* Double check: memory full condition or message too big */
2868 if (available_disk < MIN_FREE_SPACE ||
2869 expected_size > available_disk) {
2870 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
2871 modest_platform_information_banner (NULL, NULL, msg);
2878 * djcb: if we're in low-memory state, we only allow for
2879 * saving messages smaller than
2880 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2881 * should still allow for sending anything critical...
2883 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2884 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2888 * djcb: we also make sure that the attachments are smaller than the max size
2889 * this is for the case where we'd try to forward a message with attachments
2890 * bigger than our max allowed size, or sending an message from drafts which
2891 * somehow got past our checks when attaching.
2893 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2894 modest_platform_run_information_dialog (
2895 GTK_WINDOW(edit_window),
2896 _KR("memr_ib_operation_disabled"),
2905 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2907 TnyTransportAccount *transport_account;
2908 ModestMailOperation *mail_operation;
2910 gchar *account_name;
2911 ModestAccountMgr *account_mgr;
2912 gboolean had_error = FALSE;
2913 ModestMainWindow *win = NULL;
2915 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2917 data = modest_msg_edit_window_get_msg_data (edit_window);
2920 if (!enough_space_for_message (edit_window, data)) {
2921 modest_msg_edit_window_free_msg_data (edit_window, data);
2925 account_name = g_strdup (data->account_name);
2926 account_mgr = modest_runtime_get_account_mgr();
2928 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2930 account_name = modest_account_mgr_get_default_account (account_mgr);
2931 if (!account_name) {
2932 g_printerr ("modest: no account found\n");
2933 modest_msg_edit_window_free_msg_data (edit_window, data);
2937 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2938 account_name = g_strdup (data->account_name);
2942 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2943 (modest_runtime_get_account_store (),
2945 TNY_ACCOUNT_TYPE_TRANSPORT));
2946 if (!transport_account) {
2947 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2948 g_free (account_name);
2949 modest_msg_edit_window_free_msg_data (edit_window, data);
2953 /* Create the mail operation */
2954 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
2956 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2958 modest_mail_operation_save_to_drafts (mail_operation,
2970 data->priority_flags,
2973 on_save_to_drafts_cb,
2974 g_object_ref(edit_window));
2976 #ifdef MODEST_TOOLKIT_HILDON2
2977 /* In hildon2 we always show the information banner on saving to drafts.
2978 * It will be a system information banner in this case.
2980 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2981 modest_platform_information_banner (NULL, NULL, text);
2984 /* Use the main window as the parent of the banner, if the
2985 main window does not exist it won't be shown, if the parent
2986 window exists then it's properly shown. We don't use the
2987 editor window because it could be closed (save to drafts
2988 could happen after closing the window */
2989 win = (ModestMainWindow *)
2990 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
2992 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2993 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
2997 modest_msg_edit_window_set_modified (edit_window, FALSE);
3000 g_free (account_name);
3001 g_object_unref (G_OBJECT (transport_account));
3002 g_object_unref (G_OBJECT (mail_operation));
3004 modest_msg_edit_window_free_msg_data (edit_window, data);
3007 * If the drafts folder is selected then make the header view
3008 * insensitive while the message is being saved to drafts
3009 * (it'll be sensitive again in on_save_to_drafts_cb()). This
3010 * is not very clean but it avoids letting the drafts folder
3011 * in an inconsistent state: the user could edit the message
3012 * being saved and undesirable things would happen.
3013 * In the average case the user won't notice anything at
3014 * all. In the worst case (the user is editing a really big
3015 * file from Drafts) the header view will be insensitive
3016 * during the saving process (10 or 20 seconds, depending on
3017 * the message). Anyway this is just a quick workaround: once
3018 * we find a better solution it should be removed
3019 * See NB#65125 (commend #18) for details.
3021 if (!had_error && win != NULL) {
3022 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
3023 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
3025 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
3027 if (modest_tny_folder_is_local_folder(folder)) {
3028 TnyFolderType folder_type;
3029 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
3030 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
3031 GtkWidget *hdrview = modest_main_window_get_child_widget(
3032 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3033 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
3037 if (folder != NULL) g_object_unref(folder);
3044 /* For instance, when clicking the Send toolbar button when editing a message: */
3046 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3048 TnyTransportAccount *transport_account = NULL;
3049 gboolean had_error = FALSE;
3051 ModestAccountMgr *account_mgr;
3052 gchar *account_name;
3053 ModestMailOperation *mail_operation;
3055 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
3057 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
3060 data = modest_msg_edit_window_get_msg_data (edit_window);
3063 if (!enough_space_for_message (edit_window, data)) {
3064 modest_msg_edit_window_free_msg_data (edit_window, data);
3068 account_mgr = modest_runtime_get_account_mgr();
3069 account_name = g_strdup (data->account_name);
3071 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3074 account_name = modest_account_mgr_get_default_account (account_mgr);
3076 if (!account_name) {
3077 modest_msg_edit_window_free_msg_data (edit_window, data);
3078 /* Run account setup wizard */
3079 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
3084 /* Get the currently-active transport account for this modest account: */
3085 if (strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
3087 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3088 (modest_runtime_get_account_store (),
3089 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
3092 if (!transport_account) {
3093 modest_msg_edit_window_free_msg_data (edit_window, data);
3094 /* Run account setup wizard */
3095 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
3100 /* Create the mail operation */
3101 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
3102 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3104 modest_mail_operation_send_new_mail (mail_operation,
3118 data->priority_flags);
3120 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3121 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
3123 if (modest_mail_operation_get_error (mail_operation) != NULL) {
3124 const GError *error = modest_mail_operation_get_error (mail_operation);
3125 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3126 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3127 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3128 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3134 g_free (account_name);
3135 g_object_unref (G_OBJECT (transport_account));
3136 g_object_unref (G_OBJECT (mail_operation));
3138 modest_msg_edit_window_free_msg_data (edit_window, data);
3141 modest_msg_edit_window_set_sent (edit_window, TRUE);
3143 /* Save settings and close the window: */
3144 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3151 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3152 ModestMsgEditWindow *window)
3154 ModestMsgEditFormatState *format_state = NULL;
3156 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3157 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3159 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3162 format_state = modest_msg_edit_window_get_format_state (window);
3163 g_return_if_fail (format_state != NULL);
3165 format_state->bold = gtk_toggle_action_get_active (action);
3166 modest_msg_edit_window_set_format_state (window, format_state);
3167 g_free (format_state);
3172 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3173 ModestMsgEditWindow *window)
3175 ModestMsgEditFormatState *format_state = NULL;
3177 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3178 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3180 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3183 format_state = modest_msg_edit_window_get_format_state (window);
3184 g_return_if_fail (format_state != NULL);
3186 format_state->italics = gtk_toggle_action_get_active (action);
3187 modest_msg_edit_window_set_format_state (window, format_state);
3188 g_free (format_state);
3193 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3194 ModestMsgEditWindow *window)
3196 ModestMsgEditFormatState *format_state = NULL;
3198 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3199 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3201 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3204 format_state = modest_msg_edit_window_get_format_state (window);
3205 g_return_if_fail (format_state != NULL);
3207 format_state->bullet = gtk_toggle_action_get_active (action);
3208 modest_msg_edit_window_set_format_state (window, format_state);
3209 g_free (format_state);
3214 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3215 GtkRadioAction *selected,
3216 ModestMsgEditWindow *window)
3218 ModestMsgEditFormatState *format_state = NULL;
3219 GtkJustification value;
3221 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3223 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3226 value = gtk_radio_action_get_current_value (selected);
3228 format_state = modest_msg_edit_window_get_format_state (window);
3229 g_return_if_fail (format_state != NULL);
3231 format_state->justification = value;
3232 modest_msg_edit_window_set_format_state (window, format_state);
3233 g_free (format_state);
3237 modest_ui_actions_on_select_editor_color (GtkAction *action,
3238 ModestMsgEditWindow *window)
3240 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3241 g_return_if_fail (GTK_IS_ACTION (action));
3243 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3246 modest_msg_edit_window_select_color (window);
3250 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3251 ModestMsgEditWindow *window)
3253 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3254 g_return_if_fail (GTK_IS_ACTION (action));
3256 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3259 modest_msg_edit_window_select_background_color (window);
3263 modest_ui_actions_on_insert_image (GObject *object,
3264 ModestMsgEditWindow *window)
3266 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3269 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3272 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3275 modest_msg_edit_window_insert_image (window);
3279 modest_ui_actions_on_attach_file (GtkAction *action,
3280 ModestMsgEditWindow *window)
3282 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3283 g_return_if_fail (GTK_IS_ACTION (action));
3285 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3288 modest_msg_edit_window_offer_attach_file (window);
3292 modest_ui_actions_on_remove_attachments (GtkAction *action,
3293 ModestMsgEditWindow *window)
3295 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3297 modest_msg_edit_window_remove_attachments (window, NULL);
3301 do_create_folder_cb (ModestMailOperation *mail_op,
3302 TnyFolderStore *parent_folder,
3303 TnyFolder *new_folder,
3306 gchar *suggested_name = (gchar *) user_data;
3307 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3308 const GError *error;
3310 error = modest_mail_operation_get_error (mail_op);
3313 /* Show an error. If there was some problem writing to
3314 disk, show it, otherwise show the generic folder
3315 create error. We do it here and not in an error
3316 handler because the call to do_create_folder will
3317 stop the main loop in a gtk_dialog_run and then,
3318 the message won't be shown until that dialog is
3320 modest_ui_actions_disk_operations_error_handler (mail_op,
3321 _("mail_in_ui_folder_create_error"));
3323 if (!is_memory_full_error ((GError *) error, mail_op)) {
3324 /* Try again if there is no full memory condition */
3325 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3328 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3329 * FIXME: any other? */
3330 GtkWidget *folder_view;
3332 if (MODEST_IS_MAIN_WINDOW(source_win))
3334 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3335 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3337 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3338 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3340 /* Select the newly created folder. It could happen
3341 that the widget is no longer there (i.e. the window
3342 has been destroyed, so we need to check this */
3344 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3346 g_object_unref (new_folder);
3348 /* Free. Note that the first time it'll be NULL so noop */
3349 g_free (suggested_name);
3350 g_object_unref (source_win);
3355 TnyFolderStore *parent;
3356 } CreateFolderConnect;
3359 do_create_folder_performer (gboolean canceled,
3361 GtkWindow *parent_window,
3362 TnyAccount *account,
3365 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3366 ModestMailOperation *mail_op;
3368 if (canceled || err) {
3369 /* In memory full conditions we could get this error here */
3370 check_memory_full_error ((GtkWidget *) parent_window, err);
3374 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3375 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3377 modest_mail_operation_create_folder (mail_op,
3379 (const gchar *) helper->folder_name,
3380 do_create_folder_cb,
3381 g_strdup (helper->folder_name));
3382 g_object_unref (mail_op);
3386 g_object_unref (helper->parent);
3387 if (helper->folder_name)
3388 g_free (helper->folder_name);
3389 g_slice_free (CreateFolderConnect, helper);
3394 do_create_folder (GtkWindow *parent_window,
3395 TnyFolderStore *suggested_parent,
3396 const gchar *suggested_name)
3399 gchar *folder_name = NULL;
3400 TnyFolderStore *parent_folder = NULL;
3402 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3404 (gchar *) suggested_name,
3408 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3409 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3410 helper->folder_name = g_strdup (folder_name);
3411 helper->parent = g_object_ref (parent_folder);
3413 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3416 do_create_folder_performer,
3421 g_free (folder_name);
3423 g_object_unref (parent_folder);
3427 modest_ui_actions_create_folder(GtkWidget *parent_window,
3428 GtkWidget *folder_view,
3429 TnyFolderStore *parent_folder)
3431 if (!parent_folder) {
3432 #ifdef MODEST_TOOLKIT_HILDON2
3433 ModestTnyAccountStore *acc_store;
3435 acc_store = modest_runtime_get_account_store ();
3437 parent_folder = (TnyFolderStore *)
3438 modest_tny_account_store_get_local_folders_account (acc_store);
3440 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3444 if (parent_folder) {
3445 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3446 g_object_unref (parent_folder);
3451 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3454 g_return_if_fail (MODEST_IS_WINDOW(window));
3456 if (MODEST_IS_MAIN_WINDOW (window)) {
3457 GtkWidget *folder_view;
3459 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3460 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3464 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3465 #ifdef MODEST_TOOLKIT_HILDON2
3466 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3467 GtkWidget *folder_view;
3469 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3470 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3473 g_assert_not_reached ();
3478 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3481 const GError *error = NULL;
3482 gchar *message = NULL;
3485 /* Get error message */
3486 error = modest_mail_operation_get_error (mail_op);
3488 g_return_if_reached ();
3490 mem_full = is_memory_full_error ((GError *) error, mail_op);
3492 message = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3493 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3494 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3495 message = _CS("ckdg_ib_folder_already_exists");
3496 } else if (error->domain == TNY_ERROR_DOMAIN &&
3497 error->code == TNY_SERVICE_ERROR_STATE) {
3498 /* This means that the folder is already in use (a
3499 message is opened for example */
3500 message = _("emev_ni_internal_error");
3502 message = _CS("ckdg_ib_unable_to_rename");
3505 /* We don't set a parent for the dialog because the dialog
3506 will be destroyed so the banner won't appear */
3507 modest_platform_information_banner (NULL, NULL, message);
3514 TnyFolderStore *folder;
3519 on_rename_folder_cb (ModestMailOperation *mail_op,
3520 TnyFolder *new_folder,
3523 ModestFolderView *folder_view;
3525 /* If the window was closed when renaming a folder, or if
3526 * it's not a main window this will happen */
3527 if (!MODEST_IS_FOLDER_VIEW (user_data))
3530 folder_view = MODEST_FOLDER_VIEW (user_data);
3531 /* Note that if the rename fails new_folder will be NULL */
3533 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3535 modest_folder_view_select_first_inbox_or_local (folder_view);
3537 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3541 on_rename_folder_performer (gboolean canceled,
3543 GtkWindow *parent_window,
3544 TnyAccount *account,
3547 ModestMailOperation *mail_op = NULL;
3548 GtkTreeSelection *sel = NULL;
3549 GtkWidget *folder_view = NULL;
3550 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3552 if (canceled || err) {
3553 /* In memory full conditions we could get this error here */
3554 check_memory_full_error ((GtkWidget *) parent_window, err);
3558 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3559 modest_ui_actions_rename_folder_error_handler,
3560 parent_window, NULL);
3562 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3565 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3567 folder_view = modest_main_window_get_child_widget (
3568 MODEST_MAIN_WINDOW (parent_window),
3569 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3571 #ifdef MODEST_TOOLKIT_HILDON2
3572 else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3573 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3574 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3578 /* Clear the folders view */
3579 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3580 gtk_tree_selection_unselect_all (sel);
3582 /* Actually rename the folder */
3583 modest_mail_operation_rename_folder (mail_op,
3584 TNY_FOLDER (data->folder),
3585 (const gchar *) (data->new_name),
3586 on_rename_folder_cb,
3588 g_object_unref (mail_op);
3591 g_object_unref (data->folder);
3592 g_free (data->new_name);
3597 modest_ui_actions_on_rename_folder (GtkAction *action,
3598 ModestWindow *window)
3600 modest_ui_actions_on_edit_mode_rename_folder (window);
3604 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3606 TnyFolderStore *folder;
3607 GtkWidget *folder_view;
3608 gboolean do_rename = TRUE;
3610 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3612 if (MODEST_IS_MAIN_WINDOW (window)) {
3613 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3614 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3618 #ifdef MODEST_TOOLKIT_HILDON2
3619 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3620 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3626 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3631 if (TNY_IS_FOLDER (folder)) {
3632 gchar *folder_name = NULL;
3634 const gchar *current_name;
3635 TnyFolderStore *parent;
3637 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3638 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3639 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
3640 parent, current_name,
3642 g_object_unref (parent);
3644 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3647 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3648 rename_folder_data->folder = g_object_ref (folder);
3649 rename_folder_data->new_name = folder_name;
3650 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
3651 folder, on_rename_folder_performer, rename_folder_data);
3654 g_object_unref (folder);
3659 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3662 GObject *win = modest_mail_operation_get_source (mail_op);
3664 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3665 _("mail_in_ui_folder_delete_error"),
3667 g_object_unref (win);
3671 TnyFolderStore *folder;
3672 gboolean move_to_trash;
3676 on_delete_folder_cb (gboolean canceled,
3678 GtkWindow *parent_window,
3679 TnyAccount *account,
3682 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3683 GtkWidget *folder_view;
3684 ModestMailOperation *mail_op;
3685 GtkTreeSelection *sel;
3687 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
3688 g_object_unref (G_OBJECT (info->folder));
3693 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
3694 folder_view = modest_main_window_get_child_widget (
3695 MODEST_MAIN_WINDOW (parent_window),
3696 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3697 #ifdef MODEST_TOOLKIT_HILDON2
3698 } else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3699 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
3702 g_object_unref (G_OBJECT (info->folder));
3707 /* Unselect the folder before deleting it to free the headers */
3708 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3709 gtk_tree_selection_unselect_all (sel);
3711 /* Create the mail operation */
3713 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3714 modest_ui_actions_delete_folder_error_handler,
3717 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3719 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3721 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3723 g_object_unref (G_OBJECT (mail_op));
3724 g_object_unref (G_OBJECT (info->folder));
3729 delete_folder (ModestWindow *window, gboolean move_to_trash)
3731 TnyFolderStore *folder;
3732 GtkWidget *folder_view;
3736 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3738 if (MODEST_IS_MAIN_WINDOW (window)) {
3740 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3741 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3742 #ifdef MODEST_TOOLKIT_HILDON2
3743 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3744 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3752 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3757 /* Show an error if it's an account */
3758 if (!TNY_IS_FOLDER (folder)) {
3759 modest_platform_run_information_dialog (GTK_WINDOW (window),
3760 _("mail_in_ui_folder_delete_error"),
3762 g_object_unref (G_OBJECT (folder));
3767 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3768 tny_folder_get_name (TNY_FOLDER (folder)));
3769 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
3770 (const gchar *) message);
3773 if (response == GTK_RESPONSE_OK) {
3774 DeleteFolderInfo *info;
3775 info = g_new0(DeleteFolderInfo, 1);
3776 info->folder = folder;
3777 info->move_to_trash = move_to_trash;
3778 g_object_ref (G_OBJECT (info->folder));
3779 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder));
3780 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
3782 TNY_FOLDER_STORE (account),
3783 on_delete_folder_cb, info);
3784 g_object_unref (account);
3789 g_object_unref (G_OBJECT (folder));
3793 modest_ui_actions_on_delete_folder (GtkAction *action,
3794 ModestWindow *window)
3796 modest_ui_actions_on_edit_mode_delete_folder (window);
3800 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
3802 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
3804 return delete_folder (window, FALSE);
3808 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3810 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3812 delete_folder (MODEST_WINDOW (main_window), TRUE);
3816 typedef struct _PasswordDialogFields {
3817 GtkWidget *username;
3818 GtkWidget *password;
3820 } PasswordDialogFields;
3823 password_dialog_check_field (GtkEditable *editable,
3824 PasswordDialogFields *fields)
3827 gboolean any_value_empty = FALSE;
3829 #ifdef MODEST_TOOLKIT_HILDON2
3830 value = hildon_entry_get_text (HILDON_ENTRY (fields->username));
3832 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
3834 if ((value == NULL) || value[0] == '\0') {
3835 any_value_empty = TRUE;
3837 #ifdef MODEST_TOOLKIT_HILDON2
3838 value = hildon_entry_get_text (HILDON_ENTRY (fields->password));
3840 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
3842 if ((value == NULL) || value[0] == '\0') {
3843 any_value_empty = TRUE;
3845 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3849 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3850 const gchar* server_account_name,
3855 ModestMainWindow *main_window)
3857 g_return_if_fail(server_account_name);
3858 gboolean completed = FALSE;
3859 PasswordDialogFields *fields = NULL;
3861 /* Initalize output parameters: */
3868 #ifndef MODEST_TOOLKIT_GTK
3869 /* Maemo uses a different (awkward) button order,
3870 * It should probably just use gtk_alternative_dialog_button_order ().
3872 #ifdef MODEST_TOOLKIT_HILDON2
3874 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3877 _HL("wdgt_bd_done"),
3878 GTK_RESPONSE_ACCEPT,
3880 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
3881 HILDON_MARGIN_DOUBLE);
3884 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3887 _("mcen_bd_dialog_ok"),
3888 GTK_RESPONSE_ACCEPT,
3889 _("mcen_bd_dialog_cancel"),
3890 GTK_RESPONSE_REJECT,
3892 #endif /* MODEST_TOOLKIT_HILDON2 */
3895 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3899 GTK_RESPONSE_REJECT,
3901 GTK_RESPONSE_ACCEPT,
3903 #endif /* MODEST_TOOLKIT_GTK */
3905 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3907 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3908 modest_runtime_get_account_mgr(), server_account_name);
3909 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3910 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3913 gtk_widget_destroy (dialog);
3917 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3918 GtkWidget *label = gtk_label_new (txt);
3919 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
3921 g_free (server_name);
3922 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
3927 gchar *initial_username = modest_account_mgr_get_server_account_username (
3928 modest_runtime_get_account_mgr(), server_account_name);
3930 #ifdef MODEST_TOOLKIT_HILDON2
3931 GtkWidget *entry_username = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
3932 if (initial_username)
3933 hildon_entry_set_text (HILDON_ENTRY (entry_username), initial_username);
3935 GtkWidget *entry_username = gtk_entry_new ();
3936 if (initial_username)
3937 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
3939 /* Dim this if a connection has ever succeeded with this username,
3940 * as per the UI spec: */
3941 /* const gboolean username_known = */
3942 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3943 /* modest_runtime_get_account_mgr(), server_account_name); */
3944 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3946 /* We drop the username sensitive code and disallow changing it here
3947 * as tinymail does not support really changing the username in the callback
3949 gtk_widget_set_sensitive (entry_username, FALSE);
3951 #ifndef MODEST_TOOLKIT_GTK
3952 /* Auto-capitalization is the default, so let's turn it off: */
3953 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3955 /* Create a size group to be used by all captions.
3956 * Note that HildonCaption does not create a default size group if we do not specify one.
3957 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3958 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3960 #ifdef MODEST_TOOLKIT_HILDON2
3961 GtkWidget *caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
3962 _("mail_fi_username"), FALSE,
3965 GtkWidget *caption = hildon_caption_new (sizegroup,
3966 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
3968 gtk_widget_show (entry_username);
3969 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3970 FALSE, FALSE, MODEST_MARGIN_HALF);
3971 gtk_widget_show (caption);
3973 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
3975 #endif /* !MODEST_TOOLKIT_GTK */
3978 #ifdef MODEST_TOOLKIT_HILDON2
3979 GtkWidget *entry_password = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
3981 GtkWidget *entry_password = gtk_entry_new ();
3983 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3984 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3986 #ifndef MODEST_TOOLKIT_GTK
3987 /* Auto-capitalization is the default, so let's turn it off: */
3988 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3989 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3991 #ifdef MODEST_TOOLKIT_HILDON2
3992 caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
3993 _("mail_fi_password"), FALSE,
3996 caption = hildon_caption_new (sizegroup,
3997 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
3999 gtk_widget_show (entry_password);
4000 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4001 FALSE, FALSE, MODEST_MARGIN_HALF);
4002 gtk_widget_show (caption);
4003 g_object_unref (sizegroup);
4005 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
4007 #endif /* !MODEST_TOOLKIT_GTK */
4009 if (initial_username != NULL)
4010 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
4012 /* This is not in the Maemo UI spec:
4013 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
4014 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
4018 fields = g_slice_new0 (PasswordDialogFields);
4019 fields->username = entry_username;
4020 fields->password = entry_password;
4021 fields->dialog = dialog;
4023 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
4024 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
4025 password_dialog_check_field (NULL, fields);
4027 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4029 while (!completed) {
4031 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
4033 #ifdef MODEST_TOOLKIT_HILDON2
4034 *username = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_username)));
4036 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
4039 /* Note that an empty field becomes the "" string */
4040 if (*username && strlen (*username) > 0) {
4041 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
4042 server_account_name,
4046 const gboolean username_was_changed =
4047 (strcmp (*username, initial_username) != 0);
4048 if (username_was_changed) {
4049 g_warning ("%s: tinymail does not yet support changing the "
4050 "username in the get_password() callback.\n", __FUNCTION__);
4056 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
4057 _("mcen_ib_username_pw_incorrect"));
4063 #ifdef MODEST_TOOLKIT_HILDON2
4064 *password = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_password)));
4066 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
4069 /* We do not save the password in the configuration,
4070 * because this function is only called for passwords that should
4071 * not be remembered:
4072 modest_server_account_set_password (
4073 modest_runtime_get_account_mgr(), server_account_name,
4080 #ifndef MODEST_TOOLKIT_HILDON2
4081 /* Set parent to NULL or the banner will disappear with its parent dialog */
4082 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
4094 /* This is not in the Maemo UI spec:
4095 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
4101 g_free (initial_username);
4102 gtk_widget_destroy (dialog);
4103 g_slice_free (PasswordDialogFields, fields);
4105 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
4109 modest_ui_actions_on_cut (GtkAction *action,
4110 ModestWindow *window)
4112 GtkWidget *focused_widget;
4113 GtkClipboard *clipboard;
4115 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4116 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4117 if (GTK_IS_EDITABLE (focused_widget)) {
4118 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
4119 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4120 gtk_clipboard_store (clipboard);
4121 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4122 GtkTextBuffer *buffer;
4124 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4125 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4126 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
4127 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4128 gtk_clipboard_store (clipboard);
4130 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4131 TnyList *header_list = modest_header_view_get_selected_headers (
4132 MODEST_HEADER_VIEW (focused_widget));
4133 gboolean continue_download = FALSE;
4134 gint num_of_unc_msgs;
4136 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4138 if (num_of_unc_msgs) {
4139 TnyAccount *account = get_account_from_header_list (header_list);
4141 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4142 g_object_unref (account);
4146 if (num_of_unc_msgs == 0 || continue_download) {
4147 /* modest_platform_information_banner (
4148 NULL, NULL, _CS("mcen_ib_getting_items"));*/
4149 modest_header_view_cut_selection (
4150 MODEST_HEADER_VIEW (focused_widget));
4153 g_object_unref (header_list);
4154 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4155 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4160 modest_ui_actions_on_copy (GtkAction *action,
4161 ModestWindow *window)
4163 GtkClipboard *clipboard;
4164 GtkWidget *focused_widget;
4165 gboolean copied = TRUE;
4167 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4168 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4170 if (GTK_IS_LABEL (focused_widget)) {
4172 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4173 gtk_clipboard_set_text (clipboard, selection, -1);
4175 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4176 gtk_clipboard_store (clipboard);
4177 } else if (GTK_IS_EDITABLE (focused_widget)) {
4178 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4179 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4180 gtk_clipboard_store (clipboard);
4181 } else if (GTK_IS_HTML (focused_widget)) {
4184 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4185 if ((sel == NULL) || (sel[0] == '\0')) {
4188 gtk_html_copy (GTK_HTML (focused_widget));
4189 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4190 gtk_clipboard_store (clipboard);
4192 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4193 GtkTextBuffer *buffer;
4194 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4195 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4196 gtk_text_buffer_copy_clipboard (buffer, clipboard);
4197 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4198 gtk_clipboard_store (clipboard);
4200 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4201 TnyList *header_list = modest_header_view_get_selected_headers (
4202 MODEST_HEADER_VIEW (focused_widget));
4203 gboolean continue_download = FALSE;
4204 gint num_of_unc_msgs;
4206 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4208 if (num_of_unc_msgs) {
4209 TnyAccount *account = get_account_from_header_list (header_list);
4211 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4212 g_object_unref (account);
4216 if (num_of_unc_msgs == 0 || continue_download) {
4217 modest_platform_information_banner (
4218 NULL, NULL, _CS("mcen_ib_getting_items"));
4219 modest_header_view_copy_selection (
4220 MODEST_HEADER_VIEW (focused_widget));
4224 g_object_unref (header_list);
4226 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4227 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4230 /* Show information banner if there was a copy to clipboard */
4232 modest_platform_information_banner (
4233 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4237 modest_ui_actions_on_undo (GtkAction *action,
4238 ModestWindow *window)
4240 ModestEmailClipboard *clipboard = NULL;
4242 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4243 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4244 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4245 /* Clear clipboard source */
4246 clipboard = modest_runtime_get_email_clipboard ();
4247 modest_email_clipboard_clear (clipboard);
4250 g_return_if_reached ();
4255 modest_ui_actions_on_redo (GtkAction *action,
4256 ModestWindow *window)
4258 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4259 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4262 g_return_if_reached ();
4268 destroy_information_note (ModestMailOperation *mail_op,
4271 /* destroy information note */
4272 gtk_widget_destroy (GTK_WIDGET(user_data));
4276 destroy_folder_information_note (ModestMailOperation *mail_op,
4277 TnyFolder *new_folder,
4280 /* destroy information note */
4281 gtk_widget_destroy (GTK_WIDGET(user_data));
4286 paste_as_attachment_free (gpointer data)
4288 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4290 if (helper->banner) {
4291 gtk_widget_destroy (helper->banner);
4292 g_object_unref (helper->banner);
4298 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4303 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4304 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4309 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4314 modest_ui_actions_on_paste (GtkAction *action,
4315 ModestWindow *window)
4317 GtkWidget *focused_widget = NULL;
4318 GtkWidget *inf_note = NULL;
4319 ModestMailOperation *mail_op = NULL;
4321 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4322 if (GTK_IS_EDITABLE (focused_widget)) {
4323 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4324 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4325 ModestEmailClipboard *e_clipboard = NULL;
4326 e_clipboard = modest_runtime_get_email_clipboard ();
4327 if (modest_email_clipboard_cleared (e_clipboard)) {
4328 GtkTextBuffer *buffer;
4329 GtkClipboard *clipboard;
4331 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4332 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4333 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4334 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4335 ModestMailOperation *mail_op;
4336 TnyFolder *src_folder = NULL;
4337 TnyList *data = NULL;
4339 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4340 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4341 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4342 _CS("ckct_nw_pasting"));
4343 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4344 mail_op = modest_mail_operation_new (G_OBJECT (window));
4345 if (helper->banner != NULL) {
4346 g_object_ref (G_OBJECT (helper->banner));
4347 gtk_widget_show (GTK_WIDGET (helper->banner));
4351 modest_mail_operation_get_msgs_full (mail_op,
4353 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4355 paste_as_attachment_free);
4359 g_object_unref (data);
4361 g_object_unref (src_folder);
4364 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4365 ModestEmailClipboard *clipboard = NULL;
4366 TnyFolder *src_folder = NULL;
4367 TnyFolderStore *folder_store = NULL;
4368 TnyList *data = NULL;
4369 gboolean delete = FALSE;
4371 /* Check clipboard source */
4372 clipboard = modest_runtime_get_email_clipboard ();
4373 if (modest_email_clipboard_cleared (clipboard))
4376 /* Get elements to paste */
4377 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4379 /* Create a new mail operation */
4380 mail_op = modest_mail_operation_new (G_OBJECT(window));
4382 /* Get destination folder */
4383 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4385 /* transfer messages */
4389 /* Ask for user confirmation */
4391 modest_ui_actions_msgs_move_to_confirmation (window,
4392 TNY_FOLDER (folder_store),
4396 if (response == GTK_RESPONSE_OK) {
4397 /* Launch notification */
4398 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4399 _CS("ckct_nw_pasting"));
4400 if (inf_note != NULL) {
4401 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4402 gtk_widget_show (GTK_WIDGET(inf_note));
4405 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4406 modest_mail_operation_xfer_msgs (mail_op,
4408 TNY_FOLDER (folder_store),
4410 destroy_information_note,
4413 g_object_unref (mail_op);
4416 } else if (src_folder != NULL) {
4417 /* Launch notification */
4418 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4419 _CS("ckct_nw_pasting"));
4420 if (inf_note != NULL) {
4421 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4422 gtk_widget_show (GTK_WIDGET(inf_note));
4425 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4426 modest_mail_operation_xfer_folder (mail_op,
4430 destroy_folder_information_note,
4436 g_object_unref (data);
4437 if (src_folder != NULL)
4438 g_object_unref (src_folder);
4439 if (folder_store != NULL)
4440 g_object_unref (folder_store);
4446 modest_ui_actions_on_select_all (GtkAction *action,
4447 ModestWindow *window)
4449 GtkWidget *focused_widget;
4451 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4452 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4453 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4454 } else if (GTK_IS_LABEL (focused_widget)) {
4455 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4456 } else if (GTK_IS_EDITABLE (focused_widget)) {
4457 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4458 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4459 GtkTextBuffer *buffer;
4460 GtkTextIter start, end;
4462 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4463 gtk_text_buffer_get_start_iter (buffer, &start);
4464 gtk_text_buffer_get_end_iter (buffer, &end);
4465 gtk_text_buffer_select_range (buffer, &start, &end);
4466 } else if (GTK_IS_HTML (focused_widget)) {
4467 gtk_html_select_all (GTK_HTML (focused_widget));
4468 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4469 GtkWidget *header_view = focused_widget;
4470 GtkTreeSelection *selection = NULL;
4472 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4473 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4474 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4477 /* Disable window dimming management */
4478 modest_window_disable_dimming (MODEST_WINDOW(window));
4480 /* Select all messages */
4481 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4482 gtk_tree_selection_select_all (selection);
4484 /* Set focuse on header view */
4485 gtk_widget_grab_focus (header_view);
4487 /* Enable window dimming management */
4488 modest_window_enable_dimming (MODEST_WINDOW(window));
4489 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4490 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4496 modest_ui_actions_on_mark_as_read (GtkAction *action,
4497 ModestWindow *window)
4499 g_return_if_fail (MODEST_IS_WINDOW(window));
4501 /* Mark each header as read */
4502 do_headers_action (window, headers_action_mark_as_read, NULL);
4506 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4507 ModestWindow *window)
4509 g_return_if_fail (MODEST_IS_WINDOW(window));
4511 /* Mark each header as read */
4512 do_headers_action (window, headers_action_mark_as_unread, NULL);
4516 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4517 GtkRadioAction *selected,
4518 ModestWindow *window)
4522 value = gtk_radio_action_get_current_value (selected);
4523 if (MODEST_IS_WINDOW (window)) {
4524 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4529 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4530 GtkRadioAction *selected,
4531 ModestWindow *window)
4533 TnyHeaderFlags flags;
4534 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4536 flags = gtk_radio_action_get_current_value (selected);
4537 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4541 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4542 GtkRadioAction *selected,
4543 ModestWindow *window)
4547 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4549 file_format = gtk_radio_action_get_current_value (selected);
4550 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4555 modest_ui_actions_on_zoom_plus (GtkAction *action,
4556 ModestWindow *window)
4558 g_return_if_fail (MODEST_IS_WINDOW (window));
4560 modest_window_zoom_plus (MODEST_WINDOW (window));
4564 modest_ui_actions_on_zoom_minus (GtkAction *action,
4565 ModestWindow *window)
4567 g_return_if_fail (MODEST_IS_WINDOW (window));
4569 modest_window_zoom_minus (MODEST_WINDOW (window));
4573 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4574 ModestWindow *window)
4576 ModestWindowMgr *mgr;
4577 gboolean fullscreen, active;
4578 g_return_if_fail (MODEST_IS_WINDOW (window));
4580 mgr = modest_runtime_get_window_mgr ();
4582 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4583 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4585 if (active != fullscreen) {
4586 modest_window_mgr_set_fullscreen_mode (mgr, active);
4587 #ifndef MODEST_TOOLKIT_HILDON2
4588 gtk_window_present (GTK_WINDOW (window));
4594 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4595 ModestWindow *window)
4597 ModestWindowMgr *mgr;
4598 gboolean fullscreen;
4600 g_return_if_fail (MODEST_IS_WINDOW (window));
4602 mgr = modest_runtime_get_window_mgr ();
4603 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4604 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4606 #ifndef MODEST_TOOLKIT_HILDON2
4607 gtk_window_present (GTK_WINDOW (window));
4612 * Used by modest_ui_actions_on_details to call do_headers_action
4615 headers_action_show_details (TnyHeader *header,
4616 ModestWindow *window,
4620 gboolean async_retrieval;
4623 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4624 async_retrieval = TRUE;
4625 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
4627 async_retrieval = FALSE;
4629 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header, async_retrieval, msg);
4631 g_object_unref (msg);
4635 * Show the header details in a ModestDetailsDialog widget
4638 modest_ui_actions_on_details (GtkAction *action,
4641 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4645 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4649 header = tny_msg_get_header (msg);
4651 headers_action_show_details (header, win, NULL);
4652 g_object_unref (header);
4654 g_object_unref (msg);
4656 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4657 GtkWidget *folder_view, *header_view;
4659 /* Check which widget has the focus */
4660 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4661 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4662 if (gtk_widget_is_focus (folder_view)) {
4663 TnyFolderStore *folder_store
4664 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4665 if (!folder_store) {
4666 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4669 /* Show only when it's a folder */
4670 /* This function should not be called for account items,
4671 * because we dim the menu item for them. */
4672 if (TNY_IS_FOLDER (folder_store)) {
4673 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4674 TNY_FOLDER (folder_store));
4677 g_object_unref (folder_store);
4680 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4681 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4682 /* Show details of each header */
4683 do_headers_action (win, headers_action_show_details, header_view);
4685 #ifdef MODEST_TOOLKIT_HILDON2
4686 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4688 GtkWidget *header_view;
4690 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4691 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4693 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4695 g_object_unref (folder);
4702 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4703 ModestMsgEditWindow *window)
4705 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4707 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4711 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4712 ModestMsgEditWindow *window)
4714 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4716 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4720 modest_ui_actions_toggle_folders_view (GtkAction *action,
4721 ModestMainWindow *main_window)
4723 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4725 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4726 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4728 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4732 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4733 ModestWindow *window)
4735 gboolean active, fullscreen = FALSE;
4736 ModestWindowMgr *mgr;
4738 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4740 /* Check if we want to toggle the toolbar view in fullscreen
4742 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4743 "ViewShowToolbarFullScreen")) {
4747 /* Toggle toolbar */
4748 mgr = modest_runtime_get_window_mgr ();
4749 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4753 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4754 ModestMsgEditWindow *window)
4756 modest_msg_edit_window_select_font (window);
4761 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4762 const gchar *display_name,
4765 /* don't update the display name if it was already set;
4766 * updating the display name apparently is expensive */
4767 const gchar* old_name = gtk_window_get_title (window);
4769 if (display_name == NULL)
4772 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4773 return; /* don't do anything */
4775 /* This is usually used to change the title of the main window, which
4776 * is the one that holds the folder view. Note that this change can
4777 * happen even when the widget doesn't have the focus. */
4778 gtk_window_set_title (window, display_name);
4783 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4785 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4786 modest_msg_edit_window_select_contacts (window);
4790 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4792 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4793 modest_msg_edit_window_check_names (window, FALSE);
4796 #ifndef MODEST_TOOLKIT_HILDON2
4798 * This function is used to track changes in the selection of the
4799 * folder view that is inside the "move to" dialog to enable/disable
4800 * the OK button because we do not want the user to select a disallowed
4801 * destination for a folder.
4802 * The user also not desired to be able to use NEW button on items where
4803 * folder creation is not possibel.
4806 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4807 TnyFolderStore *folder_store,
4811 GtkWidget *dialog = NULL;
4812 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4813 gboolean moving_folder = FALSE;
4814 gboolean is_local_account = TRUE;
4815 GtkWidget *folder_view = NULL;
4816 ModestTnyFolderRules rules;
4818 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
4823 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
4827 /* check if folder_store is an remote account */
4828 if (TNY_IS_ACCOUNT (folder_store)) {
4829 TnyAccount *local_account = NULL;
4830 TnyAccount *mmc_account = NULL;
4831 ModestTnyAccountStore *account_store = NULL;
4833 account_store = modest_runtime_get_account_store ();
4834 local_account = modest_tny_account_store_get_local_folders_account (account_store);
4835 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
4837 if ((gpointer) local_account != (gpointer) folder_store &&
4838 (gpointer) mmc_account != (gpointer) folder_store) {
4839 ModestProtocolType proto;
4840 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
4841 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
4842 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
4844 is_local_account = FALSE;
4845 /* New button should be dimmed on remote
4847 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4849 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
4851 g_object_unref (local_account);
4853 /* It could not exist */
4855 g_object_unref (mmc_account);
4858 /* Check the target folder rules */
4859 if (TNY_IS_FOLDER (folder_store)) {
4860 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
4861 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
4862 ok_sensitive = FALSE;
4863 new_sensitive = FALSE;
4868 /* Check if we're moving a folder */
4869 if (MODEST_IS_MAIN_WINDOW (user_data)) {
4870 /* Get the widgets */
4871 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
4872 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4873 if (gtk_widget_is_focus (folder_view))
4874 moving_folder = TRUE;
4877 if (moving_folder) {
4878 TnyFolderStore *moved_folder = NULL, *parent = NULL;
4880 /* Get the folder to move */
4881 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4883 /* Check that we're not moving to the same folder */
4884 if (TNY_IS_FOLDER (moved_folder)) {
4885 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
4886 if (parent == folder_store)
4887 ok_sensitive = FALSE;
4888 g_object_unref (parent);
4891 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
4892 /* Do not allow to move to an account unless it's the
4893 local folders account */
4894 if (!is_local_account)
4895 ok_sensitive = FALSE;
4898 if (ok_sensitive && (moved_folder == folder_store)) {
4899 /* Do not allow to move to itself */
4900 ok_sensitive = FALSE;
4902 g_object_unref (moved_folder);
4904 TnyFolder *src_folder = NULL;
4906 /* Moving a message */
4907 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
4909 TnyHeader *header = NULL;
4910 header = modest_msg_view_window_get_header
4911 (MODEST_MSG_VIEW_WINDOW (user_data));
4912 if (!TNY_IS_HEADER(header))
4913 g_warning ("%s: could not get source header", __FUNCTION__);
4915 src_folder = tny_header_get_folder (header);
4918 g_object_unref (header);
4921 TNY_FOLDER (modest_folder_view_get_selected
4922 (MODEST_FOLDER_VIEW (folder_view)));
4925 if (TNY_IS_FOLDER(src_folder)) {
4926 /* Do not allow to move the msg to the same folder */
4927 /* Do not allow to move the msg to an account */
4928 if ((gpointer) src_folder == (gpointer) folder_store ||
4929 TNY_IS_ACCOUNT (folder_store))
4930 ok_sensitive = FALSE;
4931 g_object_unref (src_folder);
4933 g_warning ("%s: could not get source folder", __FUNCTION__);
4937 /* Set sensitivity of the OK and NEW button */
4938 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
4939 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
4944 on_move_to_dialog_response (GtkDialog *dialog,
4948 GtkWidget *parent_win;
4949 MoveToInfo *helper = NULL;
4950 ModestFolderView *folder_view;
4952 helper = (MoveToInfo *) user_data;
4954 parent_win = (GtkWidget *) helper->win;
4955 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
4956 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4959 TnyFolderStore *dst_folder;
4960 TnyFolderStore *selected;
4962 case MODEST_GTK_RESPONSE_NEW_FOLDER:
4963 selected = modest_folder_view_get_selected (folder_view);
4964 modest_ui_actions_create_folder (GTK_WIDGET (dialog), GTK_WIDGET (folder_view), selected);
4965 g_object_unref (selected);
4967 case GTK_RESPONSE_NONE:
4968 case GTK_RESPONSE_CANCEL:
4969 case GTK_RESPONSE_DELETE_EVENT:
4971 case GTK_RESPONSE_OK:
4972 dst_folder = modest_folder_view_get_selected (folder_view);
4974 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
4975 /* Clean list to move used for filtering */
4976 modest_folder_view_set_list_to_move (folder_view, NULL);
4978 modest_ui_actions_on_main_window_move_to (NULL,
4979 GTK_WIDGET (folder_view),
4981 MODEST_MAIN_WINDOW (parent_win));
4982 #ifdef MODEST_TOOLKIT_HILDON2
4983 } else if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
4984 /* Clean list to move used for filtering */
4985 modest_folder_view_set_list_to_move (folder_view, NULL);
4987 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
4990 GTK_WINDOW (parent_win));
4993 /* if the user selected a root folder
4994 (account) then do not perform any action */
4995 if (TNY_IS_ACCOUNT (dst_folder)) {
4996 g_signal_stop_emission_by_name (dialog, "response");
5000 /* Clean list to move used for filtering */
5001 modest_folder_view_set_list_to_move (folder_view, NULL);
5003 /* Moving from headers window in edit mode */
5004 modest_ui_actions_on_window_move_to (NULL, helper->list,
5006 MODEST_WINDOW (parent_win));
5010 g_object_unref (dst_folder);
5014 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
5017 /* Free the helper and exit */
5019 g_object_unref (helper->list);
5020 g_slice_free (MoveToInfo, helper);
5021 gtk_widget_destroy (GTK_WIDGET (dialog));
5025 create_move_to_dialog (GtkWindow *win,
5026 GtkWidget *folder_view,
5027 TnyList *list_to_move)
5029 GtkWidget *dialog, *tree_view = NULL;
5031 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
5033 #ifndef MODEST_TOOLKIT_HILDON2
5034 /* Track changes in the selection to
5035 * disable the OK button whenever "Move to" is not possible
5036 * disbale NEW button whenever New is not possible */
5037 g_signal_connect (tree_view,
5038 "folder_selection_changed",
5039 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
5043 /* It could happen that we're trying to move a message from a
5044 window (msg window for example) after the main window was
5045 closed, so we can not just get the model of the folder
5047 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
5048 const gchar *visible_id = NULL;
5050 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5051 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5052 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
5053 MODEST_FOLDER_VIEW(tree_view));
5056 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
5058 /* Show the same account than the one that is shown in the main window */
5059 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
5062 const gchar *active_account_name = NULL;
5063 ModestAccountMgr *mgr = NULL;
5064 ModestAccountSettings *settings = NULL;
5065 ModestServerAccountSettings *store_settings = NULL;
5067 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5068 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5069 modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view),
5070 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
5072 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
5073 mgr = modest_runtime_get_account_mgr ();
5074 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
5077 const gchar *store_account_name;
5078 store_settings = modest_account_settings_get_store_settings (settings);
5079 store_account_name = modest_server_account_settings_get_account_name (store_settings);
5081 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
5082 store_account_name);
5083 g_object_unref (store_settings);
5084 g_object_unref (settings);
5088 /* we keep a pointer to the embedded folder view, so we can
5089 * retrieve it with get_folder_view_from_move_to_dialog (see
5090 * above) later (needed for focus handling)
5092 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
5094 /* Hide special folders */
5095 #ifndef MODEST_TOOLKIT_HILDON2
5096 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
5099 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
5100 #ifndef MODEST_TOOLKIT_HILDON2
5101 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5104 gtk_widget_show (GTK_WIDGET (tree_view));
5110 * Shows a confirmation dialog to the user when we're moving messages
5111 * from a remote server to the local storage. Returns the dialog
5112 * response. If it's other kind of movement then it always returns
5115 * This one is used by the next functions:
5116 * modest_ui_actions_on_paste - commented out
5117 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
5120 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
5121 TnyFolder *dest_folder,
5125 gint response = GTK_RESPONSE_OK;
5126 TnyAccount *account = NULL;
5127 TnyFolder *src_folder = NULL;
5128 TnyIterator *iter = NULL;
5129 TnyHeader *header = NULL;
5131 /* return with OK if the destination is a remote folder */
5132 if (modest_tny_folder_is_remote_folder (dest_folder))
5133 return GTK_RESPONSE_OK;
5135 /* Get source folder */
5136 iter = tny_list_create_iterator (headers);
5137 header = TNY_HEADER (tny_iterator_get_current (iter));
5139 src_folder = tny_header_get_folder (header);
5140 g_object_unref (header);
5142 g_object_unref (iter);
5144 /* if no src_folder, message may be an attahcment */
5145 if (src_folder == NULL)
5146 return GTK_RESPONSE_CANCEL;
5148 /* If the source is a local or MMC folder */
5149 if (!modest_tny_folder_is_remote_folder (src_folder)) {
5150 g_object_unref (src_folder);
5151 return GTK_RESPONSE_OK;
5154 /* Get the account */
5155 account = tny_folder_get_account (src_folder);
5157 /* now if offline we ask the user */
5158 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
5159 response = GTK_RESPONSE_OK;
5161 response = GTK_RESPONSE_CANCEL;
5164 g_object_unref (src_folder);
5165 g_object_unref (account);
5171 move_to_helper_destroyer (gpointer user_data)
5173 MoveToHelper *helper = (MoveToHelper *) user_data;
5175 /* Close the "Pasting" information banner */
5176 if (helper->banner) {
5177 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5178 g_object_unref (helper->banner);
5180 if (gtk_tree_row_reference_valid (helper->reference)) {
5181 gtk_tree_row_reference_free (helper->reference);
5182 helper->reference = NULL;
5188 move_to_cb (ModestMailOperation *mail_op,
5191 MoveToHelper *helper = (MoveToHelper *) user_data;
5192 GObject *object = modest_mail_operation_get_source (mail_op);
5194 /* Note that the operation could have failed, in that case do
5196 if (modest_mail_operation_get_status (mail_op) !=
5197 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5200 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5201 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5203 if (!modest_msg_view_window_select_next_message (self) &&
5204 !modest_msg_view_window_select_previous_message (self)) {
5205 /* No more messages to view, so close this window */
5206 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5208 } else if (MODEST_IS_MAIN_WINDOW (object) &&
5209 gtk_tree_row_reference_valid (helper->reference)) {
5210 GtkWidget *header_view;
5212 GtkTreeSelection *sel;
5214 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5215 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5216 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5217 path = gtk_tree_row_reference_get_path (helper->reference);
5218 /* We need to unselect the previous one
5219 because we could be copying instead of
5221 gtk_tree_selection_unselect_all (sel);
5222 gtk_tree_selection_select_path (sel, path);
5223 gtk_tree_path_free (path);
5225 g_object_unref (object);
5228 /* Destroy the helper */
5229 move_to_helper_destroyer (helper);
5233 folder_move_to_cb (ModestMailOperation *mail_op,
5234 TnyFolder *new_folder,
5237 GtkWidget *folder_view;
5240 object = modest_mail_operation_get_source (mail_op);
5241 if (MODEST_IS_MAIN_WINDOW (object)) {
5242 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5243 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5244 g_object_ref (folder_view);
5245 g_object_unref (object);
5246 move_to_cb (mail_op, user_data);
5247 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5248 g_object_unref (folder_view);
5250 move_to_cb (mail_op, user_data);
5255 msgs_move_to_cb (ModestMailOperation *mail_op,
5258 move_to_cb (mail_op, user_data);
5262 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5265 GObject *win = NULL;
5267 #ifndef MODEST_TOOLKIT_HILDON2
5268 ModestWindow *main_window = NULL;
5270 /* Disable next automatic folder selection */
5271 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5272 FALSE); /* don't create */
5274 GtkWidget *folder_view = NULL;
5276 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5277 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5278 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5280 if (user_data && TNY_IS_FOLDER (user_data)) {
5281 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5282 TNY_FOLDER (user_data), FALSE);
5286 /* Show notification dialog only if the main window exists */
5287 win = modest_mail_operation_get_source (mail_op);
5288 modest_platform_run_information_dialog ((GtkWindow *) win,
5289 _("mail_in_ui_folder_move_target_error"),
5292 g_object_unref (win);
5296 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5305 gint pending_purges = 0;
5306 gboolean some_purged = FALSE;
5307 ModestWindow *win = MODEST_WINDOW (user_data);
5308 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5310 /* If there was any error */
5311 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5312 modest_window_mgr_unregister_header (mgr, header);
5316 /* Once the message has been retrieved for purging, we check if
5317 * it's all ok for purging */
5319 parts = tny_simple_list_new ();
5320 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5321 iter = tny_list_create_iterator (parts);
5323 while (!tny_iterator_is_done (iter)) {
5325 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5326 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5327 if (tny_mime_part_is_purged (part))
5334 g_object_unref (part);
5336 tny_iterator_next (iter);
5338 g_object_unref (iter);
5341 if (pending_purges>0) {
5343 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5345 if (response == GTK_RESPONSE_OK) {
5348 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5349 iter = tny_list_create_iterator (parts);
5350 while (!tny_iterator_is_done (iter)) {
5353 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5354 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5355 tny_mime_part_set_purged (part);
5358 g_object_unref (part);
5360 tny_iterator_next (iter);
5362 g_object_unref (iter);
5364 tny_msg_rewrite_cache (msg);
5366 gtk_widget_destroy (info);
5370 modest_window_mgr_unregister_header (mgr, header);
5372 g_object_unref (parts);
5376 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5377 ModestMainWindow *win)
5379 GtkWidget *header_view;
5380 TnyList *header_list;
5382 TnyHeaderFlags flags;
5383 ModestWindow *msg_view_window = NULL;
5386 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5388 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5389 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5391 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5393 g_warning ("%s: no header selected", __FUNCTION__);
5397 if (tny_list_get_length (header_list) == 1) {
5398 TnyIterator *iter = tny_list_create_iterator (header_list);
5399 header = TNY_HEADER (tny_iterator_get_current (iter));
5400 g_object_unref (iter);
5404 if (!header || !TNY_IS_HEADER(header)) {
5405 g_warning ("%s: header is not valid", __FUNCTION__);
5409 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5410 header, &msg_view_window);
5411 flags = tny_header_get_flags (header);
5412 if (!(flags & TNY_HEADER_FLAG_CACHED))
5415 if (msg_view_window != NULL)
5416 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5418 /* do nothing; uid was registered before, so window is probably on it's way */
5419 g_warning ("debug: header %p has already been registered", header);
5422 ModestMailOperation *mail_op = NULL;
5423 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5424 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5425 modest_ui_actions_disk_operations_error_handler,
5427 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5428 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5430 g_object_unref (mail_op);
5433 g_object_unref (header);
5435 g_object_unref (header_list);
5439 * Checks if we need a connection to do the transfer and if the user
5440 * wants to connect to complete it
5443 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5444 TnyFolderStore *src_folder,
5446 TnyFolder *dst_folder,
5447 gboolean delete_originals,
5448 gboolean *need_connection,
5451 TnyAccount *src_account;
5452 gint uncached_msgs = 0;
5454 /* We don't need any further check if
5456 * 1- the source folder is local OR
5457 * 2- the device is already online
5459 if (!modest_tny_folder_store_is_remote (src_folder) ||
5460 tny_device_is_online (modest_runtime_get_device())) {
5461 *need_connection = FALSE;
5466 /* We must ask for a connection when
5468 * - the message(s) is not already cached OR
5469 * - the message(s) is cached but the leave_on_server setting
5470 * is FALSE (because we need to sync the source folder to
5471 * delete the message from the server (for IMAP we could do it
5472 * offline, it'll take place the next time we get a
5475 uncached_msgs = header_list_count_uncached_msgs (headers);
5476 src_account = get_account_from_folder_store (src_folder);
5477 if (uncached_msgs > 0) {
5481 *need_connection = TRUE;
5482 num_headers = tny_list_get_length (headers);
5483 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5485 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5486 GTK_RESPONSE_CANCEL) {
5492 /* The transfer is possible and the user wants to */
5495 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5496 const gchar *account_name;
5497 gboolean leave_on_server;
5499 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5500 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5503 if (leave_on_server == TRUE) {
5504 *need_connection = FALSE;
5506 *need_connection = TRUE;
5509 *need_connection = FALSE;
5514 g_object_unref (src_account);
5518 xfer_messages_error_handler (ModestMailOperation *mail_op,
5522 const GError *error;
5524 win = modest_mail_operation_get_source (mail_op);
5525 error = modest_mail_operation_get_error (mail_op);
5527 if (error && is_memory_full_error ((GError *) error, mail_op)) {
5528 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
5529 modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
5532 modest_platform_run_information_dialog ((GtkWindow *) win,
5533 _("mail_in_ui_folder_move_target_error"),
5537 g_object_unref (win);
5541 TnyFolderStore *dst_folder;
5546 * Utility function that transfer messages from both the main window
5547 * and the msg view window when using the "Move to" dialog
5550 xfer_messages_performer (gboolean canceled,
5552 GtkWindow *parent_window,
5553 TnyAccount *account,
5556 ModestWindow *win = MODEST_WINDOW (parent_window);
5557 TnyAccount *dst_account = NULL;
5558 gboolean dst_forbids_message_add = FALSE;
5559 XferMsgsHelper *helper;
5560 MoveToHelper *movehelper;
5561 ModestMailOperation *mail_op;
5563 helper = (XferMsgsHelper *) user_data;
5565 if (canceled || err) {
5566 if (!check_memory_full_error ((GtkWidget *) parent_window, err)) {
5567 /* Show the proper error message */
5568 modest_ui_actions_on_account_connection_error (parent_window, account);
5573 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5575 /* tinymail will return NULL for local folders it seems */
5576 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5577 modest_tny_account_get_protocol_type (dst_account),
5578 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_MESSAGE_ADD);
5579 g_object_unref (dst_account);
5581 if (dst_forbids_message_add) {
5582 modest_platform_information_banner (GTK_WIDGET (win),
5584 ngettext("mail_in_ui_folder_move_target_error",
5585 "mail_in_ui_folder_move_targets_error",
5586 tny_list_get_length (helper->headers)));
5590 movehelper = g_new0 (MoveToHelper, 1);
5592 #ifndef MODEST_TOOLKIT_HILDON2
5593 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5594 _CS("ckct_nw_pasting"));
5595 if (movehelper->banner != NULL) {
5596 g_object_ref (movehelper->banner);
5597 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5601 if (MODEST_IS_MAIN_WINDOW (win)) {
5602 GtkWidget *header_view =
5603 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5604 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5605 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5608 /* Perform the mail operation */
5609 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5610 xfer_messages_error_handler,
5612 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5615 modest_mail_operation_xfer_msgs (mail_op,
5617 TNY_FOLDER (helper->dst_folder),
5622 g_object_unref (G_OBJECT (mail_op));
5624 g_object_unref (helper->dst_folder);
5625 g_object_unref (helper->headers);
5626 g_slice_free (XferMsgsHelper, helper);
5630 TnyFolder *src_folder;
5631 TnyFolderStore *dst_folder;
5632 gboolean delete_original;
5633 GtkWidget *folder_view;
5637 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
5638 TnyAccount *account, gpointer user_data)
5640 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5641 GtkTreeSelection *sel;
5642 ModestMailOperation *mail_op = NULL;
5644 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
5645 g_object_unref (G_OBJECT (info->src_folder));
5646 g_object_unref (G_OBJECT (info->dst_folder));
5651 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5652 #ifndef MODEST_TOOLKIT_HILDON2
5653 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5654 _CS("ckct_nw_pasting"));
5655 if (helper->banner != NULL) {
5656 g_object_ref (helper->banner);
5657 gtk_widget_show (GTK_WIDGET(helper->banner));
5660 /* Clean folder on header view before moving it */
5661 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5662 gtk_tree_selection_unselect_all (sel);
5664 /* Let gtk events run. We need that the folder
5665 view frees its reference to the source
5666 folder *before* issuing the mail operation
5667 so we need the signal handler of selection
5668 changed to happen before the mail
5670 while (gtk_events_pending ())
5671 gtk_main_iteration (); */
5674 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5675 modest_ui_actions_move_folder_error_handler,
5676 info->src_folder, NULL);
5677 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5680 /* Select *after* the changes */
5681 /* TODO: this function hangs UI after transfer */
5682 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
5683 /* TNY_FOLDER (src_folder), TRUE); */
5685 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
5686 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5687 TNY_FOLDER (info->dst_folder), TRUE);
5689 modest_mail_operation_xfer_folder (mail_op,
5690 TNY_FOLDER (info->src_folder),
5692 info->delete_original,
5695 g_object_unref (G_OBJECT (info->src_folder));
5697 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5700 /* Unref mail operation */
5701 g_object_unref (G_OBJECT (mail_op));
5702 g_object_unref (G_OBJECT (info->dst_folder));
5707 get_account_from_folder_store (TnyFolderStore *folder_store)
5709 if (TNY_IS_ACCOUNT (folder_store))
5710 return g_object_ref (folder_store);
5712 return tny_folder_get_account (TNY_FOLDER (folder_store));
5716 * UI handler for the "Move to" action when invoked from the
5720 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5721 GtkWidget *folder_view,
5722 TnyFolderStore *dst_folder,
5723 ModestMainWindow *win)
5725 ModestHeaderView *header_view = NULL;
5726 TnyFolderStore *src_folder = NULL;
5728 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5730 /* Get the source folder */
5731 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5733 /* Get header view */
5734 header_view = (ModestHeaderView *)
5735 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5737 /* Get folder or messages to transfer */
5738 if (gtk_widget_is_focus (folder_view)) {
5739 gboolean do_xfer = TRUE;
5741 /* Allow only to transfer folders to the local root folder */
5742 if (TNY_IS_ACCOUNT (dst_folder) &&
5743 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5744 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5746 } else if (!TNY_IS_FOLDER (src_folder)) {
5747 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5752 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5753 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5755 info->src_folder = g_object_ref (src_folder);
5756 info->dst_folder = g_object_ref (dst_folder);
5757 info->delete_original = TRUE;
5758 info->folder_view = folder_view;
5760 connect_info->callback = on_move_folder_cb;
5761 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5762 connect_info->data = info;
5764 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5765 TNY_FOLDER_STORE (src_folder),
5768 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5771 headers = modest_header_view_get_selected_headers(header_view);
5773 /* Transfer the messages */
5774 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
5775 headers, TNY_FOLDER (dst_folder));
5777 g_object_unref (headers);
5781 g_object_unref (src_folder);
5784 #ifdef MODEST_TOOLKIT_HILDON2
5786 * UI handler for the "Move to" action when invoked from the
5787 * ModestFolderWindow
5790 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
5791 TnyFolderStore *dst_folder,
5795 TnyFolderStore *src_folder = NULL;
5796 TnyIterator *iterator;
5798 if (tny_list_get_length (selection) != 1)
5801 iterator = tny_list_create_iterator (selection);
5802 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
5803 g_object_unref (iterator);
5806 gboolean do_xfer = TRUE;
5808 /* Allow only to transfer folders to the local root folder */
5809 if (TNY_IS_ACCOUNT (dst_folder) &&
5810 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5811 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5814 modest_platform_run_information_dialog (win,
5815 _("mail_in_ui_folder_move_target_error"),
5817 } else if (!TNY_IS_FOLDER (src_folder)) {
5818 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5823 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5824 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5826 info->src_folder = g_object_ref (src_folder);
5827 info->dst_folder = g_object_ref (dst_folder);
5828 info->delete_original = TRUE;
5829 info->folder_view = folder_view;
5831 connect_info->callback = on_move_folder_cb;
5832 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5833 connect_info->data = info;
5835 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5836 TNY_FOLDER_STORE (src_folder),
5841 g_object_unref (src_folder);
5847 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
5848 TnyFolder *src_folder,
5850 TnyFolder *dst_folder)
5852 gboolean need_connection = TRUE;
5853 gboolean do_xfer = TRUE;
5854 XferMsgsHelper *helper;
5856 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5857 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5858 g_return_if_fail (TNY_IS_LIST (headers));
5860 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5861 headers, TNY_FOLDER (dst_folder),
5862 TRUE, &need_connection,
5865 /* If we don't want to transfer just return */
5869 /* Create the helper */
5870 helper = g_slice_new (XferMsgsHelper);
5871 helper->dst_folder = g_object_ref (dst_folder);
5872 helper->headers = g_object_ref (headers);
5874 if (need_connection) {
5875 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5876 connect_info->callback = xfer_messages_performer;
5877 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5878 connect_info->data = helper;
5880 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5881 TNY_FOLDER_STORE (src_folder),
5884 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5885 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
5886 src_account, helper);
5887 g_object_unref (src_account);
5892 * UI handler for the "Move to" action when invoked from the
5893 * ModestMsgViewWindow
5896 modest_ui_actions_on_window_move_to (GtkAction *action,
5898 TnyFolderStore *dst_folder,
5901 TnyFolder *src_folder = NULL;
5903 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5906 TnyHeader *header = NULL;
5909 iter = tny_list_create_iterator (headers);
5910 header = (TnyHeader *) tny_iterator_get_current (iter);
5911 src_folder = tny_header_get_folder (header);
5913 /* Transfer the messages */
5914 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
5916 TNY_FOLDER (dst_folder));
5919 g_object_unref (header);
5920 g_object_unref (iter);
5921 g_object_unref (src_folder);
5926 modest_ui_actions_on_move_to (GtkAction *action,
5929 modest_ui_actions_on_edit_mode_move_to (win);
5933 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
5935 GtkWidget *dialog = NULL;
5936 MoveToInfo *helper = NULL;
5937 TnyList *list_to_move;
5939 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
5941 #ifndef MODEST_TOOLKIT_HILDON2
5942 /* Get the main window if exists */
5943 ModestMainWindow *main_window;
5944 if (MODEST_IS_MAIN_WINDOW (win))
5945 main_window = MODEST_MAIN_WINDOW (win);
5948 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5949 FALSE)); /* don't create */
5952 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
5957 if (tny_list_get_length (list_to_move) < 1) {
5958 g_object_unref (list_to_move);
5962 /* Create and run the dialog */
5963 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
5964 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
5965 GTK_WINDOW (dialog),
5969 helper = g_slice_new0 (MoveToInfo);
5970 helper->list = list_to_move;
5973 /* Listen to response signal */
5974 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
5976 /* Show the dialog */
5977 gtk_widget_show (dialog);
5983 * Calls #HeadersFunc for each header already selected in the main
5984 * window or the message currently being shown in the msg view window
5987 do_headers_action (ModestWindow *win,
5991 TnyList *headers_list = NULL;
5992 TnyIterator *iter = NULL;
5993 TnyHeader *header = NULL;
5994 TnyFolder *folder = NULL;
5997 headers_list = get_selected_headers (win);
6001 /* Get the folder */
6002 iter = tny_list_create_iterator (headers_list);
6003 header = TNY_HEADER (tny_iterator_get_current (iter));
6005 folder = tny_header_get_folder (header);
6006 g_object_unref (header);
6009 /* Call the function for each header */
6010 while (!tny_iterator_is_done (iter)) {
6011 header = TNY_HEADER (tny_iterator_get_current (iter));
6012 func (header, win, user_data);
6013 g_object_unref (header);
6014 tny_iterator_next (iter);
6017 /* Trick: do a poke status in order to speed up the signaling
6020 tny_folder_poke_status (folder);
6021 g_object_unref (folder);
6025 g_object_unref (iter);
6026 g_object_unref (headers_list);
6030 modest_ui_actions_view_attachment (GtkAction *action,
6031 ModestWindow *window)
6033 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6034 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
6036 /* not supported window for this action */
6037 g_return_if_reached ();
6042 modest_ui_actions_save_attachments (GtkAction *action,
6043 ModestWindow *window)
6045 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6047 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
6050 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
6052 /* not supported window for this action */
6053 g_return_if_reached ();
6058 modest_ui_actions_remove_attachments (GtkAction *action,
6059 ModestWindow *window)
6061 if (MODEST_IS_MAIN_WINDOW (window)) {
6062 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
6063 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6064 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
6066 /* not supported window for this action */
6067 g_return_if_reached ();
6072 modest_ui_actions_on_settings (GtkAction *action,
6077 dialog = modest_platform_get_global_settings_dialog ();
6078 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
6079 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
6080 gtk_widget_show_all (dialog);
6082 gtk_dialog_run (GTK_DIALOG (dialog));
6084 gtk_widget_destroy (dialog);
6088 modest_ui_actions_on_help (GtkAction *action,
6091 /* Help app is not available at all in fremantle */
6092 #ifndef MODEST_TOOLKIT_HILDON2
6093 const gchar *help_id;
6095 g_return_if_fail (win && GTK_IS_WINDOW(win));
6097 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
6100 modest_platform_show_help (GTK_WINDOW (win), help_id);
6105 modest_ui_actions_on_csm_help (GtkAction *action,
6108 /* Help app is not available at all in fremantle */
6109 #ifndef MODEST_TOOLKIT_HILDON2
6111 const gchar* help_id = NULL;
6112 GtkWidget *folder_view;
6113 TnyFolderStore *folder_store;
6115 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
6117 /* Get selected folder */
6118 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
6119 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6120 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6122 /* Switch help_id */
6123 if (folder_store && TNY_IS_FOLDER (folder_store))
6124 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
6127 g_object_unref (folder_store);
6130 modest_platform_show_help (GTK_WINDOW (win), help_id);
6132 modest_ui_actions_on_help (action, win);
6137 retrieve_contents_cb (ModestMailOperation *mail_op,
6144 /* We only need this callback to show an error in case of
6145 memory low condition */
6146 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
6147 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
6152 retrieve_msg_contents_performer (gboolean canceled,
6154 GtkWindow *parent_window,
6155 TnyAccount *account,
6158 ModestMailOperation *mail_op;
6159 TnyList *headers = TNY_LIST (user_data);
6161 if (err || canceled) {
6162 check_memory_full_error ((GtkWidget *) parent_window, err);
6166 /* Create mail operation */
6167 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
6168 modest_ui_actions_disk_operations_error_handler,
6170 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
6171 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
6174 g_object_unref (mail_op);
6176 g_object_unref (headers);
6177 g_object_unref (account);
6181 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
6182 ModestWindow *window)
6184 TnyList *headers = NULL;
6185 TnyAccount *account = NULL;
6186 TnyIterator *iter = NULL;
6187 TnyHeader *header = NULL;
6188 TnyFolder *folder = NULL;
6191 headers = get_selected_headers (window);
6195 /* Pick the account */
6196 iter = tny_list_create_iterator (headers);
6197 header = TNY_HEADER (tny_iterator_get_current (iter));
6198 folder = tny_header_get_folder (header);
6199 account = tny_folder_get_account (folder);
6200 g_object_unref (folder);
6201 g_object_unref (header);
6202 g_object_unref (iter);
6204 /* Connect and perform the message retrieval */
6205 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6206 g_object_ref (account),
6207 retrieve_msg_contents_performer,
6208 g_object_ref (headers));
6211 g_object_unref (account);
6212 g_object_unref (headers);
6216 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6218 g_return_if_fail (MODEST_IS_WINDOW (window));
6221 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6225 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6227 g_return_if_fail (MODEST_IS_WINDOW (window));
6230 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6234 modest_ui_actions_on_email_menu_activated (GtkAction *action,
6235 ModestWindow *window)
6237 g_return_if_fail (MODEST_IS_WINDOW (window));
6240 modest_ui_actions_check_menu_dimming_rules (window);
6244 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
6245 ModestWindow *window)
6247 g_return_if_fail (MODEST_IS_WINDOW (window));
6250 modest_ui_actions_check_menu_dimming_rules (window);
6254 modest_ui_actions_on_view_menu_activated (GtkAction *action,
6255 ModestWindow *window)
6257 g_return_if_fail (MODEST_IS_WINDOW (window));
6260 modest_ui_actions_check_menu_dimming_rules (window);
6264 modest_ui_actions_on_format_menu_activated (GtkAction *action,
6265 ModestWindow *window)
6267 g_return_if_fail (MODEST_IS_WINDOW (window));
6270 modest_ui_actions_check_menu_dimming_rules (window);
6274 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
6275 ModestWindow *window)
6277 g_return_if_fail (MODEST_IS_WINDOW (window));
6280 modest_ui_actions_check_menu_dimming_rules (window);
6284 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
6285 ModestWindow *window)
6287 g_return_if_fail (MODEST_IS_WINDOW (window));
6290 modest_ui_actions_check_menu_dimming_rules (window);
6294 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
6295 ModestWindow *window)
6297 g_return_if_fail (MODEST_IS_WINDOW (window));
6300 modest_ui_actions_check_menu_dimming_rules (window);
6304 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
6305 ModestWindow *window)
6307 g_return_if_fail (MODEST_IS_WINDOW (window));
6310 modest_ui_actions_check_menu_dimming_rules (window);
6314 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
6315 ModestWindow *window)
6317 g_return_if_fail (MODEST_IS_WINDOW (window));
6320 modest_ui_actions_check_menu_dimming_rules (window);
6324 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6326 g_return_if_fail (MODEST_IS_WINDOW (window));
6328 /* we check for low-mem; in that case, show a warning, and don't allow
6331 if (modest_platform_check_memory_low (window, TRUE))
6334 modest_platform_show_search_messages (GTK_WINDOW (window));
6338 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6340 g_return_if_fail (MODEST_IS_WINDOW (win));
6343 /* we check for low-mem; in that case, show a warning, and don't allow
6344 * for the addressbook
6346 if (modest_platform_check_memory_low (win, TRUE))
6350 modest_platform_show_addressbook (GTK_WINDOW (win));
6355 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6356 ModestWindow *window)
6359 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6361 if (GTK_IS_TOGGLE_ACTION (action))
6362 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6366 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window),
6371 on_send_receive_finished (ModestMailOperation *mail_op,
6374 GtkWidget *header_view, *folder_view;
6375 TnyFolderStore *folder_store;
6376 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6378 /* Set send/receive operation finished */
6379 modest_main_window_notify_send_receive_completed (main_win);
6381 /* Don't refresh the current folder if there were any errors */
6382 if (modest_mail_operation_get_status (mail_op) !=
6383 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6386 /* Refresh the current folder if we're viewing a window. We do
6387 this because the user won't be able to see the new mails in
6388 the selected folder after a Send&Receive because it only
6389 performs a poke_status, i.e, only the number of read/unread
6390 messages is updated, but the new headers are not
6392 folder_view = modest_main_window_get_child_widget (main_win,
6393 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6397 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6399 /* Do not need to refresh INBOX again because the
6400 update_account does it always automatically */
6401 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6402 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6403 ModestMailOperation *refresh_op;
6405 header_view = modest_main_window_get_child_widget (main_win,
6406 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6408 /* We do not need to set the contents style
6409 because it hasn't changed. We also do not
6410 need to save the widget status. Just force
6412 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6413 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6414 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6415 folder_refreshed_cb, main_win);
6416 g_object_unref (refresh_op);
6420 g_object_unref (folder_store);
6425 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6431 const gchar* server_name = NULL;
6432 TnyTransportAccount *transport;
6433 gchar *message = NULL;
6434 ModestProtocol *protocol;
6436 /* Don't show anything if the user cancelled something or the
6437 * send receive request is not interactive. Authentication
6438 * errors are managed by the account store so no need to show
6439 * a dialog here again */
6440 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6441 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6442 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6446 /* Get the server name. Note that we could be using a
6447 connection specific transport account */
6448 transport = (TnyTransportAccount *)
6449 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
6451 ModestTnyAccountStore *acc_store;
6452 const gchar *acc_name;
6453 TnyTransportAccount *conn_specific;
6455 acc_store = modest_runtime_get_account_store();
6456 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
6457 conn_specific = (TnyTransportAccount *)
6458 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
6459 if (conn_specific) {
6460 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
6461 g_object_unref (conn_specific);
6463 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
6465 g_object_unref (transport);
6469 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
6470 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
6471 tny_account_get_proto (TNY_ACCOUNT (transport)));
6473 g_warning ("%s: Account with no proto", __FUNCTION__);
6477 /* Show the appropriate message text for the GError: */
6478 switch (err->code) {
6479 case TNY_SERVICE_ERROR_CONNECT:
6480 message = modest_protocol_get_translation (protocol,
6481 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
6484 case TNY_SERVICE_ERROR_SEND:
6485 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6487 case TNY_SERVICE_ERROR_UNAVAILABLE:
6488 message = modest_protocol_get_translation (protocol,
6489 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
6493 g_warning ("%s: unexpected ERROR %d",
6494 __FUNCTION__, err->code);
6495 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6499 modest_platform_run_information_dialog (NULL, message, FALSE);
6504 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6509 ModestWindow *top_window = NULL;
6510 ModestWindowMgr *mgr = NULL;
6511 GtkWidget *header_view = NULL;
6512 TnyFolder *selected_folder = NULL;
6513 TnyFolderType folder_type;
6515 mgr = modest_runtime_get_window_mgr ();
6516 top_window = modest_window_mgr_get_current_top (mgr);
6521 #ifndef MODEST_TOOLKIT_HILDON2
6522 if (MODEST_IS_MAIN_WINDOW (top_window)) {
6523 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (top_window),
6524 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6527 if (MODEST_IS_HEADER_WINDOW (top_window)) {
6528 header_view = (GtkWidget *)
6529 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
6533 /* Get selected folder */
6535 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
6536 if (!selected_folder)
6539 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6540 #if GTK_CHECK_VERSION(2, 8, 0)
6541 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
6542 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6543 GtkTreeViewColumn *tree_column;
6545 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6546 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6548 gtk_tree_view_column_queue_resize (tree_column);
6550 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
6551 gtk_widget_queue_draw (header_view);
6554 #ifndef MODEST_TOOLKIT_HILDON2
6555 /* Rerun dimming rules, because the message could become deletable for example */
6556 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6557 MODEST_DIMMING_RULES_TOOLBAR);
6558 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6559 MODEST_DIMMING_RULES_MENU);
6563 g_object_unref (selected_folder);
6567 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6568 TnyAccount *account)
6570 ModestProtocolType protocol_type;
6571 ModestProtocol *protocol;
6572 gchar *error_note = NULL;
6574 protocol_type = modest_tny_account_get_protocol_type (account);
6575 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6578 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6579 if (error_note == NULL) {
6580 g_warning ("%s: This should not be reached", __FUNCTION__);
6582 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6583 g_free (error_note);
6588 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6592 TnyFolderStore *folder = NULL;
6593 TnyAccount *account = NULL;
6594 ModestProtocolType proto;
6595 ModestProtocol *protocol;
6596 TnyHeader *header = NULL;
6598 if (MODEST_IS_MAIN_WINDOW (win)) {
6599 GtkWidget *header_view;
6600 TnyList* headers = NULL;
6602 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6603 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6604 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6605 if (!headers || tny_list_get_length (headers) == 0) {
6607 g_object_unref (headers);
6610 iter = tny_list_create_iterator (headers);
6611 header = TNY_HEADER (tny_iterator_get_current (iter));
6612 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6613 g_object_unref (iter);
6614 g_object_unref (headers);
6615 #ifdef MODEST_TOOLKIT_HILDON2
6616 } else if (MODEST_IS_HEADER_WINDOW (win)) {
6617 GtkWidget *header_view;
6618 TnyList* headers = NULL;
6620 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
6621 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6622 if (!headers || tny_list_get_length (headers) == 0) {
6624 g_object_unref (headers);
6627 iter = tny_list_create_iterator (headers);
6628 header = TNY_HEADER (tny_iterator_get_current (iter));
6630 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6632 g_warning ("List should contain headers");
6634 g_object_unref (iter);
6635 g_object_unref (headers);
6637 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6638 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6639 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6642 if (!header || !folder)
6645 /* Get the account type */
6646 account = tny_folder_get_account (TNY_FOLDER (folder));
6647 proto = modest_tny_account_get_protocol_type (account);
6648 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6651 subject = tny_header_dup_subject (header);
6652 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6656 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6662 g_object_unref (account);
6664 g_object_unref (folder);
6666 g_object_unref (header);
6672 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6673 const gchar *account_name,
6674 const gchar *account_title)
6676 ModestAccountMgr *account_mgr;
6679 ModestProtocol *protocol;
6680 gboolean removed = FALSE;
6682 g_return_val_if_fail (account_name, FALSE);
6683 g_return_val_if_fail (account_title, FALSE);
6685 account_mgr = modest_runtime_get_account_mgr();
6687 /* The warning text depends on the account type: */
6688 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6689 modest_account_mgr_get_store_protocol (account_mgr,
6691 txt = modest_protocol_get_translation (protocol,
6692 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6695 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6697 response = modest_platform_run_confirmation_dialog (parent_window, txt);
6701 if (response == GTK_RESPONSE_OK) {
6702 /* Remove account. If it succeeds then it also removes
6703 the account from the ModestAccountView: */
6704 gboolean is_default = FALSE;
6705 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6706 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6708 g_free (default_account_name);
6710 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6712 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
6718 modest_ui_actions_on_fetch_images (GtkAction *action,
6719 ModestWindow *window)
6721 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
6723 modest_msg_view_window_fetch_images (MODEST_MSG_VIEW_WINDOW (window));
6728 modest_ui_actions_on_reload_message (const gchar *msg_id)
6730 ModestWindow *window = NULL;
6732 g_return_if_fail (msg_id && msg_id[0] != '\0');
6733 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
6739 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
6742 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));