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 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header);
4599 * Show the header details in a ModestDetailsDialog widget
4602 modest_ui_actions_on_details (GtkAction *action,
4605 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4609 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4613 header = tny_msg_get_header (msg);
4615 headers_action_show_details (header, win, NULL);
4616 g_object_unref (header);
4618 g_object_unref (msg);
4620 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4621 GtkWidget *folder_view, *header_view;
4623 /* Check which widget has the focus */
4624 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4625 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4626 if (gtk_widget_is_focus (folder_view)) {
4627 TnyFolderStore *folder_store
4628 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4629 if (!folder_store) {
4630 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4633 /* Show only when it's a folder */
4634 /* This function should not be called for account items,
4635 * because we dim the menu item for them. */
4636 if (TNY_IS_FOLDER (folder_store)) {
4637 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4638 TNY_FOLDER (folder_store));
4641 g_object_unref (folder_store);
4644 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4645 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4646 /* Show details of each header */
4647 do_headers_action (win, headers_action_show_details, header_view);
4649 #ifdef MODEST_TOOLKIT_HILDON2
4650 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4652 GtkWidget *header_view;
4654 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4655 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4657 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4659 g_object_unref (folder);
4666 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4667 ModestMsgEditWindow *window)
4669 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4671 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4675 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4676 ModestMsgEditWindow *window)
4678 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4680 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4684 modest_ui_actions_toggle_folders_view (GtkAction *action,
4685 ModestMainWindow *main_window)
4687 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4689 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4690 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4692 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4696 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4697 ModestWindow *window)
4699 gboolean active, fullscreen = FALSE;
4700 ModestWindowMgr *mgr;
4702 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4704 /* Check if we want to toggle the toolbar view in fullscreen
4706 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4707 "ViewShowToolbarFullScreen")) {
4711 /* Toggle toolbar */
4712 mgr = modest_runtime_get_window_mgr ();
4713 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4717 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4718 ModestMsgEditWindow *window)
4720 modest_msg_edit_window_select_font (window);
4725 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4726 const gchar *display_name,
4729 /* don't update the display name if it was already set;
4730 * updating the display name apparently is expensive */
4731 const gchar* old_name = gtk_window_get_title (window);
4733 if (display_name == NULL)
4736 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4737 return; /* don't do anything */
4739 /* This is usually used to change the title of the main window, which
4740 * is the one that holds the folder view. Note that this change can
4741 * happen even when the widget doesn't have the focus. */
4742 gtk_window_set_title (window, display_name);
4747 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4749 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4750 modest_msg_edit_window_select_contacts (window);
4754 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4756 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4757 modest_msg_edit_window_check_names (window, FALSE);
4760 #ifndef MODEST_TOOLKIT_HILDON2
4762 * This function is used to track changes in the selection of the
4763 * folder view that is inside the "move to" dialog to enable/disable
4764 * the OK button because we do not want the user to select a disallowed
4765 * destination for a folder.
4766 * The user also not desired to be able to use NEW button on items where
4767 * folder creation is not possibel.
4770 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4771 TnyFolderStore *folder_store,
4775 GtkWidget *dialog = NULL;
4776 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4777 gboolean moving_folder = FALSE;
4778 gboolean is_local_account = TRUE;
4779 GtkWidget *folder_view = NULL;
4780 ModestTnyFolderRules rules;
4782 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
4787 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
4791 /* check if folder_store is an remote account */
4792 if (TNY_IS_ACCOUNT (folder_store)) {
4793 TnyAccount *local_account = NULL;
4794 TnyAccount *mmc_account = NULL;
4795 ModestTnyAccountStore *account_store = NULL;
4797 account_store = modest_runtime_get_account_store ();
4798 local_account = modest_tny_account_store_get_local_folders_account (account_store);
4799 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
4801 if ((gpointer) local_account != (gpointer) folder_store &&
4802 (gpointer) mmc_account != (gpointer) folder_store) {
4803 ModestProtocolType proto;
4804 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
4805 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
4806 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
4808 is_local_account = FALSE;
4809 /* New button should be dimmed on remote
4811 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4813 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
4815 g_object_unref (local_account);
4817 /* It could not exist */
4819 g_object_unref (mmc_account);
4822 /* Check the target folder rules */
4823 if (TNY_IS_FOLDER (folder_store)) {
4824 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
4825 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
4826 ok_sensitive = FALSE;
4827 new_sensitive = FALSE;
4832 /* Check if we're moving a folder */
4833 if (MODEST_IS_MAIN_WINDOW (user_data)) {
4834 /* Get the widgets */
4835 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
4836 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4837 if (gtk_widget_is_focus (folder_view))
4838 moving_folder = TRUE;
4841 if (moving_folder) {
4842 TnyFolderStore *moved_folder = NULL, *parent = NULL;
4844 /* Get the folder to move */
4845 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4847 /* Check that we're not moving to the same folder */
4848 if (TNY_IS_FOLDER (moved_folder)) {
4849 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
4850 if (parent == folder_store)
4851 ok_sensitive = FALSE;
4852 g_object_unref (parent);
4855 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
4856 /* Do not allow to move to an account unless it's the
4857 local folders account */
4858 if (!is_local_account)
4859 ok_sensitive = FALSE;
4862 if (ok_sensitive && (moved_folder == folder_store)) {
4863 /* Do not allow to move to itself */
4864 ok_sensitive = FALSE;
4866 g_object_unref (moved_folder);
4868 TnyFolder *src_folder = NULL;
4870 /* Moving a message */
4871 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
4873 TnyHeader *header = NULL;
4874 header = modest_msg_view_window_get_header
4875 (MODEST_MSG_VIEW_WINDOW (user_data));
4876 if (!TNY_IS_HEADER(header))
4877 g_warning ("%s: could not get source header", __FUNCTION__);
4879 src_folder = tny_header_get_folder (header);
4882 g_object_unref (header);
4885 TNY_FOLDER (modest_folder_view_get_selected
4886 (MODEST_FOLDER_VIEW (folder_view)));
4889 if (TNY_IS_FOLDER(src_folder)) {
4890 /* Do not allow to move the msg to the same folder */
4891 /* Do not allow to move the msg to an account */
4892 if ((gpointer) src_folder == (gpointer) folder_store ||
4893 TNY_IS_ACCOUNT (folder_store))
4894 ok_sensitive = FALSE;
4895 g_object_unref (src_folder);
4897 g_warning ("%s: could not get source folder", __FUNCTION__);
4901 /* Set sensitivity of the OK and NEW button */
4902 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
4903 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
4908 on_move_to_dialog_response (GtkDialog *dialog,
4912 GtkWidget *parent_win;
4913 MoveToInfo *helper = NULL;
4914 ModestFolderView *folder_view;
4916 helper = (MoveToInfo *) user_data;
4918 parent_win = (GtkWidget *) helper->win;
4919 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
4920 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4923 TnyFolderStore *dst_folder;
4925 case MODEST_GTK_RESPONSE_NEW_FOLDER:
4926 modest_ui_actions_create_folder (GTK_WIDGET (dialog), GTK_WIDGET (folder_view));
4928 case GTK_RESPONSE_NONE:
4929 case GTK_RESPONSE_CANCEL:
4930 case GTK_RESPONSE_DELETE_EVENT:
4932 case GTK_RESPONSE_OK:
4933 dst_folder = modest_folder_view_get_selected (folder_view);
4935 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
4936 /* Clean list to move used for filtering */
4937 modest_folder_view_set_list_to_move (folder_view, NULL);
4939 modest_ui_actions_on_main_window_move_to (NULL,
4940 GTK_WIDGET (folder_view),
4942 MODEST_MAIN_WINDOW (parent_win));
4943 #ifdef MODEST_TOOLKIT_HILDON2
4944 } else if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
4945 /* Clean list to move used for filtering */
4946 modest_folder_view_set_list_to_move (folder_view, NULL);
4948 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
4951 GTK_WINDOW (parent_win));
4954 /* if the user selected a root folder
4955 (account) then do not perform any action */
4956 if (TNY_IS_ACCOUNT (dst_folder)) {
4957 g_signal_stop_emission_by_name (dialog, "response");
4961 /* Clean list to move used for filtering */
4962 modest_folder_view_set_list_to_move (folder_view, NULL);
4964 /* Moving from headers window in edit mode */
4965 modest_ui_actions_on_window_move_to (NULL, helper->list,
4967 MODEST_WINDOW (parent_win));
4971 g_object_unref (dst_folder);
4975 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
4978 /* Free the helper and exit */
4980 g_object_unref (helper->list);
4981 g_slice_free (MoveToInfo, helper);
4982 gtk_widget_destroy (GTK_WIDGET (dialog));
4986 create_move_to_dialog (GtkWindow *win,
4987 GtkWidget *folder_view,
4988 TnyList *list_to_move)
4990 GtkWidget *dialog, *tree_view = NULL;
4992 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
4994 #ifndef MODEST_TOOLKIT_HILDON2
4995 /* Track changes in the selection to
4996 * disable the OK button whenever "Move to" is not possible
4997 * disbale NEW button whenever New is not possible */
4998 g_signal_connect (tree_view,
4999 "folder_selection_changed",
5000 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
5004 /* It could happen that we're trying to move a message from a
5005 window (msg window for example) after the main window was
5006 closed, so we can not just get the model of the folder
5008 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
5009 const gchar *visible_id = NULL;
5011 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5012 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5013 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
5014 MODEST_FOLDER_VIEW(tree_view));
5017 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
5019 /* Show the same account than the one that is shown in the main window */
5020 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
5023 const gchar *active_account_name = NULL;
5024 ModestAccountMgr *mgr = NULL;
5025 ModestAccountSettings *settings = NULL;
5026 ModestServerAccountSettings *store_settings = NULL;
5028 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5029 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5030 modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view),
5031 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
5033 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
5034 mgr = modest_runtime_get_account_mgr ();
5035 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
5038 const gchar *store_account_name;
5039 store_settings = modest_account_settings_get_store_settings (settings);
5040 store_account_name = modest_server_account_settings_get_account_name (store_settings);
5042 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
5043 store_account_name);
5044 g_object_unref (store_settings);
5045 g_object_unref (settings);
5049 /* we keep a pointer to the embedded folder view, so we can
5050 * retrieve it with get_folder_view_from_move_to_dialog (see
5051 * above) later (needed for focus handling)
5053 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
5055 /* Hide special folders */
5056 #ifndef MODEST_TOOLKIT_HILDON2
5057 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
5060 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
5061 #ifndef MODEST_TOOLKIT_HILDON2
5062 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5065 gtk_widget_show (GTK_WIDGET (tree_view));
5071 * Shows a confirmation dialog to the user when we're moving messages
5072 * from a remote server to the local storage. Returns the dialog
5073 * response. If it's other kind of movement then it always returns
5076 * This one is used by the next functions:
5077 * modest_ui_actions_on_paste - commented out
5078 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
5081 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
5082 TnyFolder *dest_folder,
5086 gint response = GTK_RESPONSE_OK;
5087 TnyAccount *account = NULL;
5088 TnyFolder *src_folder = NULL;
5089 TnyIterator *iter = NULL;
5090 TnyHeader *header = NULL;
5092 /* return with OK if the destination is a remote folder */
5093 if (modest_tny_folder_is_remote_folder (dest_folder))
5094 return GTK_RESPONSE_OK;
5096 /* Get source folder */
5097 iter = tny_list_create_iterator (headers);
5098 header = TNY_HEADER (tny_iterator_get_current (iter));
5100 src_folder = tny_header_get_folder (header);
5101 g_object_unref (header);
5103 g_object_unref (iter);
5105 /* if no src_folder, message may be an attahcment */
5106 if (src_folder == NULL)
5107 return GTK_RESPONSE_CANCEL;
5109 /* If the source is a local or MMC folder */
5110 if (!modest_tny_folder_is_remote_folder (src_folder)) {
5111 g_object_unref (src_folder);
5112 return GTK_RESPONSE_OK;
5115 /* Get the account */
5116 account = tny_folder_get_account (src_folder);
5118 /* now if offline we ask the user */
5119 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
5120 response = GTK_RESPONSE_OK;
5122 response = GTK_RESPONSE_CANCEL;
5125 g_object_unref (src_folder);
5126 g_object_unref (account);
5132 move_to_helper_destroyer (gpointer user_data)
5134 MoveToHelper *helper = (MoveToHelper *) user_data;
5136 /* Close the "Pasting" information banner */
5137 if (helper->banner) {
5138 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5139 g_object_unref (helper->banner);
5141 if (gtk_tree_row_reference_valid (helper->reference)) {
5142 gtk_tree_row_reference_free (helper->reference);
5143 helper->reference = NULL;
5149 move_to_cb (ModestMailOperation *mail_op,
5152 MoveToHelper *helper = (MoveToHelper *) user_data;
5153 GObject *object = modest_mail_operation_get_source (mail_op);
5155 /* Note that the operation could have failed, in that case do
5157 if (modest_mail_operation_get_status (mail_op) !=
5158 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5161 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5162 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5164 if (!modest_msg_view_window_select_next_message (self) &&
5165 !modest_msg_view_window_select_previous_message (self)) {
5166 /* No more messages to view, so close this window */
5167 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5169 } else if (MODEST_IS_MAIN_WINDOW (object) &&
5170 gtk_tree_row_reference_valid (helper->reference)) {
5171 GtkWidget *header_view;
5173 GtkTreeSelection *sel;
5175 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5176 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5177 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5178 path = gtk_tree_row_reference_get_path (helper->reference);
5179 /* We need to unselect the previous one
5180 because we could be copying instead of
5182 gtk_tree_selection_unselect_all (sel);
5183 gtk_tree_selection_select_path (sel, path);
5184 gtk_tree_path_free (path);
5186 g_object_unref (object);
5189 /* Destroy the helper */
5190 move_to_helper_destroyer (helper);
5194 folder_move_to_cb (ModestMailOperation *mail_op,
5195 TnyFolder *new_folder,
5198 GtkWidget *folder_view;
5201 object = modest_mail_operation_get_source (mail_op);
5202 if (MODEST_IS_MAIN_WINDOW (object)) {
5203 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5204 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5205 g_object_ref (folder_view);
5206 g_object_unref (object);
5207 move_to_cb (mail_op, user_data);
5208 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5209 g_object_unref (folder_view);
5211 move_to_cb (mail_op, user_data);
5216 msgs_move_to_cb (ModestMailOperation *mail_op,
5219 move_to_cb (mail_op, user_data);
5223 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5226 GObject *win = NULL;
5228 #ifndef MODEST_TOOLKIT_HILDON2
5229 ModestWindow *main_window = NULL;
5231 /* Disable next automatic folder selection */
5232 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5233 FALSE); /* don't create */
5235 GtkWidget *folder_view = NULL;
5237 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5238 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5239 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5241 if (user_data && TNY_IS_FOLDER (user_data)) {
5242 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5243 TNY_FOLDER (user_data), FALSE);
5247 /* Show notification dialog only if the main window exists */
5248 win = modest_mail_operation_get_source (mail_op);
5249 modest_platform_run_information_dialog ((GtkWindow *) win,
5250 _("mail_in_ui_folder_move_target_error"),
5253 g_object_unref (win);
5257 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5266 gint pending_purges = 0;
5267 gboolean some_purged = FALSE;
5268 ModestWindow *win = MODEST_WINDOW (user_data);
5269 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5271 /* If there was any error */
5272 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5273 modest_window_mgr_unregister_header (mgr, header);
5277 /* Once the message has been retrieved for purging, we check if
5278 * it's all ok for purging */
5280 parts = tny_simple_list_new ();
5281 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5282 iter = tny_list_create_iterator (parts);
5284 while (!tny_iterator_is_done (iter)) {
5286 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5287 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5288 if (tny_mime_part_is_purged (part))
5295 g_object_unref (part);
5297 tny_iterator_next (iter);
5299 g_object_unref (iter);
5302 if (pending_purges>0) {
5304 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5306 if (response == GTK_RESPONSE_OK) {
5309 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5310 iter = tny_list_create_iterator (parts);
5311 while (!tny_iterator_is_done (iter)) {
5314 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5315 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5316 tny_mime_part_set_purged (part);
5319 g_object_unref (part);
5321 tny_iterator_next (iter);
5323 g_object_unref (iter);
5325 tny_msg_rewrite_cache (msg);
5327 gtk_widget_destroy (info);
5331 modest_window_mgr_unregister_header (mgr, header);
5333 g_object_unref (parts);
5337 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5338 ModestMainWindow *win)
5340 GtkWidget *header_view;
5341 TnyList *header_list;
5343 TnyHeaderFlags flags;
5344 ModestWindow *msg_view_window = NULL;
5347 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5349 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5350 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5352 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5354 g_warning ("%s: no header selected", __FUNCTION__);
5358 if (tny_list_get_length (header_list) == 1) {
5359 TnyIterator *iter = tny_list_create_iterator (header_list);
5360 header = TNY_HEADER (tny_iterator_get_current (iter));
5361 g_object_unref (iter);
5365 if (!header || !TNY_IS_HEADER(header)) {
5366 g_warning ("%s: header is not valid", __FUNCTION__);
5370 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5371 header, &msg_view_window);
5372 flags = tny_header_get_flags (header);
5373 if (!(flags & TNY_HEADER_FLAG_CACHED))
5376 if (msg_view_window != NULL)
5377 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5379 /* do nothing; uid was registered before, so window is probably on it's way */
5380 g_warning ("debug: header %p has already been registered", header);
5383 ModestMailOperation *mail_op = NULL;
5384 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5385 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5386 modest_ui_actions_disk_operations_error_handler,
5388 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5389 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5391 g_object_unref (mail_op);
5394 g_object_unref (header);
5396 g_object_unref (header_list);
5400 * Checks if we need a connection to do the transfer and if the user
5401 * wants to connect to complete it
5404 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5405 TnyFolderStore *src_folder,
5407 TnyFolder *dst_folder,
5408 gboolean delete_originals,
5409 gboolean *need_connection,
5412 TnyAccount *src_account;
5413 gint uncached_msgs = 0;
5415 /* We don't need any further check if
5417 * 1- the source folder is local OR
5418 * 2- the device is already online
5420 if (!modest_tny_folder_store_is_remote (src_folder) ||
5421 tny_device_is_online (modest_runtime_get_device())) {
5422 *need_connection = FALSE;
5427 /* We must ask for a connection when
5429 * - the message(s) is not already cached OR
5430 * - the message(s) is cached but the leave_on_server setting
5431 * is FALSE (because we need to sync the source folder to
5432 * delete the message from the server (for IMAP we could do it
5433 * offline, it'll take place the next time we get a
5436 uncached_msgs = header_list_count_uncached_msgs (headers);
5437 src_account = get_account_from_folder_store (src_folder);
5438 if (uncached_msgs > 0) {
5442 *need_connection = TRUE;
5443 num_headers = tny_list_get_length (headers);
5444 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5446 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5447 GTK_RESPONSE_CANCEL) {
5453 /* The transfer is possible and the user wants to */
5456 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5457 const gchar *account_name;
5458 gboolean leave_on_server;
5460 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5461 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5464 if (leave_on_server == TRUE) {
5465 *need_connection = FALSE;
5467 *need_connection = TRUE;
5470 *need_connection = FALSE;
5475 g_object_unref (src_account);
5479 xfer_messages_error_handler (ModestMailOperation *mail_op,
5483 const GError *error;
5485 win = modest_mail_operation_get_source (mail_op);
5486 error = modest_mail_operation_get_error (mail_op);
5488 if (error && is_memory_full_error ((GError *) error, mail_op))
5489 modest_platform_information_banner ((GtkWidget *) win,
5490 NULL, _KR("cerm_device_memory_full"));
5492 modest_platform_run_information_dialog ((GtkWindow *) win,
5493 _("mail_in_ui_folder_move_target_error"),
5496 g_object_unref (win);
5500 TnyFolderStore *dst_folder;
5505 * Utility function that transfer messages from both the main window
5506 * and the msg view window when using the "Move to" dialog
5509 xfer_messages_performer (gboolean canceled,
5511 GtkWindow *parent_window,
5512 TnyAccount *account,
5515 ModestWindow *win = MODEST_WINDOW (parent_window);
5516 TnyAccount *dst_account = NULL;
5517 gboolean dst_forbids_message_add = FALSE;
5518 XferMsgsHelper *helper;
5519 MoveToHelper *movehelper;
5520 ModestMailOperation *mail_op;
5522 helper = (XferMsgsHelper *) user_data;
5524 if (canceled || err) {
5525 if (!check_memory_full_error ((GtkWidget *) parent_window, err)) {
5526 /* Show the proper error message */
5527 modest_ui_actions_on_account_connection_error (parent_window, account);
5532 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5534 /* tinymail will return NULL for local folders it seems */
5535 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5536 modest_tny_account_get_protocol_type (dst_account),
5537 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_MESSAGE_ADD);
5538 g_object_unref (dst_account);
5540 if (dst_forbids_message_add) {
5541 modest_platform_information_banner (GTK_WIDGET (win),
5543 ngettext("mail_in_ui_folder_move_target_error",
5544 "mail_in_ui_folder_move_targets_error",
5545 tny_list_get_length (helper->headers)));
5549 movehelper = g_new0 (MoveToHelper, 1);
5551 #ifndef MODEST_TOOLKIT_HILDON2
5552 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5553 _CS("ckct_nw_pasting"));
5554 if (movehelper->banner != NULL) {
5555 g_object_ref (movehelper->banner);
5556 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5560 if (MODEST_IS_MAIN_WINDOW (win)) {
5561 GtkWidget *header_view =
5562 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5563 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5564 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5567 /* Perform the mail operation */
5568 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5569 xfer_messages_error_handler,
5571 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5574 modest_mail_operation_xfer_msgs (mail_op,
5576 TNY_FOLDER (helper->dst_folder),
5581 g_object_unref (G_OBJECT (mail_op));
5583 g_object_unref (helper->dst_folder);
5584 g_object_unref (helper->headers);
5585 g_slice_free (XferMsgsHelper, helper);
5589 TnyFolder *src_folder;
5590 TnyFolderStore *dst_folder;
5591 gboolean delete_original;
5592 GtkWidget *folder_view;
5596 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
5597 TnyAccount *account, gpointer user_data)
5599 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5600 GtkTreeSelection *sel;
5601 ModestMailOperation *mail_op = NULL;
5603 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
5604 g_object_unref (G_OBJECT (info->src_folder));
5605 g_object_unref (G_OBJECT (info->dst_folder));
5610 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5611 #ifndef MODEST_TOOLKIT_HILDON2
5612 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5613 _CS("ckct_nw_pasting"));
5614 if (helper->banner != NULL) {
5615 g_object_ref (helper->banner);
5616 gtk_widget_show (GTK_WIDGET(helper->banner));
5619 /* Clean folder on header view before moving it */
5620 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5621 gtk_tree_selection_unselect_all (sel);
5623 /* Let gtk events run. We need that the folder
5624 view frees its reference to the source
5625 folder *before* issuing the mail operation
5626 so we need the signal handler of selection
5627 changed to happen before the mail
5629 while (gtk_events_pending ())
5630 gtk_main_iteration (); */
5633 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5634 modest_ui_actions_move_folder_error_handler,
5635 info->src_folder, NULL);
5636 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5639 /* Select *after* the changes */
5640 /* TODO: this function hangs UI after transfer */
5641 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
5642 /* TNY_FOLDER (src_folder), TRUE); */
5644 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
5645 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5646 TNY_FOLDER (info->dst_folder), TRUE);
5648 modest_mail_operation_xfer_folder (mail_op,
5649 TNY_FOLDER (info->src_folder),
5651 info->delete_original,
5654 g_object_unref (G_OBJECT (info->src_folder));
5656 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5659 /* Unref mail operation */
5660 g_object_unref (G_OBJECT (mail_op));
5661 g_object_unref (G_OBJECT (info->dst_folder));
5666 get_account_from_folder_store (TnyFolderStore *folder_store)
5668 if (TNY_IS_ACCOUNT (folder_store))
5669 return g_object_ref (folder_store);
5671 return tny_folder_get_account (TNY_FOLDER (folder_store));
5675 * UI handler for the "Move to" action when invoked from the
5679 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5680 GtkWidget *folder_view,
5681 TnyFolderStore *dst_folder,
5682 ModestMainWindow *win)
5684 ModestHeaderView *header_view = NULL;
5685 TnyFolderStore *src_folder = NULL;
5687 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5689 /* Get the source folder */
5690 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5692 /* Get header view */
5693 header_view = (ModestHeaderView *)
5694 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5696 /* Get folder or messages to transfer */
5697 if (gtk_widget_is_focus (folder_view)) {
5698 gboolean do_xfer = TRUE;
5700 /* Allow only to transfer folders to the local root folder */
5701 if (TNY_IS_ACCOUNT (dst_folder) &&
5702 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5703 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5705 } else if (!TNY_IS_FOLDER (src_folder)) {
5706 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5711 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5712 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5714 info->src_folder = g_object_ref (src_folder);
5715 info->dst_folder = g_object_ref (dst_folder);
5716 info->delete_original = TRUE;
5717 info->folder_view = folder_view;
5719 connect_info->callback = on_move_folder_cb;
5720 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5721 connect_info->data = info;
5723 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5724 TNY_FOLDER_STORE (src_folder),
5727 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5730 headers = modest_header_view_get_selected_headers(header_view);
5732 /* Transfer the messages */
5733 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
5734 headers, TNY_FOLDER (dst_folder));
5736 g_object_unref (headers);
5740 g_object_unref (src_folder);
5743 #ifdef MODEST_TOOLKIT_HILDON2
5745 * UI handler for the "Move to" action when invoked from the
5746 * ModestFolderWindow
5749 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
5750 TnyFolderStore *dst_folder,
5754 TnyFolderStore *src_folder = NULL;
5755 TnyIterator *iterator;
5757 if (tny_list_get_length (selection) != 1)
5760 iterator = tny_list_create_iterator (selection);
5761 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
5762 g_object_unref (iterator);
5765 gboolean do_xfer = TRUE;
5767 /* Allow only to transfer folders to the local root folder */
5768 if (TNY_IS_ACCOUNT (dst_folder) &&
5769 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5770 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5773 modest_platform_run_information_dialog (win,
5774 _("mail_in_ui_folder_move_target_error"),
5776 } else if (!TNY_IS_FOLDER (src_folder)) {
5777 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5782 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5783 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5785 info->src_folder = g_object_ref (src_folder);
5786 info->dst_folder = g_object_ref (dst_folder);
5787 info->delete_original = TRUE;
5788 info->folder_view = folder_view;
5790 connect_info->callback = on_move_folder_cb;
5791 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5792 connect_info->data = info;
5794 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5795 TNY_FOLDER_STORE (src_folder),
5800 g_object_unref (src_folder);
5806 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
5807 TnyFolder *src_folder,
5809 TnyFolder *dst_folder)
5811 gboolean need_connection = TRUE;
5812 gboolean do_xfer = TRUE;
5813 XferMsgsHelper *helper;
5815 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5816 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5817 g_return_if_fail (TNY_IS_LIST (headers));
5819 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5820 headers, TNY_FOLDER (dst_folder),
5821 TRUE, &need_connection,
5824 /* If we don't want to transfer just return */
5828 /* Create the helper */
5829 helper = g_slice_new (XferMsgsHelper);
5830 helper->dst_folder = g_object_ref (dst_folder);
5831 helper->headers = g_object_ref (headers);
5833 if (need_connection) {
5834 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5835 connect_info->callback = xfer_messages_performer;
5836 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5837 connect_info->data = helper;
5839 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5840 TNY_FOLDER_STORE (src_folder),
5843 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5844 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
5845 src_account, helper);
5846 g_object_unref (src_account);
5851 * UI handler for the "Move to" action when invoked from the
5852 * ModestMsgViewWindow
5855 modest_ui_actions_on_window_move_to (GtkAction *action,
5857 TnyFolderStore *dst_folder,
5860 TnyFolder *src_folder = NULL;
5862 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5865 TnyHeader *header = NULL;
5868 iter = tny_list_create_iterator (headers);
5869 header = (TnyHeader *) tny_iterator_get_current (iter);
5870 src_folder = tny_header_get_folder (header);
5872 /* Transfer the messages */
5873 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
5875 TNY_FOLDER (dst_folder));
5878 g_object_unref (header);
5879 g_object_unref (iter);
5880 g_object_unref (src_folder);
5885 modest_ui_actions_on_move_to (GtkAction *action,
5888 modest_ui_actions_on_edit_mode_move_to (win);
5892 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
5894 GtkWidget *dialog = NULL;
5895 MoveToInfo *helper = NULL;
5896 TnyList *list_to_move;
5898 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
5900 #ifndef MODEST_TOOLKIT_HILDON2
5901 /* Get the main window if exists */
5902 ModestMainWindow *main_window;
5903 if (MODEST_IS_MAIN_WINDOW (win))
5904 main_window = MODEST_MAIN_WINDOW (win);
5907 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5908 FALSE)); /* don't create */
5911 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
5916 if (tny_list_get_length (list_to_move) < 1) {
5917 g_object_unref (list_to_move);
5921 /* Create and run the dialog */
5922 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
5923 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
5924 GTK_WINDOW (dialog),
5928 helper = g_slice_new0 (MoveToInfo);
5929 helper->list = list_to_move;
5932 /* Listen to response signal */
5933 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
5935 /* Show the dialog */
5936 gtk_widget_show (dialog);
5942 * Calls #HeadersFunc for each header already selected in the main
5943 * window or the message currently being shown in the msg view window
5946 do_headers_action (ModestWindow *win,
5950 TnyList *headers_list = NULL;
5951 TnyIterator *iter = NULL;
5952 TnyHeader *header = NULL;
5953 TnyFolder *folder = NULL;
5956 headers_list = get_selected_headers (win);
5960 /* Get the folder */
5961 iter = tny_list_create_iterator (headers_list);
5962 header = TNY_HEADER (tny_iterator_get_current (iter));
5964 folder = tny_header_get_folder (header);
5965 g_object_unref (header);
5968 /* Call the function for each header */
5969 while (!tny_iterator_is_done (iter)) {
5970 header = TNY_HEADER (tny_iterator_get_current (iter));
5971 func (header, win, user_data);
5972 g_object_unref (header);
5973 tny_iterator_next (iter);
5976 /* Trick: do a poke status in order to speed up the signaling
5979 tny_folder_poke_status (folder);
5980 g_object_unref (folder);
5984 g_object_unref (iter);
5985 g_object_unref (headers_list);
5989 modest_ui_actions_view_attachment (GtkAction *action,
5990 ModestWindow *window)
5992 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5993 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5995 /* not supported window for this action */
5996 g_return_if_reached ();
6001 modest_ui_actions_save_attachments (GtkAction *action,
6002 ModestWindow *window)
6004 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6006 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
6009 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
6011 /* not supported window for this action */
6012 g_return_if_reached ();
6017 modest_ui_actions_remove_attachments (GtkAction *action,
6018 ModestWindow *window)
6020 if (MODEST_IS_MAIN_WINDOW (window)) {
6021 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
6022 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6023 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
6025 /* not supported window for this action */
6026 g_return_if_reached ();
6031 modest_ui_actions_on_settings (GtkAction *action,
6036 dialog = modest_platform_get_global_settings_dialog ();
6037 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
6038 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
6039 gtk_widget_show_all (dialog);
6041 gtk_dialog_run (GTK_DIALOG (dialog));
6043 gtk_widget_destroy (dialog);
6047 modest_ui_actions_on_help (GtkAction *action,
6050 /* Help app is not available at all in fremantle */
6051 #ifndef MODEST_TOOLKIT_HILDON2
6052 const gchar *help_id;
6054 g_return_if_fail (win && GTK_IS_WINDOW(win));
6056 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
6059 modest_platform_show_help (GTK_WINDOW (win), help_id);
6064 modest_ui_actions_on_csm_help (GtkAction *action,
6067 /* Help app is not available at all in fremantle */
6068 #ifndef MODEST_TOOLKIT_HILDON2
6070 const gchar* help_id = NULL;
6071 GtkWidget *folder_view;
6072 TnyFolderStore *folder_store;
6074 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
6076 /* Get selected folder */
6077 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
6078 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6079 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6081 /* Switch help_id */
6082 if (folder_store && TNY_IS_FOLDER (folder_store))
6083 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
6086 g_object_unref (folder_store);
6089 modest_platform_show_help (GTK_WINDOW (win), help_id);
6091 modest_ui_actions_on_help (action, win);
6096 retrieve_contents_cb (ModestMailOperation *mail_op,
6103 /* We only need this callback to show an error in case of
6104 memory low condition */
6105 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
6106 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
6111 retrieve_msg_contents_performer (gboolean canceled,
6113 GtkWindow *parent_window,
6114 TnyAccount *account,
6117 ModestMailOperation *mail_op;
6118 TnyList *headers = TNY_LIST (user_data);
6120 if (err || canceled) {
6121 check_memory_full_error ((GtkWidget *) parent_window, err);
6125 /* Create mail operation */
6126 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
6127 modest_ui_actions_disk_operations_error_handler,
6129 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
6130 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
6133 g_object_unref (mail_op);
6135 g_object_unref (headers);
6136 g_object_unref (account);
6140 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
6141 ModestWindow *window)
6143 TnyList *headers = NULL;
6144 TnyAccount *account = NULL;
6145 TnyIterator *iter = NULL;
6146 TnyHeader *header = NULL;
6147 TnyFolder *folder = NULL;
6150 headers = get_selected_headers (window);
6154 /* Pick the account */
6155 iter = tny_list_create_iterator (headers);
6156 header = TNY_HEADER (tny_iterator_get_current (iter));
6157 folder = tny_header_get_folder (header);
6158 account = tny_folder_get_account (folder);
6159 g_object_unref (folder);
6160 g_object_unref (header);
6161 g_object_unref (iter);
6163 /* Connect and perform the message retrieval */
6164 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6165 g_object_ref (account),
6166 retrieve_msg_contents_performer,
6167 g_object_ref (headers));
6170 g_object_unref (account);
6171 g_object_unref (headers);
6175 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6177 g_return_if_fail (MODEST_IS_WINDOW (window));
6180 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6184 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6186 g_return_if_fail (MODEST_IS_WINDOW (window));
6189 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6193 modest_ui_actions_on_email_menu_activated (GtkAction *action,
6194 ModestWindow *window)
6196 g_return_if_fail (MODEST_IS_WINDOW (window));
6199 modest_ui_actions_check_menu_dimming_rules (window);
6203 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
6204 ModestWindow *window)
6206 g_return_if_fail (MODEST_IS_WINDOW (window));
6209 modest_ui_actions_check_menu_dimming_rules (window);
6213 modest_ui_actions_on_view_menu_activated (GtkAction *action,
6214 ModestWindow *window)
6216 g_return_if_fail (MODEST_IS_WINDOW (window));
6219 modest_ui_actions_check_menu_dimming_rules (window);
6223 modest_ui_actions_on_format_menu_activated (GtkAction *action,
6224 ModestWindow *window)
6226 g_return_if_fail (MODEST_IS_WINDOW (window));
6229 modest_ui_actions_check_menu_dimming_rules (window);
6233 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
6234 ModestWindow *window)
6236 g_return_if_fail (MODEST_IS_WINDOW (window));
6239 modest_ui_actions_check_menu_dimming_rules (window);
6243 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
6244 ModestWindow *window)
6246 g_return_if_fail (MODEST_IS_WINDOW (window));
6249 modest_ui_actions_check_menu_dimming_rules (window);
6253 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
6254 ModestWindow *window)
6256 g_return_if_fail (MODEST_IS_WINDOW (window));
6259 modest_ui_actions_check_menu_dimming_rules (window);
6263 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
6264 ModestWindow *window)
6266 g_return_if_fail (MODEST_IS_WINDOW (window));
6269 modest_ui_actions_check_menu_dimming_rules (window);
6273 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
6274 ModestWindow *window)
6276 g_return_if_fail (MODEST_IS_WINDOW (window));
6279 modest_ui_actions_check_menu_dimming_rules (window);
6283 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6285 g_return_if_fail (MODEST_IS_WINDOW (window));
6287 /* we check for low-mem; in that case, show a warning, and don't allow
6290 if (modest_platform_check_memory_low (window, TRUE))
6293 modest_platform_show_search_messages (GTK_WINDOW (window));
6297 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6299 g_return_if_fail (MODEST_IS_WINDOW (win));
6302 /* we check for low-mem; in that case, show a warning, and don't allow
6303 * for the addressbook
6305 if (modest_platform_check_memory_low (win, TRUE))
6309 modest_platform_show_addressbook (GTK_WINDOW (win));
6314 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6315 ModestWindow *window)
6318 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6320 if (GTK_IS_TOGGLE_ACTION (action))
6321 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6325 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window),
6330 on_send_receive_finished (ModestMailOperation *mail_op,
6333 GtkWidget *header_view, *folder_view;
6334 TnyFolderStore *folder_store;
6335 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6337 /* Set send/receive operation finished */
6338 modest_main_window_notify_send_receive_completed (main_win);
6340 /* Don't refresh the current folder if there were any errors */
6341 if (modest_mail_operation_get_status (mail_op) !=
6342 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6345 /* Refresh the current folder if we're viewing a window. We do
6346 this because the user won't be able to see the new mails in
6347 the selected folder after a Send&Receive because it only
6348 performs a poke_status, i.e, only the number of read/unread
6349 messages is updated, but the new headers are not
6351 folder_view = modest_main_window_get_child_widget (main_win,
6352 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6356 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6358 /* Do not need to refresh INBOX again because the
6359 update_account does it always automatically */
6360 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6361 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6362 ModestMailOperation *refresh_op;
6364 header_view = modest_main_window_get_child_widget (main_win,
6365 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6367 /* We do not need to set the contents style
6368 because it hasn't changed. We also do not
6369 need to save the widget status. Just force
6371 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6372 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6373 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6374 folder_refreshed_cb, main_win);
6375 g_object_unref (refresh_op);
6379 g_object_unref (folder_store);
6384 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6390 const gchar* server_name = NULL;
6391 TnyTransportAccount *transport;
6392 gchar *message = NULL;
6393 ModestProtocol *protocol;
6395 /* Don't show anything if the user cancelled something or the
6396 * send receive request is not interactive. Authentication
6397 * errors are managed by the account store so no need to show
6398 * a dialog here again */
6399 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6400 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6401 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6405 /* Get the server name. Note that we could be using a
6406 connection specific transport account */
6407 transport = (TnyTransportAccount *)
6408 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
6410 ModestTnyAccountStore *acc_store;
6411 const gchar *acc_name;
6412 TnyTransportAccount *conn_specific;
6414 acc_store = modest_runtime_get_account_store();
6415 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
6416 conn_specific = (TnyTransportAccount *)
6417 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
6418 if (conn_specific) {
6419 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
6420 g_object_unref (conn_specific);
6422 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
6424 g_object_unref (transport);
6428 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
6429 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
6430 tny_account_get_proto (TNY_ACCOUNT (transport)));
6432 g_warning ("%s: Account with no proto", __FUNCTION__);
6436 /* Show the appropriate message text for the GError: */
6437 switch (err->code) {
6438 case TNY_SERVICE_ERROR_CONNECT:
6439 message = modest_protocol_get_translation (protocol,
6440 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
6443 case TNY_SERVICE_ERROR_SEND:
6444 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6446 case TNY_SERVICE_ERROR_UNAVAILABLE:
6447 message = modest_protocol_get_translation (protocol,
6448 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
6452 g_warning ("%s: unexpected ERROR %d",
6453 __FUNCTION__, err->code);
6454 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6458 modest_platform_run_information_dialog (NULL, message, FALSE);
6463 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6468 ModestWindow *top_window = NULL;
6469 ModestWindowMgr *mgr = NULL;
6470 GtkWidget *header_view = NULL;
6471 TnyFolder *selected_folder = NULL;
6472 TnyFolderType folder_type;
6474 mgr = modest_runtime_get_window_mgr ();
6475 top_window = modest_window_mgr_get_current_top (mgr);
6480 #ifndef MODEST_TOOLKIT_HILDON2
6481 if (MODEST_IS_MAIN_WINDOW (top_window)) {
6482 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (top_window),
6483 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6486 if (MODEST_IS_HEADER_WINDOW (top_window)) {
6487 header_view = (GtkWidget *)
6488 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
6492 /* Get selected folder */
6494 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
6495 if (!selected_folder)
6498 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6499 #if GTK_CHECK_VERSION(2, 8, 0)
6500 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
6501 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6502 GtkTreeViewColumn *tree_column;
6504 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6505 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6507 gtk_tree_view_column_queue_resize (tree_column);
6509 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
6510 gtk_widget_queue_draw (header_view);
6513 #ifndef MODEST_TOOLKIT_HILDON2
6514 /* Rerun dimming rules, because the message could become deletable for example */
6515 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6516 MODEST_DIMMING_RULES_TOOLBAR);
6517 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6518 MODEST_DIMMING_RULES_MENU);
6522 g_object_unref (selected_folder);
6526 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6527 TnyAccount *account)
6529 ModestProtocolType protocol_type;
6530 ModestProtocol *protocol;
6531 gchar *error_note = NULL;
6533 protocol_type = modest_tny_account_get_protocol_type (account);
6534 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6537 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6538 if (error_note == NULL) {
6539 g_warning ("%s: This should not be reached", __FUNCTION__);
6541 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6542 g_free (error_note);
6547 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6551 TnyFolderStore *folder = NULL;
6552 TnyAccount *account = NULL;
6553 ModestProtocolType proto;
6554 ModestProtocol *protocol;
6555 TnyHeader *header = NULL;
6557 if (MODEST_IS_MAIN_WINDOW (win)) {
6558 GtkWidget *header_view;
6559 TnyList* headers = NULL;
6561 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6562 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6563 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6564 if (!headers || tny_list_get_length (headers) == 0) {
6566 g_object_unref (headers);
6569 iter = tny_list_create_iterator (headers);
6570 header = TNY_HEADER (tny_iterator_get_current (iter));
6571 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6572 g_object_unref (iter);
6573 g_object_unref (headers);
6574 #ifdef MODEST_TOOLKIT_HILDON2
6575 } else if (MODEST_IS_HEADER_WINDOW (win)) {
6576 GtkWidget *header_view;
6577 TnyList* headers = NULL;
6579 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
6580 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6581 if (!headers || tny_list_get_length (headers) == 0) {
6583 g_object_unref (headers);
6586 iter = tny_list_create_iterator (headers);
6587 header = TNY_HEADER (tny_iterator_get_current (iter));
6589 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6591 g_warning ("List should contain headers");
6593 g_object_unref (iter);
6594 g_object_unref (headers);
6596 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6597 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6598 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6601 if (!header || !folder)
6604 /* Get the account type */
6605 account = tny_folder_get_account (TNY_FOLDER (folder));
6606 proto = modest_tny_account_get_protocol_type (account);
6607 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6610 subject = tny_header_dup_subject (header);
6611 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6615 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6621 g_object_unref (account);
6623 g_object_unref (folder);
6625 g_object_unref (header);
6631 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6632 const gchar *account_name,
6633 const gchar *account_title)
6635 ModestAccountMgr *account_mgr;
6638 ModestProtocol *protocol;
6639 gboolean removed = FALSE;
6641 g_return_val_if_fail (account_name, FALSE);
6642 g_return_val_if_fail (account_title, FALSE);
6644 account_mgr = modest_runtime_get_account_mgr();
6646 /* The warning text depends on the account type: */
6647 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6648 modest_account_mgr_get_store_protocol (account_mgr,
6650 txt = modest_protocol_get_translation (protocol,
6651 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6654 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6656 response = modest_platform_run_confirmation_dialog (parent_window, txt);
6660 if (response == GTK_RESPONSE_OK) {
6661 /* Remove account. If it succeeds then it also removes
6662 the account from the ModestAccountView: */
6663 gboolean is_default = FALSE;
6664 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6665 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6667 g_free (default_account_name);
6669 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6671 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);