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;
112 GtkWidget *parent_window;
114 } ReplyForwardHelper;
116 typedef struct _MoveToHelper {
117 GtkTreeRowReference *reference;
121 typedef struct _PasteAsAttachmentHelper {
122 ModestMsgEditWindow *window;
124 } PasteAsAttachmentHelper;
132 * The do_headers_action uses this kind of functions to perform some
133 * action to each member of a list of headers
135 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
137 static void do_headers_action (ModestWindow *win,
141 static void open_msg_cb (ModestMailOperation *mail_op,
148 static void reply_forward_cb (ModestMailOperation *mail_op,
155 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
157 static void folder_refreshed_cb (ModestMailOperation *mail_op,
161 static void on_send_receive_finished (ModestMailOperation *mail_op,
164 static gint header_list_count_uncached_msgs (TnyList *header_list);
166 static gboolean connect_to_get_msg (ModestWindow *win,
167 gint num_of_uncached_msgs,
168 TnyAccount *account);
170 static gboolean remote_folder_has_leave_on_server (TnyFolderStore *folder);
172 static void do_create_folder (GtkWindow *window,
173 TnyFolderStore *parent_folder,
174 const gchar *suggested_name);
176 static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store);
178 static void modest_ui_actions_on_main_window_move_to (GtkAction *action,
179 GtkWidget *folder_view,
180 TnyFolderStore *dst_folder,
181 ModestMainWindow *win);
182 #ifdef MODEST_TOOLKIT_HILDON2
183 static void modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
184 TnyFolderStore *dst_folder,
189 static void modest_ui_actions_on_window_move_to (GtkAction *action,
190 TnyList *list_to_move,
191 TnyFolderStore *dst_folder,
195 * This function checks whether a TnyFolderStore is a pop account
198 remote_folder_has_leave_on_server (TnyFolderStore *folder)
203 g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
205 account = get_account_from_folder_store (folder);
206 result = (modest_protocol_registry_protocol_type_has_leave_on_server (modest_runtime_get_protocol_registry (),
207 modest_tny_account_get_protocol_type (account)));
208 g_object_unref (account);
213 /* FIXME: this should be merged with the similar code in modest-account-view-window */
214 /* Show the account creation wizard dialog.
215 * returns: TRUE if an account was created. FALSE if the user cancelled.
218 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
220 gboolean result = FALSE;
222 gint dialog_response;
224 /* there is no such wizard yet */
225 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
226 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (wizard), (GtkWindow *) win);
228 #ifndef MODEST_TOOLKIT_HILDON2
229 /* always present a main window in the background
230 * we do it here, so we cannot end up with two wizards (as this
231 * function might be called in modest_window_mgr_get_main_window as well */
233 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
234 TRUE); /* create if not existent */
238 ModestWindowMgr *mgr;
240 mgr = modest_runtime_get_window_mgr ();
242 window_list = modest_window_mgr_get_window_list (mgr);
243 if (window_list == NULL) {
244 ModestWindow *old_win;
245 win = MODEST_WINDOW (modest_accounts_window_new ());
246 if (modest_window_mgr_register_window (mgr, win, NULL)) {
247 gtk_widget_show_all (GTK_WIDGET (win));
249 gtk_widget_destroy (GTK_WIDGET (win));
254 win = MODEST_WINDOW (modest_folder_window_new (NULL));
255 if (modest_window_mgr_register_window (mgr, win, NULL)) {
256 gtk_widget_show_all (GTK_WIDGET (win));
258 gtk_widget_destroy (GTK_WIDGET (win));
262 g_list_free (window_list);
268 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
270 /* make sure the mainwindow is visible. We need to present the
271 wizard again to give it the focus back. show_all are needed
272 in order to get the widgets properly drawn (MainWindow main
273 paned won't be in its right position and the dialog will be
275 #ifndef MODEST_TOOLKIT_HILDON2
276 gtk_widget_show_all (GTK_WIDGET (win));
277 gtk_widget_show_all (GTK_WIDGET (wizard));
278 gtk_window_present (GTK_WINDOW (win));
279 gtk_window_present (GTK_WINDOW (wizard));
282 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
283 gtk_widget_destroy (GTK_WIDGET (wizard));
284 if (gtk_events_pending ())
285 gtk_main_iteration ();
287 if (dialog_response == GTK_RESPONSE_CANCEL) {
290 /* Check whether an account was created: */
291 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
298 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
301 const gchar *authors[] = {
302 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
305 about = gtk_about_dialog_new ();
306 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
307 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
308 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
309 _("Copyright (c) 2006, Nokia Corporation\n"
310 "All rights reserved."));
311 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
312 _("a modest e-mail client\n\n"
313 "design and implementation: Dirk-Jan C. Binnema\n"
314 "contributions from the fine people at KC and Ig\n"
315 "uses the tinymail email framework written by Philip van Hoof"));
316 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
317 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
318 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
319 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
321 gtk_dialog_run (GTK_DIALOG (about));
322 gtk_widget_destroy(about);
326 * Gets the list of currently selected messages. If the win is the
327 * main window, then it returns a newly allocated list of the headers
328 * selected in the header view. If win is the msg view window, then
329 * the value returned is a list with just a single header.
331 * The caller of this funcion must free the list.
334 get_selected_headers (ModestWindow *win)
336 if (MODEST_IS_MAIN_WINDOW(win)) {
337 GtkWidget *header_view;
339 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
340 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
341 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
343 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
344 /* for MsgViewWindows, we simply return a list with one element */
346 TnyList *list = NULL;
348 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
349 if (header != NULL) {
350 list = tny_simple_list_new ();
351 tny_list_prepend (list, G_OBJECT(header));
352 g_object_unref (G_OBJECT(header));
357 #ifdef MODEST_TOOLKIT_HILDON2
358 } else if (MODEST_IS_HEADER_WINDOW (win)) {
359 GtkWidget *header_view;
361 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
362 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
368 static GtkTreeRowReference *
369 get_next_after_selected_headers (ModestHeaderView *header_view)
371 GtkTreeSelection *sel;
372 GList *selected_rows, *node;
374 GtkTreeRowReference *result;
377 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
378 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
379 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
381 if (selected_rows == NULL)
384 node = g_list_last (selected_rows);
385 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
386 gtk_tree_path_next (path);
388 result = gtk_tree_row_reference_new (model, path);
390 gtk_tree_path_free (path);
391 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
392 g_list_free (selected_rows);
398 headers_action_mark_as_read (TnyHeader *header,
402 TnyHeaderFlags flags;
404 g_return_if_fail (TNY_IS_HEADER(header));
406 flags = tny_header_get_flags (header);
407 if (flags & TNY_HEADER_FLAG_SEEN) return;
408 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
412 headers_action_mark_as_unread (TnyHeader *header,
416 TnyHeaderFlags flags;
418 g_return_if_fail (TNY_IS_HEADER(header));
420 flags = tny_header_get_flags (header);
421 if (flags & TNY_HEADER_FLAG_SEEN) {
422 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
426 /** After deleing a message that is currently visible in a window,
427 * show the next message from the list, or close the window if there are no more messages.
430 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
432 /* Close msg view window or select next */
433 if (!modest_msg_view_window_select_next_message (win) &&
434 !modest_msg_view_window_select_previous_message (win)) {
436 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
442 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
444 modest_ui_actions_on_edit_mode_delete_message (win);
448 modest_ui_actions_on_edit_mode_delete_message (ModestWindow *win)
450 TnyList *header_list = NULL;
451 TnyIterator *iter = NULL;
452 TnyHeader *header = NULL;
453 gchar *message = NULL;
456 ModestWindowMgr *mgr;
457 GtkWidget *header_view = NULL;
458 gboolean retval = TRUE;
460 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
462 /* Check first if the header view has the focus */
463 if (MODEST_IS_MAIN_WINDOW (win)) {
465 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
466 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
467 if (!gtk_widget_is_focus (header_view))
471 /* Get the headers, either from the header view (if win is the main window),
472 * or from the message view window: */
473 header_list = get_selected_headers (win);
474 if (!header_list) return FALSE;
476 /* Check if any of the headers are already opened, or in the process of being opened */
477 if (MODEST_IS_MAIN_WINDOW (win)) {
478 gint opened_headers = 0;
480 iter = tny_list_create_iterator (header_list);
481 mgr = modest_runtime_get_window_mgr ();
482 while (!tny_iterator_is_done (iter)) {
483 header = TNY_HEADER (tny_iterator_get_current (iter));
485 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
487 g_object_unref (header);
489 tny_iterator_next (iter);
491 g_object_unref (iter);
493 if (opened_headers > 0) {
496 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
499 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg, FALSE);
502 g_object_unref (header_list);
508 if (tny_list_get_length(header_list) == 1) {
509 iter = tny_list_create_iterator (header_list);
510 header = TNY_HEADER (tny_iterator_get_current (iter));
513 subject = tny_header_dup_subject (header);
515 subject = g_strdup (_("mail_va_no_subject"));
516 desc = g_strdup_printf ("%s", subject);
518 g_object_unref (header);
521 g_object_unref (iter);
523 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
524 tny_list_get_length(header_list)), desc);
526 /* Confirmation dialog */
527 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
531 if (response == GTK_RESPONSE_OK) {
532 ModestWindow *main_window = NULL;
533 ModestWindowMgr *mgr = NULL;
534 GtkTreeModel *model = NULL;
535 GtkTreeSelection *sel = NULL;
536 GList *sel_list = NULL, *tmp = NULL;
537 GtkTreeRowReference *next_row_reference = NULL;
538 GtkTreeRowReference *prev_row_reference = NULL;
539 GtkTreePath *next_path = NULL;
540 GtkTreePath *prev_path = NULL;
541 ModestMailOperation *mail_op = NULL;
543 /* Find last selected row */
544 if (MODEST_IS_MAIN_WINDOW (win)) {
545 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
546 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
547 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
548 for (tmp=sel_list; tmp; tmp=tmp->next) {
549 if (tmp->next == NULL) {
550 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
551 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
553 gtk_tree_path_prev (prev_path);
554 gtk_tree_path_next (next_path);
556 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
557 next_row_reference = gtk_tree_row_reference_new (model, next_path);
562 /* Disable window dimming management */
563 modest_window_disable_dimming (MODEST_WINDOW(win));
565 /* Remove each header. If it's a view window header_view == NULL */
566 mail_op = modest_mail_operation_new ((GObject *) win);
567 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
569 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
570 g_object_unref (mail_op);
572 /* Enable window dimming management */
574 gtk_tree_selection_unselect_all (sel);
576 modest_window_enable_dimming (MODEST_WINDOW(win));
578 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
579 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
581 /* Get main window */
582 mgr = modest_runtime_get_window_mgr ();
583 main_window = modest_window_mgr_get_main_window (mgr, FALSE); /* don't create */
584 } else if (MODEST_IS_MAIN_WINDOW (win)) {
585 /* Move cursor to next row */
588 /* Select next or previous row */
589 if (gtk_tree_row_reference_valid (next_row_reference)) {
590 gtk_tree_selection_select_path (sel, next_path);
592 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
593 gtk_tree_selection_select_path (sel, prev_path);
597 if (gtk_tree_row_reference_valid (next_row_reference))
598 gtk_tree_row_reference_free (next_row_reference);
599 if (next_path != NULL)
600 gtk_tree_path_free (next_path);
601 if (gtk_tree_row_reference_valid (prev_row_reference))
602 gtk_tree_row_reference_free (prev_row_reference);
603 if (prev_path != NULL)
604 gtk_tree_path_free (prev_path);
607 /* Update toolbar dimming state */
609 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
610 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
614 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
615 g_list_free (sel_list);
624 g_object_unref (header_list);
632 /* delete either message or folder, based on where we are */
634 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
636 g_return_if_fail (MODEST_IS_WINDOW(win));
638 /* Check first if the header view has the focus */
639 if (MODEST_IS_MAIN_WINDOW (win)) {
641 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
642 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
643 if (gtk_widget_is_focus (w)) {
644 modest_ui_actions_on_delete_folder (action, MODEST_WINDOW(win));
648 modest_ui_actions_on_delete_message (action, win);
652 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
654 ModestWindowMgr *mgr = NULL;
656 #ifdef MODEST_PLATFORM_MAEMO
657 modest_osso_save_state();
658 #endif /* MODEST_PLATFORM_MAEMO */
660 g_debug ("closing down, clearing %d item(s) from operation queue",
661 modest_mail_operation_queue_num_elements
662 (modest_runtime_get_mail_operation_queue()));
664 /* cancel all outstanding operations */
665 modest_mail_operation_queue_cancel_all
666 (modest_runtime_get_mail_operation_queue());
668 g_debug ("queue has been cleared");
671 /* Check if there are opened editing windows */
672 mgr = modest_runtime_get_window_mgr ();
673 modest_window_mgr_close_all_windows (mgr);
675 /* note: when modest-tny-account-store is finalized,
676 it will automatically set all network connections
679 /* gtk_main_quit (); */
683 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
687 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
689 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
690 /* gtk_widget_destroy (GTK_WIDGET (win)); */
691 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
692 /* gboolean ret_value; */
693 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
694 /* } else if (MODEST_IS_WINDOW (win)) { */
695 /* gtk_widget_destroy (GTK_WIDGET (win)); */
697 /* g_return_if_reached (); */
702 modest_ui_actions_add_to_contacts (GtkAction *action, ModestWindow *win)
704 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
706 modest_msg_view_window_add_to_contacts (MODEST_MSG_VIEW_WINDOW (win));
710 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
712 GtkClipboard *clipboard = NULL;
713 gchar *selection = NULL;
715 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
716 selection = gtk_clipboard_wait_for_text (clipboard);
718 /* Question: why is the clipboard being used here?
719 * It doesn't really make a lot of sense. */
723 modest_address_book_add_address (selection);
729 modest_ui_actions_on_new_account (GtkAction *action,
730 ModestWindow *window)
732 if (!modest_ui_actions_run_account_setup_wizard (window)) {
733 g_debug ("%s: wizard was already running", __FUNCTION__);
738 modest_ui_actions_on_accounts (GtkAction *action,
741 /* This is currently only implemented for Maemo */
742 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
743 if (!modest_ui_actions_run_account_setup_wizard (win))
744 g_debug ("%s: wizard was already running", __FUNCTION__);
748 /* Show the list of accounts */
749 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
751 /* The accounts dialog must be modal */
752 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
753 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
758 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
760 /* This is currently only implemented for Maemo,
761 * because it requires an API (libconic) to detect different connection
764 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
766 /* Create the window if necessary: */
767 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
768 modest_connection_specific_smtp_window_fill_with_connections (
769 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
770 modest_runtime_get_account_mgr());
772 /* Show the window: */
773 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
774 GTK_WINDOW (specific_window), (GtkWindow *) win);
775 gtk_widget_show (specific_window);
776 #endif /* !MODEST_TOOLKIT_GTK */
780 modest_ui_actions_compose_msg(ModestWindow *win,
783 const gchar *bcc_str,
784 const gchar *subject_str,
785 const gchar *body_str,
787 gboolean set_as_modified)
789 gchar *account_name = NULL;
791 TnyAccount *account = NULL;
792 TnyFolder *folder = NULL;
793 gchar *from_str = NULL, *signature = NULL, *body = NULL;
794 gboolean use_signature = FALSE;
795 ModestWindow *msg_win = NULL;
796 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
797 ModestTnyAccountStore *store = modest_runtime_get_account_store();
798 GnomeVFSFileSize total_size, allowed_size;
800 /* we check for low-mem */
801 if (modest_platform_check_memory_low (win, TRUE))
804 #ifdef MODEST_TOOLKIT_HILDON2
805 account_name = g_strdup (modest_window_get_active_account(win));
808 account_name = modest_account_mgr_get_default_account(mgr);
811 g_printerr ("modest: no account found\n");
814 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
816 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
819 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
821 g_printerr ("modest: failed to find Drafts folder\n");
824 from_str = modest_account_mgr_get_from_string (mgr, account_name);
826 g_printerr ("modest: failed get from string for '%s'\n", account_name);
830 signature = modest_account_mgr_get_signature (mgr, account_name, &use_signature);
831 if (body_str != NULL) {
832 body = use_signature ? g_strconcat(body_str, "\n--\n", signature, NULL) : g_strdup(body_str);
834 body = use_signature ? g_strconcat("\n--\n", signature, NULL) : g_strdup("");
837 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, NULL, NULL, body, NULL, NULL, NULL);
839 g_printerr ("modest: failed to create new msg\n");
843 /* Create and register edit window */
844 /* This is destroyed by TODO. */
846 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
847 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
849 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, win)) {
850 gtk_widget_destroy (GTK_WIDGET (msg_win));
853 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
854 gtk_widget_show_all (GTK_WIDGET (msg_win));
856 while (attachments) {
858 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
859 attachments->data, allowed_size);
861 if (total_size > allowed_size) {
862 g_warning ("%s: total size: %u",
863 __FUNCTION__, (unsigned int)total_size);
866 allowed_size -= total_size;
868 attachments = g_slist_next(attachments);
875 g_free (account_name);
877 g_object_unref (G_OBJECT(account));
879 g_object_unref (G_OBJECT(folder));
881 g_object_unref (G_OBJECT(msg));
885 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
887 /* if there are no accounts yet, just show the wizard */
888 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
889 if (!modest_ui_actions_run_account_setup_wizard (win))
892 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
897 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
901 ModestMailOperationStatus status;
903 /* If there is no message or the operation was not successful */
904 status = modest_mail_operation_get_status (mail_op);
905 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
908 /* If it's a memory low issue, then show a banner */
909 error = modest_mail_operation_get_error (mail_op);
910 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
911 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
912 GObject *source = modest_mail_operation_get_source (mail_op);
913 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
914 _KR("memr_ib_operation_disabled"),
916 g_object_unref (source);
919 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
920 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
921 gchar *subject, *msg, *format = NULL;
923 subject = tny_header_dup_subject (header);
925 subject = g_strdup (_("mail_va_no_subject"));
927 account = modest_mail_operation_get_account (mail_op);
929 ModestProtocol *protocol;
930 ModestProtocolType proto;
931 proto = modest_tny_account_get_protocol_type (account);
932 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), proto);
934 format = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
935 g_object_unref (account);
939 format = g_strdup (_("emev_ni_ui_imap_message_not_available_in_server"));
941 msg = g_strdup_printf (format, subject);
942 modest_platform_run_information_dialog (NULL, msg, FALSE);
948 /* Remove the header from the preregistered uids */
949 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
967 OpenMsgBannerInfo *banner_info;
968 GtkTreeRowReference *rowref;
972 open_msg_banner_idle (gpointer userdata)
974 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
976 gdk_threads_enter ();
977 banner_info->idle_handler = 0;
978 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
979 if (banner_info->banner)
980 g_object_ref (banner_info->banner);
982 gdk_threads_leave ();
988 get_header_view_from_window (ModestWindow *window)
990 GtkWidget *header_view;
992 if (MODEST_IS_MAIN_WINDOW (window)) {
993 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
994 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
995 #ifdef MODEST_TOOLKIT_HILDON2
996 } else if (MODEST_IS_HEADER_WINDOW (window)){
997 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
1007 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
1010 gchar *account = NULL;
1011 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
1016 folder = tny_header_get_folder (header);
1017 /* Gets folder type (OUTBOX headers will be opened in edit window */
1018 if (modest_tny_folder_is_local_folder (folder)) {
1019 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1020 if (folder_type == TNY_FOLDER_TYPE_INVALID)
1021 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1024 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
1025 TnyTransportAccount *traccount = NULL;
1026 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
1027 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
1029 ModestTnySendQueue *send_queue = NULL;
1030 ModestTnySendQueueStatus status;
1032 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
1033 TNY_ACCOUNT(traccount)));
1034 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
1035 if (TNY_IS_SEND_QUEUE (send_queue)) {
1036 msg_id = modest_tny_send_queue_get_msg_id (header);
1037 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
1039 /* Only open messages in outbox with the editor if they are in Failed state */
1040 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
1043 #ifdef MODEST_TOOLKIT_HILDON2
1045 /* In Fremantle we can not
1046 open any message from
1047 outbox which is not in
1053 g_object_unref(traccount);
1055 g_warning("Cannot get transport account for message in outbox!!");
1057 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
1058 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
1062 TnyAccount *acc = tny_folder_get_account (folder);
1065 g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (acc));
1066 g_object_unref (acc);
1070 g_object_unref (folder);
1076 open_msg_cb (ModestMailOperation *mail_op,
1083 ModestWindowMgr *mgr = NULL;
1084 ModestWindow *parent_win = NULL;
1085 ModestWindow *win = NULL;
1086 gchar *account = NULL;
1087 gboolean open_in_editor = FALSE;
1089 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1091 /* Do nothing if there was any problem with the mail
1092 operation. The error will be shown by the error_handler of
1093 the mail operation */
1094 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1097 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1099 /* Mark header as read */
1100 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1102 account = get_info_from_header (header, &open_in_editor, &can_open);
1106 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1108 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1110 if (open_in_editor) {
1111 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1112 gchar *from_header = NULL, *acc_name;
1114 from_header = tny_header_dup_from (header);
1116 /* we cannot edit without a valid account... */
1117 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1118 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1119 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1121 g_free (from_header);
1126 acc_name = modest_utils_get_account_name_from_recipient (from_header);
1127 g_free (from_header);
1133 win = modest_msg_edit_window_new (msg, account, TRUE);
1135 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1137 if (helper->rowref && helper->model) {
1138 win = modest_msg_view_window_new_with_header_model (msg, account, (const gchar*) uid,
1139 helper->model, helper->rowref);
1141 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
1146 /* Register and show new window */
1148 mgr = modest_runtime_get_window_mgr ();
1149 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1150 gtk_widget_destroy (GTK_WIDGET (win));
1153 gtk_widget_show_all (GTK_WIDGET(win));
1156 /* Update toolbar dimming state */
1157 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1158 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1164 g_object_unref (parent_win);
1168 is_memory_full_error (GError *error, ModestMailOperation *mail_op)
1170 gboolean enough_free_space = TRUE;
1171 GnomeVFSURI *cache_dir_uri;
1172 const gchar *cache_dir = NULL;
1173 GnomeVFSFileSize free_space;
1174 TnyAccountStore *acc_store;
1176 acc_store = TNY_ACCOUNT_STORE (modest_runtime_get_account_store ());
1178 /* Cache dir is different in case we're using an external storage (like MMC account) */
1180 TnyAccount *account = modest_mail_operation_get_account (mail_op);
1182 if (modest_tny_account_is_memory_card_account (account)) {
1183 cache_dir = g_getenv (MODEST_MMC1_VOLUMEPATH_ENV);
1185 g_object_unref (account);
1189 /* Get the default local cache dir */
1191 cache_dir = tny_account_store_get_cache_dir (acc_store);
1193 cache_dir_uri = gnome_vfs_uri_new (cache_dir);
1194 if (cache_dir_uri) {
1195 if (gnome_vfs_get_volume_free_space (cache_dir_uri, &free_space) == GNOME_VFS_OK) {
1196 if (free_space < MIN_FREE_SPACE)
1197 enough_free_space = FALSE;
1199 gnome_vfs_uri_unref (cache_dir_uri);
1202 if ((error->code == TNY_SYSTEM_ERROR_MEMORY ||
1203 /* When asking for a mail and no space left on device
1204 tinymail returns this error */
1205 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE ||
1206 /* When the folder summary could not be read or
1208 error->code == TNY_IO_ERROR_WRITE ||
1209 error->code == TNY_IO_ERROR_READ) &&
1210 !enough_free_space) {
1218 check_memory_full_error (GtkWidget *parent_window, GError *err)
1223 if (is_memory_full_error (err, NULL))
1224 modest_platform_information_banner (parent_window,
1225 NULL, _KR("cerm_device_memory_full"));
1226 else if (err->code == TNY_SYSTEM_ERROR_MEMORY)
1227 /* If the account was created in memory full
1228 conditions then tinymail won't be able to
1229 connect so it'll return this error code */
1230 modest_platform_information_banner (parent_window,
1231 NULL, _("emev_ui_imap_inbox_select_error"));
1239 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1242 const GError *error;
1243 GObject *win = NULL;
1244 ModestMailOperationStatus status;
1246 win = modest_mail_operation_get_source (mail_op);
1247 error = modest_mail_operation_get_error (mail_op);
1248 status = modest_mail_operation_get_status (mail_op);
1250 /* If the mail op has been cancelled then it's not an error:
1251 don't show any message */
1252 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1253 if (is_memory_full_error ((GError *) error, mail_op)) {
1254 modest_platform_information_banner ((GtkWidget *) win,
1255 NULL, _KR("cerm_device_memory_full"));
1256 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1257 modest_platform_information_banner ((GtkWidget *) win,
1258 NULL, _("emev_ui_imap_inbox_select_error"));
1259 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1260 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1261 modest_platform_information_banner ((GtkWidget *) win,
1262 NULL, _CS ("sfil_ni_unable_to_open_file_not_found"));
1263 } else if (user_data) {
1264 modest_platform_information_banner ((GtkWidget *) win,
1270 g_object_unref (win);
1274 * Returns the account a list of headers belongs to. It returns a
1275 * *new* reference so don't forget to unref it
1278 get_account_from_header_list (TnyList *headers)
1280 TnyAccount *account = NULL;
1282 if (tny_list_get_length (headers) > 0) {
1283 TnyIterator *iter = tny_list_create_iterator (headers);
1284 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1285 TnyFolder *folder = tny_header_get_folder (header);
1288 g_object_unref (header);
1290 while (!tny_iterator_is_done (iter)) {
1291 header = TNY_HEADER (tny_iterator_get_current (iter));
1292 folder = tny_header_get_folder (header);
1295 g_object_unref (header);
1297 tny_iterator_next (iter);
1302 account = tny_folder_get_account (folder);
1303 g_object_unref (folder);
1307 g_object_unref (header);
1309 g_object_unref (iter);
1315 get_account_from_header (TnyHeader *header)
1317 TnyAccount *account = NULL;
1320 folder = tny_header_get_folder (header);
1323 account = tny_folder_get_account (folder);
1324 g_object_unref (folder);
1330 open_msg_helper_destroyer (gpointer user_data)
1332 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1334 if (helper->banner_info) {
1335 g_free (helper->banner_info->message);
1336 if (helper->banner_info->idle_handler > 0) {
1337 g_source_remove (helper->banner_info->idle_handler);
1338 helper->banner_info->idle_handler = 0;
1340 if (helper->banner_info->banner != NULL) {
1341 gtk_widget_destroy (helper->banner_info->banner);
1342 g_object_unref (helper->banner_info->banner);
1343 helper->banner_info->banner = NULL;
1345 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1346 helper->banner_info = NULL;
1348 g_object_unref (helper->model);
1349 g_object_unref (helper->header);
1350 gtk_tree_row_reference_free (helper->rowref);
1351 g_slice_free (OpenMsgHelper, helper);
1355 open_msg_performer(gboolean canceled,
1357 GtkWindow *parent_window,
1358 TnyAccount *account,
1361 ModestMailOperation *mail_op = NULL;
1362 gchar *error_msg = NULL;
1363 ModestProtocolType proto;
1364 TnyConnectionStatus status;
1365 OpenMsgHelper *helper = NULL;
1366 ModestProtocol *protocol;
1367 ModestProtocolRegistry *protocol_registry;
1370 helper = (OpenMsgHelper *) user_data;
1372 status = tny_account_get_connection_status (account);
1373 if (err || canceled) {
1374 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1375 /* Free the helper */
1376 open_msg_helper_destroyer (helper);
1378 /* In memory full conditions we could get this error here */
1379 check_memory_full_error ((GtkWidget *) parent_window, err);
1384 /* Get the error message depending on the protocol */
1385 proto = modest_tny_account_get_protocol_type (account);
1386 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1387 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1390 protocol_registry = modest_runtime_get_protocol_registry ();
1391 subject = tny_header_dup_subject (helper->header);
1393 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1394 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1398 if (error_msg == NULL) {
1399 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1402 #ifndef MODEST_TOOLKIT_HILDON2
1403 gboolean show_open_draft = FALSE;
1404 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1406 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1408 TnyFolderType folder_type;
1410 folder = tny_header_get_folder (helper->header);
1411 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1412 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1413 g_object_unref (folder);
1417 #ifdef MODEST_TOOLKIT_HILDON2
1420 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1423 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1424 g_free (account_name);
1425 open_msg_helper_destroyer (helper);
1430 ModestWindow *window;
1431 GtkWidget *header_view;
1434 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1435 uid = modest_tny_folder_get_header_unique_id (helper->header);
1437 window = modest_msg_view_window_new_from_header_view
1438 (MODEST_HEADER_VIEW (header_view), account_name, uid, helper->rowref);
1439 if (window != NULL) {
1440 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1442 gtk_widget_destroy (GTK_WIDGET (window));
1444 gtk_widget_show_all (GTK_WIDGET(window));
1448 g_free (account_name);
1450 open_msg_helper_destroyer (helper);
1453 g_free (account_name);
1455 /* Create the mail operation */
1457 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1458 modest_ui_actions_disk_operations_error_handler,
1459 g_strdup (error_msg), g_free);
1460 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1464 #ifndef MODEST_TOOLKIT_HILDON2
1465 if (show_open_draft) {
1466 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1467 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1468 helper->banner_info->banner = NULL;
1469 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1470 helper->banner_info);
1476 headers = TNY_LIST (tny_simple_list_new ());
1477 tny_list_prepend (headers, G_OBJECT (helper->header));
1478 modest_mail_operation_get_msgs_full (mail_op,
1482 open_msg_helper_destroyer);
1483 g_object_unref (headers);
1490 g_object_unref (mail_op);
1491 g_object_unref (account);
1495 * This function is used by both modest_ui_actions_on_open and
1496 * modest_ui_actions_on_header_activated. This way we always do the
1497 * same when trying to open messages.
1500 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1502 ModestWindowMgr *mgr = NULL;
1503 TnyAccount *account;
1504 gboolean cached = FALSE;
1506 GtkWidget *header_view = NULL;
1507 OpenMsgHelper *helper;
1508 ModestWindow *window;
1510 g_return_if_fail (header != NULL && rowref != NULL);
1512 mgr = modest_runtime_get_window_mgr ();
1515 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1516 if (header_view == NULL)
1519 /* Get the account */
1520 account = get_account_from_header (header);
1525 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1527 /* Do not open again the message and present the
1528 window to the user */
1531 #ifndef MODEST_TOOLKIT_HILDON2
1532 gtk_window_present (GTK_WINDOW (window));
1535 /* the header has been registered already, we don't do
1536 * anything but wait for the window to come up*/
1537 g_debug ("header %p already registered, waiting for window", header);
1542 /* Open each message */
1543 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1545 /* Allways download if we are online. */
1546 if (!tny_device_is_online (modest_runtime_get_device ())) {
1549 /* If ask for user permission to download the messages */
1550 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1551 _("mcen_nc_get_msg"));
1553 /* End if the user does not want to continue */
1554 if (response == GTK_RESPONSE_CANCEL) {
1560 /* We register the window for opening */
1561 modest_window_mgr_register_header (mgr, header, NULL);
1563 /* Create the helper. We need to get a reference to the model
1564 here because it could change while the message is readed
1565 (the user could switch between folders) */
1566 helper = g_slice_new (OpenMsgHelper);
1567 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1568 helper->header = g_object_ref (header);
1569 helper->rowref = gtk_tree_row_reference_copy (rowref);
1570 helper->banner_info = NULL;
1572 /* Connect to the account and perform */
1574 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1575 open_msg_performer, helper);
1577 /* Call directly the performer, do not need to connect */
1578 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1579 g_object_ref (account), helper);
1584 g_object_unref (account);
1588 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1595 /* we check for low-mem; in that case, show a warning, and don't allow
1598 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1602 headers = get_selected_headers (win);
1606 headers_count = tny_list_get_length (headers);
1607 if (headers_count != 1) {
1608 if (headers_count > 1) {
1609 /* Don't allow activation if there are more than one message selected */
1610 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1613 g_object_unref (headers);
1617 iter = tny_list_create_iterator (headers);
1618 header = TNY_HEADER (tny_iterator_get_current (iter));
1619 g_object_unref (iter);
1623 open_msg_from_header (header, NULL, win);
1624 g_object_unref (header);
1627 g_object_unref(headers);
1631 rf_helper_window_closed (gpointer data,
1634 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1636 helper->parent_window = NULL;
1639 static ReplyForwardHelper*
1640 create_reply_forward_helper (ReplyForwardAction action,
1642 guint reply_forward_type,
1645 ReplyForwardHelper *rf_helper = NULL;
1646 const gchar *active_acc = modest_window_get_active_account (win);
1648 rf_helper = g_slice_new0 (ReplyForwardHelper);
1649 rf_helper->reply_forward_type = reply_forward_type;
1650 rf_helper->action = action;
1651 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1652 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1653 rf_helper->account_name = (active_acc) ?
1654 g_strdup (active_acc) :
1655 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1657 /* Note that window could be destroyed just AFTER calling
1658 register_window so we must ensure that this pointer does
1659 not hold invalid references */
1660 if (rf_helper->parent_window)
1661 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1662 rf_helper_window_closed, rf_helper);
1668 free_reply_forward_helper (gpointer data)
1670 ReplyForwardHelper *helper;
1672 helper = (ReplyForwardHelper *) data;
1673 g_free (helper->account_name);
1675 g_object_unref (helper->header);
1676 if (helper->parent_window)
1677 g_object_weak_unref (G_OBJECT (helper->parent_window),
1678 rf_helper_window_closed, helper);
1679 g_slice_free (ReplyForwardHelper, helper);
1683 reply_forward_cb (ModestMailOperation *mail_op,
1690 TnyMsg *new_msg = NULL;
1691 ReplyForwardHelper *rf_helper;
1692 ModestWindow *msg_win = NULL;
1693 ModestEditType edit_type;
1695 TnyAccount *account = NULL;
1696 ModestWindowMgr *mgr = NULL;
1697 gchar *signature = NULL;
1698 gboolean use_signature;
1700 /* If there was any error. The mail operation could be NULL,
1701 this means that we already have the message downloaded and
1702 that we didn't do a mail operation to retrieve it */
1703 rf_helper = (ReplyForwardHelper *) user_data;
1704 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1707 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1708 rf_helper->account_name);
1709 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr(),
1710 rf_helper->account_name,
1713 /* Create reply mail */
1714 switch (rf_helper->action) {
1717 modest_tny_msg_create_reply_msg (msg, header, from,
1718 (use_signature) ? signature : NULL,
1719 rf_helper->reply_forward_type,
1720 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1722 case ACTION_REPLY_TO_ALL:
1724 modest_tny_msg_create_reply_msg (msg, header, from,
1725 (use_signature) ? signature : NULL,
1726 rf_helper->reply_forward_type,
1727 MODEST_TNY_MSG_REPLY_MODE_ALL);
1728 edit_type = MODEST_EDIT_TYPE_REPLY;
1730 case ACTION_FORWARD:
1732 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1733 rf_helper->reply_forward_type);
1734 edit_type = MODEST_EDIT_TYPE_FORWARD;
1737 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1739 g_return_if_reached ();
1747 g_warning ("%s: failed to create message\n", __FUNCTION__);
1751 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1752 rf_helper->account_name,
1753 TNY_ACCOUNT_TYPE_STORE);
1755 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1759 /* Create and register the windows */
1760 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1761 mgr = modest_runtime_get_window_mgr ();
1762 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1764 /* Note that register_window could have deleted the account */
1765 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1766 gdouble parent_zoom;
1768 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1769 modest_window_set_zoom (msg_win, parent_zoom);
1772 /* Show edit window */
1773 gtk_widget_show_all (GTK_WIDGET (msg_win));
1776 /* We always unregister the header because the message is
1777 forwarded or replied so the original one is no longer
1779 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1782 g_object_unref (G_OBJECT (new_msg));
1784 g_object_unref (G_OBJECT (account));
1785 free_reply_forward_helper (rf_helper);
1788 /* Checks a list of headers. If any of them are not currently
1789 * downloaded (CACHED) then returns TRUE else returns FALSE.
1792 header_list_count_uncached_msgs (TnyList *header_list)
1795 gint uncached_messages = 0;
1797 iter = tny_list_create_iterator (header_list);
1798 while (!tny_iterator_is_done (iter)) {
1801 header = TNY_HEADER (tny_iterator_get_current (iter));
1803 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1804 uncached_messages ++;
1805 g_object_unref (header);
1808 tny_iterator_next (iter);
1810 g_object_unref (iter);
1812 return uncached_messages;
1815 /* Returns FALSE if the user does not want to download the
1816 * messages. Returns TRUE if the user allowed the download.
1819 connect_to_get_msg (ModestWindow *win,
1820 gint num_of_uncached_msgs,
1821 TnyAccount *account)
1823 GtkResponseType response;
1825 /* Allways download if we are online. */
1826 if (tny_device_is_online (modest_runtime_get_device ()))
1829 /* If offline, then ask for user permission to download the messages */
1830 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1831 ngettext("mcen_nc_get_msg",
1833 num_of_uncached_msgs));
1835 if (response == GTK_RESPONSE_CANCEL)
1838 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1842 reply_forward_performer (gboolean canceled,
1844 GtkWindow *parent_window,
1845 TnyAccount *account,
1848 ReplyForwardHelper *rf_helper = NULL;
1849 ModestMailOperation *mail_op;
1851 rf_helper = (ReplyForwardHelper *) user_data;
1853 if (canceled || err) {
1854 free_reply_forward_helper (rf_helper);
1858 /* Retrieve the message */
1859 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1860 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1861 modest_ui_actions_disk_operations_error_handler,
1863 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1864 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1867 g_object_unref(mail_op);
1871 * Common code for the reply and forward actions
1874 reply_forward (ReplyForwardAction action, ModestWindow *win)
1876 ReplyForwardHelper *rf_helper = NULL;
1877 guint reply_forward_type;
1879 g_return_if_fail (MODEST_IS_WINDOW(win));
1881 /* we check for low-mem; in that case, show a warning, and don't allow
1882 * reply/forward (because it could potentially require a lot of memory */
1883 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1887 /* we need an account when editing */
1888 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1889 if (!modest_ui_actions_run_account_setup_wizard (win))
1893 reply_forward_type =
1894 modest_conf_get_int (modest_runtime_get_conf (),
1895 (action == ACTION_FORWARD) ?
1896 MODEST_CONF_FORWARD_TYPE :
1897 MODEST_CONF_REPLY_TYPE,
1900 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1902 TnyHeader *header = NULL;
1903 /* Get header and message. Do not free them here, the
1904 reply_forward_cb must do it */
1905 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1906 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1908 if (msg && header) {
1910 rf_helper = create_reply_forward_helper (action, win,
1911 reply_forward_type, header);
1912 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1914 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1918 g_object_unref (msg);
1920 g_object_unref (header);
1922 TnyHeader *header = NULL;
1924 gboolean do_retrieve = TRUE;
1925 TnyList *header_list = NULL;
1927 header_list = get_selected_headers (win);
1930 /* Check that only one message is selected for replying */
1931 if (tny_list_get_length (header_list) != 1) {
1932 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1933 NULL, _("mcen_ib_select_one_message"));
1934 g_object_unref (header_list);
1938 /* Only reply/forward to one message */
1939 iter = tny_list_create_iterator (header_list);
1940 header = TNY_HEADER (tny_iterator_get_current (iter));
1941 g_object_unref (iter);
1943 /* Retrieve messages */
1944 do_retrieve = (action == ACTION_FORWARD) ||
1945 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1948 TnyAccount *account = NULL;
1949 TnyFolder *folder = NULL;
1950 gdouble download = TRUE;
1951 guint uncached_msgs = 0;
1953 folder = tny_header_get_folder (header);
1955 goto do_retrieve_frees;
1956 account = tny_folder_get_account (folder);
1958 goto do_retrieve_frees;
1960 uncached_msgs = header_list_count_uncached_msgs (header_list);
1962 if (uncached_msgs > 0) {
1963 /* Allways download if we are online. */
1964 if (!tny_device_is_online (modest_runtime_get_device ())) {
1967 /* If ask for user permission to download the messages */
1968 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1969 ngettext("mcen_nc_get_msg",
1973 /* End if the user does not want to continue */
1974 if (response == GTK_RESPONSE_CANCEL)
1981 rf_helper = create_reply_forward_helper (action, win,
1982 reply_forward_type, header);
1983 if (uncached_msgs > 0) {
1984 modest_platform_connect_and_perform (GTK_WINDOW (win),
1986 reply_forward_performer,
1989 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
1990 account, rf_helper);
1995 g_object_unref (account);
1997 g_object_unref (folder);
1999 reply_forward_cb (NULL, header, FALSE, NULL, NULL, rf_helper);
2002 g_object_unref (header_list);
2003 g_object_unref (header);
2008 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
2010 g_return_if_fail (MODEST_IS_WINDOW(win));
2012 reply_forward (ACTION_REPLY, win);
2016 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
2018 g_return_if_fail (MODEST_IS_WINDOW(win));
2020 reply_forward (ACTION_FORWARD, win);
2024 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
2026 g_return_if_fail (MODEST_IS_WINDOW(win));
2028 reply_forward (ACTION_REPLY_TO_ALL, win);
2032 modest_ui_actions_on_next (GtkAction *action,
2033 ModestWindow *window)
2035 if (MODEST_IS_MAIN_WINDOW (window)) {
2036 GtkWidget *header_view;
2038 header_view = modest_main_window_get_child_widget (
2039 MODEST_MAIN_WINDOW(window),
2040 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2044 modest_header_view_select_next (
2045 MODEST_HEADER_VIEW(header_view));
2046 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2047 modest_msg_view_window_select_next_message (
2048 MODEST_MSG_VIEW_WINDOW (window));
2050 g_return_if_reached ();
2055 modest_ui_actions_on_prev (GtkAction *action,
2056 ModestWindow *window)
2058 g_return_if_fail (MODEST_IS_WINDOW(window));
2060 if (MODEST_IS_MAIN_WINDOW (window)) {
2061 GtkWidget *header_view;
2062 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2063 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2067 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
2068 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2069 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
2071 g_return_if_reached ();
2076 modest_ui_actions_on_sort (GtkAction *action,
2077 ModestWindow *window)
2079 GtkWidget *header_view = NULL;
2081 g_return_if_fail (MODEST_IS_WINDOW(window));
2083 if (MODEST_IS_MAIN_WINDOW (window)) {
2084 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2085 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2086 #ifdef MODEST_TOOLKIT_HILDON2
2087 } else if (MODEST_IS_HEADER_WINDOW (window)) {
2088 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2093 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
2098 /* Show sorting dialog */
2099 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
2103 new_messages_arrived (ModestMailOperation *self,
2104 TnyList *new_headers,
2108 gboolean show_visual_notifications;
2110 source = modest_mail_operation_get_source (self);
2111 show_visual_notifications = (source) ? FALSE : TRUE;
2113 g_object_unref (source);
2115 /* Notify new messages have been downloaded. If the
2116 send&receive was invoked by the user then do not show any
2117 visual notification, only play a sound and activate the LED
2118 (for the Maemo version) */
2119 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0)
2120 modest_platform_on_new_headers_received (new_headers,
2121 show_visual_notifications);
2126 retrieve_all_messages_cb (GObject *source,
2128 guint retrieve_limit)
2134 window = GTK_WINDOW (source);
2135 msg = g_strdup_printf (_("mail_nc_msg_count_limit_exceeded"),
2136 num_msgs, retrieve_limit);
2138 /* Ask the user if they want to retrieve all the messages */
2140 modest_platform_run_confirmation_dialog_with_buttons (window, msg,
2141 _("mcen_bd_get_all"),
2142 _("mcen_bd_newest_only"));
2143 /* Free and return */
2145 return (response == GTK_RESPONSE_ACCEPT) ? TRUE : FALSE;
2149 TnyAccount *account;
2151 gchar *account_name;
2152 gboolean poke_status;
2153 gboolean interactive;
2154 ModestMailOperation *mail_op;
2158 do_send_receive_performer (gboolean canceled,
2160 GtkWindow *parent_window,
2161 TnyAccount *account,
2164 SendReceiveInfo *info;
2166 info = (SendReceiveInfo *) user_data;
2168 if (err || canceled) {
2169 /* In memory full conditions we could get this error here */
2170 check_memory_full_error ((GtkWidget *) parent_window, err);
2172 if (info->mail_op) {
2173 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2179 /* Set send/receive operation in progress */
2180 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2181 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2184 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2185 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2186 G_CALLBACK (on_send_receive_finished),
2189 /* Send & receive. */
2190 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2191 (info->win) ? retrieve_all_messages_cb : NULL,
2192 new_messages_arrived, info->win);
2197 g_object_unref (G_OBJECT (info->mail_op));
2198 if (info->account_name)
2199 g_free (info->account_name);
2201 g_object_unref (info->win);
2203 g_object_unref (info->account);
2204 g_slice_free (SendReceiveInfo, info);
2208 * This function performs the send & receive required actions. The
2209 * window is used to create the mail operation. Typically it should
2210 * always be the main window, but we pass it as argument in order to
2214 modest_ui_actions_do_send_receive (const gchar *account_name,
2215 gboolean force_connection,
2216 gboolean poke_status,
2217 gboolean interactive,
2220 gchar *acc_name = NULL;
2221 SendReceiveInfo *info;
2222 ModestTnyAccountStore *acc_store;
2224 /* If no account name was provided then get the current account, and if
2225 there is no current account then pick the default one: */
2226 if (!account_name) {
2228 acc_name = g_strdup (modest_window_get_active_account (win));
2230 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2232 g_printerr ("modest: cannot get default account\n");
2236 acc_name = g_strdup (account_name);
2239 acc_store = modest_runtime_get_account_store ();
2241 /* Create the info for the connect and perform */
2242 info = g_slice_new (SendReceiveInfo);
2243 info->account_name = acc_name;
2244 info->win = (win) ? g_object_ref (win) : NULL;
2245 info->poke_status = poke_status;
2246 info->interactive = interactive;
2247 info->account = modest_tny_account_store_get_server_account (acc_store, acc_name,
2248 TNY_ACCOUNT_TYPE_STORE);
2249 /* We need to create the operation here, because otherwise it
2250 could happen that the queue emits the queue-empty signal
2251 while we're trying to connect the account */
2252 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2253 modest_ui_actions_disk_operations_error_handler,
2255 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2257 /* Invoke the connect and perform */
2258 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2259 force_connection, info->account,
2260 do_send_receive_performer, info);
2265 modest_ui_actions_do_cancel_send (const gchar *account_name,
2268 TnyTransportAccount *transport_account;
2269 TnySendQueue *send_queue = NULL;
2270 GError *error = NULL;
2272 /* Get transport account */
2274 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2275 (modest_runtime_get_account_store(),
2277 TNY_ACCOUNT_TYPE_TRANSPORT));
2278 if (!transport_account) {
2279 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2284 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2285 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2286 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2287 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2288 "modest: could not find send queue for account\n");
2290 /* Cancel the current send */
2291 tny_account_cancel (TNY_ACCOUNT (transport_account));
2293 /* Suspend all pending messages */
2294 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2298 if (transport_account != NULL)
2299 g_object_unref (G_OBJECT (transport_account));
2303 modest_ui_actions_cancel_send_all (ModestWindow *win)
2305 GSList *account_names, *iter;
2307 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2310 iter = account_names;
2312 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2313 iter = g_slist_next (iter);
2316 modest_account_mgr_free_account_names (account_names);
2317 account_names = NULL;
2321 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2324 /* Check if accounts exist */
2325 gboolean accounts_exist =
2326 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2328 /* If not, allow the user to create an account before trying to send/receive. */
2329 if (!accounts_exist)
2330 modest_ui_actions_on_accounts (NULL, win);
2332 /* Cancel all sending operaitons */
2333 modest_ui_actions_cancel_send_all (win);
2337 * Refreshes all accounts. This function will be used by automatic
2341 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2342 gboolean force_connection,
2343 gboolean poke_status,
2344 gboolean interactive)
2346 GSList *account_names, *iter;
2348 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2351 iter = account_names;
2353 modest_ui_actions_do_send_receive ((const char*) iter->data,
2355 poke_status, interactive, win);
2356 iter = g_slist_next (iter);
2359 modest_account_mgr_free_account_names (account_names);
2360 account_names = NULL;
2364 * Handler of the click on Send&Receive button in the main toolbar
2367 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2369 /* Check if accounts exist */
2370 gboolean accounts_exist;
2373 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2375 /* If not, allow the user to create an account before trying to send/receive. */
2376 if (!accounts_exist)
2377 modest_ui_actions_on_accounts (NULL, win);
2379 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2380 if (MODEST_IS_MAIN_WINDOW (win)) {
2381 GtkWidget *folder_view;
2382 TnyFolderStore *folder_store;
2385 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2386 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2390 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2393 g_object_unref (folder_store);
2394 /* Refresh the active account. Force the connection if needed
2395 and poke the status of all folders */
2396 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2397 #ifdef MODEST_TOOLKIT_HILDON2
2398 } else if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2399 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2402 const gchar *active_account;
2403 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2405 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2412 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2415 GtkWidget *header_view;
2417 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2419 header_view = modest_main_window_get_child_widget (main_window,
2420 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2424 conf = modest_runtime_get_conf ();
2426 /* what is saved/restored is depending on the style; thus; we save with
2427 * old style, then update the style, and restore for this new style
2429 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2431 if (modest_header_view_get_style
2432 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2433 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2434 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2436 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2437 MODEST_HEADER_VIEW_STYLE_DETAILS);
2439 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2440 MODEST_CONF_HEADER_VIEW_KEY);
2445 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2447 ModestMainWindow *main_window)
2449 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2450 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2452 /* in the case the folder is empty, show the empty folder message and focus
2454 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2455 if (modest_header_view_is_empty (header_view)) {
2456 TnyFolder *folder = modest_header_view_get_folder (header_view);
2457 GtkWidget *folder_view =
2458 modest_main_window_get_child_widget (main_window,
2459 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2460 if (folder != NULL) {
2461 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2462 g_object_unref (folder);
2464 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2468 /* If no header has been selected then exit */
2473 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2474 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2476 /* Update toolbar dimming state */
2477 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2478 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2482 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2485 ModestWindow *window)
2487 GtkWidget *open_widget;
2488 GtkTreeRowReference *rowref;
2490 g_return_if_fail (MODEST_IS_WINDOW(window));
2491 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2492 g_return_if_fail (TNY_IS_HEADER (header));
2494 if (modest_header_view_count_selected_headers (header_view) > 1) {
2495 /* Don't allow activation if there are more than one message selected */
2496 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2500 /* we check for low-mem; in that case, show a warning, and don't allow
2501 * activating headers
2503 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2506 if (MODEST_IS_MAIN_WINDOW (window)) {
2507 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2508 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2509 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2513 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2514 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2515 gtk_tree_row_reference_free (rowref);
2519 set_active_account_from_tny_account (TnyAccount *account,
2520 ModestWindow *window)
2522 const gchar *server_acc_name = tny_account_get_id (account);
2524 /* We need the TnyAccount provided by the
2525 account store because that is the one that
2526 knows the name of the Modest account */
2527 TnyAccount *modest_server_account =
2528 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2529 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2531 if (!modest_server_account) {
2532 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2536 /* Update active account, but only if it's not a pseudo-account */
2537 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2538 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2539 const gchar *modest_acc_name =
2540 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2541 if (modest_acc_name)
2542 modest_window_set_active_account (window, modest_acc_name);
2545 g_object_unref (modest_server_account);
2550 folder_refreshed_cb (ModestMailOperation *mail_op,
2554 ModestMainWindow *win = NULL;
2555 GtkWidget *folder_view;
2556 const GError *error;
2558 g_return_if_fail (TNY_IS_FOLDER (folder));
2560 win = MODEST_MAIN_WINDOW (user_data);
2562 /* Check if the operation failed due to memory low conditions */
2563 error = modest_mail_operation_get_error (mail_op);
2564 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2565 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2566 modest_platform_run_information_dialog (GTK_WINDOW (win),
2567 _KR("memr_ib_operation_disabled"),
2573 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2576 TnyFolderStore *current_folder;
2578 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2579 if (current_folder) {
2580 gboolean different = ((TnyFolderStore *) folder != current_folder);
2581 g_object_unref (current_folder);
2587 /* Check if folder is empty and set headers view contents style */
2588 if (tny_folder_get_all_count (folder) == 0)
2589 modest_main_window_set_contents_style (win,
2590 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2595 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2596 TnyFolderStore *folder_store,
2598 ModestMainWindow *main_window)
2601 GtkWidget *header_view;
2603 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2605 header_view = modest_main_window_get_child_widget(main_window,
2606 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2610 conf = modest_runtime_get_conf ();
2612 if (TNY_IS_ACCOUNT (folder_store)) {
2614 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2616 /* Show account details */
2617 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2620 if (TNY_IS_FOLDER (folder_store) && selected) {
2621 TnyAccount *account;
2622 const gchar *account_name = NULL;
2624 /* Update the active account */
2625 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2627 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2629 modest_tny_account_get_parent_modest_account_name_for_server_account (account);
2630 g_object_unref (account);
2634 /* Set the header style by default, it could
2635 be changed later by the refresh callback to
2637 modest_main_window_set_contents_style (main_window,
2638 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2640 /* Set folder on header view. This function
2641 will call tny_folder_refresh_async so we
2642 pass a callback that will be called when
2643 finished. We use that callback to set the
2644 empty view if there are no messages */
2645 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2646 TNY_FOLDER (folder_store),
2648 MODEST_WINDOW (main_window),
2649 folder_refreshed_cb,
2652 /* Restore configuration. We need to do this
2653 *after* the set_folder because the widget
2654 memory asks the header view about its
2656 modest_widget_memory_restore (modest_runtime_get_conf (),
2657 G_OBJECT(header_view),
2658 MODEST_CONF_HEADER_VIEW_KEY);
2660 /* No need to save the header view
2661 configuration for Maemo because it only
2662 saves the sorting stuff and that it's
2663 already being done by the sort
2664 dialog. Remove it when the GNOME version
2665 has the same behaviour */
2666 #ifdef MODEST_TOOLKIT_GTK
2667 if (modest_main_window_get_contents_style (main_window) ==
2668 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2669 modest_widget_memory_save (conf, G_OBJECT (header_view),
2670 MODEST_CONF_HEADER_VIEW_KEY);
2672 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2676 /* Update dimming state */
2677 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2678 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2682 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2689 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2691 online = tny_device_is_online (modest_runtime_get_device());
2694 /* already online -- the item is simply not there... */
2695 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2697 GTK_MESSAGE_WARNING,
2699 _("The %s you selected cannot be found"),
2701 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2702 gtk_dialog_run (GTK_DIALOG(dialog));
2704 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2707 _("mcen_bd_dialog_cancel"),
2708 GTK_RESPONSE_REJECT,
2709 _("mcen_bd_dialog_ok"),
2710 GTK_RESPONSE_ACCEPT,
2712 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2713 "Do you want to get online?"), item);
2714 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2715 gtk_label_new (txt), FALSE, FALSE, 0);
2716 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2719 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2720 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2721 /* TODO: Comment about why is this commented out: */
2722 /* modest_platform_connect_and_wait (); */
2725 gtk_widget_destroy (dialog);
2729 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2732 /* g_message ("%s %s", __FUNCTION__, link); */
2737 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2740 modest_platform_activate_uri (link);
2744 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2747 modest_platform_show_uri_popup (link);
2751 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2754 /* we check for low-mem; in that case, show a warning, and don't allow
2755 * viewing attachments
2757 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2760 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2764 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2765 const gchar *address,
2768 /* g_message ("%s %s", __FUNCTION__, address); */
2772 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2773 TnyMsg *saved_draft,
2776 ModestMsgEditWindow *edit_window;
2778 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2779 #ifndef MODEST_TOOLKIT_HILDON2
2780 ModestMainWindow *win;
2782 /* FIXME. Make the header view sensitive again. This is a
2783 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2785 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2786 modest_runtime_get_window_mgr(), FALSE));
2788 GtkWidget *hdrview = modest_main_window_get_child_widget(
2789 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2790 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2794 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2796 /* Set draft is there was no error */
2797 if (!modest_mail_operation_get_error (mail_op))
2798 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2800 g_object_unref(edit_window);
2804 enough_space_for_message (ModestMsgEditWindow *edit_window,
2807 TnyAccountStore *acc_store;
2808 guint64 available_disk, expected_size;
2813 acc_store = TNY_ACCOUNT_STORE (modest_runtime_get_account_store());
2814 available_disk = modest_utils_get_available_space (NULL);
2815 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2816 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2821 /* Double check: memory full condition or message too big */
2822 if (available_disk < MIN_FREE_SPACE ||
2823 expected_size > available_disk) {
2825 modest_platform_information_banner (NULL, NULL,
2826 _KR("cerm_device_memory_full"));
2831 * djcb: if we're in low-memory state, we only allow for
2832 * saving messages smaller than
2833 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2834 * should still allow for sending anything critical...
2836 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2837 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2841 * djcb: we also make sure that the attachments are smaller than the max size
2842 * this is for the case where we'd try to forward a message with attachments
2843 * bigger than our max allowed size, or sending an message from drafts which
2844 * somehow got past our checks when attaching.
2846 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2847 modest_platform_run_information_dialog (
2848 GTK_WINDOW(edit_window),
2849 _KR("memr_ib_operation_disabled"),
2858 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2860 TnyTransportAccount *transport_account;
2861 ModestMailOperation *mail_operation;
2863 gchar *account_name, *from;
2864 ModestAccountMgr *account_mgr;
2865 gboolean had_error = FALSE;
2866 ModestMainWindow *win = NULL;
2868 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2870 data = modest_msg_edit_window_get_msg_data (edit_window);
2873 if (!enough_space_for_message (edit_window, data)) {
2874 modest_msg_edit_window_free_msg_data (edit_window, data);
2878 account_name = g_strdup (data->account_name);
2879 account_mgr = modest_runtime_get_account_mgr();
2881 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2883 account_name = modest_account_mgr_get_default_account (account_mgr);
2884 if (!account_name) {
2885 g_printerr ("modest: no account found\n");
2886 modest_msg_edit_window_free_msg_data (edit_window, data);
2890 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2891 account_name = g_strdup (data->account_name);
2895 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2896 (modest_runtime_get_account_store (),
2898 TNY_ACCOUNT_TYPE_TRANSPORT));
2899 if (!transport_account) {
2900 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2901 g_free (account_name);
2902 modest_msg_edit_window_free_msg_data (edit_window, data);
2905 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2907 /* Create the mail operation */
2908 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
2910 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2912 modest_mail_operation_save_to_drafts (mail_operation,
2924 data->priority_flags,
2927 on_save_to_drafts_cb,
2928 g_object_ref(edit_window));
2930 #ifdef MODEST_TOOLKIT_HILDON2
2931 /* In hildon2 we always show the information banner on saving to drafts.
2932 * It will be a system information banner in this case.
2934 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2935 modest_platform_information_banner (NULL, NULL, text);
2938 /* Use the main window as the parent of the banner, if the
2939 main window does not exist it won't be shown, if the parent
2940 window exists then it's properly shown. We don't use the
2941 editor window because it could be closed (save to drafts
2942 could happen after closing the window */
2943 win = (ModestMainWindow *)
2944 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
2946 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2947 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
2951 modest_msg_edit_window_set_modified (edit_window, FALSE);
2955 g_free (account_name);
2956 g_object_unref (G_OBJECT (transport_account));
2957 g_object_unref (G_OBJECT (mail_operation));
2959 modest_msg_edit_window_free_msg_data (edit_window, data);
2962 * If the drafts folder is selected then make the header view
2963 * insensitive while the message is being saved to drafts
2964 * (it'll be sensitive again in on_save_to_drafts_cb()). This
2965 * is not very clean but it avoids letting the drafts folder
2966 * in an inconsistent state: the user could edit the message
2967 * being saved and undesirable things would happen.
2968 * In the average case the user won't notice anything at
2969 * all. In the worst case (the user is editing a really big
2970 * file from Drafts) the header view will be insensitive
2971 * during the saving process (10 or 20 seconds, depending on
2972 * the message). Anyway this is just a quick workaround: once
2973 * we find a better solution it should be removed
2974 * See NB#65125 (commend #18) for details.
2976 if (!had_error && win != NULL) {
2977 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
2978 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
2980 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
2982 if (modest_tny_folder_is_local_folder(folder)) {
2983 TnyFolderType folder_type;
2984 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
2985 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
2986 GtkWidget *hdrview = modest_main_window_get_child_widget(
2987 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2988 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
2992 if (folder != NULL) g_object_unref(folder);
2999 /* For instance, when clicking the Send toolbar button when editing a message: */
3001 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3003 TnyTransportAccount *transport_account = NULL;
3004 gboolean had_error = FALSE;
3006 ModestAccountMgr *account_mgr;
3007 gchar *account_name;
3009 ModestMailOperation *mail_operation;
3011 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
3013 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
3016 data = modest_msg_edit_window_get_msg_data (edit_window);
3019 if (!enough_space_for_message (edit_window, data)) {
3020 modest_msg_edit_window_free_msg_data (edit_window, data);
3024 account_mgr = modest_runtime_get_account_mgr();
3025 account_name = g_strdup (data->account_name);
3027 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3030 account_name = modest_account_mgr_get_default_account (account_mgr);
3032 if (!account_name) {
3033 modest_msg_edit_window_free_msg_data (edit_window, data);
3034 /* Run account setup wizard */
3035 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
3040 /* Get the currently-active transport account for this modest account: */
3041 if (strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
3043 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3044 (modest_runtime_get_account_store (),
3045 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
3048 if (!transport_account) {
3049 modest_msg_edit_window_free_msg_data (edit_window, data);
3050 /* Run account setup wizard */
3051 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
3056 /* Create the mail operation */
3057 from = modest_account_mgr_get_from_string (account_mgr, account_name);
3058 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
3059 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3061 modest_mail_operation_send_new_mail (mail_operation,
3075 data->priority_flags);
3077 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3078 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
3080 if (modest_mail_operation_get_error (mail_operation) != NULL) {
3081 const GError *error = modest_mail_operation_get_error (mail_operation);
3082 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3083 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3084 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3085 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3092 g_free (account_name);
3093 g_object_unref (G_OBJECT (transport_account));
3094 g_object_unref (G_OBJECT (mail_operation));
3096 modest_msg_edit_window_free_msg_data (edit_window, data);
3099 modest_msg_edit_window_set_sent (edit_window, TRUE);
3101 /* Save settings and close the window: */
3102 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3109 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3110 ModestMsgEditWindow *window)
3112 ModestMsgEditFormatState *format_state = NULL;
3114 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3115 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3117 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3120 format_state = modest_msg_edit_window_get_format_state (window);
3121 g_return_if_fail (format_state != NULL);
3123 format_state->bold = gtk_toggle_action_get_active (action);
3124 modest_msg_edit_window_set_format_state (window, format_state);
3125 g_free (format_state);
3130 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3131 ModestMsgEditWindow *window)
3133 ModestMsgEditFormatState *format_state = NULL;
3135 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3136 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3138 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3141 format_state = modest_msg_edit_window_get_format_state (window);
3142 g_return_if_fail (format_state != NULL);
3144 format_state->italics = gtk_toggle_action_get_active (action);
3145 modest_msg_edit_window_set_format_state (window, format_state);
3146 g_free (format_state);
3151 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3152 ModestMsgEditWindow *window)
3154 ModestMsgEditFormatState *format_state = NULL;
3156 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3157 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3159 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3162 format_state = modest_msg_edit_window_get_format_state (window);
3163 g_return_if_fail (format_state != NULL);
3165 format_state->bullet = gtk_toggle_action_get_active (action);
3166 modest_msg_edit_window_set_format_state (window, format_state);
3167 g_free (format_state);
3172 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3173 GtkRadioAction *selected,
3174 ModestMsgEditWindow *window)
3176 ModestMsgEditFormatState *format_state = NULL;
3177 GtkJustification value;
3179 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3181 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3184 value = gtk_radio_action_get_current_value (selected);
3186 format_state = modest_msg_edit_window_get_format_state (window);
3187 g_return_if_fail (format_state != NULL);
3189 format_state->justification = value;
3190 modest_msg_edit_window_set_format_state (window, format_state);
3191 g_free (format_state);
3195 modest_ui_actions_on_select_editor_color (GtkAction *action,
3196 ModestMsgEditWindow *window)
3198 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3199 g_return_if_fail (GTK_IS_ACTION (action));
3201 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3204 modest_msg_edit_window_select_color (window);
3208 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3209 ModestMsgEditWindow *window)
3211 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3212 g_return_if_fail (GTK_IS_ACTION (action));
3214 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3217 modest_msg_edit_window_select_background_color (window);
3221 modest_ui_actions_on_insert_image (GObject *object,
3222 ModestMsgEditWindow *window)
3224 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3227 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3230 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3233 modest_msg_edit_window_insert_image (window);
3237 modest_ui_actions_on_attach_file (GtkAction *action,
3238 ModestMsgEditWindow *window)
3240 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3241 g_return_if_fail (GTK_IS_ACTION (action));
3243 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3246 modest_msg_edit_window_offer_attach_file (window);
3250 modest_ui_actions_on_remove_attachments (GtkAction *action,
3251 ModestMsgEditWindow *window)
3253 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3255 modest_msg_edit_window_remove_attachments (window, NULL);
3259 do_create_folder_cb (ModestMailOperation *mail_op,
3260 TnyFolderStore *parent_folder,
3261 TnyFolder *new_folder,
3264 gchar *suggested_name = (gchar *) user_data;
3265 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3266 const GError *error;
3268 error = modest_mail_operation_get_error (mail_op);
3271 /* Show an error. If there was some problem writing to
3272 disk, show it, otherwise show the generic folder
3273 create error. We do it here and not in an error
3274 handler because the call to do_create_folder will
3275 stop the main loop in a gtk_dialog_run and then,
3276 the message won't be shown until that dialog is
3278 modest_ui_actions_disk_operations_error_handler (mail_op,
3279 _("mail_in_ui_folder_create_error"));
3281 if (!is_memory_full_error ((GError *) error, mail_op)) {
3282 /* Try again if there is no full memory condition */
3283 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3286 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3287 * FIXME: any other? */
3288 GtkWidget *folder_view;
3290 if (MODEST_IS_MAIN_WINDOW(source_win))
3292 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3293 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3295 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3296 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3298 /* Select the newly created folder. It could happen
3299 that the widget is no longer there (i.e. the window
3300 has been destroyed, so we need to check this */
3302 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3304 g_object_unref (new_folder);
3306 /* Free. Note that the first time it'll be NULL so noop */
3307 g_free (suggested_name);
3308 g_object_unref (source_win);
3313 TnyFolderStore *parent;
3314 } CreateFolderConnect;
3317 do_create_folder_performer (gboolean canceled,
3319 GtkWindow *parent_window,
3320 TnyAccount *account,
3323 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3324 ModestMailOperation *mail_op;
3326 if (canceled || err) {
3327 /* In memory full conditions we could get this error here */
3328 check_memory_full_error ((GtkWidget *) parent_window, err);
3332 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3333 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3335 modest_mail_operation_create_folder (mail_op,
3337 (const gchar *) helper->folder_name,
3338 do_create_folder_cb,
3339 g_strdup (helper->folder_name));
3340 g_object_unref (mail_op);
3344 g_object_unref (helper->parent);
3345 if (helper->folder_name)
3346 g_free (helper->folder_name);
3347 g_slice_free (CreateFolderConnect, helper);
3352 do_create_folder (GtkWindow *parent_window,
3353 TnyFolderStore *suggested_parent,
3354 const gchar *suggested_name)
3357 gchar *folder_name = NULL;
3358 TnyFolderStore *parent_folder = NULL;
3360 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3362 (gchar *) suggested_name,
3366 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3367 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3368 helper->folder_name = g_strdup (folder_name);
3369 helper->parent = g_object_ref (parent_folder);
3371 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3374 do_create_folder_performer,
3379 g_free (folder_name);
3381 g_object_unref (parent_folder);
3385 modest_ui_actions_create_folder(GtkWidget *parent_window,
3386 GtkWidget *folder_view)
3388 TnyFolderStore *parent_folder;
3390 #ifdef MODEST_TOOLKIT_HILDON2
3391 ModestTnyAccountStore *acc_store;
3393 acc_store = modest_runtime_get_account_store ();
3395 parent_folder = (TnyFolderStore *)
3396 modest_tny_account_store_get_local_folders_account (acc_store);
3398 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3401 if (parent_folder) {
3402 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3403 g_object_unref (parent_folder);
3408 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3411 g_return_if_fail (MODEST_IS_WINDOW(window));
3413 if (MODEST_IS_MAIN_WINDOW (window)) {
3414 GtkWidget *folder_view;
3416 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3417 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3421 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view);
3422 #ifdef MODEST_TOOLKIT_HILDON2
3423 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3424 GtkWidget *folder_view;
3426 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3427 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view);
3430 g_assert_not_reached ();
3435 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3438 const GError *error = NULL;
3439 const gchar *message = NULL;
3441 /* Get error message */
3442 error = modest_mail_operation_get_error (mail_op);
3444 g_return_if_reached ();
3446 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3447 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3448 message = _CS("ckdg_ib_folder_already_exists");
3449 } else if (error->domain == TNY_ERROR_DOMAIN &&
3450 error->code == TNY_SERVICE_ERROR_STATE) {
3451 /* This means that the folder is already in use (a
3452 message is opened for example */
3453 message = _("emev_ni_internal_error");
3455 message = _CS("ckdg_ib_unable_to_rename");
3458 /* We don't set a parent for the dialog because the dialog
3459 will be destroyed so the banner won't appear */
3460 modest_platform_information_banner (NULL, NULL, message);
3464 TnyFolderStore *folder;
3469 on_rename_folder_cb (ModestMailOperation *mail_op,
3470 TnyFolder *new_folder,
3473 ModestFolderView *folder_view;
3475 /* If the window was closed when renaming a folder, or if
3476 * it's not a main window this will happen */
3477 if (!MODEST_IS_FOLDER_VIEW (user_data))
3480 folder_view = MODEST_FOLDER_VIEW (user_data);
3481 /* Note that if the rename fails new_folder will be NULL */
3483 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3485 modest_folder_view_select_first_inbox_or_local (folder_view);
3487 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3491 on_rename_folder_performer (gboolean canceled,
3493 GtkWindow *parent_window,
3494 TnyAccount *account,
3497 ModestMailOperation *mail_op = NULL;
3498 GtkTreeSelection *sel = NULL;
3499 GtkWidget *folder_view = NULL;
3500 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3502 if (canceled || err) {
3503 /* In memory full conditions we could get this error here */
3504 check_memory_full_error ((GtkWidget *) parent_window, err);
3508 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3509 modest_ui_actions_rename_folder_error_handler,
3510 parent_window, NULL);
3512 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3515 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3517 folder_view = modest_main_window_get_child_widget (
3518 MODEST_MAIN_WINDOW (parent_window),
3519 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3521 #ifdef MODEST_TOOLKIT_HILDON2
3522 else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3523 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3524 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3528 /* Clear the folders view */
3529 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3530 gtk_tree_selection_unselect_all (sel);
3532 /* Actually rename the folder */
3533 modest_mail_operation_rename_folder (mail_op,
3534 TNY_FOLDER (data->folder),
3535 (const gchar *) (data->new_name),
3536 on_rename_folder_cb,
3538 g_object_unref (mail_op);
3541 g_object_unref (data->folder);
3542 g_free (data->new_name);
3547 modest_ui_actions_on_rename_folder (GtkAction *action,
3548 ModestWindow *window)
3550 modest_ui_actions_on_edit_mode_rename_folder (window);
3554 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3556 TnyFolderStore *folder;
3557 GtkWidget *folder_view;
3558 gboolean do_rename = TRUE;
3560 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3562 if (MODEST_IS_MAIN_WINDOW (window)) {
3563 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3564 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3568 #ifdef MODEST_TOOLKIT_HILDON2
3569 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3570 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3576 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3581 if (TNY_IS_FOLDER (folder)) {
3582 gchar *folder_name = NULL;
3584 const gchar *current_name;
3585 TnyFolderStore *parent;
3587 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3588 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3589 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
3590 parent, current_name,
3592 g_object_unref (parent);
3594 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3597 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3598 rename_folder_data->folder = g_object_ref (folder);
3599 rename_folder_data->new_name = folder_name;
3600 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
3601 folder, on_rename_folder_performer, rename_folder_data);
3604 g_object_unref (folder);
3609 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3612 GObject *win = modest_mail_operation_get_source (mail_op);
3614 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3615 _("mail_in_ui_folder_delete_error"),
3617 g_object_unref (win);
3621 TnyFolderStore *folder;
3622 gboolean move_to_trash;
3626 on_delete_folder_cb (gboolean canceled,
3628 GtkWindow *parent_window,
3629 TnyAccount *account,
3632 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3633 GtkWidget *folder_view;
3634 ModestMailOperation *mail_op;
3635 GtkTreeSelection *sel;
3637 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
3638 g_object_unref (G_OBJECT (info->folder));
3643 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
3644 folder_view = modest_main_window_get_child_widget (
3645 MODEST_MAIN_WINDOW (parent_window),
3646 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3647 #ifdef MODEST_TOOLKIT_HILDON2
3648 } else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3649 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
3652 g_object_unref (G_OBJECT (info->folder));
3657 /* Unselect the folder before deleting it to free the headers */
3658 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3659 gtk_tree_selection_unselect_all (sel);
3661 /* Create the mail operation */
3663 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3664 modest_ui_actions_delete_folder_error_handler,
3667 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3669 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3671 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3673 g_object_unref (G_OBJECT (mail_op));
3674 g_object_unref (G_OBJECT (info->folder));
3679 delete_folder (ModestWindow *window, gboolean move_to_trash)
3681 TnyFolderStore *folder;
3682 GtkWidget *folder_view;
3686 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3688 if (MODEST_IS_MAIN_WINDOW (window)) {
3690 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3691 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3692 #ifdef MODEST_TOOLKIT_HILDON2
3693 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3694 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3702 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3707 /* Show an error if it's an account */
3708 if (!TNY_IS_FOLDER (folder)) {
3709 modest_platform_run_information_dialog (GTK_WINDOW (window),
3710 _("mail_in_ui_folder_delete_error"),
3712 g_object_unref (G_OBJECT (folder));
3717 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3718 tny_folder_get_name (TNY_FOLDER (folder)));
3719 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
3720 (const gchar *) message);
3723 if (response == GTK_RESPONSE_OK) {
3724 DeleteFolderInfo *info;
3725 info = g_new0(DeleteFolderInfo, 1);
3726 info->folder = folder;
3727 info->move_to_trash = move_to_trash;
3728 g_object_ref (G_OBJECT (info->folder));
3729 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder));
3730 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
3732 TNY_FOLDER_STORE (account),
3733 on_delete_folder_cb, info);
3734 g_object_unref (account);
3739 g_object_unref (G_OBJECT (folder));
3743 modest_ui_actions_on_delete_folder (GtkAction *action,
3744 ModestWindow *window)
3746 modest_ui_actions_on_edit_mode_delete_folder (window);
3750 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
3752 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
3754 return delete_folder (window, FALSE);
3758 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3760 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3762 delete_folder (MODEST_WINDOW (main_window), TRUE);
3766 typedef struct _PasswordDialogFields {
3767 GtkWidget *username;
3768 GtkWidget *password;
3770 } PasswordDialogFields;
3773 password_dialog_check_field (GtkEditable *editable,
3774 PasswordDialogFields *fields)
3777 gboolean any_value_empty = FALSE;
3779 #ifdef MODEST_TOOLKIT_HILDON2
3780 value = hildon_entry_get_text (HILDON_ENTRY (fields->username));
3782 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
3784 if ((value == NULL) || value[0] == '\0') {
3785 any_value_empty = TRUE;
3787 #ifdef MODEST_TOOLKIT_HILDON2
3788 value = hildon_entry_get_text (HILDON_ENTRY (fields->password));
3790 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
3792 if ((value == NULL) || value[0] == '\0') {
3793 any_value_empty = TRUE;
3795 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3799 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3800 const gchar* server_account_name,
3805 ModestMainWindow *main_window)
3807 g_return_if_fail(server_account_name);
3808 gboolean completed = FALSE;
3809 PasswordDialogFields *fields = NULL;
3811 /* Initalize output parameters: */
3818 #ifndef MODEST_TOOLKIT_GTK
3819 /* Maemo uses a different (awkward) button order,
3820 * It should probably just use gtk_alternative_dialog_button_order ().
3822 #ifdef MODEST_TOOLKIT_HILDON2
3824 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3827 _HL("wdgt_bd_done"),
3828 GTK_RESPONSE_ACCEPT,
3830 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
3831 HILDON_MARGIN_DOUBLE);
3834 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3837 _("mcen_bd_dialog_ok"),
3838 GTK_RESPONSE_ACCEPT,
3839 _("mcen_bd_dialog_cancel"),
3840 GTK_RESPONSE_REJECT,
3842 #endif /* MODEST_TOOLKIT_HILDON2 */
3845 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3849 GTK_RESPONSE_REJECT,
3851 GTK_RESPONSE_ACCEPT,
3853 #endif /* MODEST_TOOLKIT_GTK */
3855 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3857 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3858 modest_runtime_get_account_mgr(), server_account_name);
3859 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3860 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3863 gtk_widget_destroy (dialog);
3867 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3868 GtkWidget *label = gtk_label_new (txt);
3869 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
3871 g_free (server_name);
3872 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
3877 gchar *initial_username = modest_account_mgr_get_server_account_username (
3878 modest_runtime_get_account_mgr(), server_account_name);
3880 #ifdef MODEST_TOOLKIT_HILDON2
3881 GtkWidget *entry_username = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
3882 if (initial_username)
3883 hildon_entry_set_text (HILDON_ENTRY (entry_username), initial_username);
3885 GtkWidget *entry_username = gtk_entry_new ();
3886 if (initial_username)
3887 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
3889 /* Dim this if a connection has ever succeeded with this username,
3890 * as per the UI spec: */
3891 /* const gboolean username_known = */
3892 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3893 /* modest_runtime_get_account_mgr(), server_account_name); */
3894 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3896 /* We drop the username sensitive code and disallow changing it here
3897 * as tinymail does not support really changing the username in the callback
3899 gtk_widget_set_sensitive (entry_username, FALSE);
3901 #ifndef MODEST_TOOLKIT_GTK
3902 /* Auto-capitalization is the default, so let's turn it off: */
3903 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3905 /* Create a size group to be used by all captions.
3906 * Note that HildonCaption does not create a default size group if we do not specify one.
3907 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3908 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3910 #ifdef MODEST_TOOLKIT_HILDON2
3911 GtkWidget *caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
3912 _("mail_fi_username"), FALSE,
3915 GtkWidget *caption = hildon_caption_new (sizegroup,
3916 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
3918 gtk_widget_show (entry_username);
3919 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3920 FALSE, FALSE, MODEST_MARGIN_HALF);
3921 gtk_widget_show (caption);
3923 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
3925 #endif /* !MODEST_TOOLKIT_GTK */
3928 #ifdef MODEST_TOOLKIT_HILDON2
3929 GtkWidget *entry_password = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
3931 GtkWidget *entry_password = gtk_entry_new ();
3933 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3934 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3936 #ifndef MODEST_TOOLKIT_GTK
3937 /* Auto-capitalization is the default, so let's turn it off: */
3938 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3939 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3941 #ifdef MODEST_TOOLKIT_HILDON2
3942 caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
3943 _("mail_fi_password"), FALSE,
3946 caption = hildon_caption_new (sizegroup,
3947 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
3949 gtk_widget_show (entry_password);
3950 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3951 FALSE, FALSE, MODEST_MARGIN_HALF);
3952 gtk_widget_show (caption);
3953 g_object_unref (sizegroup);
3955 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
3957 #endif /* !MODEST_TOOLKIT_GTK */
3959 if (initial_username != NULL)
3960 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3962 /* This is not in the Maemo UI spec:
3963 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3964 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3968 fields = g_slice_new0 (PasswordDialogFields);
3969 fields->username = entry_username;
3970 fields->password = entry_password;
3971 fields->dialog = dialog;
3973 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3974 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3975 password_dialog_check_field (NULL, fields);
3977 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3979 while (!completed) {
3981 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3983 #ifdef MODEST_TOOLKIT_HILDON2
3984 *username = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_username)));
3986 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
3989 /* Note that an empty field becomes the "" string */
3990 if (*username && strlen (*username) > 0) {
3991 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
3992 server_account_name,
3996 const gboolean username_was_changed =
3997 (strcmp (*username, initial_username) != 0);
3998 if (username_was_changed) {
3999 g_warning ("%s: tinymail does not yet support changing the "
4000 "username in the get_password() callback.\n", __FUNCTION__);
4006 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
4007 _("mcen_ib_username_pw_incorrect"));
4013 #ifdef MODEST_TOOLKIT_HILDON2
4014 *password = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_password)));
4016 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
4019 /* We do not save the password in the configuration,
4020 * because this function is only called for passwords that should
4021 * not be remembered:
4022 modest_server_account_set_password (
4023 modest_runtime_get_account_mgr(), server_account_name,
4030 #ifndef MODEST_TOOLKIT_HILDON2
4031 /* Set parent to NULL or the banner will disappear with its parent dialog */
4032 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
4044 /* This is not in the Maemo UI spec:
4045 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
4051 g_free (initial_username);
4052 gtk_widget_destroy (dialog);
4053 g_slice_free (PasswordDialogFields, fields);
4055 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
4059 modest_ui_actions_on_cut (GtkAction *action,
4060 ModestWindow *window)
4062 GtkWidget *focused_widget;
4063 GtkClipboard *clipboard;
4065 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4066 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4067 if (GTK_IS_EDITABLE (focused_widget)) {
4068 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
4069 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4070 gtk_clipboard_store (clipboard);
4071 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4072 GtkTextBuffer *buffer;
4074 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4075 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4076 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
4077 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4078 gtk_clipboard_store (clipboard);
4080 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4081 TnyList *header_list = modest_header_view_get_selected_headers (
4082 MODEST_HEADER_VIEW (focused_widget));
4083 gboolean continue_download = FALSE;
4084 gint num_of_unc_msgs;
4086 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4088 if (num_of_unc_msgs) {
4089 TnyAccount *account = get_account_from_header_list (header_list);
4091 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4092 g_object_unref (account);
4096 if (num_of_unc_msgs == 0 || continue_download) {
4097 /* modest_platform_information_banner (
4098 NULL, NULL, _CS("mcen_ib_getting_items"));*/
4099 modest_header_view_cut_selection (
4100 MODEST_HEADER_VIEW (focused_widget));
4103 g_object_unref (header_list);
4104 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4105 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4110 modest_ui_actions_on_copy (GtkAction *action,
4111 ModestWindow *window)
4113 GtkClipboard *clipboard;
4114 GtkWidget *focused_widget;
4115 gboolean copied = TRUE;
4117 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4118 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4120 if (GTK_IS_LABEL (focused_widget)) {
4122 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4123 gtk_clipboard_set_text (clipboard, selection, -1);
4125 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4126 gtk_clipboard_store (clipboard);
4127 } else if (GTK_IS_EDITABLE (focused_widget)) {
4128 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4129 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4130 gtk_clipboard_store (clipboard);
4131 } else if (GTK_IS_HTML (focused_widget)) {
4134 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4135 if ((sel == NULL) || (sel[0] == '\0')) {
4138 gtk_html_copy (GTK_HTML (focused_widget));
4139 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4140 gtk_clipboard_store (clipboard);
4142 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4143 GtkTextBuffer *buffer;
4144 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4145 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4146 gtk_text_buffer_copy_clipboard (buffer, clipboard);
4147 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4148 gtk_clipboard_store (clipboard);
4150 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4151 TnyList *header_list = modest_header_view_get_selected_headers (
4152 MODEST_HEADER_VIEW (focused_widget));
4153 gboolean continue_download = FALSE;
4154 gint num_of_unc_msgs;
4156 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4158 if (num_of_unc_msgs) {
4159 TnyAccount *account = get_account_from_header_list (header_list);
4161 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4162 g_object_unref (account);
4166 if (num_of_unc_msgs == 0 || continue_download) {
4167 modest_platform_information_banner (
4168 NULL, NULL, _CS("mcen_ib_getting_items"));
4169 modest_header_view_copy_selection (
4170 MODEST_HEADER_VIEW (focused_widget));
4174 g_object_unref (header_list);
4176 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4177 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4180 /* Show information banner if there was a copy to clipboard */
4182 modest_platform_information_banner (
4183 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4187 modest_ui_actions_on_undo (GtkAction *action,
4188 ModestWindow *window)
4190 ModestEmailClipboard *clipboard = NULL;
4192 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4193 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4194 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4195 /* Clear clipboard source */
4196 clipboard = modest_runtime_get_email_clipboard ();
4197 modest_email_clipboard_clear (clipboard);
4200 g_return_if_reached ();
4205 modest_ui_actions_on_redo (GtkAction *action,
4206 ModestWindow *window)
4208 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4209 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4212 g_return_if_reached ();
4218 destroy_information_note (ModestMailOperation *mail_op,
4221 /* destroy information note */
4222 gtk_widget_destroy (GTK_WIDGET(user_data));
4226 destroy_folder_information_note (ModestMailOperation *mail_op,
4227 TnyFolder *new_folder,
4230 /* destroy information note */
4231 gtk_widget_destroy (GTK_WIDGET(user_data));
4236 paste_as_attachment_free (gpointer data)
4238 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4240 if (helper->banner) {
4241 gtk_widget_destroy (helper->banner);
4242 g_object_unref (helper->banner);
4248 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4253 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4254 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4259 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4264 modest_ui_actions_on_paste (GtkAction *action,
4265 ModestWindow *window)
4267 GtkWidget *focused_widget = NULL;
4268 GtkWidget *inf_note = NULL;
4269 ModestMailOperation *mail_op = NULL;
4271 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4272 if (GTK_IS_EDITABLE (focused_widget)) {
4273 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4274 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4275 ModestEmailClipboard *e_clipboard = NULL;
4276 e_clipboard = modest_runtime_get_email_clipboard ();
4277 if (modest_email_clipboard_cleared (e_clipboard)) {
4278 GtkTextBuffer *buffer;
4279 GtkClipboard *clipboard;
4281 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4282 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4283 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4284 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4285 ModestMailOperation *mail_op;
4286 TnyFolder *src_folder = NULL;
4287 TnyList *data = NULL;
4289 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4290 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4291 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4292 _CS("ckct_nw_pasting"));
4293 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4294 mail_op = modest_mail_operation_new (G_OBJECT (window));
4295 if (helper->banner != NULL) {
4296 g_object_ref (G_OBJECT (helper->banner));
4297 gtk_widget_show (GTK_WIDGET (helper->banner));
4301 modest_mail_operation_get_msgs_full (mail_op,
4303 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4305 paste_as_attachment_free);
4309 g_object_unref (data);
4311 g_object_unref (src_folder);
4314 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4315 ModestEmailClipboard *clipboard = NULL;
4316 TnyFolder *src_folder = NULL;
4317 TnyFolderStore *folder_store = NULL;
4318 TnyList *data = NULL;
4319 gboolean delete = FALSE;
4321 /* Check clipboard source */
4322 clipboard = modest_runtime_get_email_clipboard ();
4323 if (modest_email_clipboard_cleared (clipboard))
4326 /* Get elements to paste */
4327 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4329 /* Create a new mail operation */
4330 mail_op = modest_mail_operation_new (G_OBJECT(window));
4332 /* Get destination folder */
4333 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4335 /* transfer messages */
4339 /* Ask for user confirmation */
4341 modest_ui_actions_msgs_move_to_confirmation (window,
4342 TNY_FOLDER (folder_store),
4346 if (response == GTK_RESPONSE_OK) {
4347 /* Launch notification */
4348 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4349 _CS("ckct_nw_pasting"));
4350 if (inf_note != NULL) {
4351 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4352 gtk_widget_show (GTK_WIDGET(inf_note));
4355 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4356 modest_mail_operation_xfer_msgs (mail_op,
4358 TNY_FOLDER (folder_store),
4360 destroy_information_note,
4363 g_object_unref (mail_op);
4366 } else if (src_folder != NULL) {
4367 /* Launch notification */
4368 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4369 _CS("ckct_nw_pasting"));
4370 if (inf_note != NULL) {
4371 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4372 gtk_widget_show (GTK_WIDGET(inf_note));
4375 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4376 modest_mail_operation_xfer_folder (mail_op,
4380 destroy_folder_information_note,
4386 g_object_unref (data);
4387 if (src_folder != NULL)
4388 g_object_unref (src_folder);
4389 if (folder_store != NULL)
4390 g_object_unref (folder_store);
4396 modest_ui_actions_on_select_all (GtkAction *action,
4397 ModestWindow *window)
4399 GtkWidget *focused_widget;
4401 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4402 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4403 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4404 } else if (GTK_IS_LABEL (focused_widget)) {
4405 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4406 } else if (GTK_IS_EDITABLE (focused_widget)) {
4407 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4408 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4409 GtkTextBuffer *buffer;
4410 GtkTextIter start, end;
4412 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4413 gtk_text_buffer_get_start_iter (buffer, &start);
4414 gtk_text_buffer_get_end_iter (buffer, &end);
4415 gtk_text_buffer_select_range (buffer, &start, &end);
4416 } else if (GTK_IS_HTML (focused_widget)) {
4417 gtk_html_select_all (GTK_HTML (focused_widget));
4418 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4419 GtkWidget *header_view = focused_widget;
4420 GtkTreeSelection *selection = NULL;
4422 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4423 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4424 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4427 /* Disable window dimming management */
4428 modest_window_disable_dimming (MODEST_WINDOW(window));
4430 /* Select all messages */
4431 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4432 gtk_tree_selection_select_all (selection);
4434 /* Set focuse on header view */
4435 gtk_widget_grab_focus (header_view);
4437 /* Enable window dimming management */
4438 modest_window_enable_dimming (MODEST_WINDOW(window));
4439 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4440 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4446 modest_ui_actions_on_mark_as_read (GtkAction *action,
4447 ModestWindow *window)
4449 g_return_if_fail (MODEST_IS_WINDOW(window));
4451 /* Mark each header as read */
4452 do_headers_action (window, headers_action_mark_as_read, NULL);
4456 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4457 ModestWindow *window)
4459 g_return_if_fail (MODEST_IS_WINDOW(window));
4461 /* Mark each header as read */
4462 do_headers_action (window, headers_action_mark_as_unread, NULL);
4466 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4467 GtkRadioAction *selected,
4468 ModestWindow *window)
4472 value = gtk_radio_action_get_current_value (selected);
4473 if (MODEST_IS_WINDOW (window)) {
4474 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4479 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4480 GtkRadioAction *selected,
4481 ModestWindow *window)
4483 TnyHeaderFlags flags;
4484 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4486 flags = gtk_radio_action_get_current_value (selected);
4487 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4491 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4492 GtkRadioAction *selected,
4493 ModestWindow *window)
4497 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4499 file_format = gtk_radio_action_get_current_value (selected);
4500 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4505 modest_ui_actions_on_zoom_plus (GtkAction *action,
4506 ModestWindow *window)
4508 g_return_if_fail (MODEST_IS_WINDOW (window));
4510 modest_window_zoom_plus (MODEST_WINDOW (window));
4514 modest_ui_actions_on_zoom_minus (GtkAction *action,
4515 ModestWindow *window)
4517 g_return_if_fail (MODEST_IS_WINDOW (window));
4519 modest_window_zoom_minus (MODEST_WINDOW (window));
4523 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4524 ModestWindow *window)
4526 ModestWindowMgr *mgr;
4527 gboolean fullscreen, active;
4528 g_return_if_fail (MODEST_IS_WINDOW (window));
4530 mgr = modest_runtime_get_window_mgr ();
4532 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4533 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4535 if (active != fullscreen) {
4536 modest_window_mgr_set_fullscreen_mode (mgr, active);
4537 #ifndef MODEST_TOOLKIT_HILDON2
4538 gtk_window_present (GTK_WINDOW (window));
4544 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4545 ModestWindow *window)
4547 ModestWindowMgr *mgr;
4548 gboolean fullscreen;
4550 g_return_if_fail (MODEST_IS_WINDOW (window));
4552 mgr = modest_runtime_get_window_mgr ();
4553 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4554 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4556 #ifndef MODEST_TOOLKIT_HILDON2
4557 gtk_window_present (GTK_WINDOW (window));
4562 * Used by modest_ui_actions_on_details to call do_headers_action
4565 headers_action_show_details (TnyHeader *header,
4566 ModestWindow *window,
4570 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header);
4574 * Show the header details in a ModestDetailsDialog widget
4577 modest_ui_actions_on_details (GtkAction *action,
4580 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4584 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4588 header = tny_msg_get_header (msg);
4590 headers_action_show_details (header, win, NULL);
4591 g_object_unref (header);
4593 g_object_unref (msg);
4595 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4596 GtkWidget *folder_view, *header_view;
4598 /* Check which widget has the focus */
4599 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4600 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4601 if (gtk_widget_is_focus (folder_view)) {
4602 TnyFolderStore *folder_store
4603 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4604 if (!folder_store) {
4605 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4608 /* Show only when it's a folder */
4609 /* This function should not be called for account items,
4610 * because we dim the menu item for them. */
4611 if (TNY_IS_FOLDER (folder_store)) {
4612 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4613 TNY_FOLDER (folder_store));
4616 g_object_unref (folder_store);
4619 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4620 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4621 /* Show details of each header */
4622 do_headers_action (win, headers_action_show_details, header_view);
4624 #ifdef MODEST_TOOLKIT_HILDON2
4625 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4627 GtkWidget *header_view;
4629 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4630 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4632 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4634 g_object_unref (folder);
4641 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4642 ModestMsgEditWindow *window)
4644 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4646 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4650 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4651 ModestMsgEditWindow *window)
4653 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4655 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4659 modest_ui_actions_toggle_folders_view (GtkAction *action,
4660 ModestMainWindow *main_window)
4662 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4664 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4665 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4667 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4671 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4672 ModestWindow *window)
4674 gboolean active, fullscreen = FALSE;
4675 ModestWindowMgr *mgr;
4677 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4679 /* Check if we want to toggle the toolbar view in fullscreen
4681 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4682 "ViewShowToolbarFullScreen")) {
4686 /* Toggle toolbar */
4687 mgr = modest_runtime_get_window_mgr ();
4688 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4692 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4693 ModestMsgEditWindow *window)
4695 modest_msg_edit_window_select_font (window);
4700 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4701 const gchar *display_name,
4704 /* don't update the display name if it was already set;
4705 * updating the display name apparently is expensive */
4706 const gchar* old_name = gtk_window_get_title (window);
4708 if (display_name == NULL)
4711 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4712 return; /* don't do anything */
4714 /* This is usually used to change the title of the main window, which
4715 * is the one that holds the folder view. Note that this change can
4716 * happen even when the widget doesn't have the focus. */
4717 gtk_window_set_title (window, display_name);
4722 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4724 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4725 modest_msg_edit_window_select_contacts (window);
4729 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4731 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4732 modest_msg_edit_window_check_names (window, FALSE);
4735 #ifndef MODEST_TOOLKIT_HILDON2
4737 * This function is used to track changes in the selection of the
4738 * folder view that is inside the "move to" dialog to enable/disable
4739 * the OK button because we do not want the user to select a disallowed
4740 * destination for a folder.
4741 * The user also not desired to be able to use NEW button on items where
4742 * folder creation is not possibel.
4745 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4746 TnyFolderStore *folder_store,
4750 GtkWidget *dialog = NULL;
4751 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4752 gboolean moving_folder = FALSE;
4753 gboolean is_local_account = TRUE;
4754 GtkWidget *folder_view = NULL;
4755 ModestTnyFolderRules rules;
4757 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
4762 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
4766 /* check if folder_store is an remote account */
4767 if (TNY_IS_ACCOUNT (folder_store)) {
4768 TnyAccount *local_account = NULL;
4769 TnyAccount *mmc_account = NULL;
4770 ModestTnyAccountStore *account_store = NULL;
4772 account_store = modest_runtime_get_account_store ();
4773 local_account = modest_tny_account_store_get_local_folders_account (account_store);
4774 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
4776 if ((gpointer) local_account != (gpointer) folder_store &&
4777 (gpointer) mmc_account != (gpointer) folder_store) {
4778 ModestProtocolType proto;
4779 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
4780 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
4781 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
4783 is_local_account = FALSE;
4784 /* New button should be dimmed on remote
4786 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4788 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
4790 g_object_unref (local_account);
4792 /* It could not exist */
4794 g_object_unref (mmc_account);
4797 /* Check the target folder rules */
4798 if (TNY_IS_FOLDER (folder_store)) {
4799 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
4800 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
4801 ok_sensitive = FALSE;
4802 new_sensitive = FALSE;
4807 /* Check if we're moving a folder */
4808 if (MODEST_IS_MAIN_WINDOW (user_data)) {
4809 /* Get the widgets */
4810 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
4811 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4812 if (gtk_widget_is_focus (folder_view))
4813 moving_folder = TRUE;
4816 if (moving_folder) {
4817 TnyFolderStore *moved_folder = NULL, *parent = NULL;
4819 /* Get the folder to move */
4820 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4822 /* Check that we're not moving to the same folder */
4823 if (TNY_IS_FOLDER (moved_folder)) {
4824 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
4825 if (parent == folder_store)
4826 ok_sensitive = FALSE;
4827 g_object_unref (parent);
4830 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
4831 /* Do not allow to move to an account unless it's the
4832 local folders account */
4833 if (!is_local_account)
4834 ok_sensitive = FALSE;
4837 if (ok_sensitive && (moved_folder == folder_store)) {
4838 /* Do not allow to move to itself */
4839 ok_sensitive = FALSE;
4841 g_object_unref (moved_folder);
4843 TnyFolder *src_folder = NULL;
4845 /* Moving a message */
4846 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
4848 TnyHeader *header = NULL;
4849 header = modest_msg_view_window_get_header
4850 (MODEST_MSG_VIEW_WINDOW (user_data));
4851 if (!TNY_IS_HEADER(header))
4852 g_warning ("%s: could not get source header", __FUNCTION__);
4854 src_folder = tny_header_get_folder (header);
4857 g_object_unref (header);
4860 TNY_FOLDER (modest_folder_view_get_selected
4861 (MODEST_FOLDER_VIEW (folder_view)));
4864 if (TNY_IS_FOLDER(src_folder)) {
4865 /* Do not allow to move the msg to the same folder */
4866 /* Do not allow to move the msg to an account */
4867 if ((gpointer) src_folder == (gpointer) folder_store ||
4868 TNY_IS_ACCOUNT (folder_store))
4869 ok_sensitive = FALSE;
4870 g_object_unref (src_folder);
4872 g_warning ("%s: could not get source folder", __FUNCTION__);
4876 /* Set sensitivity of the OK and NEW button */
4877 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
4878 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
4883 on_move_to_dialog_response (GtkDialog *dialog,
4887 GtkWidget *parent_win;
4888 MoveToInfo *helper = NULL;
4889 ModestFolderView *folder_view;
4891 helper = (MoveToInfo *) user_data;
4893 parent_win = (GtkWidget *) helper->win;
4894 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
4895 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4898 TnyFolderStore *dst_folder;
4900 case MODEST_GTK_RESPONSE_NEW_FOLDER:
4901 modest_ui_actions_create_folder (GTK_WIDGET (dialog), GTK_WIDGET (folder_view));
4903 case GTK_RESPONSE_NONE:
4904 case GTK_RESPONSE_CANCEL:
4905 case GTK_RESPONSE_DELETE_EVENT:
4907 case GTK_RESPONSE_OK:
4908 dst_folder = modest_folder_view_get_selected (folder_view);
4910 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
4911 /* Clean list to move used for filtering */
4912 modest_folder_view_set_list_to_move (folder_view, NULL);
4914 modest_ui_actions_on_main_window_move_to (NULL,
4915 GTK_WIDGET (folder_view),
4917 MODEST_MAIN_WINDOW (parent_win));
4918 #ifdef MODEST_TOOLKIT_HILDON2
4919 } else if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
4920 /* Clean list to move used for filtering */
4921 modest_folder_view_set_list_to_move (folder_view, NULL);
4923 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
4926 GTK_WINDOW (parent_win));
4929 /* if the user selected a root folder
4930 (account) then do not perform any action */
4931 if (TNY_IS_ACCOUNT (dst_folder)) {
4932 g_signal_stop_emission_by_name (dialog, "response");
4936 /* Clean list to move used for filtering */
4937 modest_folder_view_set_list_to_move (folder_view, NULL);
4939 /* Moving from headers window in edit mode */
4940 modest_ui_actions_on_window_move_to (NULL, helper->list,
4942 MODEST_WINDOW (parent_win));
4946 g_object_unref (dst_folder);
4950 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
4953 /* Free the helper and exit */
4955 g_object_unref (helper->list);
4956 g_slice_free (MoveToInfo, helper);
4957 gtk_widget_destroy (GTK_WIDGET (dialog));
4961 create_move_to_dialog (GtkWindow *win,
4962 GtkWidget *folder_view,
4963 TnyList *list_to_move)
4965 GtkWidget *dialog, *tree_view = NULL;
4967 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
4969 #ifndef MODEST_TOOLKIT_HILDON2
4970 /* Track changes in the selection to
4971 * disable the OK button whenever "Move to" is not possible
4972 * disbale NEW button whenever New is not possible */
4973 g_signal_connect (tree_view,
4974 "folder_selection_changed",
4975 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
4979 /* It could happen that we're trying to move a message from a
4980 window (msg window for example) after the main window was
4981 closed, so we can not just get the model of the folder
4983 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4984 const gchar *visible_id = NULL;
4986 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4987 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4988 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4989 MODEST_FOLDER_VIEW(tree_view));
4992 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4994 /* Show the same account than the one that is shown in the main window */
4995 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
4998 const gchar *active_account_name = NULL;
4999 ModestAccountMgr *mgr = NULL;
5000 ModestAccountSettings *settings = NULL;
5001 ModestServerAccountSettings *store_settings = NULL;
5003 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5004 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5005 modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view),
5006 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
5008 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
5009 mgr = modest_runtime_get_account_mgr ();
5010 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
5013 const gchar *store_account_name;
5014 store_settings = modest_account_settings_get_store_settings (settings);
5015 store_account_name = modest_server_account_settings_get_account_name (store_settings);
5017 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
5018 store_account_name);
5019 g_object_unref (store_settings);
5020 g_object_unref (settings);
5024 /* we keep a pointer to the embedded folder view, so we can
5025 * retrieve it with get_folder_view_from_move_to_dialog (see
5026 * above) later (needed for focus handling)
5028 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
5030 /* Hide special folders */
5031 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
5033 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
5034 #ifndef MODEST_TOOLKIT_HILDON2
5035 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5038 gtk_widget_show (GTK_WIDGET (tree_view));
5044 * Shows a confirmation dialog to the user when we're moving messages
5045 * from a remote server to the local storage. Returns the dialog
5046 * response. If it's other kind of movement then it always returns
5049 * This one is used by the next functions:
5050 * modest_ui_actions_on_paste - commented out
5051 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
5054 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
5055 TnyFolder *dest_folder,
5059 gint response = GTK_RESPONSE_OK;
5060 TnyAccount *account = NULL;
5061 TnyFolder *src_folder = NULL;
5062 TnyIterator *iter = NULL;
5063 TnyHeader *header = NULL;
5065 /* return with OK if the destination is a remote folder */
5066 if (modest_tny_folder_is_remote_folder (dest_folder))
5067 return GTK_RESPONSE_OK;
5069 /* Get source folder */
5070 iter = tny_list_create_iterator (headers);
5071 header = TNY_HEADER (tny_iterator_get_current (iter));
5073 src_folder = tny_header_get_folder (header);
5074 g_object_unref (header);
5076 g_object_unref (iter);
5078 /* if no src_folder, message may be an attahcment */
5079 if (src_folder == NULL)
5080 return GTK_RESPONSE_CANCEL;
5082 /* If the source is a local or MMC folder */
5083 if (!modest_tny_folder_is_remote_folder (src_folder)) {
5084 g_object_unref (src_folder);
5085 return GTK_RESPONSE_OK;
5088 /* Get the account */
5089 account = tny_folder_get_account (src_folder);
5091 /* now if offline we ask the user */
5092 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
5093 response = GTK_RESPONSE_OK;
5095 response = GTK_RESPONSE_CANCEL;
5098 g_object_unref (src_folder);
5099 g_object_unref (account);
5105 move_to_helper_destroyer (gpointer user_data)
5107 MoveToHelper *helper = (MoveToHelper *) user_data;
5109 /* Close the "Pasting" information banner */
5110 if (helper->banner) {
5111 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5112 g_object_unref (helper->banner);
5114 if (gtk_tree_row_reference_valid (helper->reference)) {
5115 gtk_tree_row_reference_free (helper->reference);
5116 helper->reference = NULL;
5122 move_to_cb (ModestMailOperation *mail_op,
5125 MoveToHelper *helper = (MoveToHelper *) user_data;
5126 GObject *object = modest_mail_operation_get_source (mail_op);
5128 /* Note that the operation could have failed, in that case do
5130 if (modest_mail_operation_get_status (mail_op) !=
5131 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5134 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5135 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5137 if (!modest_msg_view_window_select_next_message (self) &&
5138 !modest_msg_view_window_select_previous_message (self)) {
5139 /* No more messages to view, so close this window */
5140 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5142 } else if (MODEST_IS_MAIN_WINDOW (object) &&
5143 gtk_tree_row_reference_valid (helper->reference)) {
5144 GtkWidget *header_view;
5146 GtkTreeSelection *sel;
5148 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5149 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5150 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5151 path = gtk_tree_row_reference_get_path (helper->reference);
5152 /* We need to unselect the previous one
5153 because we could be copying instead of
5155 gtk_tree_selection_unselect_all (sel);
5156 gtk_tree_selection_select_path (sel, path);
5157 gtk_tree_path_free (path);
5159 g_object_unref (object);
5162 /* Destroy the helper */
5163 move_to_helper_destroyer (helper);
5167 folder_move_to_cb (ModestMailOperation *mail_op,
5168 TnyFolder *new_folder,
5171 GtkWidget *folder_view;
5174 object = modest_mail_operation_get_source (mail_op);
5175 if (MODEST_IS_MAIN_WINDOW (object)) {
5176 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5177 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5178 g_object_ref (folder_view);
5179 g_object_unref (object);
5180 move_to_cb (mail_op, user_data);
5181 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5182 g_object_unref (folder_view);
5184 move_to_cb (mail_op, user_data);
5189 msgs_move_to_cb (ModestMailOperation *mail_op,
5192 move_to_cb (mail_op, user_data);
5196 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5199 GObject *win = NULL;
5201 #ifndef MODEST_TOOLKIT_HILDON2
5202 ModestWindow *main_window = NULL;
5204 /* Disable next automatic folder selection */
5205 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5206 FALSE); /* don't create */
5208 GtkWidget *folder_view = NULL;
5210 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5211 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5212 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5214 if (user_data && TNY_IS_FOLDER (user_data)) {
5215 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5216 TNY_FOLDER (user_data), FALSE);
5220 /* Show notification dialog only if the main window exists */
5221 win = modest_mail_operation_get_source (mail_op);
5222 modest_platform_run_information_dialog ((GtkWindow *) win,
5223 _("mail_in_ui_folder_move_target_error"),
5226 g_object_unref (win);
5230 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5239 gint pending_purges = 0;
5240 gboolean some_purged = FALSE;
5241 ModestWindow *win = MODEST_WINDOW (user_data);
5242 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5244 /* If there was any error */
5245 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5246 modest_window_mgr_unregister_header (mgr, header);
5250 /* Once the message has been retrieved for purging, we check if
5251 * it's all ok for purging */
5253 parts = tny_simple_list_new ();
5254 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5255 iter = tny_list_create_iterator (parts);
5257 while (!tny_iterator_is_done (iter)) {
5259 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5260 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5261 if (tny_mime_part_is_purged (part))
5268 g_object_unref (part);
5270 tny_iterator_next (iter);
5272 g_object_unref (iter);
5275 if (pending_purges>0) {
5277 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5279 if (response == GTK_RESPONSE_OK) {
5282 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5283 iter = tny_list_create_iterator (parts);
5284 while (!tny_iterator_is_done (iter)) {
5287 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5288 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5289 tny_mime_part_set_purged (part);
5292 g_object_unref (part);
5294 tny_iterator_next (iter);
5296 g_object_unref (iter);
5298 tny_msg_rewrite_cache (msg);
5300 gtk_widget_destroy (info);
5304 modest_window_mgr_unregister_header (mgr, header);
5306 g_object_unref (parts);
5310 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5311 ModestMainWindow *win)
5313 GtkWidget *header_view;
5314 TnyList *header_list;
5316 TnyHeaderFlags flags;
5317 ModestWindow *msg_view_window = NULL;
5320 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5322 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5323 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5325 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5327 g_warning ("%s: no header selected", __FUNCTION__);
5331 if (tny_list_get_length (header_list) == 1) {
5332 TnyIterator *iter = tny_list_create_iterator (header_list);
5333 header = TNY_HEADER (tny_iterator_get_current (iter));
5334 g_object_unref (iter);
5338 if (!header || !TNY_IS_HEADER(header)) {
5339 g_warning ("%s: header is not valid", __FUNCTION__);
5343 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5344 header, &msg_view_window);
5345 flags = tny_header_get_flags (header);
5346 if (!(flags & TNY_HEADER_FLAG_CACHED))
5349 if (msg_view_window != NULL)
5350 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5352 /* do nothing; uid was registered before, so window is probably on it's way */
5353 g_warning ("debug: header %p has already been registered", header);
5356 ModestMailOperation *mail_op = NULL;
5357 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5358 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5359 modest_ui_actions_disk_operations_error_handler,
5361 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5362 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5364 g_object_unref (mail_op);
5367 g_object_unref (header);
5369 g_object_unref (header_list);
5373 * Checks if we need a connection to do the transfer and if the user
5374 * wants to connect to complete it
5377 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5378 TnyFolderStore *src_folder,
5380 TnyFolder *dst_folder,
5381 gboolean delete_originals,
5382 gboolean *need_connection,
5385 TnyAccount *src_account;
5386 gint uncached_msgs = 0;
5388 /* We don't need any further check if
5390 * 1- the source folder is local OR
5391 * 2- the device is already online
5393 if (!modest_tny_folder_store_is_remote (src_folder) ||
5394 tny_device_is_online (modest_runtime_get_device())) {
5395 *need_connection = FALSE;
5400 /* We must ask for a connection when
5402 * - the message(s) is not already cached OR
5403 * - the message(s) is cached but the leave_on_server setting
5404 * is FALSE (because we need to sync the source folder to
5405 * delete the message from the server (for IMAP we could do it
5406 * offline, it'll take place the next time we get a
5409 uncached_msgs = header_list_count_uncached_msgs (headers);
5410 src_account = get_account_from_folder_store (src_folder);
5411 if (uncached_msgs > 0) {
5415 *need_connection = TRUE;
5416 num_headers = tny_list_get_length (headers);
5417 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5419 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5420 GTK_RESPONSE_CANCEL) {
5426 /* The transfer is possible and the user wants to */
5429 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5430 const gchar *account_name;
5431 gboolean leave_on_server;
5433 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5434 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5437 if (leave_on_server == TRUE) {
5438 *need_connection = FALSE;
5440 *need_connection = TRUE;
5443 *need_connection = FALSE;
5448 g_object_unref (src_account);
5452 xfer_messages_error_handler (ModestMailOperation *mail_op,
5456 const GError *error;
5458 win = modest_mail_operation_get_source (mail_op);
5459 error = modest_mail_operation_get_error (mail_op);
5461 if (error && is_memory_full_error ((GError *) error, mail_op))
5462 modest_platform_information_banner ((GtkWidget *) win,
5463 NULL, _KR("cerm_device_memory_full"));
5465 modest_platform_run_information_dialog ((GtkWindow *) win,
5466 _("mail_in_ui_folder_move_target_error"),
5469 g_object_unref (win);
5473 TnyFolderStore *dst_folder;
5478 * Utility function that transfer messages from both the main window
5479 * and the msg view window when using the "Move to" dialog
5482 xfer_messages_performer (gboolean canceled,
5484 GtkWindow *parent_window,
5485 TnyAccount *account,
5488 ModestWindow *win = MODEST_WINDOW (parent_window);
5489 TnyAccount *dst_account = NULL;
5490 gboolean dst_forbids_message_add = FALSE;
5491 XferMsgsHelper *helper;
5492 MoveToHelper *movehelper;
5493 ModestMailOperation *mail_op;
5495 helper = (XferMsgsHelper *) user_data;
5497 if (canceled || err) {
5498 if (!check_memory_full_error ((GtkWidget *) parent_window, err)) {
5499 /* Show the proper error message */
5500 modest_ui_actions_on_account_connection_error (parent_window, account);
5505 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5507 /* tinymail will return NULL for local folders it seems */
5508 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5509 modest_tny_account_get_protocol_type (dst_account),
5510 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_MESSAGE_ADD);
5511 g_object_unref (dst_account);
5513 if (dst_forbids_message_add) {
5514 modest_platform_information_banner (GTK_WIDGET (win),
5516 ngettext("mail_in_ui_folder_move_target_error",
5517 "mail_in_ui_folder_move_targets_error",
5518 tny_list_get_length (helper->headers)));
5522 movehelper = g_new0 (MoveToHelper, 1);
5524 #ifndef MODEST_TOOLKIT_HILDON2
5525 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5526 _CS("ckct_nw_pasting"));
5527 if (movehelper->banner != NULL) {
5528 g_object_ref (movehelper->banner);
5529 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5533 if (MODEST_IS_MAIN_WINDOW (win)) {
5534 GtkWidget *header_view =
5535 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5536 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5537 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5540 /* Perform the mail operation */
5541 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5542 xfer_messages_error_handler,
5544 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5547 modest_mail_operation_xfer_msgs (mail_op,
5549 TNY_FOLDER (helper->dst_folder),
5554 g_object_unref (G_OBJECT (mail_op));
5556 g_object_unref (helper->dst_folder);
5557 g_object_unref (helper->headers);
5558 g_slice_free (XferMsgsHelper, helper);
5562 TnyFolder *src_folder;
5563 TnyFolderStore *dst_folder;
5564 gboolean delete_original;
5565 GtkWidget *folder_view;
5569 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
5570 TnyAccount *account, gpointer user_data)
5572 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5573 GtkTreeSelection *sel;
5574 ModestMailOperation *mail_op = NULL;
5576 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
5577 g_object_unref (G_OBJECT (info->src_folder));
5578 g_object_unref (G_OBJECT (info->dst_folder));
5583 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5584 #ifndef MODEST_TOOLKIT_HILDON2
5585 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5586 _CS("ckct_nw_pasting"));
5587 if (helper->banner != NULL) {
5588 g_object_ref (helper->banner);
5589 gtk_widget_show (GTK_WIDGET(helper->banner));
5592 /* Clean folder on header view before moving it */
5593 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5594 gtk_tree_selection_unselect_all (sel);
5596 /* Let gtk events run. We need that the folder
5597 view frees its reference to the source
5598 folder *before* issuing the mail operation
5599 so we need the signal handler of selection
5600 changed to happen before the mail
5602 while (gtk_events_pending ())
5603 gtk_main_iteration (); */
5606 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5607 modest_ui_actions_move_folder_error_handler,
5608 info->src_folder, NULL);
5609 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5612 /* Select *after* the changes */
5613 /* TODO: this function hangs UI after transfer */
5614 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
5615 /* TNY_FOLDER (src_folder), TRUE); */
5617 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
5618 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5619 TNY_FOLDER (info->dst_folder), TRUE);
5621 modest_mail_operation_xfer_folder (mail_op,
5622 TNY_FOLDER (info->src_folder),
5624 info->delete_original,
5627 g_object_unref (G_OBJECT (info->src_folder));
5629 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5632 /* Unref mail operation */
5633 g_object_unref (G_OBJECT (mail_op));
5634 g_object_unref (G_OBJECT (info->dst_folder));
5639 get_account_from_folder_store (TnyFolderStore *folder_store)
5641 if (TNY_IS_ACCOUNT (folder_store))
5642 return g_object_ref (folder_store);
5644 return tny_folder_get_account (TNY_FOLDER (folder_store));
5648 * UI handler for the "Move to" action when invoked from the
5652 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5653 GtkWidget *folder_view,
5654 TnyFolderStore *dst_folder,
5655 ModestMainWindow *win)
5657 ModestHeaderView *header_view = NULL;
5658 TnyFolderStore *src_folder = NULL;
5660 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5662 /* Get the source folder */
5663 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5665 /* Get header view */
5666 header_view = (ModestHeaderView *)
5667 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5669 /* Get folder or messages to transfer */
5670 if (gtk_widget_is_focus (folder_view)) {
5671 gboolean do_xfer = TRUE;
5673 /* Allow only to transfer folders to the local root folder */
5674 if (TNY_IS_ACCOUNT (dst_folder) &&
5675 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5676 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5678 } else if (!TNY_IS_FOLDER (src_folder)) {
5679 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5684 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5685 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5687 info->src_folder = g_object_ref (src_folder);
5688 info->dst_folder = g_object_ref (dst_folder);
5689 info->delete_original = TRUE;
5690 info->folder_view = folder_view;
5692 connect_info->callback = on_move_folder_cb;
5693 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5694 connect_info->data = info;
5696 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5697 TNY_FOLDER_STORE (src_folder),
5700 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5703 headers = modest_header_view_get_selected_headers(header_view);
5705 /* Transfer the messages */
5706 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
5707 headers, TNY_FOLDER (dst_folder));
5709 g_object_unref (headers);
5713 g_object_unref (src_folder);
5716 #ifdef MODEST_TOOLKIT_HILDON2
5718 * UI handler for the "Move to" action when invoked from the
5719 * ModestFolderWindow
5722 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
5723 TnyFolderStore *dst_folder,
5727 TnyFolderStore *src_folder = NULL;
5728 TnyIterator *iterator;
5730 if (tny_list_get_length (selection) != 1)
5733 iterator = tny_list_create_iterator (selection);
5734 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
5735 g_object_unref (iterator);
5738 gboolean do_xfer = TRUE;
5740 /* Allow only to transfer folders to the local root folder */
5741 if (TNY_IS_ACCOUNT (dst_folder) &&
5742 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5743 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5746 modest_platform_run_information_dialog (win,
5747 _("mail_in_ui_folder_move_target_error"),
5749 } else if (!TNY_IS_FOLDER (src_folder)) {
5750 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5755 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5756 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5758 info->src_folder = g_object_ref (src_folder);
5759 info->dst_folder = g_object_ref (dst_folder);
5760 info->delete_original = TRUE;
5761 info->folder_view = folder_view;
5763 connect_info->callback = on_move_folder_cb;
5764 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5765 connect_info->data = info;
5767 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5768 TNY_FOLDER_STORE (src_folder),
5773 g_object_unref (src_folder);
5779 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
5780 TnyFolder *src_folder,
5782 TnyFolder *dst_folder)
5784 gboolean need_connection = TRUE;
5785 gboolean do_xfer = TRUE;
5786 XferMsgsHelper *helper;
5788 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5789 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5790 g_return_if_fail (TNY_IS_LIST (headers));
5792 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5793 headers, TNY_FOLDER (dst_folder),
5794 TRUE, &need_connection,
5797 /* If we don't want to transfer just return */
5801 /* Create the helper */
5802 helper = g_slice_new (XferMsgsHelper);
5803 helper->dst_folder = g_object_ref (dst_folder);
5804 helper->headers = g_object_ref (headers);
5806 if (need_connection) {
5807 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5808 connect_info->callback = xfer_messages_performer;
5809 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5810 connect_info->data = helper;
5812 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5813 TNY_FOLDER_STORE (src_folder),
5816 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5817 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
5818 src_account, helper);
5819 g_object_unref (src_account);
5824 * UI handler for the "Move to" action when invoked from the
5825 * ModestMsgViewWindow
5828 modest_ui_actions_on_window_move_to (GtkAction *action,
5830 TnyFolderStore *dst_folder,
5833 TnyFolder *src_folder = NULL;
5835 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5838 TnyHeader *header = NULL;
5841 iter = tny_list_create_iterator (headers);
5842 header = (TnyHeader *) tny_iterator_get_current (iter);
5843 src_folder = tny_header_get_folder (header);
5845 /* Transfer the messages */
5846 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
5848 TNY_FOLDER (dst_folder));
5851 g_object_unref (header);
5852 g_object_unref (iter);
5853 g_object_unref (src_folder);
5858 modest_ui_actions_on_move_to (GtkAction *action,
5861 modest_ui_actions_on_edit_mode_move_to (win);
5865 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
5867 GtkWidget *dialog = NULL;
5868 MoveToInfo *helper = NULL;
5869 TnyList *list_to_move;
5871 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
5873 #ifndef MODEST_TOOLKIT_HILDON2
5874 /* Get the main window if exists */
5875 ModestMainWindow *main_window;
5876 if (MODEST_IS_MAIN_WINDOW (win))
5877 main_window = MODEST_MAIN_WINDOW (win);
5880 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5881 FALSE)); /* don't create */
5884 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
5889 if (tny_list_get_length (list_to_move) < 1) {
5890 g_object_unref (list_to_move);
5894 /* Create and run the dialog */
5895 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
5896 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
5897 GTK_WINDOW (dialog),
5901 helper = g_slice_new0 (MoveToInfo);
5902 helper->list = list_to_move;
5905 /* Listen to response signal */
5906 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
5908 /* Show the dialog */
5909 gtk_widget_show (dialog);
5915 * Calls #HeadersFunc for each header already selected in the main
5916 * window or the message currently being shown in the msg view window
5919 do_headers_action (ModestWindow *win,
5923 TnyList *headers_list = NULL;
5924 TnyIterator *iter = NULL;
5925 TnyHeader *header = NULL;
5926 TnyFolder *folder = NULL;
5929 headers_list = get_selected_headers (win);
5933 /* Get the folder */
5934 iter = tny_list_create_iterator (headers_list);
5935 header = TNY_HEADER (tny_iterator_get_current (iter));
5937 folder = tny_header_get_folder (header);
5938 g_object_unref (header);
5941 /* Call the function for each header */
5942 while (!tny_iterator_is_done (iter)) {
5943 header = TNY_HEADER (tny_iterator_get_current (iter));
5944 func (header, win, user_data);
5945 g_object_unref (header);
5946 tny_iterator_next (iter);
5949 /* Trick: do a poke status in order to speed up the signaling
5952 tny_folder_poke_status (folder);
5953 g_object_unref (folder);
5957 g_object_unref (iter);
5958 g_object_unref (headers_list);
5962 modest_ui_actions_view_attachment (GtkAction *action,
5963 ModestWindow *window)
5965 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5966 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5968 /* not supported window for this action */
5969 g_return_if_reached ();
5974 modest_ui_actions_save_attachments (GtkAction *action,
5975 ModestWindow *window)
5977 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5979 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5982 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5984 /* not supported window for this action */
5985 g_return_if_reached ();
5990 modest_ui_actions_remove_attachments (GtkAction *action,
5991 ModestWindow *window)
5993 if (MODEST_IS_MAIN_WINDOW (window)) {
5994 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
5995 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5996 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5998 /* not supported window for this action */
5999 g_return_if_reached ();
6004 modest_ui_actions_on_settings (GtkAction *action,
6009 dialog = modest_platform_get_global_settings_dialog ();
6010 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
6011 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
6012 gtk_widget_show_all (dialog);
6014 gtk_dialog_run (GTK_DIALOG (dialog));
6016 gtk_widget_destroy (dialog);
6020 modest_ui_actions_on_help (GtkAction *action,
6023 /* Help app is not available at all in fremantle */
6024 #ifndef MODEST_TOOLKIT_HILDON2
6025 const gchar *help_id;
6027 g_return_if_fail (win && GTK_IS_WINDOW(win));
6029 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
6032 modest_platform_show_help (GTK_WINDOW (win), help_id);
6037 modest_ui_actions_on_csm_help (GtkAction *action,
6040 /* Help app is not available at all in fremantle */
6041 #ifndef MODEST_TOOLKIT_HILDON2
6043 const gchar* help_id = NULL;
6044 GtkWidget *folder_view;
6045 TnyFolderStore *folder_store;
6047 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
6049 /* Get selected folder */
6050 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
6051 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6052 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6054 /* Switch help_id */
6055 if (folder_store && TNY_IS_FOLDER (folder_store))
6056 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
6059 g_object_unref (folder_store);
6062 modest_platform_show_help (GTK_WINDOW (win), help_id);
6064 modest_ui_actions_on_help (action, win);
6069 retrieve_contents_cb (ModestMailOperation *mail_op,
6076 /* We only need this callback to show an error in case of
6077 memory low condition */
6078 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
6079 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
6084 retrieve_msg_contents_performer (gboolean canceled,
6086 GtkWindow *parent_window,
6087 TnyAccount *account,
6090 ModestMailOperation *mail_op;
6091 TnyList *headers = TNY_LIST (user_data);
6093 if (err || canceled) {
6094 check_memory_full_error ((GtkWidget *) parent_window, err);
6098 /* Create mail operation */
6099 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
6100 modest_ui_actions_disk_operations_error_handler,
6102 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
6103 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
6106 g_object_unref (mail_op);
6108 g_object_unref (headers);
6109 g_object_unref (account);
6113 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
6114 ModestWindow *window)
6116 TnyList *headers = NULL;
6117 TnyAccount *account = NULL;
6118 TnyIterator *iter = NULL;
6119 TnyHeader *header = NULL;
6120 TnyFolder *folder = NULL;
6123 headers = get_selected_headers (window);
6127 /* Pick the account */
6128 iter = tny_list_create_iterator (headers);
6129 header = TNY_HEADER (tny_iterator_get_current (iter));
6130 folder = tny_header_get_folder (header);
6131 account = tny_folder_get_account (folder);
6132 g_object_unref (folder);
6133 g_object_unref (header);
6134 g_object_unref (iter);
6136 /* Connect and perform the message retrieval */
6137 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6138 g_object_ref (account),
6139 retrieve_msg_contents_performer,
6140 g_object_ref (headers));
6143 g_object_unref (account);
6144 g_object_unref (headers);
6148 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6150 g_return_if_fail (MODEST_IS_WINDOW (window));
6153 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6157 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6159 g_return_if_fail (MODEST_IS_WINDOW (window));
6162 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6166 modest_ui_actions_on_email_menu_activated (GtkAction *action,
6167 ModestWindow *window)
6169 g_return_if_fail (MODEST_IS_WINDOW (window));
6172 modest_ui_actions_check_menu_dimming_rules (window);
6176 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
6177 ModestWindow *window)
6179 g_return_if_fail (MODEST_IS_WINDOW (window));
6182 modest_ui_actions_check_menu_dimming_rules (window);
6186 modest_ui_actions_on_view_menu_activated (GtkAction *action,
6187 ModestWindow *window)
6189 g_return_if_fail (MODEST_IS_WINDOW (window));
6192 modest_ui_actions_check_menu_dimming_rules (window);
6196 modest_ui_actions_on_format_menu_activated (GtkAction *action,
6197 ModestWindow *window)
6199 g_return_if_fail (MODEST_IS_WINDOW (window));
6202 modest_ui_actions_check_menu_dimming_rules (window);
6206 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
6207 ModestWindow *window)
6209 g_return_if_fail (MODEST_IS_WINDOW (window));
6212 modest_ui_actions_check_menu_dimming_rules (window);
6216 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
6217 ModestWindow *window)
6219 g_return_if_fail (MODEST_IS_WINDOW (window));
6222 modest_ui_actions_check_menu_dimming_rules (window);
6226 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
6227 ModestWindow *window)
6229 g_return_if_fail (MODEST_IS_WINDOW (window));
6232 modest_ui_actions_check_menu_dimming_rules (window);
6236 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
6237 ModestWindow *window)
6239 g_return_if_fail (MODEST_IS_WINDOW (window));
6242 modest_ui_actions_check_menu_dimming_rules (window);
6246 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
6247 ModestWindow *window)
6249 g_return_if_fail (MODEST_IS_WINDOW (window));
6252 modest_ui_actions_check_menu_dimming_rules (window);
6256 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6258 g_return_if_fail (MODEST_IS_WINDOW (window));
6260 /* we check for low-mem; in that case, show a warning, and don't allow
6263 if (modest_platform_check_memory_low (window, TRUE))
6266 modest_platform_show_search_messages (GTK_WINDOW (window));
6270 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6272 g_return_if_fail (MODEST_IS_WINDOW (win));
6275 /* we check for low-mem; in that case, show a warning, and don't allow
6276 * for the addressbook
6278 if (modest_platform_check_memory_low (win, TRUE))
6282 modest_platform_show_addressbook (GTK_WINDOW (win));
6287 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6288 ModestWindow *window)
6291 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6293 if (GTK_IS_TOGGLE_ACTION (action))
6294 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6298 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window),
6303 on_send_receive_finished (ModestMailOperation *mail_op,
6306 GtkWidget *header_view, *folder_view;
6307 TnyFolderStore *folder_store;
6308 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6310 /* Set send/receive operation finished */
6311 modest_main_window_notify_send_receive_completed (main_win);
6313 /* Don't refresh the current folder if there were any errors */
6314 if (modest_mail_operation_get_status (mail_op) !=
6315 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6318 /* Refresh the current folder if we're viewing a window. We do
6319 this because the user won't be able to see the new mails in
6320 the selected folder after a Send&Receive because it only
6321 performs a poke_status, i.e, only the number of read/unread
6322 messages is updated, but the new headers are not
6324 folder_view = modest_main_window_get_child_widget (main_win,
6325 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6329 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6331 /* Do not need to refresh INBOX again because the
6332 update_account does it always automatically */
6333 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6334 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6335 ModestMailOperation *refresh_op;
6337 header_view = modest_main_window_get_child_widget (main_win,
6338 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6340 /* We do not need to set the contents style
6341 because it hasn't changed. We also do not
6342 need to save the widget status. Just force
6344 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6345 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6346 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6347 folder_refreshed_cb, main_win);
6348 g_object_unref (refresh_op);
6352 g_object_unref (folder_store);
6357 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6363 const gchar* server_name = NULL;
6364 TnyTransportAccount *transport;
6365 gchar *message = NULL;
6366 ModestProtocol *protocol;
6368 /* Don't show anything if the user cancelled something or the
6369 * send receive request is not interactive. Authentication
6370 * errors are managed by the account store so no need to show
6371 * a dialog here again */
6372 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6373 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6374 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6378 /* Get the server name. Note that we could be using a
6379 connection specific transport account */
6380 transport = (TnyTransportAccount *)
6381 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
6383 ModestTnyAccountStore *acc_store;
6384 const gchar *acc_name;
6385 TnyTransportAccount *conn_specific;
6387 acc_store = modest_runtime_get_account_store();
6388 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
6389 conn_specific = (TnyTransportAccount *)
6390 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
6391 if (conn_specific) {
6392 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
6393 g_object_unref (conn_specific);
6395 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
6397 g_object_unref (transport);
6401 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
6402 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
6403 tny_account_get_proto (TNY_ACCOUNT (transport)));
6405 g_warning ("%s: Account with no proto", __FUNCTION__);
6409 /* Show the appropriate message text for the GError: */
6410 switch (err->code) {
6411 case TNY_SERVICE_ERROR_CONNECT:
6412 message = modest_protocol_get_translation (protocol,
6413 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
6416 case TNY_SERVICE_ERROR_SEND:
6417 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6419 case TNY_SERVICE_ERROR_UNAVAILABLE:
6420 message = modest_protocol_get_translation (protocol,
6421 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
6425 g_warning ("%s: unexpected ERROR %d",
6426 __FUNCTION__, err->code);
6427 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6431 modest_platform_run_information_dialog (NULL, message, FALSE);
6436 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6441 ModestWindow *top_window = NULL;
6442 ModestWindowMgr *mgr = NULL;
6443 GtkWidget *header_view = NULL;
6444 TnyFolder *selected_folder = NULL;
6445 TnyFolderType folder_type;
6447 mgr = modest_runtime_get_window_mgr ();
6448 top_window = modest_window_mgr_get_current_top (mgr);
6453 #ifndef MODEST_TOOLKIT_HILDON2
6454 if (MODEST_IS_MAIN_WINDOW (top_window)) {
6455 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (top_window),
6456 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6459 if (MODEST_IS_HEADER_WINDOW (top_window)) {
6460 header_view = (GtkWidget *)
6461 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
6465 /* Get selected folder */
6467 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
6468 if (!selected_folder)
6471 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6472 #if GTK_CHECK_VERSION(2, 8, 0)
6473 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
6474 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6475 GtkTreeViewColumn *tree_column;
6477 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6478 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6480 gtk_tree_view_column_queue_resize (tree_column);
6482 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
6483 gtk_widget_queue_draw (header_view);
6486 #ifndef MODEST_TOOLKIT_HILDON2
6487 /* Rerun dimming rules, because the message could become deletable for example */
6488 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6489 MODEST_DIMMING_RULES_TOOLBAR);
6490 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6491 MODEST_DIMMING_RULES_MENU);
6495 g_object_unref (selected_folder);
6499 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6500 TnyAccount *account)
6502 ModestProtocolType protocol_type;
6503 ModestProtocol *protocol;
6504 gchar *error_note = NULL;
6506 protocol_type = modest_tny_account_get_protocol_type (account);
6507 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6510 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6511 if (error_note == NULL) {
6512 g_warning ("%s: This should not be reached", __FUNCTION__);
6514 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6515 g_free (error_note);
6520 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6524 TnyFolderStore *folder = NULL;
6525 TnyAccount *account = NULL;
6526 ModestProtocolType proto;
6527 ModestProtocol *protocol;
6528 TnyHeader *header = NULL;
6530 if (MODEST_IS_MAIN_WINDOW (win)) {
6531 GtkWidget *header_view;
6532 TnyList* headers = NULL;
6534 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6535 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6536 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6537 if (!headers || tny_list_get_length (headers) == 0) {
6539 g_object_unref (headers);
6542 iter = tny_list_create_iterator (headers);
6543 header = TNY_HEADER (tny_iterator_get_current (iter));
6544 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6545 g_object_unref (iter);
6546 g_object_unref (headers);
6547 #ifdef MODEST_TOOLKIT_HILDON2
6548 } else if (MODEST_IS_HEADER_WINDOW (win)) {
6549 GtkWidget *header_view;
6550 TnyList* headers = NULL;
6552 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
6553 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6554 if (!headers || tny_list_get_length (headers) == 0) {
6556 g_object_unref (headers);
6559 iter = tny_list_create_iterator (headers);
6560 header = TNY_HEADER (tny_iterator_get_current (iter));
6562 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6564 g_warning ("List should contain headers");
6566 g_object_unref (iter);
6567 g_object_unref (headers);
6569 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6570 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6571 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6574 if (!header || !folder)
6577 /* Get the account type */
6578 account = tny_folder_get_account (TNY_FOLDER (folder));
6579 proto = modest_tny_account_get_protocol_type (account);
6580 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6583 subject = tny_header_dup_subject (header);
6584 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6588 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6594 g_object_unref (account);
6596 g_object_unref (folder);
6598 g_object_unref (header);
6604 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6605 const gchar *account_name,
6606 const gchar *account_title)
6608 ModestAccountMgr *account_mgr;
6611 ModestProtocol *protocol;
6612 gboolean removed = FALSE;
6614 g_return_val_if_fail (account_name, FALSE);
6615 g_return_val_if_fail (account_title, FALSE);
6617 account_mgr = modest_runtime_get_account_mgr();
6619 /* The warning text depends on the account type: */
6620 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6621 modest_account_mgr_get_store_protocol (account_mgr,
6623 txt = modest_protocol_get_translation (protocol,
6624 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6627 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6629 response = modest_platform_run_confirmation_dialog (parent_window, txt);
6633 if (response == GTK_RESPONSE_OK) {
6634 /* Remove account. If it succeeds then it also removes
6635 the account from the ModestAccountView: */
6636 gboolean is_default = FALSE;
6637 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6638 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6640 g_free (default_account_name);
6642 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6644 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);