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 ModestWindow *old_win;
246 win = MODEST_WINDOW (modest_accounts_window_new ());
247 if (modest_window_mgr_register_window (mgr, win, NULL)) {
248 gtk_widget_show_all (GTK_WIDGET (win));
250 gtk_widget_destroy (GTK_WIDGET (win));
255 win = MODEST_WINDOW (modest_folder_window_new (NULL));
256 if (modest_window_mgr_register_window (mgr, win, NULL)) {
257 gtk_widget_show_all (GTK_WIDGET (win));
259 gtk_widget_destroy (GTK_WIDGET (win));
263 g_list_free (window_list);
269 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
271 /* make sure the mainwindow is visible. We need to present the
272 wizard again to give it the focus back. show_all are needed
273 in order to get the widgets properly drawn (MainWindow main
274 paned won't be in its right position and the dialog will be
276 #ifndef MODEST_TOOLKIT_HILDON2
277 gtk_widget_show_all (GTK_WIDGET (win));
278 gtk_widget_show_all (GTK_WIDGET (wizard));
279 gtk_window_present (GTK_WINDOW (win));
280 gtk_window_present (GTK_WINDOW (wizard));
283 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
284 gtk_widget_destroy (GTK_WIDGET (wizard));
285 if (gtk_events_pending ())
286 gtk_main_iteration ();
288 if (dialog_response == GTK_RESPONSE_CANCEL) {
291 /* Check whether an account was created: */
292 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
299 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
302 const gchar *authors[] = {
303 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
306 about = gtk_about_dialog_new ();
307 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
308 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
309 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
310 _("Copyright (c) 2006, Nokia Corporation\n"
311 "All rights reserved."));
312 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
313 _("a modest e-mail client\n\n"
314 "design and implementation: Dirk-Jan C. Binnema\n"
315 "contributions from the fine people at KC and Ig\n"
316 "uses the tinymail email framework written by Philip van Hoof"));
317 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
318 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
319 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
320 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
322 gtk_dialog_run (GTK_DIALOG (about));
323 gtk_widget_destroy(about);
327 * Gets the list of currently selected messages. If the win is the
328 * main window, then it returns a newly allocated list of the headers
329 * selected in the header view. If win is the msg view window, then
330 * the value returned is a list with just a single header.
332 * The caller of this funcion must free the list.
335 get_selected_headers (ModestWindow *win)
337 if (MODEST_IS_MAIN_WINDOW(win)) {
338 GtkWidget *header_view;
340 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
341 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
342 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
344 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
345 /* for MsgViewWindows, we simply return a list with one element */
347 TnyList *list = NULL;
349 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
350 if (header != NULL) {
351 list = tny_simple_list_new ();
352 tny_list_prepend (list, G_OBJECT(header));
353 g_object_unref (G_OBJECT(header));
358 #ifdef MODEST_TOOLKIT_HILDON2
359 } else if (MODEST_IS_HEADER_WINDOW (win)) {
360 GtkWidget *header_view;
362 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
363 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
369 static GtkTreeRowReference *
370 get_next_after_selected_headers (ModestHeaderView *header_view)
372 GtkTreeSelection *sel;
373 GList *selected_rows, *node;
375 GtkTreeRowReference *result;
378 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
379 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
380 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
382 if (selected_rows == NULL)
385 node = g_list_last (selected_rows);
386 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
387 gtk_tree_path_next (path);
389 result = gtk_tree_row_reference_new (model, path);
391 gtk_tree_path_free (path);
392 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
393 g_list_free (selected_rows);
399 headers_action_mark_as_read (TnyHeader *header,
403 TnyHeaderFlags flags;
405 g_return_if_fail (TNY_IS_HEADER(header));
407 flags = tny_header_get_flags (header);
408 if (flags & TNY_HEADER_FLAG_SEEN) return;
409 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
413 headers_action_mark_as_unread (TnyHeader *header,
417 TnyHeaderFlags flags;
419 g_return_if_fail (TNY_IS_HEADER(header));
421 flags = tny_header_get_flags (header);
422 if (flags & TNY_HEADER_FLAG_SEEN) {
423 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
427 /** After deleing a message that is currently visible in a window,
428 * show the next message from the list, or close the window if there are no more messages.
431 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
433 /* Close msg view window or select next */
434 if (!modest_msg_view_window_select_next_message (win) &&
435 !modest_msg_view_window_select_previous_message (win)) {
437 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
443 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
445 modest_ui_actions_on_edit_mode_delete_message (win);
449 modest_ui_actions_on_edit_mode_delete_message (ModestWindow *win)
451 TnyList *header_list = NULL;
452 TnyIterator *iter = NULL;
453 TnyHeader *header = NULL;
454 gchar *message = NULL;
457 ModestWindowMgr *mgr;
458 GtkWidget *header_view = NULL;
459 gboolean retval = TRUE;
461 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
463 /* Check first if the header view has the focus */
464 if (MODEST_IS_MAIN_WINDOW (win)) {
466 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
467 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
468 if (!gtk_widget_is_focus (header_view))
472 /* Get the headers, either from the header view (if win is the main window),
473 * or from the message view window: */
474 header_list = get_selected_headers (win);
475 if (!header_list) return FALSE;
477 /* Check if any of the headers are already opened, or in the process of being opened */
478 if (MODEST_IS_MAIN_WINDOW (win)) {
479 gint opened_headers = 0;
481 iter = tny_list_create_iterator (header_list);
482 mgr = modest_runtime_get_window_mgr ();
483 while (!tny_iterator_is_done (iter)) {
484 header = TNY_HEADER (tny_iterator_get_current (iter));
486 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
488 g_object_unref (header);
490 tny_iterator_next (iter);
492 g_object_unref (iter);
494 if (opened_headers > 0) {
497 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
500 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg, FALSE);
503 g_object_unref (header_list);
509 if (tny_list_get_length(header_list) == 1) {
510 iter = tny_list_create_iterator (header_list);
511 header = TNY_HEADER (tny_iterator_get_current (iter));
514 subject = tny_header_dup_subject (header);
516 subject = g_strdup (_("mail_va_no_subject"));
517 desc = g_strdup_printf ("%s", subject);
519 g_object_unref (header);
522 g_object_unref (iter);
524 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
525 tny_list_get_length(header_list)), desc);
527 /* Confirmation dialog */
528 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
532 if (response == GTK_RESPONSE_OK) {
533 ModestWindow *main_window = NULL;
534 ModestWindowMgr *mgr = NULL;
535 GtkTreeModel *model = NULL;
536 GtkTreeSelection *sel = NULL;
537 GList *sel_list = NULL, *tmp = NULL;
538 GtkTreeRowReference *next_row_reference = NULL;
539 GtkTreeRowReference *prev_row_reference = NULL;
540 GtkTreePath *next_path = NULL;
541 GtkTreePath *prev_path = NULL;
542 ModestMailOperation *mail_op = NULL;
544 /* Find last selected row */
545 if (MODEST_IS_MAIN_WINDOW (win)) {
546 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
547 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
548 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
549 for (tmp=sel_list; tmp; tmp=tmp->next) {
550 if (tmp->next == NULL) {
551 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
552 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
554 gtk_tree_path_prev (prev_path);
555 gtk_tree_path_next (next_path);
557 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
558 next_row_reference = gtk_tree_row_reference_new (model, next_path);
563 /* Disable window dimming management */
564 modest_window_disable_dimming (MODEST_WINDOW(win));
566 /* Remove each header. If it's a view window header_view == NULL */
567 mail_op = modest_mail_operation_new ((GObject *) win);
568 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
570 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
571 g_object_unref (mail_op);
573 /* Enable window dimming management */
575 gtk_tree_selection_unselect_all (sel);
577 modest_window_enable_dimming (MODEST_WINDOW(win));
579 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
580 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
582 /* Get main window */
583 mgr = modest_runtime_get_window_mgr ();
584 main_window = modest_window_mgr_get_main_window (mgr, FALSE); /* don't create */
585 } else if (MODEST_IS_MAIN_WINDOW (win)) {
586 /* Move cursor to next row */
589 /* Select next or previous row */
590 if (gtk_tree_row_reference_valid (next_row_reference)) {
591 gtk_tree_selection_select_path (sel, next_path);
593 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
594 gtk_tree_selection_select_path (sel, prev_path);
598 if (gtk_tree_row_reference_valid (next_row_reference))
599 gtk_tree_row_reference_free (next_row_reference);
600 if (next_path != NULL)
601 gtk_tree_path_free (next_path);
602 if (gtk_tree_row_reference_valid (prev_row_reference))
603 gtk_tree_row_reference_free (prev_row_reference);
604 if (prev_path != NULL)
605 gtk_tree_path_free (prev_path);
608 /* Update toolbar dimming state */
610 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
611 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
615 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
616 g_list_free (sel_list);
625 g_object_unref (header_list);
633 /* delete either message or folder, based on where we are */
635 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
637 g_return_if_fail (MODEST_IS_WINDOW(win));
639 /* Check first if the header view has the focus */
640 if (MODEST_IS_MAIN_WINDOW (win)) {
642 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
643 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
644 if (gtk_widget_is_focus (w)) {
645 modest_ui_actions_on_delete_folder (action, MODEST_WINDOW(win));
649 modest_ui_actions_on_delete_message (action, win);
653 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
655 ModestWindowMgr *mgr = NULL;
657 #ifdef MODEST_PLATFORM_MAEMO
658 modest_osso_save_state();
659 #endif /* MODEST_PLATFORM_MAEMO */
661 g_debug ("closing down, clearing %d item(s) from operation queue",
662 modest_mail_operation_queue_num_elements
663 (modest_runtime_get_mail_operation_queue()));
665 /* cancel all outstanding operations */
666 modest_mail_operation_queue_cancel_all
667 (modest_runtime_get_mail_operation_queue());
669 g_debug ("queue has been cleared");
672 /* Check if there are opened editing windows */
673 mgr = modest_runtime_get_window_mgr ();
674 modest_window_mgr_close_all_windows (mgr);
676 /* note: when modest-tny-account-store is finalized,
677 it will automatically set all network connections
680 /* gtk_main_quit (); */
684 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
688 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
690 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
691 /* gtk_widget_destroy (GTK_WIDGET (win)); */
692 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
693 /* gboolean ret_value; */
694 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
695 /* } else if (MODEST_IS_WINDOW (win)) { */
696 /* gtk_widget_destroy (GTK_WIDGET (win)); */
698 /* g_return_if_reached (); */
703 modest_ui_actions_add_to_contacts (GtkAction *action, ModestWindow *win)
705 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
707 modest_msg_view_window_add_to_contacts (MODEST_MSG_VIEW_WINDOW (win));
711 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
713 GtkClipboard *clipboard = NULL;
714 gchar *selection = NULL;
716 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
717 selection = gtk_clipboard_wait_for_text (clipboard);
719 /* Question: why is the clipboard being used here?
720 * It doesn't really make a lot of sense. */
724 modest_address_book_add_address (selection);
730 modest_ui_actions_on_new_account (GtkAction *action,
731 ModestWindow *window)
733 if (!modest_ui_actions_run_account_setup_wizard (window)) {
734 g_debug ("%s: wizard was already running", __FUNCTION__);
739 modest_ui_actions_on_accounts (GtkAction *action,
742 /* This is currently only implemented for Maemo */
743 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
744 if (!modest_ui_actions_run_account_setup_wizard (win))
745 g_debug ("%s: wizard was already running", __FUNCTION__);
749 /* Show the list of accounts */
750 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
752 /* The accounts dialog must be modal */
753 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
754 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
759 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
761 /* This is currently only implemented for Maemo,
762 * because it requires an API (libconic) to detect different connection
765 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
767 /* Create the window if necessary: */
768 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
769 modest_connection_specific_smtp_window_fill_with_connections (
770 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
771 modest_runtime_get_account_mgr());
773 /* Show the window: */
774 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
775 GTK_WINDOW (specific_window), (GtkWindow *) win);
776 gtk_widget_show (specific_window);
777 #endif /* !MODEST_TOOLKIT_GTK */
781 modest_ui_actions_compose_msg(ModestWindow *win,
784 const gchar *bcc_str,
785 const gchar *subject_str,
786 const gchar *body_str,
788 gboolean set_as_modified)
790 gchar *account_name = NULL;
791 const gchar *mailbox;
793 TnyAccount *account = NULL;
794 TnyFolder *folder = NULL;
795 gchar *from_str = NULL, *signature = NULL, *body = NULL;
796 gchar *recipient = NULL;
797 gboolean use_signature = FALSE;
798 ModestWindow *msg_win = NULL;
799 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
800 ModestTnyAccountStore *store = modest_runtime_get_account_store();
801 GnomeVFSFileSize total_size, allowed_size;
803 /* we check for low-mem */
804 if (modest_platform_check_memory_low (win, TRUE))
807 #ifdef MODEST_TOOLKIT_HILDON2
809 account_name = g_strdup (modest_window_get_active_account(win));
812 account_name = modest_account_mgr_get_default_account(mgr);
815 g_printerr ("modest: no account found\n");
820 mailbox = modest_window_get_active_mailbox (win);
823 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
825 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
828 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
830 g_printerr ("modest: failed to find Drafts folder\n");
833 from_str = modest_account_mgr_get_from_string (mgr, account_name, mailbox);
835 g_printerr ("modest: failed get from string for '%s'\n", account_name);
839 recipient = modest_text_utils_get_email_address (from_str);
840 signature = modest_account_mgr_get_signature_from_recipient (mgr, recipient, &use_signature);
842 if (body_str != NULL) {
843 body = use_signature ? g_strconcat(body_str, "\n--\n", signature, NULL) : g_strdup(body_str);
845 body = use_signature ? g_strconcat("\n--\n", signature, NULL) : g_strdup("");
848 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, NULL, NULL, body, NULL, NULL, NULL);
850 g_printerr ("modest: failed to create new msg\n");
854 /* Create and register edit window */
855 /* This is destroyed by TODO. */
857 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
858 msg_win = modest_msg_edit_window_new (msg, account_name, mailbox, FALSE);
860 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, win)) {
861 gtk_widget_destroy (GTK_WIDGET (msg_win));
864 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
865 gtk_widget_show_all (GTK_WIDGET (msg_win));
867 while (attachments) {
869 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
870 attachments->data, allowed_size);
872 if (total_size > allowed_size) {
873 g_warning ("%s: total size: %u",
874 __FUNCTION__, (unsigned int)total_size);
877 allowed_size -= total_size;
879 attachments = g_slist_next(attachments);
886 g_free (account_name);
888 g_object_unref (G_OBJECT(account));
890 g_object_unref (G_OBJECT(folder));
892 g_object_unref (G_OBJECT(msg));
896 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
898 /* if there are no accounts yet, just show the wizard */
899 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
900 if (!modest_ui_actions_run_account_setup_wizard (win))
903 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
908 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
912 ModestMailOperationStatus status;
914 /* If there is no message or the operation was not successful */
915 status = modest_mail_operation_get_status (mail_op);
916 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
919 /* If it's a memory low issue, then show a banner */
920 error = modest_mail_operation_get_error (mail_op);
921 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
922 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
923 GObject *source = modest_mail_operation_get_source (mail_op);
924 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
925 _KR("memr_ib_operation_disabled"),
927 g_object_unref (source);
930 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
931 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
932 gchar *subject, *msg, *format = NULL;
934 subject = tny_header_dup_subject (header);
936 subject = g_strdup (_("mail_va_no_subject"));
938 account = modest_mail_operation_get_account (mail_op);
940 ModestProtocol *protocol;
941 ModestProtocolType proto;
942 proto = modest_tny_account_get_protocol_type (account);
943 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), proto);
945 format = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
946 g_object_unref (account);
950 format = g_strdup (_("emev_ni_ui_imap_message_not_available_in_server"));
952 msg = g_strdup_printf (format, subject);
953 modest_platform_run_information_dialog (NULL, msg, FALSE);
959 /* Remove the header from the preregistered uids */
960 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
978 OpenMsgBannerInfo *banner_info;
979 GtkTreeRowReference *rowref;
983 open_msg_banner_idle (gpointer userdata)
985 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
987 gdk_threads_enter ();
988 banner_info->idle_handler = 0;
989 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
990 if (banner_info->banner)
991 g_object_ref (banner_info->banner);
993 gdk_threads_leave ();
999 get_header_view_from_window (ModestWindow *window)
1001 GtkWidget *header_view;
1003 if (MODEST_IS_MAIN_WINDOW (window)) {
1004 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
1005 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1006 #ifdef MODEST_TOOLKIT_HILDON2
1007 } else if (MODEST_IS_HEADER_WINDOW (window)){
1008 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
1018 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
1021 gchar *account = NULL;
1022 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
1027 folder = tny_header_get_folder (header);
1028 /* Gets folder type (OUTBOX headers will be opened in edit window */
1029 if (modest_tny_folder_is_local_folder (folder)) {
1030 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1031 if (folder_type == TNY_FOLDER_TYPE_INVALID)
1032 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1035 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
1036 TnyTransportAccount *traccount = NULL;
1037 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
1038 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
1040 ModestTnySendQueue *send_queue = NULL;
1041 ModestTnySendQueueStatus status;
1043 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
1044 TNY_ACCOUNT(traccount)));
1045 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
1046 if (TNY_IS_SEND_QUEUE (send_queue)) {
1047 msg_id = modest_tny_send_queue_get_msg_id (header);
1048 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
1050 /* Only open messages in outbox with the editor if they are in Failed state */
1051 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
1054 #ifdef MODEST_TOOLKIT_HILDON2
1056 /* In Fremantle we can not
1057 open any message from
1058 outbox which is not in
1064 g_object_unref(traccount);
1066 g_warning("Cannot get transport account for message in outbox!!");
1068 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
1069 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
1073 TnyAccount *acc = tny_folder_get_account (folder);
1076 g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (acc));
1077 g_object_unref (acc);
1081 g_object_unref (folder);
1087 open_msg_cb (ModestMailOperation *mail_op,
1094 ModestWindowMgr *mgr = NULL;
1095 ModestWindow *parent_win = NULL;
1096 ModestWindow *win = NULL;
1097 gchar *account = NULL;
1098 gboolean open_in_editor = FALSE;
1100 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1102 /* Do nothing if there was any problem with the mail
1103 operation. The error will be shown by the error_handler of
1104 the mail operation */
1105 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1108 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1110 /* Mark header as read */
1111 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1113 account = get_info_from_header (header, &open_in_editor, &can_open);
1117 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1119 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1121 if (open_in_editor) {
1122 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1123 gchar *from_header = NULL, *acc_name;
1124 gchar *mailbox = NULL;
1126 from_header = tny_header_dup_from (header);
1128 /* we cannot edit without a valid account... */
1129 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1130 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1131 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1133 g_free (from_header);
1138 acc_name = modest_utils_get_account_name_from_recipient (from_header, &mailbox);
1139 g_free (from_header);
1145 win = modest_msg_edit_window_new (msg, account, mailbox, TRUE);
1149 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1150 const gchar *mailbox = NULL;
1152 if (parent_win && MODEST_IS_WINDOW (parent_win))
1153 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_win));
1155 if (helper->rowref && helper->model) {
1156 win = modest_msg_view_window_new_with_header_model (msg, account, mailbox, (const gchar*) uid,
1157 helper->model, helper->rowref);
1159 win = modest_msg_view_window_new_for_attachment (msg, account, mailbox, (const gchar*) uid);
1164 /* Register and show new window */
1166 mgr = modest_runtime_get_window_mgr ();
1167 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1168 gtk_widget_destroy (GTK_WIDGET (win));
1171 gtk_widget_show_all (GTK_WIDGET(win));
1174 /* Update toolbar dimming state */
1175 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1176 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1182 g_object_unref (parent_win);
1186 is_memory_full_error (GError *error, ModestMailOperation *mail_op)
1188 gboolean enough_free_space = TRUE;
1189 GnomeVFSURI *cache_dir_uri;
1190 const gchar *cache_dir = NULL;
1191 GnomeVFSFileSize free_space;
1192 TnyAccountStore *acc_store;
1194 acc_store = TNY_ACCOUNT_STORE (modest_runtime_get_account_store ());
1196 /* Cache dir is different in case we're using an external storage (like MMC account) */
1198 TnyAccount *account = modest_mail_operation_get_account (mail_op);
1200 if (modest_tny_account_is_memory_card_account (account)) {
1201 cache_dir = g_getenv (MODEST_MMC1_VOLUMEPATH_ENV);
1203 g_object_unref (account);
1207 /* Get the default local cache dir */
1209 cache_dir = tny_account_store_get_cache_dir (acc_store);
1211 cache_dir_uri = gnome_vfs_uri_new (cache_dir);
1212 if (cache_dir_uri) {
1213 if (gnome_vfs_get_volume_free_space (cache_dir_uri, &free_space) == GNOME_VFS_OK) {
1214 if (free_space < MIN_FREE_SPACE)
1215 enough_free_space = FALSE;
1217 gnome_vfs_uri_unref (cache_dir_uri);
1220 if ((error->code == TNY_SYSTEM_ERROR_MEMORY ||
1221 /* When asking for a mail and no space left on device
1222 tinymail returns this error */
1223 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE ||
1224 /* When the folder summary could not be read or
1226 error->code == TNY_IO_ERROR_WRITE ||
1227 error->code == TNY_IO_ERROR_READ) &&
1228 !enough_free_space) {
1236 check_memory_full_error (GtkWidget *parent_window, GError *err)
1241 if (is_memory_full_error (err, NULL))
1242 modest_platform_information_banner (parent_window,
1243 NULL, _KR("cerm_device_memory_full"));
1244 else if (err->code == TNY_SYSTEM_ERROR_MEMORY)
1245 /* If the account was created in memory full
1246 conditions then tinymail won't be able to
1247 connect so it'll return this error code */
1248 modest_platform_information_banner (parent_window,
1249 NULL, _("emev_ui_imap_inbox_select_error"));
1257 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1260 const GError *error;
1261 GObject *win = NULL;
1262 ModestMailOperationStatus status;
1264 win = modest_mail_operation_get_source (mail_op);
1265 error = modest_mail_operation_get_error (mail_op);
1266 status = modest_mail_operation_get_status (mail_op);
1268 /* If the mail op has been cancelled then it's not an error:
1269 don't show any message */
1270 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1271 if (is_memory_full_error ((GError *) error, mail_op)) {
1272 modest_platform_information_banner ((GtkWidget *) win,
1273 NULL, _KR("cerm_device_memory_full"));
1274 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1275 modest_platform_information_banner ((GtkWidget *) win,
1276 NULL, _("emev_ui_imap_inbox_select_error"));
1277 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1278 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1279 modest_platform_information_banner ((GtkWidget *) win,
1280 NULL, _CS ("sfil_ni_unable_to_open_file_not_found"));
1281 } else if (user_data) {
1282 modest_platform_information_banner ((GtkWidget *) win,
1288 g_object_unref (win);
1292 * Returns the account a list of headers belongs to. It returns a
1293 * *new* reference so don't forget to unref it
1296 get_account_from_header_list (TnyList *headers)
1298 TnyAccount *account = NULL;
1300 if (tny_list_get_length (headers) > 0) {
1301 TnyIterator *iter = tny_list_create_iterator (headers);
1302 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1303 TnyFolder *folder = tny_header_get_folder (header);
1306 g_object_unref (header);
1308 while (!tny_iterator_is_done (iter)) {
1309 header = TNY_HEADER (tny_iterator_get_current (iter));
1310 folder = tny_header_get_folder (header);
1313 g_object_unref (header);
1315 tny_iterator_next (iter);
1320 account = tny_folder_get_account (folder);
1321 g_object_unref (folder);
1325 g_object_unref (header);
1327 g_object_unref (iter);
1333 get_account_from_header (TnyHeader *header)
1335 TnyAccount *account = NULL;
1338 folder = tny_header_get_folder (header);
1341 account = tny_folder_get_account (folder);
1342 g_object_unref (folder);
1348 open_msg_helper_destroyer (gpointer user_data)
1350 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1352 if (helper->banner_info) {
1353 g_free (helper->banner_info->message);
1354 if (helper->banner_info->idle_handler > 0) {
1355 g_source_remove (helper->banner_info->idle_handler);
1356 helper->banner_info->idle_handler = 0;
1358 if (helper->banner_info->banner != NULL) {
1359 gtk_widget_destroy (helper->banner_info->banner);
1360 g_object_unref (helper->banner_info->banner);
1361 helper->banner_info->banner = NULL;
1363 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1364 helper->banner_info = NULL;
1366 g_object_unref (helper->model);
1367 g_object_unref (helper->header);
1368 gtk_tree_row_reference_free (helper->rowref);
1369 g_slice_free (OpenMsgHelper, helper);
1373 open_msg_performer(gboolean canceled,
1375 GtkWindow *parent_window,
1376 TnyAccount *account,
1379 ModestMailOperation *mail_op = NULL;
1380 gchar *error_msg = NULL;
1381 ModestProtocolType proto;
1382 TnyConnectionStatus status;
1383 OpenMsgHelper *helper = NULL;
1384 ModestProtocol *protocol;
1385 ModestProtocolRegistry *protocol_registry;
1388 helper = (OpenMsgHelper *) user_data;
1390 status = tny_account_get_connection_status (account);
1391 if (err || canceled) {
1392 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1393 /* Free the helper */
1394 open_msg_helper_destroyer (helper);
1396 /* In memory full conditions we could get this error here */
1397 check_memory_full_error ((GtkWidget *) parent_window, err);
1402 /* Get the error message depending on the protocol */
1403 proto = modest_tny_account_get_protocol_type (account);
1404 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1405 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1408 protocol_registry = modest_runtime_get_protocol_registry ();
1409 subject = tny_header_dup_subject (helper->header);
1411 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1412 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1416 if (error_msg == NULL) {
1417 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1420 #ifndef MODEST_TOOLKIT_HILDON2
1421 gboolean show_open_draft = FALSE;
1422 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1424 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1426 TnyFolderType folder_type;
1428 folder = tny_header_get_folder (helper->header);
1429 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1430 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1431 g_object_unref (folder);
1435 #ifdef MODEST_TOOLKIT_HILDON2
1438 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1441 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1442 g_free (account_name);
1443 open_msg_helper_destroyer (helper);
1448 ModestWindow *window;
1449 GtkWidget *header_view;
1452 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1453 uid = modest_tny_folder_get_header_unique_id (helper->header);
1455 const gchar *mailbox = NULL;
1456 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_window));
1457 window = modest_msg_view_window_new_from_header_view
1458 (MODEST_HEADER_VIEW (header_view), account_name, mailbox, uid, helper->rowref);
1459 if (window != NULL) {
1460 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1462 gtk_widget_destroy (GTK_WIDGET (window));
1464 gtk_widget_show_all (GTK_WIDGET(window));
1468 g_free (account_name);
1470 open_msg_helper_destroyer (helper);
1473 g_free (account_name);
1475 /* Create the mail operation */
1477 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1478 modest_ui_actions_disk_operations_error_handler,
1479 g_strdup (error_msg), g_free);
1480 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1484 #ifndef MODEST_TOOLKIT_HILDON2
1485 if (show_open_draft) {
1486 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1487 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1488 helper->banner_info->banner = NULL;
1489 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1490 helper->banner_info);
1496 headers = TNY_LIST (tny_simple_list_new ());
1497 tny_list_prepend (headers, G_OBJECT (helper->header));
1498 modest_mail_operation_get_msgs_full (mail_op,
1502 open_msg_helper_destroyer);
1503 g_object_unref (headers);
1510 g_object_unref (mail_op);
1511 g_object_unref (account);
1515 * This function is used by both modest_ui_actions_on_open and
1516 * modest_ui_actions_on_header_activated. This way we always do the
1517 * same when trying to open messages.
1520 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1522 ModestWindowMgr *mgr = NULL;
1523 TnyAccount *account;
1524 gboolean cached = FALSE;
1526 GtkWidget *header_view = NULL;
1527 OpenMsgHelper *helper;
1528 ModestWindow *window;
1530 g_return_if_fail (header != NULL && rowref != NULL);
1532 mgr = modest_runtime_get_window_mgr ();
1535 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1536 if (header_view == NULL)
1539 /* Get the account */
1540 account = get_account_from_header (header);
1545 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1547 /* Do not open again the message and present the
1548 window to the user */
1551 #ifndef MODEST_TOOLKIT_HILDON2
1552 gtk_window_present (GTK_WINDOW (window));
1555 /* the header has been registered already, we don't do
1556 * anything but wait for the window to come up*/
1557 g_debug ("header %p already registered, waiting for window", header);
1562 /* Open each message */
1563 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1565 /* Allways download if we are online. */
1566 if (!tny_device_is_online (modest_runtime_get_device ())) {
1569 /* If ask for user permission to download the messages */
1570 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1571 _("mcen_nc_get_msg"));
1573 /* End if the user does not want to continue */
1574 if (response == GTK_RESPONSE_CANCEL) {
1580 /* We register the window for opening */
1581 modest_window_mgr_register_header (mgr, header, NULL);
1583 /* Create the helper. We need to get a reference to the model
1584 here because it could change while the message is readed
1585 (the user could switch between folders) */
1586 helper = g_slice_new (OpenMsgHelper);
1587 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1588 helper->header = g_object_ref (header);
1589 helper->rowref = gtk_tree_row_reference_copy (rowref);
1590 helper->banner_info = NULL;
1592 /* Connect to the account and perform */
1594 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1595 open_msg_performer, helper);
1597 /* Call directly the performer, do not need to connect */
1598 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1599 g_object_ref (account), helper);
1604 g_object_unref (account);
1608 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1615 /* we check for low-mem; in that case, show a warning, and don't allow
1618 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1622 headers = get_selected_headers (win);
1626 headers_count = tny_list_get_length (headers);
1627 if (headers_count != 1) {
1628 if (headers_count > 1) {
1629 /* Don't allow activation if there are more than one message selected */
1630 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1633 g_object_unref (headers);
1637 iter = tny_list_create_iterator (headers);
1638 header = TNY_HEADER (tny_iterator_get_current (iter));
1639 g_object_unref (iter);
1643 open_msg_from_header (header, NULL, win);
1644 g_object_unref (header);
1647 g_object_unref(headers);
1651 rf_helper_window_closed (gpointer data,
1654 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1656 helper->parent_window = NULL;
1659 static ReplyForwardHelper*
1660 create_reply_forward_helper (ReplyForwardAction action,
1662 guint reply_forward_type,
1665 ReplyForwardHelper *rf_helper = NULL;
1666 const gchar *active_acc = modest_window_get_active_account (win);
1667 const gchar *active_mailbox = modest_window_get_active_mailbox (win);
1669 rf_helper = g_slice_new0 (ReplyForwardHelper);
1670 rf_helper->reply_forward_type = reply_forward_type;
1671 rf_helper->action = action;
1672 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1673 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1674 rf_helper->account_name = (active_acc) ?
1675 g_strdup (active_acc) :
1676 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1677 rf_helper->mailbox = g_strdup (active_mailbox);
1679 /* Note that window could be destroyed just AFTER calling
1680 register_window so we must ensure that this pointer does
1681 not hold invalid references */
1682 if (rf_helper->parent_window)
1683 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1684 rf_helper_window_closed, rf_helper);
1690 free_reply_forward_helper (gpointer data)
1692 ReplyForwardHelper *helper;
1694 helper = (ReplyForwardHelper *) data;
1695 g_free (helper->account_name);
1696 g_free (helper->mailbox);
1698 g_object_unref (helper->header);
1699 if (helper->parent_window)
1700 g_object_weak_unref (G_OBJECT (helper->parent_window),
1701 rf_helper_window_closed, helper);
1702 g_slice_free (ReplyForwardHelper, helper);
1706 reply_forward_cb (ModestMailOperation *mail_op,
1713 TnyMsg *new_msg = NULL;
1714 ReplyForwardHelper *rf_helper;
1715 ModestWindow *msg_win = NULL;
1716 ModestEditType edit_type;
1718 TnyAccount *account = NULL;
1719 ModestWindowMgr *mgr = NULL;
1720 gchar *signature = NULL;
1721 gboolean use_signature;
1724 /* If there was any error. The mail operation could be NULL,
1725 this means that we already have the message downloaded and
1726 that we didn't do a mail operation to retrieve it */
1727 rf_helper = (ReplyForwardHelper *) user_data;
1728 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1731 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1732 rf_helper->account_name, rf_helper->mailbox);
1733 recipient = modest_text_utils_get_email_address (from);
1734 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr(),
1739 /* Create reply mail */
1740 switch (rf_helper->action) {
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_SENDER);
1748 case ACTION_REPLY_TO_ALL:
1750 modest_tny_msg_create_reply_msg (msg, header, from,
1751 (use_signature) ? signature : NULL,
1752 rf_helper->reply_forward_type,
1753 MODEST_TNY_MSG_REPLY_MODE_ALL);
1754 edit_type = MODEST_EDIT_TYPE_REPLY;
1756 case ACTION_FORWARD:
1758 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1759 rf_helper->reply_forward_type);
1760 edit_type = MODEST_EDIT_TYPE_FORWARD;
1763 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1765 g_return_if_reached ();
1773 g_warning ("%s: failed to create message\n", __FUNCTION__);
1777 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1778 rf_helper->account_name,
1779 TNY_ACCOUNT_TYPE_STORE);
1781 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1785 /* Create and register the windows */
1786 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, rf_helper->mailbox, FALSE);
1787 mgr = modest_runtime_get_window_mgr ();
1788 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1790 /* Note that register_window could have deleted the account */
1791 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1792 gdouble parent_zoom;
1794 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1795 modest_window_set_zoom (msg_win, parent_zoom);
1798 /* Show edit window */
1799 gtk_widget_show_all (GTK_WIDGET (msg_win));
1802 /* We always unregister the header because the message is
1803 forwarded or replied so the original one is no longer
1805 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1808 g_object_unref (G_OBJECT (new_msg));
1810 g_object_unref (G_OBJECT (account));
1811 free_reply_forward_helper (rf_helper);
1814 /* Checks a list of headers. If any of them are not currently
1815 * downloaded (CACHED) then returns TRUE else returns FALSE.
1818 header_list_count_uncached_msgs (TnyList *header_list)
1821 gint uncached_messages = 0;
1823 iter = tny_list_create_iterator (header_list);
1824 while (!tny_iterator_is_done (iter)) {
1827 header = TNY_HEADER (tny_iterator_get_current (iter));
1829 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1830 uncached_messages ++;
1831 g_object_unref (header);
1834 tny_iterator_next (iter);
1836 g_object_unref (iter);
1838 return uncached_messages;
1841 /* Returns FALSE if the user does not want to download the
1842 * messages. Returns TRUE if the user allowed the download.
1845 connect_to_get_msg (ModestWindow *win,
1846 gint num_of_uncached_msgs,
1847 TnyAccount *account)
1849 GtkResponseType response;
1851 /* Allways download if we are online. */
1852 if (tny_device_is_online (modest_runtime_get_device ()))
1855 /* If offline, then ask for user permission to download the messages */
1856 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1857 ngettext("mcen_nc_get_msg",
1859 num_of_uncached_msgs));
1861 if (response == GTK_RESPONSE_CANCEL)
1864 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1868 reply_forward_performer (gboolean canceled,
1870 GtkWindow *parent_window,
1871 TnyAccount *account,
1874 ReplyForwardHelper *rf_helper = NULL;
1875 ModestMailOperation *mail_op;
1877 rf_helper = (ReplyForwardHelper *) user_data;
1879 if (canceled || err) {
1880 free_reply_forward_helper (rf_helper);
1884 /* Retrieve the message */
1885 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1886 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1887 modest_ui_actions_disk_operations_error_handler,
1889 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1890 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1893 g_object_unref(mail_op);
1897 * Common code for the reply and forward actions
1900 reply_forward (ReplyForwardAction action, ModestWindow *win)
1902 ReplyForwardHelper *rf_helper = NULL;
1903 guint reply_forward_type;
1905 g_return_if_fail (MODEST_IS_WINDOW(win));
1907 /* we check for low-mem; in that case, show a warning, and don't allow
1908 * reply/forward (because it could potentially require a lot of memory */
1909 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1913 /* we need an account when editing */
1914 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1915 if (!modest_ui_actions_run_account_setup_wizard (win))
1919 reply_forward_type =
1920 modest_conf_get_int (modest_runtime_get_conf (),
1921 (action == ACTION_FORWARD) ?
1922 MODEST_CONF_FORWARD_TYPE :
1923 MODEST_CONF_REPLY_TYPE,
1926 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1928 TnyHeader *header = NULL;
1929 /* Get header and message. Do not free them here, the
1930 reply_forward_cb must do it */
1931 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1932 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1934 if (msg && header) {
1936 rf_helper = create_reply_forward_helper (action, win,
1937 reply_forward_type, header);
1938 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1940 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1944 g_object_unref (msg);
1946 g_object_unref (header);
1948 TnyHeader *header = NULL;
1950 gboolean do_retrieve = TRUE;
1951 TnyList *header_list = NULL;
1953 header_list = get_selected_headers (win);
1956 /* Check that only one message is selected for replying */
1957 if (tny_list_get_length (header_list) != 1) {
1958 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1959 NULL, _("mcen_ib_select_one_message"));
1960 g_object_unref (header_list);
1964 /* Only reply/forward to one message */
1965 iter = tny_list_create_iterator (header_list);
1966 header = TNY_HEADER (tny_iterator_get_current (iter));
1967 g_object_unref (iter);
1969 /* Retrieve messages */
1970 do_retrieve = (action == ACTION_FORWARD) ||
1971 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1974 TnyAccount *account = NULL;
1975 TnyFolder *folder = NULL;
1976 gdouble download = TRUE;
1977 guint uncached_msgs = 0;
1979 folder = tny_header_get_folder (header);
1981 goto do_retrieve_frees;
1982 account = tny_folder_get_account (folder);
1984 goto do_retrieve_frees;
1986 uncached_msgs = header_list_count_uncached_msgs (header_list);
1988 if (uncached_msgs > 0) {
1989 /* Allways download if we are online. */
1990 if (!tny_device_is_online (modest_runtime_get_device ())) {
1993 /* If ask for user permission to download the messages */
1994 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1995 ngettext("mcen_nc_get_msg",
1999 /* End if the user does not want to continue */
2000 if (response == GTK_RESPONSE_CANCEL)
2007 rf_helper = create_reply_forward_helper (action, win,
2008 reply_forward_type, header);
2009 if (uncached_msgs > 0) {
2010 modest_platform_connect_and_perform (GTK_WINDOW (win),
2012 reply_forward_performer,
2015 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
2016 account, rf_helper);
2021 g_object_unref (account);
2023 g_object_unref (folder);
2025 reply_forward_cb (NULL, header, FALSE, NULL, NULL, rf_helper);
2028 g_object_unref (header_list);
2029 g_object_unref (header);
2034 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
2036 g_return_if_fail (MODEST_IS_WINDOW(win));
2038 reply_forward (ACTION_REPLY, win);
2042 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
2044 g_return_if_fail (MODEST_IS_WINDOW(win));
2046 reply_forward (ACTION_FORWARD, win);
2050 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
2052 g_return_if_fail (MODEST_IS_WINDOW(win));
2054 reply_forward (ACTION_REPLY_TO_ALL, win);
2058 modest_ui_actions_on_next (GtkAction *action,
2059 ModestWindow *window)
2061 if (MODEST_IS_MAIN_WINDOW (window)) {
2062 GtkWidget *header_view;
2064 header_view = modest_main_window_get_child_widget (
2065 MODEST_MAIN_WINDOW(window),
2066 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2070 modest_header_view_select_next (
2071 MODEST_HEADER_VIEW(header_view));
2072 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2073 modest_msg_view_window_select_next_message (
2074 MODEST_MSG_VIEW_WINDOW (window));
2076 g_return_if_reached ();
2081 modest_ui_actions_on_prev (GtkAction *action,
2082 ModestWindow *window)
2084 g_return_if_fail (MODEST_IS_WINDOW(window));
2086 if (MODEST_IS_MAIN_WINDOW (window)) {
2087 GtkWidget *header_view;
2088 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2089 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2093 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
2094 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2095 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
2097 g_return_if_reached ();
2102 modest_ui_actions_on_sort (GtkAction *action,
2103 ModestWindow *window)
2105 GtkWidget *header_view = NULL;
2107 g_return_if_fail (MODEST_IS_WINDOW(window));
2109 if (MODEST_IS_MAIN_WINDOW (window)) {
2110 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2111 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2112 #ifdef MODEST_TOOLKIT_HILDON2
2113 } else if (MODEST_IS_HEADER_WINDOW (window)) {
2114 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2119 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
2124 /* Show sorting dialog */
2125 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
2129 new_messages_arrived (ModestMailOperation *self,
2130 TnyList *new_headers,
2134 gboolean show_visual_notifications;
2136 source = modest_mail_operation_get_source (self);
2137 show_visual_notifications = (source) ? FALSE : TRUE;
2139 g_object_unref (source);
2141 /* Notify new messages have been downloaded. If the
2142 send&receive was invoked by the user then do not show any
2143 visual notification, only play a sound and activate the LED
2144 (for the Maemo version) */
2145 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0)
2146 modest_platform_on_new_headers_received (new_headers,
2147 show_visual_notifications);
2152 retrieve_all_messages_cb (GObject *source,
2154 guint retrieve_limit)
2160 window = GTK_WINDOW (source);
2161 msg = g_strdup_printf (_("mail_nc_msg_count_limit_exceeded"),
2162 num_msgs, retrieve_limit);
2164 /* Ask the user if they want to retrieve all the messages */
2166 modest_platform_run_confirmation_dialog_with_buttons (window, msg,
2167 _("mcen_bd_get_all"),
2168 _("mcen_bd_newest_only"));
2169 /* Free and return */
2171 return (response == GTK_RESPONSE_ACCEPT) ? TRUE : FALSE;
2175 TnyAccount *account;
2177 gchar *account_name;
2178 gboolean poke_status;
2179 gboolean interactive;
2180 ModestMailOperation *mail_op;
2184 do_send_receive_performer (gboolean canceled,
2186 GtkWindow *parent_window,
2187 TnyAccount *account,
2190 SendReceiveInfo *info;
2192 info = (SendReceiveInfo *) user_data;
2194 if (err || canceled) {
2195 /* In memory full conditions we could get this error here */
2196 check_memory_full_error ((GtkWidget *) parent_window, err);
2198 if (info->mail_op) {
2199 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2205 /* Set send/receive operation in progress */
2206 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2207 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2210 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2211 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2212 G_CALLBACK (on_send_receive_finished),
2215 /* Send & receive. */
2216 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2217 (info->win) ? retrieve_all_messages_cb : NULL,
2218 new_messages_arrived, info->win);
2223 g_object_unref (G_OBJECT (info->mail_op));
2224 if (info->account_name)
2225 g_free (info->account_name);
2227 g_object_unref (info->win);
2229 g_object_unref (info->account);
2230 g_slice_free (SendReceiveInfo, info);
2234 * This function performs the send & receive required actions. The
2235 * window is used to create the mail operation. Typically it should
2236 * always be the main window, but we pass it as argument in order to
2240 modest_ui_actions_do_send_receive (const gchar *account_name,
2241 gboolean force_connection,
2242 gboolean poke_status,
2243 gboolean interactive,
2246 gchar *acc_name = NULL;
2247 SendReceiveInfo *info;
2248 ModestTnyAccountStore *acc_store;
2250 /* If no account name was provided then get the current account, and if
2251 there is no current account then pick the default one: */
2252 if (!account_name) {
2254 acc_name = g_strdup (modest_window_get_active_account (win));
2256 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2258 g_printerr ("modest: cannot get default account\n");
2262 acc_name = g_strdup (account_name);
2265 acc_store = modest_runtime_get_account_store ();
2267 /* Create the info for the connect and perform */
2268 info = g_slice_new (SendReceiveInfo);
2269 info->account_name = acc_name;
2270 info->win = (win) ? g_object_ref (win) : NULL;
2271 info->poke_status = poke_status;
2272 info->interactive = interactive;
2273 info->account = modest_tny_account_store_get_server_account (acc_store, acc_name,
2274 TNY_ACCOUNT_TYPE_STORE);
2275 /* We need to create the operation here, because otherwise it
2276 could happen that the queue emits the queue-empty signal
2277 while we're trying to connect the account */
2278 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2279 modest_ui_actions_disk_operations_error_handler,
2281 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2283 /* Invoke the connect and perform */
2284 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2285 force_connection, info->account,
2286 do_send_receive_performer, info);
2291 modest_ui_actions_do_cancel_send (const gchar *account_name,
2294 TnyTransportAccount *transport_account;
2295 TnySendQueue *send_queue = NULL;
2296 GError *error = NULL;
2298 /* Get transport account */
2300 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2301 (modest_runtime_get_account_store(),
2303 TNY_ACCOUNT_TYPE_TRANSPORT));
2304 if (!transport_account) {
2305 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2310 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2311 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2312 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2313 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2314 "modest: could not find send queue for account\n");
2316 /* Cancel the current send */
2317 tny_account_cancel (TNY_ACCOUNT (transport_account));
2319 /* Suspend all pending messages */
2320 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2324 if (transport_account != NULL)
2325 g_object_unref (G_OBJECT (transport_account));
2329 modest_ui_actions_cancel_send_all (ModestWindow *win)
2331 GSList *account_names, *iter;
2333 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2336 iter = account_names;
2338 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2339 iter = g_slist_next (iter);
2342 modest_account_mgr_free_account_names (account_names);
2343 account_names = NULL;
2347 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2350 /* Check if accounts exist */
2351 gboolean accounts_exist =
2352 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2354 /* If not, allow the user to create an account before trying to send/receive. */
2355 if (!accounts_exist)
2356 modest_ui_actions_on_accounts (NULL, win);
2358 /* Cancel all sending operaitons */
2359 modest_ui_actions_cancel_send_all (win);
2363 * Refreshes all accounts. This function will be used by automatic
2367 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2368 gboolean force_connection,
2369 gboolean poke_status,
2370 gboolean interactive)
2372 GSList *account_names, *iter;
2374 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2377 iter = account_names;
2379 modest_ui_actions_do_send_receive ((const char*) iter->data,
2381 poke_status, interactive, win);
2382 iter = g_slist_next (iter);
2385 modest_account_mgr_free_account_names (account_names);
2386 account_names = NULL;
2390 * Handler of the click on Send&Receive button in the main toolbar
2393 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2395 /* Check if accounts exist */
2396 gboolean accounts_exist;
2399 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2401 /* If not, allow the user to create an account before trying to send/receive. */
2402 if (!accounts_exist)
2403 modest_ui_actions_on_accounts (NULL, win);
2405 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2406 if (MODEST_IS_MAIN_WINDOW (win)) {
2407 GtkWidget *folder_view;
2408 TnyFolderStore *folder_store;
2411 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2412 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2416 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2419 g_object_unref (folder_store);
2420 /* Refresh the active account. Force the connection if needed
2421 and poke the status of all folders */
2422 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2423 #ifdef MODEST_TOOLKIT_HILDON2
2424 } else if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2425 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2428 const gchar *active_account;
2429 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2431 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2438 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2441 GtkWidget *header_view;
2443 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2445 header_view = modest_main_window_get_child_widget (main_window,
2446 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2450 conf = modest_runtime_get_conf ();
2452 /* what is saved/restored is depending on the style; thus; we save with
2453 * old style, then update the style, and restore for this new style
2455 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2457 if (modest_header_view_get_style
2458 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2459 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2460 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2462 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2463 MODEST_HEADER_VIEW_STYLE_DETAILS);
2465 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2466 MODEST_CONF_HEADER_VIEW_KEY);
2471 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2473 ModestMainWindow *main_window)
2475 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2476 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2478 /* in the case the folder is empty, show the empty folder message and focus
2480 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2481 if (modest_header_view_is_empty (header_view)) {
2482 TnyFolder *folder = modest_header_view_get_folder (header_view);
2483 GtkWidget *folder_view =
2484 modest_main_window_get_child_widget (main_window,
2485 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2486 if (folder != NULL) {
2487 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2488 g_object_unref (folder);
2490 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2494 /* If no header has been selected then exit */
2499 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2500 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2502 /* Update toolbar dimming state */
2503 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2504 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2508 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2511 ModestWindow *window)
2513 GtkWidget *open_widget;
2514 GtkTreeRowReference *rowref;
2516 g_return_if_fail (MODEST_IS_WINDOW(window));
2517 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2518 g_return_if_fail (TNY_IS_HEADER (header));
2520 if (modest_header_view_count_selected_headers (header_view) > 1) {
2521 /* Don't allow activation if there are more than one message selected */
2522 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2526 /* we check for low-mem; in that case, show a warning, and don't allow
2527 * activating headers
2529 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2532 if (MODEST_IS_MAIN_WINDOW (window)) {
2533 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2534 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2535 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2539 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2540 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2541 gtk_tree_row_reference_free (rowref);
2545 set_active_account_from_tny_account (TnyAccount *account,
2546 ModestWindow *window)
2548 const gchar *server_acc_name = tny_account_get_id (account);
2550 /* We need the TnyAccount provided by the
2551 account store because that is the one that
2552 knows the name of the Modest account */
2553 TnyAccount *modest_server_account =
2554 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2555 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2557 if (!modest_server_account) {
2558 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2562 /* Update active account, but only if it's not a pseudo-account */
2563 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2564 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2565 const gchar *modest_acc_name =
2566 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2567 if (modest_acc_name)
2568 modest_window_set_active_account (window, modest_acc_name);
2571 g_object_unref (modest_server_account);
2576 folder_refreshed_cb (ModestMailOperation *mail_op,
2580 ModestMainWindow *win = NULL;
2581 GtkWidget *folder_view, *header_view;
2582 const GError *error;
2584 g_return_if_fail (TNY_IS_FOLDER (folder));
2586 win = MODEST_MAIN_WINDOW (user_data);
2588 /* Check if the operation failed due to memory low conditions */
2589 error = modest_mail_operation_get_error (mail_op);
2590 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2591 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2592 modest_platform_run_information_dialog (GTK_WINDOW (win),
2593 _KR("memr_ib_operation_disabled"),
2599 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2601 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2604 TnyFolderStore *current_folder;
2606 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2607 if (current_folder) {
2608 gboolean different = ((TnyFolderStore *) folder != current_folder);
2609 g_object_unref (current_folder);
2615 /* Check if folder is empty and set headers view contents style */
2616 if ((tny_folder_get_all_count (folder) == 0) ||
2617 modest_header_view_is_empty (MODEST_HEADER_VIEW (header_view)))
2618 modest_main_window_set_contents_style (win,
2619 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2623 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2624 TnyFolderStore *folder_store,
2626 ModestMainWindow *main_window)
2629 GtkWidget *header_view;
2631 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2633 header_view = modest_main_window_get_child_widget(main_window,
2634 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2638 conf = modest_runtime_get_conf ();
2640 if (TNY_IS_ACCOUNT (folder_store)) {
2642 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2644 /* Show account details */
2645 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2648 if (TNY_IS_FOLDER (folder_store) && selected) {
2649 TnyAccount *account;
2650 const gchar *account_name = NULL;
2652 /* Update the active account */
2653 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2655 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2657 modest_tny_account_get_parent_modest_account_name_for_server_account (account);
2658 g_object_unref (account);
2662 /* Set the header style by default, it could
2663 be changed later by the refresh callback to
2665 modest_main_window_set_contents_style (main_window,
2666 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2668 /* Set folder on header view. This function
2669 will call tny_folder_refresh_async so we
2670 pass a callback that will be called when
2671 finished. We use that callback to set the
2672 empty view if there are no messages */
2673 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2674 TNY_FOLDER (folder_store),
2676 MODEST_WINDOW (main_window),
2677 folder_refreshed_cb,
2680 /* Restore configuration. We need to do this
2681 *after* the set_folder because the widget
2682 memory asks the header view about its
2684 modest_widget_memory_restore (modest_runtime_get_conf (),
2685 G_OBJECT(header_view),
2686 MODEST_CONF_HEADER_VIEW_KEY);
2688 /* No need to save the header view
2689 configuration for Maemo because it only
2690 saves the sorting stuff and that it's
2691 already being done by the sort
2692 dialog. Remove it when the GNOME version
2693 has the same behaviour */
2694 #ifdef MODEST_TOOLKIT_GTK
2695 if (modest_main_window_get_contents_style (main_window) ==
2696 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2697 modest_widget_memory_save (conf, G_OBJECT (header_view),
2698 MODEST_CONF_HEADER_VIEW_KEY);
2700 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2704 /* Update dimming state */
2705 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2706 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2710 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2717 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2719 online = tny_device_is_online (modest_runtime_get_device());
2722 /* already online -- the item is simply not there... */
2723 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2725 GTK_MESSAGE_WARNING,
2727 _("The %s you selected cannot be found"),
2729 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2730 gtk_dialog_run (GTK_DIALOG(dialog));
2732 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2735 _("mcen_bd_dialog_cancel"),
2736 GTK_RESPONSE_REJECT,
2737 _("mcen_bd_dialog_ok"),
2738 GTK_RESPONSE_ACCEPT,
2740 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2741 "Do you want to get online?"), item);
2742 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2743 gtk_label_new (txt), FALSE, FALSE, 0);
2744 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2747 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2748 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2749 /* TODO: Comment about why is this commented out: */
2750 /* modest_platform_connect_and_wait (); */
2753 gtk_widget_destroy (dialog);
2757 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2760 /* g_message ("%s %s", __FUNCTION__, link); */
2765 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2768 modest_platform_activate_uri (link);
2772 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2775 modest_platform_show_uri_popup (link);
2779 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2782 /* we check for low-mem; in that case, show a warning, and don't allow
2783 * viewing attachments
2785 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2788 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2792 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2793 const gchar *address,
2796 /* g_message ("%s %s", __FUNCTION__, address); */
2800 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2801 TnyMsg *saved_draft,
2804 ModestMsgEditWindow *edit_window;
2806 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2807 #ifndef MODEST_TOOLKIT_HILDON2
2808 ModestMainWindow *win;
2810 /* FIXME. Make the header view sensitive again. This is a
2811 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2813 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2814 modest_runtime_get_window_mgr(), FALSE));
2816 GtkWidget *hdrview = modest_main_window_get_child_widget(
2817 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2818 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2822 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2824 /* Set draft is there was no error */
2825 if (!modest_mail_operation_get_error (mail_op))
2826 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2828 g_object_unref(edit_window);
2832 enough_space_for_message (ModestMsgEditWindow *edit_window,
2835 TnyAccountStore *acc_store;
2836 guint64 available_disk, expected_size;
2841 acc_store = TNY_ACCOUNT_STORE (modest_runtime_get_account_store());
2842 available_disk = modest_utils_get_available_space (NULL);
2843 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2844 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2849 /* Double check: memory full condition or message too big */
2850 if (available_disk < MIN_FREE_SPACE ||
2851 expected_size > available_disk) {
2853 modest_platform_information_banner (NULL, NULL,
2854 _KR("cerm_device_memory_full"));
2859 * djcb: if we're in low-memory state, we only allow for
2860 * saving messages smaller than
2861 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2862 * should still allow for sending anything critical...
2864 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2865 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2869 * djcb: we also make sure that the attachments are smaller than the max size
2870 * this is for the case where we'd try to forward a message with attachments
2871 * bigger than our max allowed size, or sending an message from drafts which
2872 * somehow got past our checks when attaching.
2874 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2875 modest_platform_run_information_dialog (
2876 GTK_WINDOW(edit_window),
2877 _KR("memr_ib_operation_disabled"),
2886 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2888 TnyTransportAccount *transport_account;
2889 ModestMailOperation *mail_operation;
2891 gchar *account_name;
2892 ModestAccountMgr *account_mgr;
2893 gboolean had_error = FALSE;
2894 ModestMainWindow *win = NULL;
2896 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2898 data = modest_msg_edit_window_get_msg_data (edit_window);
2901 if (!enough_space_for_message (edit_window, data)) {
2902 modest_msg_edit_window_free_msg_data (edit_window, data);
2906 account_name = g_strdup (data->account_name);
2907 account_mgr = modest_runtime_get_account_mgr();
2909 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2911 account_name = modest_account_mgr_get_default_account (account_mgr);
2912 if (!account_name) {
2913 g_printerr ("modest: no account found\n");
2914 modest_msg_edit_window_free_msg_data (edit_window, data);
2918 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2919 account_name = g_strdup (data->account_name);
2923 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2924 (modest_runtime_get_account_store (),
2926 TNY_ACCOUNT_TYPE_TRANSPORT));
2927 if (!transport_account) {
2928 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2929 g_free (account_name);
2930 modest_msg_edit_window_free_msg_data (edit_window, data);
2934 /* Create the mail operation */
2935 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
2937 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2939 modest_mail_operation_save_to_drafts (mail_operation,
2951 data->priority_flags,
2954 on_save_to_drafts_cb,
2955 g_object_ref(edit_window));
2957 #ifdef MODEST_TOOLKIT_HILDON2
2958 /* In hildon2 we always show the information banner on saving to drafts.
2959 * It will be a system information banner in this case.
2961 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2962 modest_platform_information_banner (NULL, NULL, text);
2965 /* Use the main window as the parent of the banner, if the
2966 main window does not exist it won't be shown, if the parent
2967 window exists then it's properly shown. We don't use the
2968 editor window because it could be closed (save to drafts
2969 could happen after closing the window */
2970 win = (ModestMainWindow *)
2971 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
2973 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2974 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
2978 modest_msg_edit_window_set_modified (edit_window, FALSE);
2981 g_free (account_name);
2982 g_object_unref (G_OBJECT (transport_account));
2983 g_object_unref (G_OBJECT (mail_operation));
2985 modest_msg_edit_window_free_msg_data (edit_window, data);
2988 * If the drafts folder is selected then make the header view
2989 * insensitive while the message is being saved to drafts
2990 * (it'll be sensitive again in on_save_to_drafts_cb()). This
2991 * is not very clean but it avoids letting the drafts folder
2992 * in an inconsistent state: the user could edit the message
2993 * being saved and undesirable things would happen.
2994 * In the average case the user won't notice anything at
2995 * all. In the worst case (the user is editing a really big
2996 * file from Drafts) the header view will be insensitive
2997 * during the saving process (10 or 20 seconds, depending on
2998 * the message). Anyway this is just a quick workaround: once
2999 * we find a better solution it should be removed
3000 * See NB#65125 (commend #18) for details.
3002 if (!had_error && win != NULL) {
3003 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
3004 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
3006 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
3008 if (modest_tny_folder_is_local_folder(folder)) {
3009 TnyFolderType folder_type;
3010 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
3011 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
3012 GtkWidget *hdrview = modest_main_window_get_child_widget(
3013 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3014 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
3018 if (folder != NULL) g_object_unref(folder);
3025 /* For instance, when clicking the Send toolbar button when editing a message: */
3027 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3029 TnyTransportAccount *transport_account = NULL;
3030 gboolean had_error = FALSE;
3032 ModestAccountMgr *account_mgr;
3033 gchar *account_name;
3034 ModestMailOperation *mail_operation;
3036 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
3038 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
3041 data = modest_msg_edit_window_get_msg_data (edit_window);
3044 if (!enough_space_for_message (edit_window, data)) {
3045 modest_msg_edit_window_free_msg_data (edit_window, data);
3049 account_mgr = modest_runtime_get_account_mgr();
3050 account_name = g_strdup (data->account_name);
3052 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3055 account_name = modest_account_mgr_get_default_account (account_mgr);
3057 if (!account_name) {
3058 modest_msg_edit_window_free_msg_data (edit_window, data);
3059 /* Run account setup wizard */
3060 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
3065 /* Get the currently-active transport account for this modest account: */
3066 if (strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
3068 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3069 (modest_runtime_get_account_store (),
3070 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
3073 if (!transport_account) {
3074 modest_msg_edit_window_free_msg_data (edit_window, data);
3075 /* Run account setup wizard */
3076 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
3081 /* Create the mail operation */
3082 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
3083 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3085 modest_mail_operation_send_new_mail (mail_operation,
3099 data->priority_flags);
3101 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3102 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
3104 if (modest_mail_operation_get_error (mail_operation) != NULL) {
3105 const GError *error = modest_mail_operation_get_error (mail_operation);
3106 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3107 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3108 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3109 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3115 g_free (account_name);
3116 g_object_unref (G_OBJECT (transport_account));
3117 g_object_unref (G_OBJECT (mail_operation));
3119 modest_msg_edit_window_free_msg_data (edit_window, data);
3122 modest_msg_edit_window_set_sent (edit_window, TRUE);
3124 /* Save settings and close the window: */
3125 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3132 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3133 ModestMsgEditWindow *window)
3135 ModestMsgEditFormatState *format_state = NULL;
3137 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3138 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3140 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3143 format_state = modest_msg_edit_window_get_format_state (window);
3144 g_return_if_fail (format_state != NULL);
3146 format_state->bold = gtk_toggle_action_get_active (action);
3147 modest_msg_edit_window_set_format_state (window, format_state);
3148 g_free (format_state);
3153 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3154 ModestMsgEditWindow *window)
3156 ModestMsgEditFormatState *format_state = NULL;
3158 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3159 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3161 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3164 format_state = modest_msg_edit_window_get_format_state (window);
3165 g_return_if_fail (format_state != NULL);
3167 format_state->italics = gtk_toggle_action_get_active (action);
3168 modest_msg_edit_window_set_format_state (window, format_state);
3169 g_free (format_state);
3174 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3175 ModestMsgEditWindow *window)
3177 ModestMsgEditFormatState *format_state = NULL;
3179 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3180 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3182 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3185 format_state = modest_msg_edit_window_get_format_state (window);
3186 g_return_if_fail (format_state != NULL);
3188 format_state->bullet = gtk_toggle_action_get_active (action);
3189 modest_msg_edit_window_set_format_state (window, format_state);
3190 g_free (format_state);
3195 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3196 GtkRadioAction *selected,
3197 ModestMsgEditWindow *window)
3199 ModestMsgEditFormatState *format_state = NULL;
3200 GtkJustification value;
3202 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3204 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3207 value = gtk_radio_action_get_current_value (selected);
3209 format_state = modest_msg_edit_window_get_format_state (window);
3210 g_return_if_fail (format_state != NULL);
3212 format_state->justification = value;
3213 modest_msg_edit_window_set_format_state (window, format_state);
3214 g_free (format_state);
3218 modest_ui_actions_on_select_editor_color (GtkAction *action,
3219 ModestMsgEditWindow *window)
3221 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3222 g_return_if_fail (GTK_IS_ACTION (action));
3224 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3227 modest_msg_edit_window_select_color (window);
3231 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3232 ModestMsgEditWindow *window)
3234 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3235 g_return_if_fail (GTK_IS_ACTION (action));
3237 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3240 modest_msg_edit_window_select_background_color (window);
3244 modest_ui_actions_on_insert_image (GObject *object,
3245 ModestMsgEditWindow *window)
3247 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3250 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3253 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3256 modest_msg_edit_window_insert_image (window);
3260 modest_ui_actions_on_attach_file (GtkAction *action,
3261 ModestMsgEditWindow *window)
3263 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3264 g_return_if_fail (GTK_IS_ACTION (action));
3266 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3269 modest_msg_edit_window_offer_attach_file (window);
3273 modest_ui_actions_on_remove_attachments (GtkAction *action,
3274 ModestMsgEditWindow *window)
3276 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3278 modest_msg_edit_window_remove_attachments (window, NULL);
3282 do_create_folder_cb (ModestMailOperation *mail_op,
3283 TnyFolderStore *parent_folder,
3284 TnyFolder *new_folder,
3287 gchar *suggested_name = (gchar *) user_data;
3288 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3289 const GError *error;
3291 error = modest_mail_operation_get_error (mail_op);
3294 /* Show an error. If there was some problem writing to
3295 disk, show it, otherwise show the generic folder
3296 create error. We do it here and not in an error
3297 handler because the call to do_create_folder will
3298 stop the main loop in a gtk_dialog_run and then,
3299 the message won't be shown until that dialog is
3301 modest_ui_actions_disk_operations_error_handler (mail_op,
3302 _("mail_in_ui_folder_create_error"));
3304 if (!is_memory_full_error ((GError *) error, mail_op)) {
3305 /* Try again if there is no full memory condition */
3306 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3309 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3310 * FIXME: any other? */
3311 GtkWidget *folder_view;
3313 if (MODEST_IS_MAIN_WINDOW(source_win))
3315 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3316 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3318 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3319 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3321 /* Select the newly created folder. It could happen
3322 that the widget is no longer there (i.e. the window
3323 has been destroyed, so we need to check this */
3325 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3327 g_object_unref (new_folder);
3329 /* Free. Note that the first time it'll be NULL so noop */
3330 g_free (suggested_name);
3331 g_object_unref (source_win);
3336 TnyFolderStore *parent;
3337 } CreateFolderConnect;
3340 do_create_folder_performer (gboolean canceled,
3342 GtkWindow *parent_window,
3343 TnyAccount *account,
3346 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3347 ModestMailOperation *mail_op;
3349 if (canceled || err) {
3350 /* In memory full conditions we could get this error here */
3351 check_memory_full_error ((GtkWidget *) parent_window, err);
3355 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3356 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3358 modest_mail_operation_create_folder (mail_op,
3360 (const gchar *) helper->folder_name,
3361 do_create_folder_cb,
3362 g_strdup (helper->folder_name));
3363 g_object_unref (mail_op);
3367 g_object_unref (helper->parent);
3368 if (helper->folder_name)
3369 g_free (helper->folder_name);
3370 g_slice_free (CreateFolderConnect, helper);
3375 do_create_folder (GtkWindow *parent_window,
3376 TnyFolderStore *suggested_parent,
3377 const gchar *suggested_name)
3380 gchar *folder_name = NULL;
3381 TnyFolderStore *parent_folder = NULL;
3383 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3385 (gchar *) suggested_name,
3389 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3390 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3391 helper->folder_name = g_strdup (folder_name);
3392 helper->parent = g_object_ref (parent_folder);
3394 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3397 do_create_folder_performer,
3402 g_free (folder_name);
3404 g_object_unref (parent_folder);
3408 modest_ui_actions_create_folder(GtkWidget *parent_window,
3409 GtkWidget *folder_view)
3411 TnyFolderStore *parent_folder;
3413 #ifdef MODEST_TOOLKIT_HILDON2
3414 ModestTnyAccountStore *acc_store;
3416 acc_store = modest_runtime_get_account_store ();
3418 parent_folder = (TnyFolderStore *)
3419 modest_tny_account_store_get_local_folders_account (acc_store);
3421 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3424 if (parent_folder) {
3425 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3426 g_object_unref (parent_folder);
3431 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3434 g_return_if_fail (MODEST_IS_WINDOW(window));
3436 if (MODEST_IS_MAIN_WINDOW (window)) {
3437 GtkWidget *folder_view;
3439 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3440 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3444 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view);
3445 #ifdef MODEST_TOOLKIT_HILDON2
3446 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3447 GtkWidget *folder_view;
3449 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3450 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view);
3453 g_assert_not_reached ();
3458 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3461 const GError *error = NULL;
3462 const gchar *message = NULL;
3464 /* Get error message */
3465 error = modest_mail_operation_get_error (mail_op);
3467 g_return_if_reached ();
3469 if (is_memory_full_error ((GError *) error, mail_op)) {
3470 message = _KR("cerm_device_memory_full");
3471 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3472 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3473 message = _CS("ckdg_ib_folder_already_exists");
3474 } else if (error->domain == TNY_ERROR_DOMAIN &&
3475 error->code == TNY_SERVICE_ERROR_STATE) {
3476 /* This means that the folder is already in use (a
3477 message is opened for example */
3478 message = _("emev_ni_internal_error");
3480 message = _CS("ckdg_ib_unable_to_rename");
3483 /* We don't set a parent for the dialog because the dialog
3484 will be destroyed so the banner won't appear */
3485 modest_platform_information_banner (NULL, NULL, message);
3489 TnyFolderStore *folder;
3494 on_rename_folder_cb (ModestMailOperation *mail_op,
3495 TnyFolder *new_folder,
3498 ModestFolderView *folder_view;
3500 /* If the window was closed when renaming a folder, or if
3501 * it's not a main window this will happen */
3502 if (!MODEST_IS_FOLDER_VIEW (user_data))
3505 folder_view = MODEST_FOLDER_VIEW (user_data);
3506 /* Note that if the rename fails new_folder will be NULL */
3508 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3510 modest_folder_view_select_first_inbox_or_local (folder_view);
3512 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3516 on_rename_folder_performer (gboolean canceled,
3518 GtkWindow *parent_window,
3519 TnyAccount *account,
3522 ModestMailOperation *mail_op = NULL;
3523 GtkTreeSelection *sel = NULL;
3524 GtkWidget *folder_view = NULL;
3525 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3527 if (canceled || err) {
3528 /* In memory full conditions we could get this error here */
3529 check_memory_full_error ((GtkWidget *) parent_window, err);
3533 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3534 modest_ui_actions_rename_folder_error_handler,
3535 parent_window, NULL);
3537 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3540 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3542 folder_view = modest_main_window_get_child_widget (
3543 MODEST_MAIN_WINDOW (parent_window),
3544 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3546 #ifdef MODEST_TOOLKIT_HILDON2
3547 else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3548 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3549 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3553 /* Clear the folders view */
3554 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3555 gtk_tree_selection_unselect_all (sel);
3557 /* Actually rename the folder */
3558 modest_mail_operation_rename_folder (mail_op,
3559 TNY_FOLDER (data->folder),
3560 (const gchar *) (data->new_name),
3561 on_rename_folder_cb,
3563 g_object_unref (mail_op);
3566 g_object_unref (data->folder);
3567 g_free (data->new_name);
3572 modest_ui_actions_on_rename_folder (GtkAction *action,
3573 ModestWindow *window)
3575 modest_ui_actions_on_edit_mode_rename_folder (window);
3579 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3581 TnyFolderStore *folder;
3582 GtkWidget *folder_view;
3583 gboolean do_rename = TRUE;
3585 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3587 if (MODEST_IS_MAIN_WINDOW (window)) {
3588 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3589 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3593 #ifdef MODEST_TOOLKIT_HILDON2
3594 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3595 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3601 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3606 if (TNY_IS_FOLDER (folder)) {
3607 gchar *folder_name = NULL;
3609 const gchar *current_name;
3610 TnyFolderStore *parent;
3612 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3613 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3614 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
3615 parent, current_name,
3617 g_object_unref (parent);
3619 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3622 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3623 rename_folder_data->folder = g_object_ref (folder);
3624 rename_folder_data->new_name = folder_name;
3625 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
3626 folder, on_rename_folder_performer, rename_folder_data);
3629 g_object_unref (folder);
3634 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3637 GObject *win = modest_mail_operation_get_source (mail_op);
3639 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3640 _("mail_in_ui_folder_delete_error"),
3642 g_object_unref (win);
3646 TnyFolderStore *folder;
3647 gboolean move_to_trash;
3651 on_delete_folder_cb (gboolean canceled,
3653 GtkWindow *parent_window,
3654 TnyAccount *account,
3657 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3658 GtkWidget *folder_view;
3659 ModestMailOperation *mail_op;
3660 GtkTreeSelection *sel;
3662 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
3663 g_object_unref (G_OBJECT (info->folder));
3668 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
3669 folder_view = modest_main_window_get_child_widget (
3670 MODEST_MAIN_WINDOW (parent_window),
3671 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3672 #ifdef MODEST_TOOLKIT_HILDON2
3673 } else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3674 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
3677 g_object_unref (G_OBJECT (info->folder));
3682 /* Unselect the folder before deleting it to free the headers */
3683 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3684 gtk_tree_selection_unselect_all (sel);
3686 /* Create the mail operation */
3688 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3689 modest_ui_actions_delete_folder_error_handler,
3692 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3694 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3696 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3698 g_object_unref (G_OBJECT (mail_op));
3699 g_object_unref (G_OBJECT (info->folder));
3704 delete_folder (ModestWindow *window, gboolean move_to_trash)
3706 TnyFolderStore *folder;
3707 GtkWidget *folder_view;
3711 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3713 if (MODEST_IS_MAIN_WINDOW (window)) {
3715 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3716 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3717 #ifdef MODEST_TOOLKIT_HILDON2
3718 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3719 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3727 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3732 /* Show an error if it's an account */
3733 if (!TNY_IS_FOLDER (folder)) {
3734 modest_platform_run_information_dialog (GTK_WINDOW (window),
3735 _("mail_in_ui_folder_delete_error"),
3737 g_object_unref (G_OBJECT (folder));
3742 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3743 tny_folder_get_name (TNY_FOLDER (folder)));
3744 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
3745 (const gchar *) message);
3748 if (response == GTK_RESPONSE_OK) {
3749 DeleteFolderInfo *info;
3750 info = g_new0(DeleteFolderInfo, 1);
3751 info->folder = folder;
3752 info->move_to_trash = move_to_trash;
3753 g_object_ref (G_OBJECT (info->folder));
3754 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder));
3755 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
3757 TNY_FOLDER_STORE (account),
3758 on_delete_folder_cb, info);
3759 g_object_unref (account);
3764 g_object_unref (G_OBJECT (folder));
3768 modest_ui_actions_on_delete_folder (GtkAction *action,
3769 ModestWindow *window)
3771 modest_ui_actions_on_edit_mode_delete_folder (window);
3775 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
3777 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
3779 return delete_folder (window, FALSE);
3783 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3785 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3787 delete_folder (MODEST_WINDOW (main_window), TRUE);
3791 typedef struct _PasswordDialogFields {
3792 GtkWidget *username;
3793 GtkWidget *password;
3795 } PasswordDialogFields;
3798 password_dialog_check_field (GtkEditable *editable,
3799 PasswordDialogFields *fields)
3802 gboolean any_value_empty = FALSE;
3804 #ifdef MODEST_TOOLKIT_HILDON2
3805 value = hildon_entry_get_text (HILDON_ENTRY (fields->username));
3807 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
3809 if ((value == NULL) || value[0] == '\0') {
3810 any_value_empty = TRUE;
3812 #ifdef MODEST_TOOLKIT_HILDON2
3813 value = hildon_entry_get_text (HILDON_ENTRY (fields->password));
3815 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
3817 if ((value == NULL) || value[0] == '\0') {
3818 any_value_empty = TRUE;
3820 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3824 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3825 const gchar* server_account_name,
3830 ModestMainWindow *main_window)
3832 g_return_if_fail(server_account_name);
3833 gboolean completed = FALSE;
3834 PasswordDialogFields *fields = NULL;
3836 /* Initalize output parameters: */
3843 #ifndef MODEST_TOOLKIT_GTK
3844 /* Maemo uses a different (awkward) button order,
3845 * It should probably just use gtk_alternative_dialog_button_order ().
3847 #ifdef MODEST_TOOLKIT_HILDON2
3849 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3852 _HL("wdgt_bd_done"),
3853 GTK_RESPONSE_ACCEPT,
3855 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
3856 HILDON_MARGIN_DOUBLE);
3859 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3862 _("mcen_bd_dialog_ok"),
3863 GTK_RESPONSE_ACCEPT,
3864 _("mcen_bd_dialog_cancel"),
3865 GTK_RESPONSE_REJECT,
3867 #endif /* MODEST_TOOLKIT_HILDON2 */
3870 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3874 GTK_RESPONSE_REJECT,
3876 GTK_RESPONSE_ACCEPT,
3878 #endif /* MODEST_TOOLKIT_GTK */
3880 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3882 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3883 modest_runtime_get_account_mgr(), server_account_name);
3884 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3885 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3888 gtk_widget_destroy (dialog);
3892 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3893 GtkWidget *label = gtk_label_new (txt);
3894 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
3896 g_free (server_name);
3897 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
3902 gchar *initial_username = modest_account_mgr_get_server_account_username (
3903 modest_runtime_get_account_mgr(), server_account_name);
3905 #ifdef MODEST_TOOLKIT_HILDON2
3906 GtkWidget *entry_username = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
3907 if (initial_username)
3908 hildon_entry_set_text (HILDON_ENTRY (entry_username), initial_username);
3910 GtkWidget *entry_username = gtk_entry_new ();
3911 if (initial_username)
3912 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
3914 /* Dim this if a connection has ever succeeded with this username,
3915 * as per the UI spec: */
3916 /* const gboolean username_known = */
3917 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3918 /* modest_runtime_get_account_mgr(), server_account_name); */
3919 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3921 /* We drop the username sensitive code and disallow changing it here
3922 * as tinymail does not support really changing the username in the callback
3924 gtk_widget_set_sensitive (entry_username, FALSE);
3926 #ifndef MODEST_TOOLKIT_GTK
3927 /* Auto-capitalization is the default, so let's turn it off: */
3928 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3930 /* Create a size group to be used by all captions.
3931 * Note that HildonCaption does not create a default size group if we do not specify one.
3932 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3933 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3935 #ifdef MODEST_TOOLKIT_HILDON2
3936 GtkWidget *caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
3937 _("mail_fi_username"), FALSE,
3940 GtkWidget *caption = hildon_caption_new (sizegroup,
3941 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
3943 gtk_widget_show (entry_username);
3944 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3945 FALSE, FALSE, MODEST_MARGIN_HALF);
3946 gtk_widget_show (caption);
3948 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
3950 #endif /* !MODEST_TOOLKIT_GTK */
3953 #ifdef MODEST_TOOLKIT_HILDON2
3954 GtkWidget *entry_password = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
3956 GtkWidget *entry_password = gtk_entry_new ();
3958 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3959 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3961 #ifndef MODEST_TOOLKIT_GTK
3962 /* Auto-capitalization is the default, so let's turn it off: */
3963 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3964 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3966 #ifdef MODEST_TOOLKIT_HILDON2
3967 caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
3968 _("mail_fi_password"), FALSE,
3971 caption = hildon_caption_new (sizegroup,
3972 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
3974 gtk_widget_show (entry_password);
3975 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3976 FALSE, FALSE, MODEST_MARGIN_HALF);
3977 gtk_widget_show (caption);
3978 g_object_unref (sizegroup);
3980 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
3982 #endif /* !MODEST_TOOLKIT_GTK */
3984 if (initial_username != NULL)
3985 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3987 /* This is not in the Maemo UI spec:
3988 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3989 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3993 fields = g_slice_new0 (PasswordDialogFields);
3994 fields->username = entry_username;
3995 fields->password = entry_password;
3996 fields->dialog = dialog;
3998 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3999 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
4000 password_dialog_check_field (NULL, fields);
4002 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4004 while (!completed) {
4006 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
4008 #ifdef MODEST_TOOLKIT_HILDON2
4009 *username = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_username)));
4011 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
4014 /* Note that an empty field becomes the "" string */
4015 if (*username && strlen (*username) > 0) {
4016 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
4017 server_account_name,
4021 const gboolean username_was_changed =
4022 (strcmp (*username, initial_username) != 0);
4023 if (username_was_changed) {
4024 g_warning ("%s: tinymail does not yet support changing the "
4025 "username in the get_password() callback.\n", __FUNCTION__);
4031 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
4032 _("mcen_ib_username_pw_incorrect"));
4038 #ifdef MODEST_TOOLKIT_HILDON2
4039 *password = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_password)));
4041 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
4044 /* We do not save the password in the configuration,
4045 * because this function is only called for passwords that should
4046 * not be remembered:
4047 modest_server_account_set_password (
4048 modest_runtime_get_account_mgr(), server_account_name,
4055 #ifndef MODEST_TOOLKIT_HILDON2
4056 /* Set parent to NULL or the banner will disappear with its parent dialog */
4057 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
4069 /* This is not in the Maemo UI spec:
4070 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
4076 g_free (initial_username);
4077 gtk_widget_destroy (dialog);
4078 g_slice_free (PasswordDialogFields, fields);
4080 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
4084 modest_ui_actions_on_cut (GtkAction *action,
4085 ModestWindow *window)
4087 GtkWidget *focused_widget;
4088 GtkClipboard *clipboard;
4090 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4091 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4092 if (GTK_IS_EDITABLE (focused_widget)) {
4093 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
4094 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4095 gtk_clipboard_store (clipboard);
4096 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4097 GtkTextBuffer *buffer;
4099 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4100 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4101 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
4102 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4103 gtk_clipboard_store (clipboard);
4105 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4106 TnyList *header_list = modest_header_view_get_selected_headers (
4107 MODEST_HEADER_VIEW (focused_widget));
4108 gboolean continue_download = FALSE;
4109 gint num_of_unc_msgs;
4111 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4113 if (num_of_unc_msgs) {
4114 TnyAccount *account = get_account_from_header_list (header_list);
4116 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4117 g_object_unref (account);
4121 if (num_of_unc_msgs == 0 || continue_download) {
4122 /* modest_platform_information_banner (
4123 NULL, NULL, _CS("mcen_ib_getting_items"));*/
4124 modest_header_view_cut_selection (
4125 MODEST_HEADER_VIEW (focused_widget));
4128 g_object_unref (header_list);
4129 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4130 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4135 modest_ui_actions_on_copy (GtkAction *action,
4136 ModestWindow *window)
4138 GtkClipboard *clipboard;
4139 GtkWidget *focused_widget;
4140 gboolean copied = TRUE;
4142 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4143 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4145 if (GTK_IS_LABEL (focused_widget)) {
4147 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4148 gtk_clipboard_set_text (clipboard, selection, -1);
4150 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4151 gtk_clipboard_store (clipboard);
4152 } else if (GTK_IS_EDITABLE (focused_widget)) {
4153 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4154 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4155 gtk_clipboard_store (clipboard);
4156 } else if (GTK_IS_HTML (focused_widget)) {
4159 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4160 if ((sel == NULL) || (sel[0] == '\0')) {
4163 gtk_html_copy (GTK_HTML (focused_widget));
4164 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4165 gtk_clipboard_store (clipboard);
4167 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4168 GtkTextBuffer *buffer;
4169 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4170 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4171 gtk_text_buffer_copy_clipboard (buffer, clipboard);
4172 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4173 gtk_clipboard_store (clipboard);
4175 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4176 TnyList *header_list = modest_header_view_get_selected_headers (
4177 MODEST_HEADER_VIEW (focused_widget));
4178 gboolean continue_download = FALSE;
4179 gint num_of_unc_msgs;
4181 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4183 if (num_of_unc_msgs) {
4184 TnyAccount *account = get_account_from_header_list (header_list);
4186 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4187 g_object_unref (account);
4191 if (num_of_unc_msgs == 0 || continue_download) {
4192 modest_platform_information_banner (
4193 NULL, NULL, _CS("mcen_ib_getting_items"));
4194 modest_header_view_copy_selection (
4195 MODEST_HEADER_VIEW (focused_widget));
4199 g_object_unref (header_list);
4201 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4202 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4205 /* Show information banner if there was a copy to clipboard */
4207 modest_platform_information_banner (
4208 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4212 modest_ui_actions_on_undo (GtkAction *action,
4213 ModestWindow *window)
4215 ModestEmailClipboard *clipboard = NULL;
4217 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4218 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4219 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4220 /* Clear clipboard source */
4221 clipboard = modest_runtime_get_email_clipboard ();
4222 modest_email_clipboard_clear (clipboard);
4225 g_return_if_reached ();
4230 modest_ui_actions_on_redo (GtkAction *action,
4231 ModestWindow *window)
4233 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4234 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4237 g_return_if_reached ();
4243 destroy_information_note (ModestMailOperation *mail_op,
4246 /* destroy information note */
4247 gtk_widget_destroy (GTK_WIDGET(user_data));
4251 destroy_folder_information_note (ModestMailOperation *mail_op,
4252 TnyFolder *new_folder,
4255 /* destroy information note */
4256 gtk_widget_destroy (GTK_WIDGET(user_data));
4261 paste_as_attachment_free (gpointer data)
4263 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4265 if (helper->banner) {
4266 gtk_widget_destroy (helper->banner);
4267 g_object_unref (helper->banner);
4273 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4278 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4279 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4284 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4289 modest_ui_actions_on_paste (GtkAction *action,
4290 ModestWindow *window)
4292 GtkWidget *focused_widget = NULL;
4293 GtkWidget *inf_note = NULL;
4294 ModestMailOperation *mail_op = NULL;
4296 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4297 if (GTK_IS_EDITABLE (focused_widget)) {
4298 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4299 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4300 ModestEmailClipboard *e_clipboard = NULL;
4301 e_clipboard = modest_runtime_get_email_clipboard ();
4302 if (modest_email_clipboard_cleared (e_clipboard)) {
4303 GtkTextBuffer *buffer;
4304 GtkClipboard *clipboard;
4306 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4307 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4308 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4309 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4310 ModestMailOperation *mail_op;
4311 TnyFolder *src_folder = NULL;
4312 TnyList *data = NULL;
4314 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4315 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4316 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4317 _CS("ckct_nw_pasting"));
4318 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4319 mail_op = modest_mail_operation_new (G_OBJECT (window));
4320 if (helper->banner != NULL) {
4321 g_object_ref (G_OBJECT (helper->banner));
4322 gtk_widget_show (GTK_WIDGET (helper->banner));
4326 modest_mail_operation_get_msgs_full (mail_op,
4328 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4330 paste_as_attachment_free);
4334 g_object_unref (data);
4336 g_object_unref (src_folder);
4339 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4340 ModestEmailClipboard *clipboard = NULL;
4341 TnyFolder *src_folder = NULL;
4342 TnyFolderStore *folder_store = NULL;
4343 TnyList *data = NULL;
4344 gboolean delete = FALSE;
4346 /* Check clipboard source */
4347 clipboard = modest_runtime_get_email_clipboard ();
4348 if (modest_email_clipboard_cleared (clipboard))
4351 /* Get elements to paste */
4352 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4354 /* Create a new mail operation */
4355 mail_op = modest_mail_operation_new (G_OBJECT(window));
4357 /* Get destination folder */
4358 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4360 /* transfer messages */
4364 /* Ask for user confirmation */
4366 modest_ui_actions_msgs_move_to_confirmation (window,
4367 TNY_FOLDER (folder_store),
4371 if (response == GTK_RESPONSE_OK) {
4372 /* Launch notification */
4373 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4374 _CS("ckct_nw_pasting"));
4375 if (inf_note != NULL) {
4376 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4377 gtk_widget_show (GTK_WIDGET(inf_note));
4380 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4381 modest_mail_operation_xfer_msgs (mail_op,
4383 TNY_FOLDER (folder_store),
4385 destroy_information_note,
4388 g_object_unref (mail_op);
4391 } else if (src_folder != NULL) {
4392 /* Launch notification */
4393 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4394 _CS("ckct_nw_pasting"));
4395 if (inf_note != NULL) {
4396 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4397 gtk_widget_show (GTK_WIDGET(inf_note));
4400 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4401 modest_mail_operation_xfer_folder (mail_op,
4405 destroy_folder_information_note,
4411 g_object_unref (data);
4412 if (src_folder != NULL)
4413 g_object_unref (src_folder);
4414 if (folder_store != NULL)
4415 g_object_unref (folder_store);
4421 modest_ui_actions_on_select_all (GtkAction *action,
4422 ModestWindow *window)
4424 GtkWidget *focused_widget;
4426 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4427 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4428 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4429 } else if (GTK_IS_LABEL (focused_widget)) {
4430 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4431 } else if (GTK_IS_EDITABLE (focused_widget)) {
4432 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4433 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4434 GtkTextBuffer *buffer;
4435 GtkTextIter start, end;
4437 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4438 gtk_text_buffer_get_start_iter (buffer, &start);
4439 gtk_text_buffer_get_end_iter (buffer, &end);
4440 gtk_text_buffer_select_range (buffer, &start, &end);
4441 } else if (GTK_IS_HTML (focused_widget)) {
4442 gtk_html_select_all (GTK_HTML (focused_widget));
4443 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4444 GtkWidget *header_view = focused_widget;
4445 GtkTreeSelection *selection = NULL;
4447 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4448 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4449 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4452 /* Disable window dimming management */
4453 modest_window_disable_dimming (MODEST_WINDOW(window));
4455 /* Select all messages */
4456 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4457 gtk_tree_selection_select_all (selection);
4459 /* Set focuse on header view */
4460 gtk_widget_grab_focus (header_view);
4462 /* Enable window dimming management */
4463 modest_window_enable_dimming (MODEST_WINDOW(window));
4464 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4465 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4471 modest_ui_actions_on_mark_as_read (GtkAction *action,
4472 ModestWindow *window)
4474 g_return_if_fail (MODEST_IS_WINDOW(window));
4476 /* Mark each header as read */
4477 do_headers_action (window, headers_action_mark_as_read, NULL);
4481 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4482 ModestWindow *window)
4484 g_return_if_fail (MODEST_IS_WINDOW(window));
4486 /* Mark each header as read */
4487 do_headers_action (window, headers_action_mark_as_unread, NULL);
4491 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4492 GtkRadioAction *selected,
4493 ModestWindow *window)
4497 value = gtk_radio_action_get_current_value (selected);
4498 if (MODEST_IS_WINDOW (window)) {
4499 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4504 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4505 GtkRadioAction *selected,
4506 ModestWindow *window)
4508 TnyHeaderFlags flags;
4509 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4511 flags = gtk_radio_action_get_current_value (selected);
4512 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4516 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4517 GtkRadioAction *selected,
4518 ModestWindow *window)
4522 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4524 file_format = gtk_radio_action_get_current_value (selected);
4525 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4530 modest_ui_actions_on_zoom_plus (GtkAction *action,
4531 ModestWindow *window)
4533 g_return_if_fail (MODEST_IS_WINDOW (window));
4535 modest_window_zoom_plus (MODEST_WINDOW (window));
4539 modest_ui_actions_on_zoom_minus (GtkAction *action,
4540 ModestWindow *window)
4542 g_return_if_fail (MODEST_IS_WINDOW (window));
4544 modest_window_zoom_minus (MODEST_WINDOW (window));
4548 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4549 ModestWindow *window)
4551 ModestWindowMgr *mgr;
4552 gboolean fullscreen, active;
4553 g_return_if_fail (MODEST_IS_WINDOW (window));
4555 mgr = modest_runtime_get_window_mgr ();
4557 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4558 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4560 if (active != fullscreen) {
4561 modest_window_mgr_set_fullscreen_mode (mgr, active);
4562 #ifndef MODEST_TOOLKIT_HILDON2
4563 gtk_window_present (GTK_WINDOW (window));
4569 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4570 ModestWindow *window)
4572 ModestWindowMgr *mgr;
4573 gboolean fullscreen;
4575 g_return_if_fail (MODEST_IS_WINDOW (window));
4577 mgr = modest_runtime_get_window_mgr ();
4578 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4579 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4581 #ifndef MODEST_TOOLKIT_HILDON2
4582 gtk_window_present (GTK_WINDOW (window));
4587 * Used by modest_ui_actions_on_details to call do_headers_action
4590 headers_action_show_details (TnyHeader *header,
4591 ModestWindow *window,
4595 gboolean async_retrieval;
4598 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4599 async_retrieval = TRUE;
4600 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
4602 async_retrieval = FALSE;
4604 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header, async_retrieval, msg);
4606 g_object_unref (msg);
4610 * Show the header details in a ModestDetailsDialog widget
4613 modest_ui_actions_on_details (GtkAction *action,
4616 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4620 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4624 header = tny_msg_get_header (msg);
4626 headers_action_show_details (header, win, NULL);
4627 g_object_unref (header);
4629 g_object_unref (msg);
4631 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4632 GtkWidget *folder_view, *header_view;
4634 /* Check which widget has the focus */
4635 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4636 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4637 if (gtk_widget_is_focus (folder_view)) {
4638 TnyFolderStore *folder_store
4639 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4640 if (!folder_store) {
4641 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4644 /* Show only when it's a folder */
4645 /* This function should not be called for account items,
4646 * because we dim the menu item for them. */
4647 if (TNY_IS_FOLDER (folder_store)) {
4648 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4649 TNY_FOLDER (folder_store));
4652 g_object_unref (folder_store);
4655 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4656 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4657 /* Show details of each header */
4658 do_headers_action (win, headers_action_show_details, header_view);
4660 #ifdef MODEST_TOOLKIT_HILDON2
4661 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4663 GtkWidget *header_view;
4665 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4666 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4668 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4670 g_object_unref (folder);
4677 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4678 ModestMsgEditWindow *window)
4680 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4682 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4686 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4687 ModestMsgEditWindow *window)
4689 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4691 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4695 modest_ui_actions_toggle_folders_view (GtkAction *action,
4696 ModestMainWindow *main_window)
4698 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4700 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4701 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4703 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4707 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4708 ModestWindow *window)
4710 gboolean active, fullscreen = FALSE;
4711 ModestWindowMgr *mgr;
4713 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4715 /* Check if we want to toggle the toolbar view in fullscreen
4717 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4718 "ViewShowToolbarFullScreen")) {
4722 /* Toggle toolbar */
4723 mgr = modest_runtime_get_window_mgr ();
4724 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4728 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4729 ModestMsgEditWindow *window)
4731 modest_msg_edit_window_select_font (window);
4736 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4737 const gchar *display_name,
4740 /* don't update the display name if it was already set;
4741 * updating the display name apparently is expensive */
4742 const gchar* old_name = gtk_window_get_title (window);
4744 if (display_name == NULL)
4747 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4748 return; /* don't do anything */
4750 /* This is usually used to change the title of the main window, which
4751 * is the one that holds the folder view. Note that this change can
4752 * happen even when the widget doesn't have the focus. */
4753 gtk_window_set_title (window, display_name);
4758 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4760 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4761 modest_msg_edit_window_select_contacts (window);
4765 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4767 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4768 modest_msg_edit_window_check_names (window, FALSE);
4771 #ifndef MODEST_TOOLKIT_HILDON2
4773 * This function is used to track changes in the selection of the
4774 * folder view that is inside the "move to" dialog to enable/disable
4775 * the OK button because we do not want the user to select a disallowed
4776 * destination for a folder.
4777 * The user also not desired to be able to use NEW button on items where
4778 * folder creation is not possibel.
4781 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4782 TnyFolderStore *folder_store,
4786 GtkWidget *dialog = NULL;
4787 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4788 gboolean moving_folder = FALSE;
4789 gboolean is_local_account = TRUE;
4790 GtkWidget *folder_view = NULL;
4791 ModestTnyFolderRules rules;
4793 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
4798 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
4802 /* check if folder_store is an remote account */
4803 if (TNY_IS_ACCOUNT (folder_store)) {
4804 TnyAccount *local_account = NULL;
4805 TnyAccount *mmc_account = NULL;
4806 ModestTnyAccountStore *account_store = NULL;
4808 account_store = modest_runtime_get_account_store ();
4809 local_account = modest_tny_account_store_get_local_folders_account (account_store);
4810 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
4812 if ((gpointer) local_account != (gpointer) folder_store &&
4813 (gpointer) mmc_account != (gpointer) folder_store) {
4814 ModestProtocolType proto;
4815 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
4816 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
4817 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
4819 is_local_account = FALSE;
4820 /* New button should be dimmed on remote
4822 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4824 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
4826 g_object_unref (local_account);
4828 /* It could not exist */
4830 g_object_unref (mmc_account);
4833 /* Check the target folder rules */
4834 if (TNY_IS_FOLDER (folder_store)) {
4835 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
4836 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
4837 ok_sensitive = FALSE;
4838 new_sensitive = FALSE;
4843 /* Check if we're moving a folder */
4844 if (MODEST_IS_MAIN_WINDOW (user_data)) {
4845 /* Get the widgets */
4846 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
4847 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4848 if (gtk_widget_is_focus (folder_view))
4849 moving_folder = TRUE;
4852 if (moving_folder) {
4853 TnyFolderStore *moved_folder = NULL, *parent = NULL;
4855 /* Get the folder to move */
4856 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4858 /* Check that we're not moving to the same folder */
4859 if (TNY_IS_FOLDER (moved_folder)) {
4860 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
4861 if (parent == folder_store)
4862 ok_sensitive = FALSE;
4863 g_object_unref (parent);
4866 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
4867 /* Do not allow to move to an account unless it's the
4868 local folders account */
4869 if (!is_local_account)
4870 ok_sensitive = FALSE;
4873 if (ok_sensitive && (moved_folder == folder_store)) {
4874 /* Do not allow to move to itself */
4875 ok_sensitive = FALSE;
4877 g_object_unref (moved_folder);
4879 TnyFolder *src_folder = NULL;
4881 /* Moving a message */
4882 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
4884 TnyHeader *header = NULL;
4885 header = modest_msg_view_window_get_header
4886 (MODEST_MSG_VIEW_WINDOW (user_data));
4887 if (!TNY_IS_HEADER(header))
4888 g_warning ("%s: could not get source header", __FUNCTION__);
4890 src_folder = tny_header_get_folder (header);
4893 g_object_unref (header);
4896 TNY_FOLDER (modest_folder_view_get_selected
4897 (MODEST_FOLDER_VIEW (folder_view)));
4900 if (TNY_IS_FOLDER(src_folder)) {
4901 /* Do not allow to move the msg to the same folder */
4902 /* Do not allow to move the msg to an account */
4903 if ((gpointer) src_folder == (gpointer) folder_store ||
4904 TNY_IS_ACCOUNT (folder_store))
4905 ok_sensitive = FALSE;
4906 g_object_unref (src_folder);
4908 g_warning ("%s: could not get source folder", __FUNCTION__);
4912 /* Set sensitivity of the OK and NEW button */
4913 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
4914 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
4919 on_move_to_dialog_response (GtkDialog *dialog,
4923 GtkWidget *parent_win;
4924 MoveToInfo *helper = NULL;
4925 ModestFolderView *folder_view;
4927 helper = (MoveToInfo *) user_data;
4929 parent_win = (GtkWidget *) helper->win;
4930 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
4931 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4934 TnyFolderStore *dst_folder;
4936 case MODEST_GTK_RESPONSE_NEW_FOLDER:
4937 modest_ui_actions_create_folder (GTK_WIDGET (dialog), GTK_WIDGET (folder_view));
4939 case GTK_RESPONSE_NONE:
4940 case GTK_RESPONSE_CANCEL:
4941 case GTK_RESPONSE_DELETE_EVENT:
4943 case GTK_RESPONSE_OK:
4944 dst_folder = modest_folder_view_get_selected (folder_view);
4946 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
4947 /* Clean list to move used for filtering */
4948 modest_folder_view_set_list_to_move (folder_view, NULL);
4950 modest_ui_actions_on_main_window_move_to (NULL,
4951 GTK_WIDGET (folder_view),
4953 MODEST_MAIN_WINDOW (parent_win));
4954 #ifdef MODEST_TOOLKIT_HILDON2
4955 } else if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
4956 /* Clean list to move used for filtering */
4957 modest_folder_view_set_list_to_move (folder_view, NULL);
4959 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
4962 GTK_WINDOW (parent_win));
4965 /* if the user selected a root folder
4966 (account) then do not perform any action */
4967 if (TNY_IS_ACCOUNT (dst_folder)) {
4968 g_signal_stop_emission_by_name (dialog, "response");
4972 /* Clean list to move used for filtering */
4973 modest_folder_view_set_list_to_move (folder_view, NULL);
4975 /* Moving from headers window in edit mode */
4976 modest_ui_actions_on_window_move_to (NULL, helper->list,
4978 MODEST_WINDOW (parent_win));
4982 g_object_unref (dst_folder);
4986 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
4989 /* Free the helper and exit */
4991 g_object_unref (helper->list);
4992 g_slice_free (MoveToInfo, helper);
4993 gtk_widget_destroy (GTK_WIDGET (dialog));
4997 create_move_to_dialog (GtkWindow *win,
4998 GtkWidget *folder_view,
4999 TnyList *list_to_move)
5001 GtkWidget *dialog, *tree_view = NULL;
5003 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
5005 #ifndef MODEST_TOOLKIT_HILDON2
5006 /* Track changes in the selection to
5007 * disable the OK button whenever "Move to" is not possible
5008 * disbale NEW button whenever New is not possible */
5009 g_signal_connect (tree_view,
5010 "folder_selection_changed",
5011 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
5015 /* It could happen that we're trying to move a message from a
5016 window (msg window for example) after the main window was
5017 closed, so we can not just get the model of the folder
5019 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
5020 const gchar *visible_id = NULL;
5022 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5023 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5024 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
5025 MODEST_FOLDER_VIEW(tree_view));
5028 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
5030 /* Show the same account than the one that is shown in the main window */
5031 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
5034 const gchar *active_account_name = NULL;
5035 ModestAccountMgr *mgr = NULL;
5036 ModestAccountSettings *settings = NULL;
5037 ModestServerAccountSettings *store_settings = NULL;
5039 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5040 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5041 modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view),
5042 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
5044 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
5045 mgr = modest_runtime_get_account_mgr ();
5046 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
5049 const gchar *store_account_name;
5050 store_settings = modest_account_settings_get_store_settings (settings);
5051 store_account_name = modest_server_account_settings_get_account_name (store_settings);
5053 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
5054 store_account_name);
5055 g_object_unref (store_settings);
5056 g_object_unref (settings);
5060 /* we keep a pointer to the embedded folder view, so we can
5061 * retrieve it with get_folder_view_from_move_to_dialog (see
5062 * above) later (needed for focus handling)
5064 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
5066 /* Hide special folders */
5067 #ifndef MODEST_TOOLKIT_HILDON2
5068 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
5071 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
5072 #ifndef MODEST_TOOLKIT_HILDON2
5073 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5076 gtk_widget_show (GTK_WIDGET (tree_view));
5082 * Shows a confirmation dialog to the user when we're moving messages
5083 * from a remote server to the local storage. Returns the dialog
5084 * response. If it's other kind of movement then it always returns
5087 * This one is used by the next functions:
5088 * modest_ui_actions_on_paste - commented out
5089 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
5092 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
5093 TnyFolder *dest_folder,
5097 gint response = GTK_RESPONSE_OK;
5098 TnyAccount *account = NULL;
5099 TnyFolder *src_folder = NULL;
5100 TnyIterator *iter = NULL;
5101 TnyHeader *header = NULL;
5103 /* return with OK if the destination is a remote folder */
5104 if (modest_tny_folder_is_remote_folder (dest_folder))
5105 return GTK_RESPONSE_OK;
5107 /* Get source folder */
5108 iter = tny_list_create_iterator (headers);
5109 header = TNY_HEADER (tny_iterator_get_current (iter));
5111 src_folder = tny_header_get_folder (header);
5112 g_object_unref (header);
5114 g_object_unref (iter);
5116 /* if no src_folder, message may be an attahcment */
5117 if (src_folder == NULL)
5118 return GTK_RESPONSE_CANCEL;
5120 /* If the source is a local or MMC folder */
5121 if (!modest_tny_folder_is_remote_folder (src_folder)) {
5122 g_object_unref (src_folder);
5123 return GTK_RESPONSE_OK;
5126 /* Get the account */
5127 account = tny_folder_get_account (src_folder);
5129 /* now if offline we ask the user */
5130 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
5131 response = GTK_RESPONSE_OK;
5133 response = GTK_RESPONSE_CANCEL;
5136 g_object_unref (src_folder);
5137 g_object_unref (account);
5143 move_to_helper_destroyer (gpointer user_data)
5145 MoveToHelper *helper = (MoveToHelper *) user_data;
5147 /* Close the "Pasting" information banner */
5148 if (helper->banner) {
5149 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5150 g_object_unref (helper->banner);
5152 if (gtk_tree_row_reference_valid (helper->reference)) {
5153 gtk_tree_row_reference_free (helper->reference);
5154 helper->reference = NULL;
5160 move_to_cb (ModestMailOperation *mail_op,
5163 MoveToHelper *helper = (MoveToHelper *) user_data;
5164 GObject *object = modest_mail_operation_get_source (mail_op);
5166 /* Note that the operation could have failed, in that case do
5168 if (modest_mail_operation_get_status (mail_op) !=
5169 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5172 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5173 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5175 if (!modest_msg_view_window_select_next_message (self) &&
5176 !modest_msg_view_window_select_previous_message (self)) {
5177 /* No more messages to view, so close this window */
5178 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5180 } else if (MODEST_IS_MAIN_WINDOW (object) &&
5181 gtk_tree_row_reference_valid (helper->reference)) {
5182 GtkWidget *header_view;
5184 GtkTreeSelection *sel;
5186 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5187 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5188 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5189 path = gtk_tree_row_reference_get_path (helper->reference);
5190 /* We need to unselect the previous one
5191 because we could be copying instead of
5193 gtk_tree_selection_unselect_all (sel);
5194 gtk_tree_selection_select_path (sel, path);
5195 gtk_tree_path_free (path);
5197 g_object_unref (object);
5200 /* Destroy the helper */
5201 move_to_helper_destroyer (helper);
5205 folder_move_to_cb (ModestMailOperation *mail_op,
5206 TnyFolder *new_folder,
5209 GtkWidget *folder_view;
5212 object = modest_mail_operation_get_source (mail_op);
5213 if (MODEST_IS_MAIN_WINDOW (object)) {
5214 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5215 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5216 g_object_ref (folder_view);
5217 g_object_unref (object);
5218 move_to_cb (mail_op, user_data);
5219 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5220 g_object_unref (folder_view);
5222 move_to_cb (mail_op, user_data);
5227 msgs_move_to_cb (ModestMailOperation *mail_op,
5230 move_to_cb (mail_op, user_data);
5234 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5237 GObject *win = NULL;
5239 #ifndef MODEST_TOOLKIT_HILDON2
5240 ModestWindow *main_window = NULL;
5242 /* Disable next automatic folder selection */
5243 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5244 FALSE); /* don't create */
5246 GtkWidget *folder_view = NULL;
5248 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5249 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5250 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5252 if (user_data && TNY_IS_FOLDER (user_data)) {
5253 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5254 TNY_FOLDER (user_data), FALSE);
5258 /* Show notification dialog only if the main window exists */
5259 win = modest_mail_operation_get_source (mail_op);
5260 modest_platform_run_information_dialog ((GtkWindow *) win,
5261 _("mail_in_ui_folder_move_target_error"),
5264 g_object_unref (win);
5268 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5277 gint pending_purges = 0;
5278 gboolean some_purged = FALSE;
5279 ModestWindow *win = MODEST_WINDOW (user_data);
5280 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5282 /* If there was any error */
5283 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5284 modest_window_mgr_unregister_header (mgr, header);
5288 /* Once the message has been retrieved for purging, we check if
5289 * it's all ok for purging */
5291 parts = tny_simple_list_new ();
5292 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5293 iter = tny_list_create_iterator (parts);
5295 while (!tny_iterator_is_done (iter)) {
5297 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5298 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5299 if (tny_mime_part_is_purged (part))
5306 g_object_unref (part);
5308 tny_iterator_next (iter);
5310 g_object_unref (iter);
5313 if (pending_purges>0) {
5315 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5317 if (response == GTK_RESPONSE_OK) {
5320 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5321 iter = tny_list_create_iterator (parts);
5322 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 tny_mime_part_set_purged (part);
5330 g_object_unref (part);
5332 tny_iterator_next (iter);
5334 g_object_unref (iter);
5336 tny_msg_rewrite_cache (msg);
5338 gtk_widget_destroy (info);
5342 modest_window_mgr_unregister_header (mgr, header);
5344 g_object_unref (parts);
5348 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5349 ModestMainWindow *win)
5351 GtkWidget *header_view;
5352 TnyList *header_list;
5354 TnyHeaderFlags flags;
5355 ModestWindow *msg_view_window = NULL;
5358 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5360 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5361 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5363 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5365 g_warning ("%s: no header selected", __FUNCTION__);
5369 if (tny_list_get_length (header_list) == 1) {
5370 TnyIterator *iter = tny_list_create_iterator (header_list);
5371 header = TNY_HEADER (tny_iterator_get_current (iter));
5372 g_object_unref (iter);
5376 if (!header || !TNY_IS_HEADER(header)) {
5377 g_warning ("%s: header is not valid", __FUNCTION__);
5381 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5382 header, &msg_view_window);
5383 flags = tny_header_get_flags (header);
5384 if (!(flags & TNY_HEADER_FLAG_CACHED))
5387 if (msg_view_window != NULL)
5388 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5390 /* do nothing; uid was registered before, so window is probably on it's way */
5391 g_warning ("debug: header %p has already been registered", header);
5394 ModestMailOperation *mail_op = NULL;
5395 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5396 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5397 modest_ui_actions_disk_operations_error_handler,
5399 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5400 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5402 g_object_unref (mail_op);
5405 g_object_unref (header);
5407 g_object_unref (header_list);
5411 * Checks if we need a connection to do the transfer and if the user
5412 * wants to connect to complete it
5415 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5416 TnyFolderStore *src_folder,
5418 TnyFolder *dst_folder,
5419 gboolean delete_originals,
5420 gboolean *need_connection,
5423 TnyAccount *src_account;
5424 gint uncached_msgs = 0;
5426 /* We don't need any further check if
5428 * 1- the source folder is local OR
5429 * 2- the device is already online
5431 if (!modest_tny_folder_store_is_remote (src_folder) ||
5432 tny_device_is_online (modest_runtime_get_device())) {
5433 *need_connection = FALSE;
5438 /* We must ask for a connection when
5440 * - the message(s) is not already cached OR
5441 * - the message(s) is cached but the leave_on_server setting
5442 * is FALSE (because we need to sync the source folder to
5443 * delete the message from the server (for IMAP we could do it
5444 * offline, it'll take place the next time we get a
5447 uncached_msgs = header_list_count_uncached_msgs (headers);
5448 src_account = get_account_from_folder_store (src_folder);
5449 if (uncached_msgs > 0) {
5453 *need_connection = TRUE;
5454 num_headers = tny_list_get_length (headers);
5455 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5457 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5458 GTK_RESPONSE_CANCEL) {
5464 /* The transfer is possible and the user wants to */
5467 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5468 const gchar *account_name;
5469 gboolean leave_on_server;
5471 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5472 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5475 if (leave_on_server == TRUE) {
5476 *need_connection = FALSE;
5478 *need_connection = TRUE;
5481 *need_connection = FALSE;
5486 g_object_unref (src_account);
5490 xfer_messages_error_handler (ModestMailOperation *mail_op,
5494 const GError *error;
5496 win = modest_mail_operation_get_source (mail_op);
5497 error = modest_mail_operation_get_error (mail_op);
5499 if (error && is_memory_full_error ((GError *) error, mail_op))
5500 modest_platform_information_banner ((GtkWidget *) win,
5501 NULL, _KR("cerm_device_memory_full"));
5503 modest_platform_run_information_dialog ((GtkWindow *) win,
5504 _("mail_in_ui_folder_move_target_error"),
5507 g_object_unref (win);
5511 TnyFolderStore *dst_folder;
5516 * Utility function that transfer messages from both the main window
5517 * and the msg view window when using the "Move to" dialog
5520 xfer_messages_performer (gboolean canceled,
5522 GtkWindow *parent_window,
5523 TnyAccount *account,
5526 ModestWindow *win = MODEST_WINDOW (parent_window);
5527 TnyAccount *dst_account = NULL;
5528 gboolean dst_forbids_message_add = FALSE;
5529 XferMsgsHelper *helper;
5530 MoveToHelper *movehelper;
5531 ModestMailOperation *mail_op;
5533 helper = (XferMsgsHelper *) user_data;
5535 if (canceled || err) {
5536 if (!check_memory_full_error ((GtkWidget *) parent_window, err)) {
5537 /* Show the proper error message */
5538 modest_ui_actions_on_account_connection_error (parent_window, account);
5543 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5545 /* tinymail will return NULL for local folders it seems */
5546 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5547 modest_tny_account_get_protocol_type (dst_account),
5548 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_MESSAGE_ADD);
5549 g_object_unref (dst_account);
5551 if (dst_forbids_message_add) {
5552 modest_platform_information_banner (GTK_WIDGET (win),
5554 ngettext("mail_in_ui_folder_move_target_error",
5555 "mail_in_ui_folder_move_targets_error",
5556 tny_list_get_length (helper->headers)));
5560 movehelper = g_new0 (MoveToHelper, 1);
5562 #ifndef MODEST_TOOLKIT_HILDON2
5563 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5564 _CS("ckct_nw_pasting"));
5565 if (movehelper->banner != NULL) {
5566 g_object_ref (movehelper->banner);
5567 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5571 if (MODEST_IS_MAIN_WINDOW (win)) {
5572 GtkWidget *header_view =
5573 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5574 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5575 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5578 /* Perform the mail operation */
5579 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5580 xfer_messages_error_handler,
5582 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5585 modest_mail_operation_xfer_msgs (mail_op,
5587 TNY_FOLDER (helper->dst_folder),
5592 g_object_unref (G_OBJECT (mail_op));
5594 g_object_unref (helper->dst_folder);
5595 g_object_unref (helper->headers);
5596 g_slice_free (XferMsgsHelper, helper);
5600 TnyFolder *src_folder;
5601 TnyFolderStore *dst_folder;
5602 gboolean delete_original;
5603 GtkWidget *folder_view;
5607 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
5608 TnyAccount *account, gpointer user_data)
5610 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5611 GtkTreeSelection *sel;
5612 ModestMailOperation *mail_op = NULL;
5614 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
5615 g_object_unref (G_OBJECT (info->src_folder));
5616 g_object_unref (G_OBJECT (info->dst_folder));
5621 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5622 #ifndef MODEST_TOOLKIT_HILDON2
5623 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5624 _CS("ckct_nw_pasting"));
5625 if (helper->banner != NULL) {
5626 g_object_ref (helper->banner);
5627 gtk_widget_show (GTK_WIDGET(helper->banner));
5630 /* Clean folder on header view before moving it */
5631 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5632 gtk_tree_selection_unselect_all (sel);
5634 /* Let gtk events run. We need that the folder
5635 view frees its reference to the source
5636 folder *before* issuing the mail operation
5637 so we need the signal handler of selection
5638 changed to happen before the mail
5640 while (gtk_events_pending ())
5641 gtk_main_iteration (); */
5644 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5645 modest_ui_actions_move_folder_error_handler,
5646 info->src_folder, NULL);
5647 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5650 /* Select *after* the changes */
5651 /* TODO: this function hangs UI after transfer */
5652 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
5653 /* TNY_FOLDER (src_folder), TRUE); */
5655 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
5656 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5657 TNY_FOLDER (info->dst_folder), TRUE);
5659 modest_mail_operation_xfer_folder (mail_op,
5660 TNY_FOLDER (info->src_folder),
5662 info->delete_original,
5665 g_object_unref (G_OBJECT (info->src_folder));
5667 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5670 /* Unref mail operation */
5671 g_object_unref (G_OBJECT (mail_op));
5672 g_object_unref (G_OBJECT (info->dst_folder));
5677 get_account_from_folder_store (TnyFolderStore *folder_store)
5679 if (TNY_IS_ACCOUNT (folder_store))
5680 return g_object_ref (folder_store);
5682 return tny_folder_get_account (TNY_FOLDER (folder_store));
5686 * UI handler for the "Move to" action when invoked from the
5690 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5691 GtkWidget *folder_view,
5692 TnyFolderStore *dst_folder,
5693 ModestMainWindow *win)
5695 ModestHeaderView *header_view = NULL;
5696 TnyFolderStore *src_folder = NULL;
5698 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5700 /* Get the source folder */
5701 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5703 /* Get header view */
5704 header_view = (ModestHeaderView *)
5705 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5707 /* Get folder or messages to transfer */
5708 if (gtk_widget_is_focus (folder_view)) {
5709 gboolean do_xfer = TRUE;
5711 /* Allow only to transfer folders to the local root folder */
5712 if (TNY_IS_ACCOUNT (dst_folder) &&
5713 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5714 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5716 } else if (!TNY_IS_FOLDER (src_folder)) {
5717 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5722 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5723 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5725 info->src_folder = g_object_ref (src_folder);
5726 info->dst_folder = g_object_ref (dst_folder);
5727 info->delete_original = TRUE;
5728 info->folder_view = folder_view;
5730 connect_info->callback = on_move_folder_cb;
5731 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5732 connect_info->data = info;
5734 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5735 TNY_FOLDER_STORE (src_folder),
5738 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5741 headers = modest_header_view_get_selected_headers(header_view);
5743 /* Transfer the messages */
5744 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
5745 headers, TNY_FOLDER (dst_folder));
5747 g_object_unref (headers);
5751 g_object_unref (src_folder);
5754 #ifdef MODEST_TOOLKIT_HILDON2
5756 * UI handler for the "Move to" action when invoked from the
5757 * ModestFolderWindow
5760 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
5761 TnyFolderStore *dst_folder,
5765 TnyFolderStore *src_folder = NULL;
5766 TnyIterator *iterator;
5768 if (tny_list_get_length (selection) != 1)
5771 iterator = tny_list_create_iterator (selection);
5772 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
5773 g_object_unref (iterator);
5776 gboolean do_xfer = TRUE;
5778 /* Allow only to transfer folders to the local root folder */
5779 if (TNY_IS_ACCOUNT (dst_folder) &&
5780 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5781 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5784 modest_platform_run_information_dialog (win,
5785 _("mail_in_ui_folder_move_target_error"),
5787 } else if (!TNY_IS_FOLDER (src_folder)) {
5788 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5793 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5794 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5796 info->src_folder = g_object_ref (src_folder);
5797 info->dst_folder = g_object_ref (dst_folder);
5798 info->delete_original = TRUE;
5799 info->folder_view = folder_view;
5801 connect_info->callback = on_move_folder_cb;
5802 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5803 connect_info->data = info;
5805 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5806 TNY_FOLDER_STORE (src_folder),
5811 g_object_unref (src_folder);
5817 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
5818 TnyFolder *src_folder,
5820 TnyFolder *dst_folder)
5822 gboolean need_connection = TRUE;
5823 gboolean do_xfer = TRUE;
5824 XferMsgsHelper *helper;
5826 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5827 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5828 g_return_if_fail (TNY_IS_LIST (headers));
5830 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5831 headers, TNY_FOLDER (dst_folder),
5832 TRUE, &need_connection,
5835 /* If we don't want to transfer just return */
5839 /* Create the helper */
5840 helper = g_slice_new (XferMsgsHelper);
5841 helper->dst_folder = g_object_ref (dst_folder);
5842 helper->headers = g_object_ref (headers);
5844 if (need_connection) {
5845 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5846 connect_info->callback = xfer_messages_performer;
5847 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5848 connect_info->data = helper;
5850 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5851 TNY_FOLDER_STORE (src_folder),
5854 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5855 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
5856 src_account, helper);
5857 g_object_unref (src_account);
5862 * UI handler for the "Move to" action when invoked from the
5863 * ModestMsgViewWindow
5866 modest_ui_actions_on_window_move_to (GtkAction *action,
5868 TnyFolderStore *dst_folder,
5871 TnyFolder *src_folder = NULL;
5873 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5876 TnyHeader *header = NULL;
5879 iter = tny_list_create_iterator (headers);
5880 header = (TnyHeader *) tny_iterator_get_current (iter);
5881 src_folder = tny_header_get_folder (header);
5883 /* Transfer the messages */
5884 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
5886 TNY_FOLDER (dst_folder));
5889 g_object_unref (header);
5890 g_object_unref (iter);
5891 g_object_unref (src_folder);
5896 modest_ui_actions_on_move_to (GtkAction *action,
5899 modest_ui_actions_on_edit_mode_move_to (win);
5903 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
5905 GtkWidget *dialog = NULL;
5906 MoveToInfo *helper = NULL;
5907 TnyList *list_to_move;
5909 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
5911 #ifndef MODEST_TOOLKIT_HILDON2
5912 /* Get the main window if exists */
5913 ModestMainWindow *main_window;
5914 if (MODEST_IS_MAIN_WINDOW (win))
5915 main_window = MODEST_MAIN_WINDOW (win);
5918 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5919 FALSE)); /* don't create */
5922 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
5927 if (tny_list_get_length (list_to_move) < 1) {
5928 g_object_unref (list_to_move);
5932 /* Create and run the dialog */
5933 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
5934 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
5935 GTK_WINDOW (dialog),
5939 helper = g_slice_new0 (MoveToInfo);
5940 helper->list = list_to_move;
5943 /* Listen to response signal */
5944 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
5946 /* Show the dialog */
5947 gtk_widget_show (dialog);
5953 * Calls #HeadersFunc for each header already selected in the main
5954 * window or the message currently being shown in the msg view window
5957 do_headers_action (ModestWindow *win,
5961 TnyList *headers_list = NULL;
5962 TnyIterator *iter = NULL;
5963 TnyHeader *header = NULL;
5964 TnyFolder *folder = NULL;
5967 headers_list = get_selected_headers (win);
5971 /* Get the folder */
5972 iter = tny_list_create_iterator (headers_list);
5973 header = TNY_HEADER (tny_iterator_get_current (iter));
5975 folder = tny_header_get_folder (header);
5976 g_object_unref (header);
5979 /* Call the function for each header */
5980 while (!tny_iterator_is_done (iter)) {
5981 header = TNY_HEADER (tny_iterator_get_current (iter));
5982 func (header, win, user_data);
5983 g_object_unref (header);
5984 tny_iterator_next (iter);
5987 /* Trick: do a poke status in order to speed up the signaling
5990 tny_folder_poke_status (folder);
5991 g_object_unref (folder);
5995 g_object_unref (iter);
5996 g_object_unref (headers_list);
6000 modest_ui_actions_view_attachment (GtkAction *action,
6001 ModestWindow *window)
6003 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6004 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
6006 /* not supported window for this action */
6007 g_return_if_reached ();
6012 modest_ui_actions_save_attachments (GtkAction *action,
6013 ModestWindow *window)
6015 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6017 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
6020 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
6022 /* not supported window for this action */
6023 g_return_if_reached ();
6028 modest_ui_actions_remove_attachments (GtkAction *action,
6029 ModestWindow *window)
6031 if (MODEST_IS_MAIN_WINDOW (window)) {
6032 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
6033 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6034 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
6036 /* not supported window for this action */
6037 g_return_if_reached ();
6042 modest_ui_actions_on_settings (GtkAction *action,
6047 dialog = modest_platform_get_global_settings_dialog ();
6048 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
6049 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
6050 gtk_widget_show_all (dialog);
6052 gtk_dialog_run (GTK_DIALOG (dialog));
6054 gtk_widget_destroy (dialog);
6058 modest_ui_actions_on_help (GtkAction *action,
6061 /* Help app is not available at all in fremantle */
6062 #ifndef MODEST_TOOLKIT_HILDON2
6063 const gchar *help_id;
6065 g_return_if_fail (win && GTK_IS_WINDOW(win));
6067 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
6070 modest_platform_show_help (GTK_WINDOW (win), help_id);
6075 modest_ui_actions_on_csm_help (GtkAction *action,
6078 /* Help app is not available at all in fremantle */
6079 #ifndef MODEST_TOOLKIT_HILDON2
6081 const gchar* help_id = NULL;
6082 GtkWidget *folder_view;
6083 TnyFolderStore *folder_store;
6085 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
6087 /* Get selected folder */
6088 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
6089 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6090 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6092 /* Switch help_id */
6093 if (folder_store && TNY_IS_FOLDER (folder_store))
6094 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
6097 g_object_unref (folder_store);
6100 modest_platform_show_help (GTK_WINDOW (win), help_id);
6102 modest_ui_actions_on_help (action, win);
6107 retrieve_contents_cb (ModestMailOperation *mail_op,
6114 /* We only need this callback to show an error in case of
6115 memory low condition */
6116 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
6117 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
6122 retrieve_msg_contents_performer (gboolean canceled,
6124 GtkWindow *parent_window,
6125 TnyAccount *account,
6128 ModestMailOperation *mail_op;
6129 TnyList *headers = TNY_LIST (user_data);
6131 if (err || canceled) {
6132 check_memory_full_error ((GtkWidget *) parent_window, err);
6136 /* Create mail operation */
6137 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
6138 modest_ui_actions_disk_operations_error_handler,
6140 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
6141 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
6144 g_object_unref (mail_op);
6146 g_object_unref (headers);
6147 g_object_unref (account);
6151 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
6152 ModestWindow *window)
6154 TnyList *headers = NULL;
6155 TnyAccount *account = NULL;
6156 TnyIterator *iter = NULL;
6157 TnyHeader *header = NULL;
6158 TnyFolder *folder = NULL;
6161 headers = get_selected_headers (window);
6165 /* Pick the account */
6166 iter = tny_list_create_iterator (headers);
6167 header = TNY_HEADER (tny_iterator_get_current (iter));
6168 folder = tny_header_get_folder (header);
6169 account = tny_folder_get_account (folder);
6170 g_object_unref (folder);
6171 g_object_unref (header);
6172 g_object_unref (iter);
6174 /* Connect and perform the message retrieval */
6175 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6176 g_object_ref (account),
6177 retrieve_msg_contents_performer,
6178 g_object_ref (headers));
6181 g_object_unref (account);
6182 g_object_unref (headers);
6186 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6188 g_return_if_fail (MODEST_IS_WINDOW (window));
6191 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6195 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6197 g_return_if_fail (MODEST_IS_WINDOW (window));
6200 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6204 modest_ui_actions_on_email_menu_activated (GtkAction *action,
6205 ModestWindow *window)
6207 g_return_if_fail (MODEST_IS_WINDOW (window));
6210 modest_ui_actions_check_menu_dimming_rules (window);
6214 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
6215 ModestWindow *window)
6217 g_return_if_fail (MODEST_IS_WINDOW (window));
6220 modest_ui_actions_check_menu_dimming_rules (window);
6224 modest_ui_actions_on_view_menu_activated (GtkAction *action,
6225 ModestWindow *window)
6227 g_return_if_fail (MODEST_IS_WINDOW (window));
6230 modest_ui_actions_check_menu_dimming_rules (window);
6234 modest_ui_actions_on_format_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_tools_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_attachment_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_toolbar_csm_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_folder_view_csm_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_header_view_csm_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_search_messages (GtkAction *action, ModestWindow *window)
6296 g_return_if_fail (MODEST_IS_WINDOW (window));
6298 /* we check for low-mem; in that case, show a warning, and don't allow
6301 if (modest_platform_check_memory_low (window, TRUE))
6304 modest_platform_show_search_messages (GTK_WINDOW (window));
6308 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6310 g_return_if_fail (MODEST_IS_WINDOW (win));
6313 /* we check for low-mem; in that case, show a warning, and don't allow
6314 * for the addressbook
6316 if (modest_platform_check_memory_low (win, TRUE))
6320 modest_platform_show_addressbook (GTK_WINDOW (win));
6325 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6326 ModestWindow *window)
6329 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6331 if (GTK_IS_TOGGLE_ACTION (action))
6332 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6336 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window),
6341 on_send_receive_finished (ModestMailOperation *mail_op,
6344 GtkWidget *header_view, *folder_view;
6345 TnyFolderStore *folder_store;
6346 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6348 /* Set send/receive operation finished */
6349 modest_main_window_notify_send_receive_completed (main_win);
6351 /* Don't refresh the current folder if there were any errors */
6352 if (modest_mail_operation_get_status (mail_op) !=
6353 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6356 /* Refresh the current folder if we're viewing a window. We do
6357 this because the user won't be able to see the new mails in
6358 the selected folder after a Send&Receive because it only
6359 performs a poke_status, i.e, only the number of read/unread
6360 messages is updated, but the new headers are not
6362 folder_view = modest_main_window_get_child_widget (main_win,
6363 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6367 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6369 /* Do not need to refresh INBOX again because the
6370 update_account does it always automatically */
6371 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6372 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6373 ModestMailOperation *refresh_op;
6375 header_view = modest_main_window_get_child_widget (main_win,
6376 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6378 /* We do not need to set the contents style
6379 because it hasn't changed. We also do not
6380 need to save the widget status. Just force
6382 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6383 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6384 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6385 folder_refreshed_cb, main_win);
6386 g_object_unref (refresh_op);
6390 g_object_unref (folder_store);
6395 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6401 const gchar* server_name = NULL;
6402 TnyTransportAccount *transport;
6403 gchar *message = NULL;
6404 ModestProtocol *protocol;
6406 /* Don't show anything if the user cancelled something or the
6407 * send receive request is not interactive. Authentication
6408 * errors are managed by the account store so no need to show
6409 * a dialog here again */
6410 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6411 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6412 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6416 /* Get the server name. Note that we could be using a
6417 connection specific transport account */
6418 transport = (TnyTransportAccount *)
6419 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
6421 ModestTnyAccountStore *acc_store;
6422 const gchar *acc_name;
6423 TnyTransportAccount *conn_specific;
6425 acc_store = modest_runtime_get_account_store();
6426 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
6427 conn_specific = (TnyTransportAccount *)
6428 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
6429 if (conn_specific) {
6430 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
6431 g_object_unref (conn_specific);
6433 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
6435 g_object_unref (transport);
6439 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
6440 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
6441 tny_account_get_proto (TNY_ACCOUNT (transport)));
6443 g_warning ("%s: Account with no proto", __FUNCTION__);
6447 /* Show the appropriate message text for the GError: */
6448 switch (err->code) {
6449 case TNY_SERVICE_ERROR_CONNECT:
6450 message = modest_protocol_get_translation (protocol,
6451 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
6454 case TNY_SERVICE_ERROR_SEND:
6455 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6457 case TNY_SERVICE_ERROR_UNAVAILABLE:
6458 message = modest_protocol_get_translation (protocol,
6459 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
6463 g_warning ("%s: unexpected ERROR %d",
6464 __FUNCTION__, err->code);
6465 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6469 modest_platform_run_information_dialog (NULL, message, FALSE);
6474 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6479 ModestWindow *top_window = NULL;
6480 ModestWindowMgr *mgr = NULL;
6481 GtkWidget *header_view = NULL;
6482 TnyFolder *selected_folder = NULL;
6483 TnyFolderType folder_type;
6485 mgr = modest_runtime_get_window_mgr ();
6486 top_window = modest_window_mgr_get_current_top (mgr);
6491 #ifndef MODEST_TOOLKIT_HILDON2
6492 if (MODEST_IS_MAIN_WINDOW (top_window)) {
6493 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (top_window),
6494 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6497 if (MODEST_IS_HEADER_WINDOW (top_window)) {
6498 header_view = (GtkWidget *)
6499 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
6503 /* Get selected folder */
6505 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
6506 if (!selected_folder)
6509 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6510 #if GTK_CHECK_VERSION(2, 8, 0)
6511 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
6512 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6513 GtkTreeViewColumn *tree_column;
6515 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6516 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6518 gtk_tree_view_column_queue_resize (tree_column);
6520 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
6521 gtk_widget_queue_draw (header_view);
6524 #ifndef MODEST_TOOLKIT_HILDON2
6525 /* Rerun dimming rules, because the message could become deletable for example */
6526 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6527 MODEST_DIMMING_RULES_TOOLBAR);
6528 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6529 MODEST_DIMMING_RULES_MENU);
6533 g_object_unref (selected_folder);
6537 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6538 TnyAccount *account)
6540 ModestProtocolType protocol_type;
6541 ModestProtocol *protocol;
6542 gchar *error_note = NULL;
6544 protocol_type = modest_tny_account_get_protocol_type (account);
6545 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6548 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6549 if (error_note == NULL) {
6550 g_warning ("%s: This should not be reached", __FUNCTION__);
6552 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6553 g_free (error_note);
6558 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6562 TnyFolderStore *folder = NULL;
6563 TnyAccount *account = NULL;
6564 ModestProtocolType proto;
6565 ModestProtocol *protocol;
6566 TnyHeader *header = NULL;
6568 if (MODEST_IS_MAIN_WINDOW (win)) {
6569 GtkWidget *header_view;
6570 TnyList* headers = NULL;
6572 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6573 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6574 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6575 if (!headers || tny_list_get_length (headers) == 0) {
6577 g_object_unref (headers);
6580 iter = tny_list_create_iterator (headers);
6581 header = TNY_HEADER (tny_iterator_get_current (iter));
6582 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6583 g_object_unref (iter);
6584 g_object_unref (headers);
6585 #ifdef MODEST_TOOLKIT_HILDON2
6586 } else if (MODEST_IS_HEADER_WINDOW (win)) {
6587 GtkWidget *header_view;
6588 TnyList* headers = NULL;
6590 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
6591 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6592 if (!headers || tny_list_get_length (headers) == 0) {
6594 g_object_unref (headers);
6597 iter = tny_list_create_iterator (headers);
6598 header = TNY_HEADER (tny_iterator_get_current (iter));
6600 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6602 g_warning ("List should contain headers");
6604 g_object_unref (iter);
6605 g_object_unref (headers);
6607 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6608 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6609 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6612 if (!header || !folder)
6615 /* Get the account type */
6616 account = tny_folder_get_account (TNY_FOLDER (folder));
6617 proto = modest_tny_account_get_protocol_type (account);
6618 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6621 subject = tny_header_dup_subject (header);
6622 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6626 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6632 g_object_unref (account);
6634 g_object_unref (folder);
6636 g_object_unref (header);
6642 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6643 const gchar *account_name,
6644 const gchar *account_title)
6646 ModestAccountMgr *account_mgr;
6649 ModestProtocol *protocol;
6650 gboolean removed = FALSE;
6652 g_return_val_if_fail (account_name, FALSE);
6653 g_return_val_if_fail (account_title, FALSE);
6655 account_mgr = modest_runtime_get_account_mgr();
6657 /* The warning text depends on the account type: */
6658 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6659 modest_account_mgr_get_store_protocol (account_mgr,
6661 txt = modest_protocol_get_translation (protocol,
6662 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6665 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6667 response = modest_platform_run_confirmation_dialog (parent_window, txt);
6671 if (response == GTK_RESPONSE_OK) {
6672 /* Remove account. If it succeeds then it also removes
6673 the account from the ModestAccountView: */
6674 gboolean is_default = FALSE;
6675 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6676 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6678 g_free (default_account_name);
6680 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6682 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);