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 modest_ui_actions_run_account_setup_wizard (window);
736 modest_ui_actions_on_accounts (GtkAction *action,
739 /* This is currently only implemented for Maemo */
740 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
741 if (!modest_ui_actions_run_account_setup_wizard (win))
742 g_debug ("%s: wizard was already running", __FUNCTION__);
746 /* Show the list of accounts */
747 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
749 /* The accounts dialog must be modal */
750 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
751 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
756 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
758 /* This is currently only implemented for Maemo,
759 * because it requires an API (libconic) to detect different connection
762 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
764 /* Create the window if necessary: */
765 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
766 modest_connection_specific_smtp_window_fill_with_connections (
767 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
768 modest_runtime_get_account_mgr());
770 /* Show the window: */
771 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
772 GTK_WINDOW (specific_window), (GtkWindow *) win);
773 gtk_widget_show (specific_window);
774 #endif /* !MODEST_TOOLKIT_GTK */
778 modest_ui_actions_compose_msg(ModestWindow *win,
781 const gchar *bcc_str,
782 const gchar *subject_str,
783 const gchar *body_str,
785 gboolean set_as_modified)
787 gchar *account_name = NULL;
789 TnyAccount *account = NULL;
790 TnyFolder *folder = NULL;
791 gchar *from_str = NULL, *signature = NULL, *body = NULL;
792 gboolean use_signature = FALSE;
793 ModestWindow *msg_win = NULL;
794 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
795 ModestTnyAccountStore *store = modest_runtime_get_account_store();
796 GnomeVFSFileSize total_size, allowed_size;
798 /* we check for low-mem */
799 if (modest_platform_check_memory_low (win, TRUE))
802 #ifdef MODEST_TOOLKIT_HILDON2
803 account_name = g_strdup (modest_window_get_active_account(win));
806 account_name = modest_account_mgr_get_default_account(mgr);
809 g_printerr ("modest: no account found\n");
812 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
814 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
817 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
819 g_printerr ("modest: failed to find Drafts folder\n");
822 from_str = modest_account_mgr_get_from_string (mgr, account_name);
824 g_printerr ("modest: failed get from string for '%s'\n", account_name);
828 signature = modest_account_mgr_get_signature (mgr, account_name, &use_signature);
829 if (body_str != NULL) {
830 body = use_signature ? g_strconcat(body_str, "\n--\n", signature, NULL) : g_strdup(body_str);
832 body = use_signature ? g_strconcat("\n--\n", signature, NULL) : g_strdup("");
835 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, body, NULL, NULL, NULL);
837 g_printerr ("modest: failed to create new msg\n");
841 /* Create and register edit window */
842 /* This is destroyed by TODO. */
844 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
845 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
847 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, win)) {
848 gtk_widget_destroy (GTK_WIDGET (msg_win));
851 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
852 gtk_widget_show_all (GTK_WIDGET (msg_win));
854 while (attachments) {
856 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
857 attachments->data, allowed_size);
859 if (total_size > allowed_size) {
860 g_warning ("%s: total size: %u",
861 __FUNCTION__, (unsigned int)total_size);
864 allowed_size -= total_size;
866 attachments = g_slist_next(attachments);
873 g_free (account_name);
875 g_object_unref (G_OBJECT(account));
877 g_object_unref (G_OBJECT(folder));
879 g_object_unref (G_OBJECT(msg));
883 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
885 /* if there are no accounts yet, just show the wizard */
886 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
887 if (!modest_ui_actions_run_account_setup_wizard (win))
890 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
895 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
899 ModestMailOperationStatus status;
901 /* If there is no message or the operation was not successful */
902 status = modest_mail_operation_get_status (mail_op);
903 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
906 /* If it's a memory low issue, then show a banner */
907 error = modest_mail_operation_get_error (mail_op);
908 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
909 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
910 GObject *source = modest_mail_operation_get_source (mail_op);
911 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
912 _KR("memr_ib_operation_disabled"),
914 g_object_unref (source);
917 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
918 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
919 gchar *subject, *msg, *format = NULL;
921 subject = tny_header_dup_subject (header);
923 subject = g_strdup (_("mail_va_no_subject"));
925 account = modest_mail_operation_get_account (mail_op);
927 ModestProtocol *protocol;
928 ModestProtocolType proto;
929 proto = modest_tny_account_get_protocol_type (account);
930 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), proto);
932 format = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
933 g_object_unref (account);
937 format = g_strdup (_("emev_ni_ui_imap_message_not_available_in_server"));
939 msg = g_strdup_printf (format, subject);
940 modest_platform_run_information_dialog (NULL, msg, FALSE);
946 /* Remove the header from the preregistered uids */
947 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
965 OpenMsgBannerInfo *banner_info;
966 GtkTreeRowReference *rowref;
970 open_msg_banner_idle (gpointer userdata)
972 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
974 gdk_threads_enter ();
975 banner_info->idle_handler = 0;
976 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
977 if (banner_info->banner)
978 g_object_ref (banner_info->banner);
980 gdk_threads_leave ();
986 get_header_view_from_window (ModestWindow *window)
988 GtkWidget *header_view;
990 if (MODEST_IS_MAIN_WINDOW (window)) {
991 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
992 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
993 #ifdef MODEST_TOOLKIT_HILDON2
994 } else if (MODEST_IS_HEADER_WINDOW (window)){
995 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
1005 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
1008 gchar *account = NULL;
1009 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
1014 folder = tny_header_get_folder (header);
1015 /* Gets folder type (OUTBOX headers will be opened in edit window */
1016 if (modest_tny_folder_is_local_folder (folder)) {
1017 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1018 if (folder_type == TNY_FOLDER_TYPE_INVALID)
1019 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1022 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
1023 TnyTransportAccount *traccount = NULL;
1024 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
1025 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
1027 ModestTnySendQueue *send_queue = NULL;
1028 ModestTnySendQueueStatus status;
1030 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
1031 TNY_ACCOUNT(traccount)));
1032 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
1033 if (TNY_IS_SEND_QUEUE (send_queue)) {
1034 msg_id = modest_tny_send_queue_get_msg_id (header);
1035 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
1037 /* Only open messages in outbox with the editor if they are in Failed state */
1038 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
1041 #ifdef MODEST_TOOLKIT_HILDON2
1043 /* In Fremantle we can not
1044 open any message from
1045 outbox which is not in
1051 g_object_unref(traccount);
1053 g_warning("Cannot get transport account for message in outbox!!");
1055 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
1056 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
1060 TnyAccount *acc = tny_folder_get_account (folder);
1063 g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (acc));
1064 g_object_unref (acc);
1068 g_object_unref (folder);
1074 open_msg_cb (ModestMailOperation *mail_op,
1081 ModestWindowMgr *mgr = NULL;
1082 ModestWindow *parent_win = NULL;
1083 ModestWindow *win = NULL;
1084 gchar *account = NULL;
1085 gboolean open_in_editor = FALSE;
1087 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1089 /* Do nothing if there was any problem with the mail
1090 operation. The error will be shown by the error_handler of
1091 the mail operation */
1092 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1095 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1097 /* Mark header as read */
1098 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1100 account = get_info_from_header (header, &open_in_editor, &can_open);
1104 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1106 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1108 if (open_in_editor) {
1109 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1110 gchar *from_header = NULL, *acc_name;
1112 from_header = tny_header_dup_from (header);
1114 /* we cannot edit without a valid account... */
1115 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1116 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1117 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1119 g_free (from_header);
1124 acc_name = modest_utils_get_account_name_from_recipient (from_header);
1125 g_free (from_header);
1131 win = modest_msg_edit_window_new (msg, account, TRUE);
1133 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1135 if (helper->rowref && helper->model) {
1136 win = modest_msg_view_window_new_with_header_model (msg, account, (const gchar*) uid,
1137 helper->model, helper->rowref);
1139 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
1144 /* Register and show new window */
1146 mgr = modest_runtime_get_window_mgr ();
1147 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1148 gtk_widget_destroy (GTK_WIDGET (win));
1151 gtk_widget_show_all (GTK_WIDGET(win));
1154 /* Update toolbar dimming state */
1155 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1156 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1162 g_object_unref (parent_win);
1166 is_memory_full_error (GError *error, ModestMailOperation *mail_op)
1168 gboolean enough_free_space = TRUE;
1169 GnomeVFSURI *cache_dir_uri;
1170 const gchar *cache_dir = NULL;
1171 GnomeVFSFileSize free_space;
1172 TnyAccountStore *acc_store;
1174 acc_store = TNY_ACCOUNT_STORE (modest_runtime_get_account_store ());
1176 /* Cache dir is different in case we're using an external storage (like MMC account) */
1178 TnyAccount *account = modest_mail_operation_get_account (mail_op);
1180 if (modest_tny_account_is_memory_card_account (account)) {
1181 cache_dir = g_getenv (MODEST_MMC1_VOLUMEPATH_ENV);
1183 g_object_unref (account);
1187 /* Get the default local cache dir */
1189 cache_dir = tny_account_store_get_cache_dir (acc_store);
1191 cache_dir_uri = gnome_vfs_uri_new (cache_dir);
1192 if (cache_dir_uri) {
1193 if (gnome_vfs_get_volume_free_space (cache_dir_uri, &free_space) == GNOME_VFS_OK) {
1194 if (free_space < MIN_FREE_SPACE)
1195 enough_free_space = FALSE;
1197 gnome_vfs_uri_unref (cache_dir_uri);
1200 if ((error->code == TNY_SYSTEM_ERROR_MEMORY ||
1201 /* When asking for a mail and no space left on device
1202 tinymail returns this error */
1203 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE ||
1204 /* When the folder summary could not be read or
1206 error->code == TNY_IO_ERROR_WRITE ||
1207 error->code == TNY_IO_ERROR_READ) &&
1208 !enough_free_space) {
1216 check_memory_full_error (GtkWidget *parent_window, GError *err)
1221 if (is_memory_full_error (err, NULL))
1222 modest_platform_information_banner (parent_window,
1223 NULL, _KR("cerm_device_memory_full"));
1224 else if (err->code == TNY_SYSTEM_ERROR_MEMORY)
1225 /* If the account was created in memory full
1226 conditions then tinymail won't be able to
1227 connect so it'll return this error code */
1228 modest_platform_information_banner (parent_window,
1229 NULL, _("emev_ui_imap_inbox_select_error"));
1237 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1240 const GError *error;
1241 GObject *win = NULL;
1242 ModestMailOperationStatus status;
1244 win = modest_mail_operation_get_source (mail_op);
1245 error = modest_mail_operation_get_error (mail_op);
1246 status = modest_mail_operation_get_status (mail_op);
1248 /* If the mail op has been cancelled then it's not an error:
1249 don't show any message */
1250 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1251 if (is_memory_full_error ((GError *) error, mail_op)) {
1252 modest_platform_information_banner ((GtkWidget *) win,
1253 NULL, _KR("cerm_device_memory_full"));
1254 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1255 modest_platform_information_banner ((GtkWidget *) win,
1256 NULL, _("emev_ui_imap_inbox_select_error"));
1257 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1258 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1259 modest_platform_information_banner ((GtkWidget *) win,
1260 NULL, _CS ("sfil_ni_unable_to_open_file_not_found"));
1261 } else if (user_data) {
1262 modest_platform_information_banner ((GtkWidget *) win,
1268 g_object_unref (win);
1272 * Returns the account a list of headers belongs to. It returns a
1273 * *new* reference so don't forget to unref it
1276 get_account_from_header_list (TnyList *headers)
1278 TnyAccount *account = NULL;
1280 if (tny_list_get_length (headers) > 0) {
1281 TnyIterator *iter = tny_list_create_iterator (headers);
1282 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1283 TnyFolder *folder = tny_header_get_folder (header);
1286 g_object_unref (header);
1288 while (!tny_iterator_is_done (iter)) {
1289 header = TNY_HEADER (tny_iterator_get_current (iter));
1290 folder = tny_header_get_folder (header);
1293 g_object_unref (header);
1295 tny_iterator_next (iter);
1300 account = tny_folder_get_account (folder);
1301 g_object_unref (folder);
1305 g_object_unref (header);
1307 g_object_unref (iter);
1313 get_account_from_header (TnyHeader *header)
1315 TnyAccount *account = NULL;
1318 folder = tny_header_get_folder (header);
1321 account = tny_folder_get_account (folder);
1322 g_object_unref (folder);
1328 open_msg_helper_destroyer (gpointer user_data)
1330 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1332 if (helper->banner_info) {
1333 g_free (helper->banner_info->message);
1334 if (helper->banner_info->idle_handler > 0) {
1335 g_source_remove (helper->banner_info->idle_handler);
1336 helper->banner_info->idle_handler = 0;
1338 if (helper->banner_info->banner != NULL) {
1339 gtk_widget_destroy (helper->banner_info->banner);
1340 g_object_unref (helper->banner_info->banner);
1341 helper->banner_info->banner = NULL;
1343 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1344 helper->banner_info = NULL;
1346 g_object_unref (helper->model);
1347 g_object_unref (helper->header);
1348 gtk_tree_row_reference_free (helper->rowref);
1349 g_slice_free (OpenMsgHelper, helper);
1353 open_msg_performer(gboolean canceled,
1355 GtkWindow *parent_window,
1356 TnyAccount *account,
1359 ModestMailOperation *mail_op = NULL;
1360 gchar *error_msg = NULL;
1361 ModestProtocolType proto;
1362 TnyConnectionStatus status;
1363 OpenMsgHelper *helper = NULL;
1364 ModestProtocol *protocol;
1365 ModestProtocolRegistry *protocol_registry;
1368 helper = (OpenMsgHelper *) user_data;
1370 status = tny_account_get_connection_status (account);
1371 if (err || canceled) {
1372 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1373 /* Free the helper */
1374 open_msg_helper_destroyer (helper);
1376 /* In memory full conditions we could get this error here */
1377 check_memory_full_error ((GtkWidget *) parent_window, err);
1382 /* Get the error message depending on the protocol */
1383 proto = modest_tny_account_get_protocol_type (account);
1384 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1385 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1388 protocol_registry = modest_runtime_get_protocol_registry ();
1389 subject = tny_header_dup_subject (helper->header);
1391 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1392 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1396 if (error_msg == NULL) {
1397 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1400 #ifndef MODEST_TOOLKIT_HILDON2
1401 gboolean show_open_draft = FALSE;
1402 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1404 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1406 TnyFolderType folder_type;
1408 folder = tny_header_get_folder (helper->header);
1409 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1410 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1411 g_object_unref (folder);
1415 #ifdef MODEST_TOOLKIT_HILDON2
1418 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1421 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1422 g_free (account_name);
1423 open_msg_helper_destroyer (helper);
1428 ModestWindow *window;
1429 GtkWidget *header_view;
1432 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1433 uid = modest_tny_folder_get_header_unique_id (helper->header);
1435 window = modest_msg_view_window_new_from_header_view
1436 (MODEST_HEADER_VIEW (header_view), account_name, uid, helper->rowref);
1437 if (window != NULL) {
1438 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1440 gtk_widget_destroy (GTK_WIDGET (window));
1442 gtk_widget_show_all (GTK_WIDGET(window));
1446 g_free (account_name);
1448 open_msg_helper_destroyer (helper);
1451 g_free (account_name);
1453 /* Create the mail operation */
1455 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1456 modest_ui_actions_disk_operations_error_handler,
1457 g_strdup (error_msg), g_free);
1458 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1462 #ifndef MODEST_TOOLKIT_HILDON2
1463 if (show_open_draft) {
1464 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1465 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1466 helper->banner_info->banner = NULL;
1467 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1468 helper->banner_info);
1474 headers = TNY_LIST (tny_simple_list_new ());
1475 tny_list_prepend (headers, G_OBJECT (helper->header));
1476 modest_mail_operation_get_msgs_full (mail_op,
1480 open_msg_helper_destroyer);
1481 g_object_unref (headers);
1488 g_object_unref (mail_op);
1489 g_object_unref (account);
1493 * This function is used by both modest_ui_actions_on_open and
1494 * modest_ui_actions_on_header_activated. This way we always do the
1495 * same when trying to open messages.
1498 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1500 ModestWindowMgr *mgr = NULL;
1501 TnyAccount *account;
1502 gboolean cached = FALSE;
1504 GtkWidget *header_view = NULL;
1505 OpenMsgHelper *helper;
1506 ModestWindow *window;
1508 g_return_if_fail (header != NULL && rowref != NULL);
1510 mgr = modest_runtime_get_window_mgr ();
1513 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1514 if (header_view == NULL)
1517 /* Get the account */
1518 account = get_account_from_header (header);
1523 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1525 /* Do not open again the message and present the
1526 window to the user */
1529 #ifndef MODEST_TOOLKIT_HILDON2
1530 gtk_window_present (GTK_WINDOW (window));
1533 /* the header has been registered already, we don't do
1534 * anything but wait for the window to come up*/
1535 g_debug ("header %p already registered, waiting for window", header);
1540 /* Open each message */
1541 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1543 /* Allways download if we are online. */
1544 if (!tny_device_is_online (modest_runtime_get_device ())) {
1547 /* If ask for user permission to download the messages */
1548 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1549 _("mcen_nc_get_msg"));
1551 /* End if the user does not want to continue */
1552 if (response == GTK_RESPONSE_CANCEL) {
1558 /* We register the window for opening */
1559 modest_window_mgr_register_header (mgr, header, NULL);
1561 /* Create the helper. We need to get a reference to the model
1562 here because it could change while the message is readed
1563 (the user could switch between folders) */
1564 helper = g_slice_new (OpenMsgHelper);
1565 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1566 helper->header = g_object_ref (header);
1567 helper->rowref = gtk_tree_row_reference_copy (rowref);
1568 helper->banner_info = NULL;
1570 /* Connect to the account and perform */
1572 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1573 open_msg_performer, helper);
1575 /* Call directly the performer, do not need to connect */
1576 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1577 g_object_ref (account), helper);
1582 g_object_unref (account);
1586 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1593 /* we check for low-mem; in that case, show a warning, and don't allow
1596 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1600 headers = get_selected_headers (win);
1604 headers_count = tny_list_get_length (headers);
1605 if (headers_count != 1) {
1606 if (headers_count > 1) {
1607 /* Don't allow activation if there are more than one message selected */
1608 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1611 g_object_unref (headers);
1615 iter = tny_list_create_iterator (headers);
1616 header = TNY_HEADER (tny_iterator_get_current (iter));
1617 g_object_unref (iter);
1621 open_msg_from_header (header, NULL, win);
1622 g_object_unref (header);
1625 g_object_unref(headers);
1629 rf_helper_window_closed (gpointer data,
1632 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1634 helper->parent_window = NULL;
1637 static ReplyForwardHelper*
1638 create_reply_forward_helper (ReplyForwardAction action,
1640 guint reply_forward_type,
1643 ReplyForwardHelper *rf_helper = NULL;
1644 const gchar *active_acc = modest_window_get_active_account (win);
1646 rf_helper = g_slice_new0 (ReplyForwardHelper);
1647 rf_helper->reply_forward_type = reply_forward_type;
1648 rf_helper->action = action;
1649 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1650 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1651 rf_helper->account_name = (active_acc) ?
1652 g_strdup (active_acc) :
1653 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1655 /* Note that window could be destroyed just AFTER calling
1656 register_window so we must ensure that this pointer does
1657 not hold invalid references */
1658 if (rf_helper->parent_window)
1659 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1660 rf_helper_window_closed, rf_helper);
1666 free_reply_forward_helper (gpointer data)
1668 ReplyForwardHelper *helper;
1670 helper = (ReplyForwardHelper *) data;
1671 g_free (helper->account_name);
1673 g_object_unref (helper->header);
1674 if (helper->parent_window)
1675 g_object_weak_unref (G_OBJECT (helper->parent_window),
1676 rf_helper_window_closed, helper);
1677 g_slice_free (ReplyForwardHelper, helper);
1681 reply_forward_cb (ModestMailOperation *mail_op,
1688 TnyMsg *new_msg = NULL;
1689 ReplyForwardHelper *rf_helper;
1690 ModestWindow *msg_win = NULL;
1691 ModestEditType edit_type;
1693 TnyAccount *account = NULL;
1694 ModestWindowMgr *mgr = NULL;
1695 gchar *signature = NULL;
1696 gboolean use_signature;
1698 /* If there was any error. The mail operation could be NULL,
1699 this means that we already have the message downloaded and
1700 that we didn't do a mail operation to retrieve it */
1701 rf_helper = (ReplyForwardHelper *) user_data;
1702 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1705 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1706 rf_helper->account_name);
1707 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr(),
1708 rf_helper->account_name,
1711 /* Create reply mail */
1712 switch (rf_helper->action) {
1715 modest_tny_msg_create_reply_msg (msg, header, from,
1716 (use_signature) ? signature : NULL,
1717 rf_helper->reply_forward_type,
1718 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1720 case ACTION_REPLY_TO_ALL:
1722 modest_tny_msg_create_reply_msg (msg, header, from,
1723 (use_signature) ? signature : NULL,
1724 rf_helper->reply_forward_type,
1725 MODEST_TNY_MSG_REPLY_MODE_ALL);
1726 edit_type = MODEST_EDIT_TYPE_REPLY;
1728 case ACTION_FORWARD:
1730 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1731 rf_helper->reply_forward_type);
1732 edit_type = MODEST_EDIT_TYPE_FORWARD;
1735 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1737 g_return_if_reached ();
1745 g_warning ("%s: failed to create message\n", __FUNCTION__);
1749 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1750 rf_helper->account_name,
1751 TNY_ACCOUNT_TYPE_STORE);
1753 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1757 /* Create and register the windows */
1758 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1759 mgr = modest_runtime_get_window_mgr ();
1760 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1762 /* Note that register_window could have deleted the account */
1763 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1764 gdouble parent_zoom;
1766 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1767 modest_window_set_zoom (msg_win, parent_zoom);
1770 /* Show edit window */
1771 gtk_widget_show_all (GTK_WIDGET (msg_win));
1774 /* We always unregister the header because the message is
1775 forwarded or replied so the original one is no longer
1777 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1780 g_object_unref (G_OBJECT (new_msg));
1782 g_object_unref (G_OBJECT (account));
1783 free_reply_forward_helper (rf_helper);
1786 /* Checks a list of headers. If any of them are not currently
1787 * downloaded (CACHED) then returns TRUE else returns FALSE.
1790 header_list_count_uncached_msgs (TnyList *header_list)
1793 gint uncached_messages = 0;
1795 iter = tny_list_create_iterator (header_list);
1796 while (!tny_iterator_is_done (iter)) {
1799 header = TNY_HEADER (tny_iterator_get_current (iter));
1801 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1802 uncached_messages ++;
1803 g_object_unref (header);
1806 tny_iterator_next (iter);
1808 g_object_unref (iter);
1810 return uncached_messages;
1813 /* Returns FALSE if the user does not want to download the
1814 * messages. Returns TRUE if the user allowed the download.
1817 connect_to_get_msg (ModestWindow *win,
1818 gint num_of_uncached_msgs,
1819 TnyAccount *account)
1821 GtkResponseType response;
1823 /* Allways download if we are online. */
1824 if (tny_device_is_online (modest_runtime_get_device ()))
1827 /* If offline, then ask for user permission to download the messages */
1828 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1829 ngettext("mcen_nc_get_msg",
1831 num_of_uncached_msgs));
1833 if (response == GTK_RESPONSE_CANCEL)
1836 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1840 reply_forward_performer (gboolean canceled,
1842 GtkWindow *parent_window,
1843 TnyAccount *account,
1846 ReplyForwardHelper *rf_helper = NULL;
1847 ModestMailOperation *mail_op;
1849 rf_helper = (ReplyForwardHelper *) user_data;
1851 if (canceled || err) {
1852 free_reply_forward_helper (rf_helper);
1856 /* Retrieve the message */
1857 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1858 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1859 modest_ui_actions_disk_operations_error_handler,
1861 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1862 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1865 g_object_unref(mail_op);
1869 * Common code for the reply and forward actions
1872 reply_forward (ReplyForwardAction action, ModestWindow *win)
1874 ReplyForwardHelper *rf_helper = NULL;
1875 guint reply_forward_type;
1877 g_return_if_fail (MODEST_IS_WINDOW(win));
1879 /* we check for low-mem; in that case, show a warning, and don't allow
1880 * reply/forward (because it could potentially require a lot of memory */
1881 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1885 /* we need an account when editing */
1886 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1887 if (!modest_ui_actions_run_account_setup_wizard (win))
1891 reply_forward_type =
1892 modest_conf_get_int (modest_runtime_get_conf (),
1893 (action == ACTION_FORWARD) ?
1894 MODEST_CONF_FORWARD_TYPE :
1895 MODEST_CONF_REPLY_TYPE,
1898 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1900 TnyHeader *header = NULL;
1901 /* Get header and message. Do not free them here, the
1902 reply_forward_cb must do it */
1903 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1904 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1906 if (msg && header) {
1908 rf_helper = create_reply_forward_helper (action, win,
1909 reply_forward_type, header);
1910 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1912 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1916 g_object_unref (msg);
1918 g_object_unref (header);
1920 TnyHeader *header = NULL;
1922 gboolean do_retrieve = TRUE;
1923 TnyList *header_list = NULL;
1925 header_list = get_selected_headers (win);
1928 /* Check that only one message is selected for replying */
1929 if (tny_list_get_length (header_list) != 1) {
1930 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1931 NULL, _("mcen_ib_select_one_message"));
1932 g_object_unref (header_list);
1936 /* Only reply/forward to one message */
1937 iter = tny_list_create_iterator (header_list);
1938 header = TNY_HEADER (tny_iterator_get_current (iter));
1939 g_object_unref (iter);
1941 /* Retrieve messages */
1942 do_retrieve = (action == ACTION_FORWARD) ||
1943 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1946 TnyAccount *account = NULL;
1947 TnyFolder *folder = NULL;
1948 gdouble download = TRUE;
1949 guint uncached_msgs = 0;
1951 folder = tny_header_get_folder (header);
1953 goto do_retrieve_frees;
1954 account = tny_folder_get_account (folder);
1956 goto do_retrieve_frees;
1958 uncached_msgs = header_list_count_uncached_msgs (header_list);
1960 if (uncached_msgs > 0) {
1961 /* Allways download if we are online. */
1962 if (!tny_device_is_online (modest_runtime_get_device ())) {
1965 /* If ask for user permission to download the messages */
1966 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1967 ngettext("mcen_nc_get_msg",
1971 /* End if the user does not want to continue */
1972 if (response == GTK_RESPONSE_CANCEL)
1979 rf_helper = create_reply_forward_helper (action, win,
1980 reply_forward_type, header);
1981 if (uncached_msgs > 0) {
1982 modest_platform_connect_and_perform (GTK_WINDOW (win),
1984 reply_forward_performer,
1987 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
1988 account, rf_helper);
1993 g_object_unref (account);
1995 g_object_unref (folder);
1997 reply_forward_cb (NULL, header, FALSE, NULL, NULL, rf_helper);
2000 g_object_unref (header_list);
2001 g_object_unref (header);
2006 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
2008 g_return_if_fail (MODEST_IS_WINDOW(win));
2010 reply_forward (ACTION_REPLY, win);
2014 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
2016 g_return_if_fail (MODEST_IS_WINDOW(win));
2018 reply_forward (ACTION_FORWARD, win);
2022 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
2024 g_return_if_fail (MODEST_IS_WINDOW(win));
2026 reply_forward (ACTION_REPLY_TO_ALL, win);
2030 modest_ui_actions_on_next (GtkAction *action,
2031 ModestWindow *window)
2033 if (MODEST_IS_MAIN_WINDOW (window)) {
2034 GtkWidget *header_view;
2036 header_view = modest_main_window_get_child_widget (
2037 MODEST_MAIN_WINDOW(window),
2038 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2042 modest_header_view_select_next (
2043 MODEST_HEADER_VIEW(header_view));
2044 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2045 modest_msg_view_window_select_next_message (
2046 MODEST_MSG_VIEW_WINDOW (window));
2048 g_return_if_reached ();
2053 modest_ui_actions_on_prev (GtkAction *action,
2054 ModestWindow *window)
2056 g_return_if_fail (MODEST_IS_WINDOW(window));
2058 if (MODEST_IS_MAIN_WINDOW (window)) {
2059 GtkWidget *header_view;
2060 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2061 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2065 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
2066 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2067 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
2069 g_return_if_reached ();
2074 modest_ui_actions_on_sort (GtkAction *action,
2075 ModestWindow *window)
2077 GtkWidget *header_view = NULL;
2079 g_return_if_fail (MODEST_IS_WINDOW(window));
2081 if (MODEST_IS_MAIN_WINDOW (window)) {
2082 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2083 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2084 #ifdef MODEST_TOOLKIT_HILDON2
2085 } else if (MODEST_IS_HEADER_WINDOW (window)) {
2086 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2091 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
2096 /* Show sorting dialog */
2097 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
2101 new_messages_arrived (ModestMailOperation *self,
2102 TnyList *new_headers,
2106 gboolean show_visual_notifications;
2108 source = modest_mail_operation_get_source (self);
2109 show_visual_notifications = (source) ? FALSE : TRUE;
2111 g_object_unref (source);
2113 /* Notify new messages have been downloaded. If the
2114 send&receive was invoked by the user then do not show any
2115 visual notification, only play a sound and activate the LED
2116 (for the Maemo version) */
2117 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0)
2118 modest_platform_on_new_headers_received (new_headers,
2119 show_visual_notifications);
2124 retrieve_all_messages_cb (GObject *source,
2126 guint retrieve_limit)
2132 window = GTK_WINDOW (source);
2133 msg = g_strdup_printf (_("mail_nc_msg_count_limit_exceeded"),
2134 num_msgs, retrieve_limit);
2136 /* Ask the user if they want to retrieve all the messages */
2138 modest_platform_run_confirmation_dialog_with_buttons (window, msg,
2139 _("mcen_bd_get_all"),
2140 _("mcen_bd_newest_only"));
2141 /* Free and return */
2143 return (response == GTK_RESPONSE_ACCEPT) ? TRUE : FALSE;
2147 TnyAccount *account;
2149 gchar *account_name;
2150 gboolean poke_status;
2151 gboolean interactive;
2152 ModestMailOperation *mail_op;
2156 do_send_receive_performer (gboolean canceled,
2158 GtkWindow *parent_window,
2159 TnyAccount *account,
2162 SendReceiveInfo *info;
2164 info = (SendReceiveInfo *) user_data;
2166 if (err || canceled) {
2167 /* In memory full conditions we could get this error here */
2168 check_memory_full_error ((GtkWidget *) parent_window, err);
2170 if (info->mail_op) {
2171 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2177 /* Set send/receive operation in progress */
2178 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2179 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2182 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2183 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2184 G_CALLBACK (on_send_receive_finished),
2187 /* Send & receive. */
2188 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2189 (info->win) ? retrieve_all_messages_cb : NULL,
2190 new_messages_arrived, info->win);
2195 g_object_unref (G_OBJECT (info->mail_op));
2196 if (info->account_name)
2197 g_free (info->account_name);
2199 g_object_unref (info->win);
2201 g_object_unref (info->account);
2202 g_slice_free (SendReceiveInfo, info);
2206 * This function performs the send & receive required actions. The
2207 * window is used to create the mail operation. Typically it should
2208 * always be the main window, but we pass it as argument in order to
2212 modest_ui_actions_do_send_receive (const gchar *account_name,
2213 gboolean force_connection,
2214 gboolean poke_status,
2215 gboolean interactive,
2218 gchar *acc_name = NULL;
2219 SendReceiveInfo *info;
2220 ModestTnyAccountStore *acc_store;
2222 /* If no account name was provided then get the current account, and if
2223 there is no current account then pick the default one: */
2224 if (!account_name) {
2226 acc_name = g_strdup (modest_window_get_active_account (win));
2228 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2230 g_printerr ("modest: cannot get default account\n");
2234 acc_name = g_strdup (account_name);
2237 acc_store = modest_runtime_get_account_store ();
2239 /* Create the info for the connect and perform */
2240 info = g_slice_new (SendReceiveInfo);
2241 info->account_name = acc_name;
2242 info->win = (win) ? g_object_ref (win) : NULL;
2243 info->poke_status = poke_status;
2244 info->interactive = interactive;
2245 info->account = modest_tny_account_store_get_server_account (acc_store, acc_name,
2246 TNY_ACCOUNT_TYPE_STORE);
2247 /* We need to create the operation here, because otherwise it
2248 could happen that the queue emits the queue-empty signal
2249 while we're trying to connect the account */
2250 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2251 modest_ui_actions_disk_operations_error_handler,
2253 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2255 /* Invoke the connect and perform */
2256 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2257 force_connection, info->account,
2258 do_send_receive_performer, info);
2263 modest_ui_actions_do_cancel_send (const gchar *account_name,
2266 TnyTransportAccount *transport_account;
2267 TnySendQueue *send_queue = NULL;
2268 GError *error = NULL;
2270 /* Get transport account */
2272 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2273 (modest_runtime_get_account_store(),
2275 TNY_ACCOUNT_TYPE_TRANSPORT));
2276 if (!transport_account) {
2277 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2282 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2283 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2284 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2285 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2286 "modest: could not find send queue for account\n");
2288 /* Cancel the current send */
2289 tny_account_cancel (TNY_ACCOUNT (transport_account));
2291 /* Suspend all pending messages */
2292 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2296 if (transport_account != NULL)
2297 g_object_unref (G_OBJECT (transport_account));
2301 modest_ui_actions_cancel_send_all (ModestWindow *win)
2303 GSList *account_names, *iter;
2305 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2308 iter = account_names;
2310 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2311 iter = g_slist_next (iter);
2314 modest_account_mgr_free_account_names (account_names);
2315 account_names = NULL;
2319 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2322 /* Check if accounts exist */
2323 gboolean accounts_exist =
2324 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2326 /* If not, allow the user to create an account before trying to send/receive. */
2327 if (!accounts_exist)
2328 modest_ui_actions_on_accounts (NULL, win);
2330 /* Cancel all sending operaitons */
2331 modest_ui_actions_cancel_send_all (win);
2335 * Refreshes all accounts. This function will be used by automatic
2339 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2340 gboolean force_connection,
2341 gboolean poke_status,
2342 gboolean interactive)
2344 GSList *account_names, *iter;
2346 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2349 iter = account_names;
2351 modest_ui_actions_do_send_receive ((const char*) iter->data,
2353 poke_status, interactive, win);
2354 iter = g_slist_next (iter);
2357 modest_account_mgr_free_account_names (account_names);
2358 account_names = NULL;
2362 * Handler of the click on Send&Receive button in the main toolbar
2365 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2367 /* Check if accounts exist */
2368 gboolean accounts_exist;
2371 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2373 /* If not, allow the user to create an account before trying to send/receive. */
2374 if (!accounts_exist)
2375 modest_ui_actions_on_accounts (NULL, win);
2377 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2378 if (MODEST_IS_MAIN_WINDOW (win)) {
2379 GtkWidget *folder_view;
2380 TnyFolderStore *folder_store;
2383 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2384 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2388 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2391 g_object_unref (folder_store);
2392 /* Refresh the active account. Force the connection if needed
2393 and poke the status of all folders */
2394 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2395 #ifdef MODEST_TOOLKIT_HILDON2
2396 } else if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2397 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2400 const gchar *active_account;
2401 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2403 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2410 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2413 GtkWidget *header_view;
2415 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2417 header_view = modest_main_window_get_child_widget (main_window,
2418 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2422 conf = modest_runtime_get_conf ();
2424 /* what is saved/restored is depending on the style; thus; we save with
2425 * old style, then update the style, and restore for this new style
2427 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2429 if (modest_header_view_get_style
2430 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2431 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2432 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2434 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2435 MODEST_HEADER_VIEW_STYLE_DETAILS);
2437 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2438 MODEST_CONF_HEADER_VIEW_KEY);
2443 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2445 ModestMainWindow *main_window)
2447 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2448 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2450 /* in the case the folder is empty, show the empty folder message and focus
2452 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2453 if (modest_header_view_is_empty (header_view)) {
2454 TnyFolder *folder = modest_header_view_get_folder (header_view);
2455 GtkWidget *folder_view =
2456 modest_main_window_get_child_widget (main_window,
2457 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2458 if (folder != NULL) {
2459 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2460 g_object_unref (folder);
2462 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2466 /* If no header has been selected then exit */
2471 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2472 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2474 /* Update toolbar dimming state */
2475 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2476 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2480 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2483 ModestWindow *window)
2485 GtkWidget *open_widget;
2486 GtkTreeRowReference *rowref;
2488 g_return_if_fail (MODEST_IS_WINDOW(window));
2489 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2490 g_return_if_fail (TNY_IS_HEADER (header));
2492 if (modest_header_view_count_selected_headers (header_view) > 1) {
2493 /* Don't allow activation if there are more than one message selected */
2494 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2498 /* we check for low-mem; in that case, show a warning, and don't allow
2499 * activating headers
2501 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2504 if (MODEST_IS_MAIN_WINDOW (window)) {
2505 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2506 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2507 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2511 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2512 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2513 gtk_tree_row_reference_free (rowref);
2517 set_active_account_from_tny_account (TnyAccount *account,
2518 ModestWindow *window)
2520 const gchar *server_acc_name = tny_account_get_id (account);
2522 /* We need the TnyAccount provided by the
2523 account store because that is the one that
2524 knows the name of the Modest account */
2525 TnyAccount *modest_server_account = modest_server_account =
2526 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2527 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2529 if (!modest_server_account) {
2530 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2534 /* Update active account, but only if it's not a pseudo-account */
2535 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2536 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2537 const gchar *modest_acc_name =
2538 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2539 if (modest_acc_name)
2540 modest_window_set_active_account (window, modest_acc_name);
2543 g_object_unref (modest_server_account);
2548 folder_refreshed_cb (ModestMailOperation *mail_op,
2552 ModestMainWindow *win = NULL;
2553 GtkWidget *folder_view;
2554 const GError *error;
2556 g_return_if_fail (TNY_IS_FOLDER (folder));
2558 win = MODEST_MAIN_WINDOW (user_data);
2560 /* Check if the operation failed due to memory low conditions */
2561 error = modest_mail_operation_get_error (mail_op);
2562 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2563 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2564 modest_platform_run_information_dialog (GTK_WINDOW (win),
2565 _KR("memr_ib_operation_disabled"),
2571 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2574 TnyFolderStore *current_folder;
2576 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2577 if (current_folder) {
2578 gboolean different = ((TnyFolderStore *) folder != current_folder);
2579 g_object_unref (current_folder);
2585 /* Check if folder is empty and set headers view contents style */
2586 if (tny_folder_get_all_count (folder) == 0)
2587 modest_main_window_set_contents_style (win,
2588 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2593 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2594 TnyFolderStore *folder_store,
2596 ModestMainWindow *main_window)
2599 GtkWidget *header_view;
2601 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2603 header_view = modest_main_window_get_child_widget(main_window,
2604 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2608 conf = modest_runtime_get_conf ();
2610 if (TNY_IS_ACCOUNT (folder_store)) {
2612 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2614 /* Show account details */
2615 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2618 if (TNY_IS_FOLDER (folder_store) && selected) {
2619 TnyAccount *account;
2620 const gchar *account_name = NULL;
2622 /* Update the active account */
2623 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2625 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2627 modest_tny_account_get_parent_modest_account_name_for_server_account (account);
2628 g_object_unref (account);
2632 /* Set the header style by default, it could
2633 be changed later by the refresh callback to
2635 modest_main_window_set_contents_style (main_window,
2636 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2638 /* Set folder on header view. This function
2639 will call tny_folder_refresh_async so we
2640 pass a callback that will be called when
2641 finished. We use that callback to set the
2642 empty view if there are no messages */
2643 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2644 TNY_FOLDER (folder_store),
2646 MODEST_WINDOW (main_window),
2647 folder_refreshed_cb,
2650 /* Restore configuration. We need to do this
2651 *after* the set_folder because the widget
2652 memory asks the header view about its
2654 modest_widget_memory_restore (modest_runtime_get_conf (),
2655 G_OBJECT(header_view),
2656 MODEST_CONF_HEADER_VIEW_KEY);
2658 /* No need to save the header view
2659 configuration for Maemo because it only
2660 saves the sorting stuff and that it's
2661 already being done by the sort
2662 dialog. Remove it when the GNOME version
2663 has the same behaviour */
2664 #ifdef MODEST_TOOLKIT_GTK
2665 if (modest_main_window_get_contents_style (main_window) ==
2666 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2667 modest_widget_memory_save (conf, G_OBJECT (header_view),
2668 MODEST_CONF_HEADER_VIEW_KEY);
2670 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2674 /* Update dimming state */
2675 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2676 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2680 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2687 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2689 online = tny_device_is_online (modest_runtime_get_device());
2692 /* already online -- the item is simply not there... */
2693 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2695 GTK_MESSAGE_WARNING,
2697 _("The %s you selected cannot be found"),
2699 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2700 gtk_dialog_run (GTK_DIALOG(dialog));
2702 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2705 _("mcen_bd_dialog_cancel"),
2706 GTK_RESPONSE_REJECT,
2707 _("mcen_bd_dialog_ok"),
2708 GTK_RESPONSE_ACCEPT,
2710 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2711 "Do you want to get online?"), item);
2712 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2713 gtk_label_new (txt), FALSE, FALSE, 0);
2714 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2717 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2718 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2719 /* TODO: Comment about why is this commented out: */
2720 /* modest_platform_connect_and_wait (); */
2723 gtk_widget_destroy (dialog);
2727 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2730 /* g_message ("%s %s", __FUNCTION__, link); */
2735 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2738 modest_platform_activate_uri (link);
2742 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2745 modest_platform_show_uri_popup (link);
2749 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2752 /* we check for low-mem; in that case, show a warning, and don't allow
2753 * viewing attachments
2755 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2758 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2762 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2763 const gchar *address,
2766 /* g_message ("%s %s", __FUNCTION__, address); */
2770 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2771 TnyMsg *saved_draft,
2774 ModestMsgEditWindow *edit_window;
2776 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2777 #ifndef MODEST_TOOLKIT_HILDON2
2778 ModestMainWindow *win;
2780 /* FIXME. Make the header view sensitive again. This is a
2781 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2783 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2784 modest_runtime_get_window_mgr(), FALSE));
2786 GtkWidget *hdrview = modest_main_window_get_child_widget(
2787 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2788 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2792 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2794 /* Set draft is there was no error */
2795 if (!modest_mail_operation_get_error (mail_op))
2796 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2798 g_object_unref(edit_window);
2802 enough_space_for_message (ModestMsgEditWindow *edit_window,
2805 TnyAccountStore *acc_store;
2806 guint64 available_disk, expected_size;
2811 acc_store = TNY_ACCOUNT_STORE (modest_runtime_get_account_store());
2812 available_disk = modest_utils_get_available_space (NULL);
2813 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2814 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2819 /* Double check: memory full condition or message too big */
2820 if (available_disk < MIN_FREE_SPACE ||
2821 expected_size > available_disk) {
2823 modest_platform_information_banner (NULL, NULL,
2824 _KR("cerm_device_memory_full"));
2829 * djcb: if we're in low-memory state, we only allow for
2830 * saving messages smaller than
2831 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2832 * should still allow for sending anything critical...
2834 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2835 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2839 * djcb: we also make sure that the attachments are smaller than the max size
2840 * this is for the case where we'd try to forward a message with attachments
2841 * bigger than our max allowed size, or sending an message from drafts which
2842 * somehow got past our checks when attaching.
2844 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2845 modest_platform_run_information_dialog (
2846 GTK_WINDOW(edit_window),
2847 _KR("memr_ib_operation_disabled"),
2856 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2858 TnyTransportAccount *transport_account;
2859 ModestMailOperation *mail_operation;
2861 gchar *account_name, *from;
2862 ModestAccountMgr *account_mgr;
2863 gboolean had_error = FALSE;
2864 ModestMainWindow *win = NULL;
2866 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2868 data = modest_msg_edit_window_get_msg_data (edit_window);
2871 if (!enough_space_for_message (edit_window, data)) {
2872 modest_msg_edit_window_free_msg_data (edit_window, data);
2876 account_name = g_strdup (data->account_name);
2877 account_mgr = modest_runtime_get_account_mgr();
2879 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2881 account_name = modest_account_mgr_get_default_account (account_mgr);
2882 if (!account_name) {
2883 g_printerr ("modest: no account found\n");
2884 modest_msg_edit_window_free_msg_data (edit_window, data);
2888 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2889 account_name = g_strdup (data->account_name);
2893 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2894 (modest_runtime_get_account_store (),
2896 TNY_ACCOUNT_TYPE_TRANSPORT));
2897 if (!transport_account) {
2898 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2899 g_free (account_name);
2900 modest_msg_edit_window_free_msg_data (edit_window, data);
2903 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2905 /* Create the mail operation */
2906 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
2908 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2910 modest_mail_operation_save_to_drafts (mail_operation,
2922 data->priority_flags,
2923 on_save_to_drafts_cb,
2924 g_object_ref(edit_window));
2926 #ifdef MODEST_TOOLKIT_HILDON2
2927 /* In hildon2 we always show the information banner on saving to drafts.
2928 * It will be a system information banner in this case.
2930 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2931 modest_platform_information_banner (NULL, NULL, text);
2934 /* Use the main window as the parent of the banner, if the
2935 main window does not exist it won't be shown, if the parent
2936 window exists then it's properly shown. We don't use the
2937 editor window because it could be closed (save to drafts
2938 could happen after closing the window */
2939 win = (ModestMainWindow *)
2940 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
2942 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2943 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
2947 modest_msg_edit_window_set_modified (edit_window, FALSE);
2951 g_free (account_name);
2952 g_object_unref (G_OBJECT (transport_account));
2953 g_object_unref (G_OBJECT (mail_operation));
2955 modest_msg_edit_window_free_msg_data (edit_window, data);
2958 * If the drafts folder is selected then make the header view
2959 * insensitive while the message is being saved to drafts
2960 * (it'll be sensitive again in on_save_to_drafts_cb()). This
2961 * is not very clean but it avoids letting the drafts folder
2962 * in an inconsistent state: the user could edit the message
2963 * being saved and undesirable things would happen.
2964 * In the average case the user won't notice anything at
2965 * all. In the worst case (the user is editing a really big
2966 * file from Drafts) the header view will be insensitive
2967 * during the saving process (10 or 20 seconds, depending on
2968 * the message). Anyway this is just a quick workaround: once
2969 * we find a better solution it should be removed
2970 * See NB#65125 (commend #18) for details.
2972 if (!had_error && win != NULL) {
2973 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
2974 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
2976 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
2978 if (modest_tny_folder_is_local_folder(folder)) {
2979 TnyFolderType folder_type;
2980 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
2981 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
2982 GtkWidget *hdrview = modest_main_window_get_child_widget(
2983 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2984 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
2988 if (folder != NULL) g_object_unref(folder);
2995 /* For instance, when clicking the Send toolbar button when editing a message: */
2997 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2999 TnyTransportAccount *transport_account = NULL;
3000 gboolean had_error = FALSE;
3002 ModestAccountMgr *account_mgr;
3003 gchar *account_name;
3005 ModestMailOperation *mail_operation;
3007 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
3009 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
3012 data = modest_msg_edit_window_get_msg_data (edit_window);
3015 if (!enough_space_for_message (edit_window, data)) {
3016 modest_msg_edit_window_free_msg_data (edit_window, data);
3020 account_mgr = modest_runtime_get_account_mgr();
3021 account_name = g_strdup (data->account_name);
3023 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3026 account_name = modest_account_mgr_get_default_account (account_mgr);
3028 if (!account_name) {
3029 modest_msg_edit_window_free_msg_data (edit_window, data);
3030 /* Run account setup wizard */
3031 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
3036 /* Get the currently-active transport account for this modest account: */
3037 if (strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
3039 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3040 (modest_runtime_get_account_store (),
3041 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
3044 if (!transport_account) {
3045 modest_msg_edit_window_free_msg_data (edit_window, data);
3046 /* Run account setup wizard */
3047 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
3052 /* Create the mail operation */
3053 from = modest_account_mgr_get_from_string (account_mgr, account_name);
3054 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
3055 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3057 modest_mail_operation_send_new_mail (mail_operation,
3069 data->priority_flags);
3071 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3072 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
3074 if (modest_mail_operation_get_error (mail_operation) != NULL) {
3075 const GError *error = modest_mail_operation_get_error (mail_operation);
3076 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3077 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3078 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3079 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3086 g_free (account_name);
3087 g_object_unref (G_OBJECT (transport_account));
3088 g_object_unref (G_OBJECT (mail_operation));
3090 modest_msg_edit_window_free_msg_data (edit_window, data);
3093 modest_msg_edit_window_set_sent (edit_window, TRUE);
3095 /* Save settings and close the window: */
3096 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3103 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3104 ModestMsgEditWindow *window)
3106 ModestMsgEditFormatState *format_state = NULL;
3108 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3109 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3111 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3114 format_state = modest_msg_edit_window_get_format_state (window);
3115 g_return_if_fail (format_state != NULL);
3117 format_state->bold = gtk_toggle_action_get_active (action);
3118 modest_msg_edit_window_set_format_state (window, format_state);
3119 g_free (format_state);
3124 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3125 ModestMsgEditWindow *window)
3127 ModestMsgEditFormatState *format_state = NULL;
3129 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3130 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3132 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3135 format_state = modest_msg_edit_window_get_format_state (window);
3136 g_return_if_fail (format_state != NULL);
3138 format_state->italics = gtk_toggle_action_get_active (action);
3139 modest_msg_edit_window_set_format_state (window, format_state);
3140 g_free (format_state);
3145 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3146 ModestMsgEditWindow *window)
3148 ModestMsgEditFormatState *format_state = NULL;
3150 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3151 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3153 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3156 format_state = modest_msg_edit_window_get_format_state (window);
3157 g_return_if_fail (format_state != NULL);
3159 format_state->bullet = gtk_toggle_action_get_active (action);
3160 modest_msg_edit_window_set_format_state (window, format_state);
3161 g_free (format_state);
3166 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3167 GtkRadioAction *selected,
3168 ModestMsgEditWindow *window)
3170 ModestMsgEditFormatState *format_state = NULL;
3171 GtkJustification value;
3173 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3175 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3178 value = gtk_radio_action_get_current_value (selected);
3180 format_state = modest_msg_edit_window_get_format_state (window);
3181 g_return_if_fail (format_state != NULL);
3183 format_state->justification = value;
3184 modest_msg_edit_window_set_format_state (window, format_state);
3185 g_free (format_state);
3189 modest_ui_actions_on_select_editor_color (GtkAction *action,
3190 ModestMsgEditWindow *window)
3192 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3193 g_return_if_fail (GTK_IS_ACTION (action));
3195 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3198 modest_msg_edit_window_select_color (window);
3202 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3203 ModestMsgEditWindow *window)
3205 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3206 g_return_if_fail (GTK_IS_ACTION (action));
3208 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3211 modest_msg_edit_window_select_background_color (window);
3215 modest_ui_actions_on_insert_image (GObject *object,
3216 ModestMsgEditWindow *window)
3218 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3221 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3224 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3227 modest_msg_edit_window_insert_image (window);
3231 modest_ui_actions_on_attach_file (GtkAction *action,
3232 ModestMsgEditWindow *window)
3234 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3235 g_return_if_fail (GTK_IS_ACTION (action));
3237 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3240 modest_msg_edit_window_offer_attach_file (window);
3244 modest_ui_actions_on_remove_attachments (GtkAction *action,
3245 ModestMsgEditWindow *window)
3247 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3249 modest_msg_edit_window_remove_attachments (window, NULL);
3253 do_create_folder_cb (ModestMailOperation *mail_op,
3254 TnyFolderStore *parent_folder,
3255 TnyFolder *new_folder,
3258 gchar *suggested_name = (gchar *) user_data;
3259 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3260 const GError *error;
3262 error = modest_mail_operation_get_error (mail_op);
3265 /* Show an error. If there was some problem writing to
3266 disk, show it, otherwise show the generic folder
3267 create error. We do it here and not in an error
3268 handler because the call to do_create_folder will
3269 stop the main loop in a gtk_dialog_run and then,
3270 the message won't be shown until that dialog is
3272 modest_ui_actions_disk_operations_error_handler (mail_op,
3273 _("mail_in_ui_folder_create_error"));
3275 if (!is_memory_full_error ((GError *) error, mail_op)) {
3276 /* Try again if there is no full memory condition */
3277 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3280 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3281 * FIXME: any other? */
3282 GtkWidget *folder_view;
3284 if (MODEST_IS_MAIN_WINDOW(source_win))
3286 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3287 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3289 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3290 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3292 /* Select the newly created folder. It could happen
3293 that the widget is no longer there (i.e. the window
3294 has been destroyed, so we need to check this */
3296 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3298 g_object_unref (new_folder);
3300 /* Free. Note that the first time it'll be NULL so noop */
3301 g_free (suggested_name);
3302 g_object_unref (source_win);
3307 TnyFolderStore *parent;
3308 } CreateFolderConnect;
3311 do_create_folder_performer (gboolean canceled,
3313 GtkWindow *parent_window,
3314 TnyAccount *account,
3317 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3318 ModestMailOperation *mail_op;
3320 if (canceled || err) {
3321 /* In memory full conditions we could get this error here */
3322 check_memory_full_error ((GtkWidget *) parent_window, err);
3326 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3327 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3329 modest_mail_operation_create_folder (mail_op,
3331 (const gchar *) helper->folder_name,
3332 do_create_folder_cb,
3333 g_strdup (helper->folder_name));
3334 g_object_unref (mail_op);
3338 g_object_unref (helper->parent);
3339 if (helper->folder_name)
3340 g_free (helper->folder_name);
3341 g_slice_free (CreateFolderConnect, helper);
3346 do_create_folder (GtkWindow *parent_window,
3347 TnyFolderStore *suggested_parent,
3348 const gchar *suggested_name)
3351 gchar *folder_name = NULL;
3352 TnyFolderStore *parent_folder = NULL;
3354 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3356 (gchar *) suggested_name,
3360 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3361 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3362 helper->folder_name = g_strdup (folder_name);
3363 helper->parent = g_object_ref (parent_folder);
3365 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3368 do_create_folder_performer,
3373 g_free (folder_name);
3375 g_object_unref (parent_folder);
3379 modest_ui_actions_create_folder(GtkWidget *parent_window,
3380 GtkWidget *folder_view)
3382 TnyFolderStore *parent_folder;
3384 #ifdef MODEST_TOOLKIT_HILDON2
3385 ModestTnyAccountStore *acc_store;
3387 acc_store = modest_runtime_get_account_store ();
3389 parent_folder = (TnyFolderStore *)
3390 modest_tny_account_store_get_local_folders_account (acc_store);
3392 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3395 if (parent_folder) {
3396 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3397 g_object_unref (parent_folder);
3402 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3405 g_return_if_fail (MODEST_IS_WINDOW(window));
3407 if (MODEST_IS_MAIN_WINDOW (window)) {
3408 GtkWidget *folder_view;
3410 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3411 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3415 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view);
3416 #ifdef MODEST_TOOLKIT_HILDON2
3417 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3418 GtkWidget *folder_view;
3420 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3421 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view);
3424 g_assert_not_reached ();
3429 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3432 const GError *error = NULL;
3433 const gchar *message = NULL;
3435 /* Get error message */
3436 error = modest_mail_operation_get_error (mail_op);
3438 g_return_if_reached ();
3440 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3441 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3442 message = _CS("ckdg_ib_folder_already_exists");
3443 } else if (error->domain == TNY_ERROR_DOMAIN &&
3444 error->code == TNY_SERVICE_ERROR_STATE) {
3445 /* This means that the folder is already in use (a
3446 message is opened for example */
3447 message = _("emev_ni_internal_error");
3449 message = _CS("ckdg_ib_unable_to_rename");
3452 /* We don't set a parent for the dialog because the dialog
3453 will be destroyed so the banner won't appear */
3454 modest_platform_information_banner (NULL, NULL, message);
3458 TnyFolderStore *folder;
3463 on_rename_folder_cb (ModestMailOperation *mail_op,
3464 TnyFolder *new_folder,
3467 ModestFolderView *folder_view;
3469 /* If the window was closed when renaming a folder, or if
3470 * it's not a main window this will happen */
3471 if (!MODEST_IS_FOLDER_VIEW (user_data))
3474 folder_view = MODEST_FOLDER_VIEW (user_data);
3475 /* Note that if the rename fails new_folder will be NULL */
3477 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3479 modest_folder_view_select_first_inbox_or_local (folder_view);
3481 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3485 on_rename_folder_performer (gboolean canceled,
3487 GtkWindow *parent_window,
3488 TnyAccount *account,
3491 ModestMailOperation *mail_op = NULL;
3492 GtkTreeSelection *sel = NULL;
3493 GtkWidget *folder_view = NULL;
3494 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3496 if (canceled || err) {
3497 /* In memory full conditions we could get this error here */
3498 check_memory_full_error ((GtkWidget *) parent_window, err);
3502 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3503 modest_ui_actions_rename_folder_error_handler,
3504 parent_window, NULL);
3506 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3509 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3511 folder_view = modest_main_window_get_child_widget (
3512 MODEST_MAIN_WINDOW (parent_window),
3513 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3515 #ifdef MODEST_TOOLKIT_HILDON2
3516 else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3517 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3518 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3522 /* Clear the folders view */
3523 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3524 gtk_tree_selection_unselect_all (sel);
3526 /* Actually rename the folder */
3527 modest_mail_operation_rename_folder (mail_op,
3528 TNY_FOLDER (data->folder),
3529 (const gchar *) (data->new_name),
3530 on_rename_folder_cb,
3532 g_object_unref (mail_op);
3535 g_object_unref (data->folder);
3536 g_free (data->new_name);
3541 modest_ui_actions_on_rename_folder (GtkAction *action,
3542 ModestWindow *window)
3544 modest_ui_actions_on_edit_mode_rename_folder (window);
3548 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3550 TnyFolderStore *folder;
3551 GtkWidget *folder_view;
3552 gboolean do_rename = TRUE;
3554 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3556 if (MODEST_IS_MAIN_WINDOW (window)) {
3557 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3558 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3562 #ifdef MODEST_TOOLKIT_HILDON2
3563 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3564 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3570 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3575 if (TNY_IS_FOLDER (folder)) {
3576 gchar *folder_name = NULL;
3578 const gchar *current_name;
3579 TnyFolderStore *parent;
3581 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3582 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3583 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
3584 parent, current_name,
3586 g_object_unref (parent);
3588 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3591 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3592 rename_folder_data->folder = g_object_ref (folder);
3593 rename_folder_data->new_name = folder_name;
3594 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
3595 folder, on_rename_folder_performer, rename_folder_data);
3598 g_object_unref (folder);
3603 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3606 GObject *win = modest_mail_operation_get_source (mail_op);
3608 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3609 _("mail_in_ui_folder_delete_error"),
3611 g_object_unref (win);
3615 TnyFolderStore *folder;
3616 gboolean move_to_trash;
3620 on_delete_folder_cb (gboolean canceled,
3622 GtkWindow *parent_window,
3623 TnyAccount *account,
3626 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3627 GtkWidget *folder_view;
3628 ModestMailOperation *mail_op;
3629 GtkTreeSelection *sel;
3631 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
3632 g_object_unref (G_OBJECT (info->folder));
3637 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
3638 folder_view = modest_main_window_get_child_widget (
3639 MODEST_MAIN_WINDOW (parent_window),
3640 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3641 #ifdef MODEST_TOOLKIT_HILDON2
3642 } else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3643 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
3646 g_object_unref (G_OBJECT (info->folder));
3651 /* Unselect the folder before deleting it to free the headers */
3652 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3653 gtk_tree_selection_unselect_all (sel);
3655 /* Create the mail operation */
3657 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3658 modest_ui_actions_delete_folder_error_handler,
3661 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3663 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3665 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3667 g_object_unref (G_OBJECT (mail_op));
3668 g_object_unref (G_OBJECT (info->folder));
3673 delete_folder (ModestWindow *window, gboolean move_to_trash)
3675 TnyFolderStore *folder;
3676 GtkWidget *folder_view;
3680 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3682 if (MODEST_IS_MAIN_WINDOW (window)) {
3684 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3685 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3686 #ifdef MODEST_TOOLKIT_HILDON2
3687 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3688 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3696 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3701 /* Show an error if it's an account */
3702 if (!TNY_IS_FOLDER (folder)) {
3703 modest_platform_run_information_dialog (GTK_WINDOW (window),
3704 _("mail_in_ui_folder_delete_error"),
3706 g_object_unref (G_OBJECT (folder));
3711 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3712 tny_folder_get_name (TNY_FOLDER (folder)));
3713 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
3714 (const gchar *) message);
3717 if (response == GTK_RESPONSE_OK) {
3718 DeleteFolderInfo *info;
3719 info = g_new0(DeleteFolderInfo, 1);
3720 info->folder = folder;
3721 info->move_to_trash = move_to_trash;
3722 g_object_ref (G_OBJECT (info->folder));
3723 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder));
3724 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
3726 TNY_FOLDER_STORE (account),
3727 on_delete_folder_cb, info);
3728 g_object_unref (account);
3733 g_object_unref (G_OBJECT (folder));
3737 modest_ui_actions_on_delete_folder (GtkAction *action,
3738 ModestWindow *window)
3740 modest_ui_actions_on_edit_mode_delete_folder (window);
3744 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
3746 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
3748 return delete_folder (window, FALSE);
3752 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3754 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3756 delete_folder (MODEST_WINDOW (main_window), TRUE);
3760 typedef struct _PasswordDialogFields {
3761 GtkWidget *username;
3762 GtkWidget *password;
3764 } PasswordDialogFields;
3767 password_dialog_check_field (GtkEditable *editable,
3768 PasswordDialogFields *fields)
3771 gboolean any_value_empty = FALSE;
3773 #ifdef MODEST_TOOLKIT_HILDON2
3774 value = hildon_entry_get_text (HILDON_ENTRY (fields->username));
3776 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
3778 if ((value == NULL) || value[0] == '\0') {
3779 any_value_empty = TRUE;
3781 #ifdef MODEST_TOOLKIT_HILDON2
3782 value = hildon_entry_get_text (HILDON_ENTRY (fields->password));
3784 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
3786 if ((value == NULL) || value[0] == '\0') {
3787 any_value_empty = TRUE;
3789 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3793 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3794 const gchar* server_account_name,
3799 ModestMainWindow *main_window)
3801 g_return_if_fail(server_account_name);
3802 gboolean completed = FALSE;
3803 PasswordDialogFields *fields = NULL;
3805 /* Initalize output parameters: */
3812 #ifndef MODEST_TOOLKIT_GTK
3813 /* Maemo uses a different (awkward) button order,
3814 * It should probably just use gtk_alternative_dialog_button_order ().
3816 #ifdef MODEST_TOOLKIT_HILDON2
3818 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3821 _HL("wdgt_bd_done"),
3822 GTK_RESPONSE_ACCEPT,
3824 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
3825 HILDON_MARGIN_DOUBLE);
3828 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3831 _("mcen_bd_dialog_ok"),
3832 GTK_RESPONSE_ACCEPT,
3833 _("mcen_bd_dialog_cancel"),
3834 GTK_RESPONSE_REJECT,
3836 #endif /* MODEST_TOOLKIT_HILDON2 */
3839 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3843 GTK_RESPONSE_REJECT,
3845 GTK_RESPONSE_ACCEPT,
3847 #endif /* MODEST_TOOLKIT_GTK */
3849 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3851 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3852 modest_runtime_get_account_mgr(), server_account_name);
3853 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3854 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3857 gtk_widget_destroy (dialog);
3861 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3862 GtkWidget *label = gtk_label_new (txt);
3863 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
3865 g_free (server_name);
3866 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
3871 gchar *initial_username = modest_account_mgr_get_server_account_username (
3872 modest_runtime_get_account_mgr(), server_account_name);
3874 #ifdef MODEST_TOOLKIT_HILDON2
3875 GtkWidget *entry_username = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
3876 if (initial_username)
3877 hildon_entry_set_text (HILDON_ENTRY (entry_username), initial_username);
3879 GtkWidget *entry_username = gtk_entry_new ();
3880 if (initial_username)
3881 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
3883 /* Dim this if a connection has ever succeeded with this username,
3884 * as per the UI spec: */
3885 /* const gboolean username_known = */
3886 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3887 /* modest_runtime_get_account_mgr(), server_account_name); */
3888 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3890 /* We drop the username sensitive code and disallow changing it here
3891 * as tinymail does not support really changing the username in the callback
3893 gtk_widget_set_sensitive (entry_username, FALSE);
3895 #ifndef MODEST_TOOLKIT_GTK
3896 /* Auto-capitalization is the default, so let's turn it off: */
3897 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3899 /* Create a size group to be used by all captions.
3900 * Note that HildonCaption does not create a default size group if we do not specify one.
3901 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3902 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3904 #ifdef MODEST_TOOLKIT_HILDON2
3905 GtkWidget *caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
3906 _("mail_fi_username"), FALSE,
3909 GtkWidget *caption = hildon_caption_new (sizegroup,
3910 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
3912 gtk_widget_show (entry_username);
3913 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3914 FALSE, FALSE, MODEST_MARGIN_HALF);
3915 gtk_widget_show (caption);
3917 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
3919 #endif /* !MODEST_TOOLKIT_GTK */
3922 #ifdef MODEST_TOOLKIT_HILDON2
3923 GtkWidget *entry_password = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
3925 GtkWidget *entry_password = gtk_entry_new ();
3927 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3928 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3930 #ifndef MODEST_TOOLKIT_GTK
3931 /* Auto-capitalization is the default, so let's turn it off: */
3932 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3933 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3935 #ifdef MODEST_TOOLKIT_HILDON2
3936 caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
3937 _("mail_fi_password"), FALSE,
3940 caption = hildon_caption_new (sizegroup,
3941 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
3943 gtk_widget_show (entry_password);
3944 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3945 FALSE, FALSE, MODEST_MARGIN_HALF);
3946 gtk_widget_show (caption);
3947 g_object_unref (sizegroup);
3949 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
3951 #endif /* !MODEST_TOOLKIT_GTK */
3953 if (initial_username != NULL)
3954 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3956 /* This is not in the Maemo UI spec:
3957 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3958 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3962 fields = g_slice_new0 (PasswordDialogFields);
3963 fields->username = entry_username;
3964 fields->password = entry_password;
3965 fields->dialog = dialog;
3967 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3968 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3969 password_dialog_check_field (NULL, fields);
3971 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3973 while (!completed) {
3975 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3977 #ifdef MODEST_TOOLKIT_HILDON2
3978 *username = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_username)));
3980 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
3983 /* Note that an empty field becomes the "" string */
3984 if (*username && strlen (*username) > 0) {
3985 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
3986 server_account_name,
3990 const gboolean username_was_changed =
3991 (strcmp (*username, initial_username) != 0);
3992 if (username_was_changed) {
3993 g_warning ("%s: tinymail does not yet support changing the "
3994 "username in the get_password() callback.\n", __FUNCTION__);
4000 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
4001 _("mcen_ib_username_pw_incorrect"));
4007 #ifdef MODEST_TOOLKIT_HILDON2
4008 *password = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_password)));
4010 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
4013 /* We do not save the password in the configuration,
4014 * because this function is only called for passwords that should
4015 * not be remembered:
4016 modest_server_account_set_password (
4017 modest_runtime_get_account_mgr(), server_account_name,
4024 #ifndef MODEST_TOOLKIT_HILDON2
4025 /* Set parent to NULL or the banner will disappear with its parent dialog */
4026 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
4038 /* This is not in the Maemo UI spec:
4039 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
4045 g_free (initial_username);
4046 gtk_widget_destroy (dialog);
4047 g_slice_free (PasswordDialogFields, fields);
4049 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
4053 modest_ui_actions_on_cut (GtkAction *action,
4054 ModestWindow *window)
4056 GtkWidget *focused_widget;
4057 GtkClipboard *clipboard;
4059 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4060 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4061 if (GTK_IS_EDITABLE (focused_widget)) {
4062 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
4063 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4064 gtk_clipboard_store (clipboard);
4065 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4066 GtkTextBuffer *buffer;
4068 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4069 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4070 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
4071 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4072 gtk_clipboard_store (clipboard);
4074 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4075 TnyList *header_list = modest_header_view_get_selected_headers (
4076 MODEST_HEADER_VIEW (focused_widget));
4077 gboolean continue_download = FALSE;
4078 gint num_of_unc_msgs;
4080 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4082 if (num_of_unc_msgs) {
4083 TnyAccount *account = get_account_from_header_list (header_list);
4085 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4086 g_object_unref (account);
4090 if (num_of_unc_msgs == 0 || continue_download) {
4091 /* modest_platform_information_banner (
4092 NULL, NULL, _CS("mcen_ib_getting_items"));*/
4093 modest_header_view_cut_selection (
4094 MODEST_HEADER_VIEW (focused_widget));
4097 g_object_unref (header_list);
4098 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4099 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4104 modest_ui_actions_on_copy (GtkAction *action,
4105 ModestWindow *window)
4107 GtkClipboard *clipboard;
4108 GtkWidget *focused_widget;
4109 gboolean copied = TRUE;
4111 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4112 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4114 if (GTK_IS_LABEL (focused_widget)) {
4116 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4117 gtk_clipboard_set_text (clipboard, selection, -1);
4119 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4120 gtk_clipboard_store (clipboard);
4121 } else if (GTK_IS_EDITABLE (focused_widget)) {
4122 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4123 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4124 gtk_clipboard_store (clipboard);
4125 } else if (GTK_IS_HTML (focused_widget)) {
4128 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4129 if ((sel == NULL) || (sel[0] == '\0')) {
4132 gtk_html_copy (GTK_HTML (focused_widget));
4133 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4134 gtk_clipboard_store (clipboard);
4136 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4137 GtkTextBuffer *buffer;
4138 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4139 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4140 gtk_text_buffer_copy_clipboard (buffer, clipboard);
4141 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4142 gtk_clipboard_store (clipboard);
4144 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4145 TnyList *header_list = modest_header_view_get_selected_headers (
4146 MODEST_HEADER_VIEW (focused_widget));
4147 gboolean continue_download = FALSE;
4148 gint num_of_unc_msgs;
4150 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4152 if (num_of_unc_msgs) {
4153 TnyAccount *account = get_account_from_header_list (header_list);
4155 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4156 g_object_unref (account);
4160 if (num_of_unc_msgs == 0 || continue_download) {
4161 modest_platform_information_banner (
4162 NULL, NULL, _CS("mcen_ib_getting_items"));
4163 modest_header_view_copy_selection (
4164 MODEST_HEADER_VIEW (focused_widget));
4168 g_object_unref (header_list);
4170 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4171 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4174 /* Show information banner if there was a copy to clipboard */
4176 modest_platform_information_banner (
4177 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4181 modest_ui_actions_on_undo (GtkAction *action,
4182 ModestWindow *window)
4184 ModestEmailClipboard *clipboard = NULL;
4186 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4187 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4188 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4189 /* Clear clipboard source */
4190 clipboard = modest_runtime_get_email_clipboard ();
4191 modest_email_clipboard_clear (clipboard);
4194 g_return_if_reached ();
4199 modest_ui_actions_on_redo (GtkAction *action,
4200 ModestWindow *window)
4202 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4203 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4206 g_return_if_reached ();
4212 destroy_information_note (ModestMailOperation *mail_op,
4215 /* destroy information note */
4216 gtk_widget_destroy (GTK_WIDGET(user_data));
4220 destroy_folder_information_note (ModestMailOperation *mail_op,
4221 TnyFolder *new_folder,
4224 /* destroy information note */
4225 gtk_widget_destroy (GTK_WIDGET(user_data));
4230 paste_as_attachment_free (gpointer data)
4232 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4234 if (helper->banner) {
4235 gtk_widget_destroy (helper->banner);
4236 g_object_unref (helper->banner);
4242 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4247 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4248 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4253 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4258 modest_ui_actions_on_paste (GtkAction *action,
4259 ModestWindow *window)
4261 GtkWidget *focused_widget = NULL;
4262 GtkWidget *inf_note = NULL;
4263 ModestMailOperation *mail_op = NULL;
4265 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4266 if (GTK_IS_EDITABLE (focused_widget)) {
4267 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4268 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4269 ModestEmailClipboard *e_clipboard = NULL;
4270 e_clipboard = modest_runtime_get_email_clipboard ();
4271 if (modest_email_clipboard_cleared (e_clipboard)) {
4272 GtkTextBuffer *buffer;
4273 GtkClipboard *clipboard;
4275 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4276 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4277 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4278 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4279 ModestMailOperation *mail_op;
4280 TnyFolder *src_folder = NULL;
4281 TnyList *data = NULL;
4283 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4284 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4285 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4286 _CS("ckct_nw_pasting"));
4287 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4288 mail_op = modest_mail_operation_new (G_OBJECT (window));
4289 if (helper->banner != NULL) {
4290 g_object_ref (G_OBJECT (helper->banner));
4291 gtk_widget_show (GTK_WIDGET (helper->banner));
4295 modest_mail_operation_get_msgs_full (mail_op,
4297 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4299 paste_as_attachment_free);
4303 g_object_unref (data);
4305 g_object_unref (src_folder);
4308 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4309 ModestEmailClipboard *clipboard = NULL;
4310 TnyFolder *src_folder = NULL;
4311 TnyFolderStore *folder_store = NULL;
4312 TnyList *data = NULL;
4313 gboolean delete = FALSE;
4315 /* Check clipboard source */
4316 clipboard = modest_runtime_get_email_clipboard ();
4317 if (modest_email_clipboard_cleared (clipboard))
4320 /* Get elements to paste */
4321 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4323 /* Create a new mail operation */
4324 mail_op = modest_mail_operation_new (G_OBJECT(window));
4326 /* Get destination folder */
4327 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4329 /* transfer messages */
4333 /* Ask for user confirmation */
4335 modest_ui_actions_msgs_move_to_confirmation (window,
4336 TNY_FOLDER (folder_store),
4340 if (response == GTK_RESPONSE_OK) {
4341 /* Launch notification */
4342 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4343 _CS("ckct_nw_pasting"));
4344 if (inf_note != NULL) {
4345 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4346 gtk_widget_show (GTK_WIDGET(inf_note));
4349 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4350 modest_mail_operation_xfer_msgs (mail_op,
4352 TNY_FOLDER (folder_store),
4354 destroy_information_note,
4357 g_object_unref (mail_op);
4360 } else if (src_folder != NULL) {
4361 /* Launch notification */
4362 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4363 _CS("ckct_nw_pasting"));
4364 if (inf_note != NULL) {
4365 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4366 gtk_widget_show (GTK_WIDGET(inf_note));
4369 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4370 modest_mail_operation_xfer_folder (mail_op,
4374 destroy_folder_information_note,
4380 g_object_unref (data);
4381 if (src_folder != NULL)
4382 g_object_unref (src_folder);
4383 if (folder_store != NULL)
4384 g_object_unref (folder_store);
4390 modest_ui_actions_on_select_all (GtkAction *action,
4391 ModestWindow *window)
4393 GtkWidget *focused_widget;
4395 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4396 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4397 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4398 } else if (GTK_IS_LABEL (focused_widget)) {
4399 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4400 } else if (GTK_IS_EDITABLE (focused_widget)) {
4401 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4402 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4403 GtkTextBuffer *buffer;
4404 GtkTextIter start, end;
4406 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4407 gtk_text_buffer_get_start_iter (buffer, &start);
4408 gtk_text_buffer_get_end_iter (buffer, &end);
4409 gtk_text_buffer_select_range (buffer, &start, &end);
4410 } else if (GTK_IS_HTML (focused_widget)) {
4411 gtk_html_select_all (GTK_HTML (focused_widget));
4412 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4413 GtkWidget *header_view = focused_widget;
4414 GtkTreeSelection *selection = NULL;
4416 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4417 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4418 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4421 /* Disable window dimming management */
4422 modest_window_disable_dimming (MODEST_WINDOW(window));
4424 /* Select all messages */
4425 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4426 gtk_tree_selection_select_all (selection);
4428 /* Set focuse on header view */
4429 gtk_widget_grab_focus (header_view);
4431 /* Enable window dimming management */
4432 modest_window_enable_dimming (MODEST_WINDOW(window));
4433 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4434 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4440 modest_ui_actions_on_mark_as_read (GtkAction *action,
4441 ModestWindow *window)
4443 g_return_if_fail (MODEST_IS_WINDOW(window));
4445 /* Mark each header as read */
4446 do_headers_action (window, headers_action_mark_as_read, NULL);
4450 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4451 ModestWindow *window)
4453 g_return_if_fail (MODEST_IS_WINDOW(window));
4455 /* Mark each header as read */
4456 do_headers_action (window, headers_action_mark_as_unread, NULL);
4460 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4461 GtkRadioAction *selected,
4462 ModestWindow *window)
4466 value = gtk_radio_action_get_current_value (selected);
4467 if (MODEST_IS_WINDOW (window)) {
4468 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4473 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4474 GtkRadioAction *selected,
4475 ModestWindow *window)
4477 TnyHeaderFlags flags;
4478 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4480 flags = gtk_radio_action_get_current_value (selected);
4481 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4485 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4486 GtkRadioAction *selected,
4487 ModestWindow *window)
4491 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4493 file_format = gtk_radio_action_get_current_value (selected);
4494 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4499 modest_ui_actions_on_zoom_plus (GtkAction *action,
4500 ModestWindow *window)
4502 g_return_if_fail (MODEST_IS_WINDOW (window));
4504 modest_window_zoom_plus (MODEST_WINDOW (window));
4508 modest_ui_actions_on_zoom_minus (GtkAction *action,
4509 ModestWindow *window)
4511 g_return_if_fail (MODEST_IS_WINDOW (window));
4513 modest_window_zoom_minus (MODEST_WINDOW (window));
4517 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4518 ModestWindow *window)
4520 ModestWindowMgr *mgr;
4521 gboolean fullscreen, active;
4522 g_return_if_fail (MODEST_IS_WINDOW (window));
4524 mgr = modest_runtime_get_window_mgr ();
4526 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4527 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4529 if (active != fullscreen) {
4530 modest_window_mgr_set_fullscreen_mode (mgr, active);
4531 #ifndef MODEST_TOOLKIT_HILDON2
4532 gtk_window_present (GTK_WINDOW (window));
4538 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4539 ModestWindow *window)
4541 ModestWindowMgr *mgr;
4542 gboolean fullscreen;
4544 g_return_if_fail (MODEST_IS_WINDOW (window));
4546 mgr = modest_runtime_get_window_mgr ();
4547 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4548 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4550 #ifndef MODEST_TOOLKIT_HILDON2
4551 gtk_window_present (GTK_WINDOW (window));
4556 * Used by modest_ui_actions_on_details to call do_headers_action
4559 headers_action_show_details (TnyHeader *header,
4560 ModestWindow *window,
4564 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header);
4568 * Show the header details in a ModestDetailsDialog widget
4571 modest_ui_actions_on_details (GtkAction *action,
4574 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4578 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4582 header = tny_msg_get_header (msg);
4584 headers_action_show_details (header, win, NULL);
4585 g_object_unref (header);
4587 g_object_unref (msg);
4589 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4590 GtkWidget *folder_view, *header_view;
4592 /* Check which widget has the focus */
4593 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4594 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4595 if (gtk_widget_is_focus (folder_view)) {
4596 TnyFolderStore *folder_store
4597 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4598 if (!folder_store) {
4599 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4602 /* Show only when it's a folder */
4603 /* This function should not be called for account items,
4604 * because we dim the menu item for them. */
4605 if (TNY_IS_FOLDER (folder_store)) {
4606 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4607 TNY_FOLDER (folder_store));
4610 g_object_unref (folder_store);
4613 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4614 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4615 /* Show details of each header */
4616 do_headers_action (win, headers_action_show_details, header_view);
4618 #ifdef MODEST_TOOLKIT_HILDON2
4619 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4621 GtkWidget *header_view;
4623 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4624 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4626 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4628 g_object_unref (folder);
4635 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4636 ModestMsgEditWindow *window)
4638 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4640 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4644 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4645 ModestMsgEditWindow *window)
4647 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4649 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4653 modest_ui_actions_toggle_folders_view (GtkAction *action,
4654 ModestMainWindow *main_window)
4656 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4658 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4659 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4661 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4665 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4666 ModestWindow *window)
4668 gboolean active, fullscreen = FALSE;
4669 ModestWindowMgr *mgr;
4671 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4673 /* Check if we want to toggle the toolbar view in fullscreen
4675 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4676 "ViewShowToolbarFullScreen")) {
4680 /* Toggle toolbar */
4681 mgr = modest_runtime_get_window_mgr ();
4682 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4686 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4687 ModestMsgEditWindow *window)
4689 modest_msg_edit_window_select_font (window);
4694 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4695 const gchar *display_name,
4698 /* don't update the display name if it was already set;
4699 * updating the display name apparently is expensive */
4700 const gchar* old_name = gtk_window_get_title (window);
4702 if (display_name == NULL)
4705 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4706 return; /* don't do anything */
4708 /* This is usually used to change the title of the main window, which
4709 * is the one that holds the folder view. Note that this change can
4710 * happen even when the widget doesn't have the focus. */
4711 gtk_window_set_title (window, display_name);
4716 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4718 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4719 modest_msg_edit_window_select_contacts (window);
4723 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4725 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4726 modest_msg_edit_window_check_names (window, FALSE);
4729 #ifndef MODEST_TOOLKIT_HILDON2
4731 * This function is used to track changes in the selection of the
4732 * folder view that is inside the "move to" dialog to enable/disable
4733 * the OK button because we do not want the user to select a disallowed
4734 * destination for a folder.
4735 * The user also not desired to be able to use NEW button on items where
4736 * folder creation is not possibel.
4739 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4740 TnyFolderStore *folder_store,
4744 GtkWidget *dialog = NULL;
4745 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4746 gboolean moving_folder = FALSE;
4747 gboolean is_local_account = TRUE;
4748 GtkWidget *folder_view = NULL;
4749 ModestTnyFolderRules rules;
4751 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
4756 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
4760 /* check if folder_store is an remote account */
4761 if (TNY_IS_ACCOUNT (folder_store)) {
4762 TnyAccount *local_account = NULL;
4763 TnyAccount *mmc_account = NULL;
4764 ModestTnyAccountStore *account_store = NULL;
4766 account_store = modest_runtime_get_account_store ();
4767 local_account = modest_tny_account_store_get_local_folders_account (account_store);
4768 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
4770 if ((gpointer) local_account != (gpointer) folder_store &&
4771 (gpointer) mmc_account != (gpointer) folder_store) {
4772 ModestProtocolType proto;
4773 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
4774 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
4775 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
4777 is_local_account = FALSE;
4778 /* New button should be dimmed on remote
4780 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4782 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
4784 g_object_unref (local_account);
4786 /* It could not exist */
4788 g_object_unref (mmc_account);
4791 /* Check the target folder rules */
4792 if (TNY_IS_FOLDER (folder_store)) {
4793 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
4794 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
4795 ok_sensitive = FALSE;
4796 new_sensitive = FALSE;
4801 /* Check if we're moving a folder */
4802 if (MODEST_IS_MAIN_WINDOW (user_data)) {
4803 /* Get the widgets */
4804 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
4805 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4806 if (gtk_widget_is_focus (folder_view))
4807 moving_folder = TRUE;
4810 if (moving_folder) {
4811 TnyFolderStore *moved_folder = NULL, *parent = NULL;
4813 /* Get the folder to move */
4814 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4816 /* Check that we're not moving to the same folder */
4817 if (TNY_IS_FOLDER (moved_folder)) {
4818 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
4819 if (parent == folder_store)
4820 ok_sensitive = FALSE;
4821 g_object_unref (parent);
4824 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
4825 /* Do not allow to move to an account unless it's the
4826 local folders account */
4827 if (!is_local_account)
4828 ok_sensitive = FALSE;
4831 if (ok_sensitive && (moved_folder == folder_store)) {
4832 /* Do not allow to move to itself */
4833 ok_sensitive = FALSE;
4835 g_object_unref (moved_folder);
4837 TnyFolder *src_folder = NULL;
4839 /* Moving a message */
4840 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
4842 TnyHeader *header = NULL;
4843 header = modest_msg_view_window_get_header
4844 (MODEST_MSG_VIEW_WINDOW (user_data));
4845 if (!TNY_IS_HEADER(header))
4846 g_warning ("%s: could not get source header", __FUNCTION__);
4848 src_folder = tny_header_get_folder (header);
4851 g_object_unref (header);
4854 TNY_FOLDER (modest_folder_view_get_selected
4855 (MODEST_FOLDER_VIEW (folder_view)));
4858 if (TNY_IS_FOLDER(src_folder)) {
4859 /* Do not allow to move the msg to the same folder */
4860 /* Do not allow to move the msg to an account */
4861 if ((gpointer) src_folder == (gpointer) folder_store ||
4862 TNY_IS_ACCOUNT (folder_store))
4863 ok_sensitive = FALSE;
4864 g_object_unref (src_folder);
4866 g_warning ("%s: could not get source folder", __FUNCTION__);
4870 /* Set sensitivity of the OK and NEW button */
4871 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
4872 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
4877 on_move_to_dialog_response (GtkDialog *dialog,
4881 GtkWidget *parent_win;
4882 MoveToInfo *helper = NULL;
4883 ModestFolderView *folder_view;
4885 helper = (MoveToInfo *) user_data;
4887 parent_win = (GtkWidget *) helper->win;
4888 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
4889 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4892 TnyFolderStore *dst_folder;
4894 case MODEST_GTK_RESPONSE_NEW_FOLDER:
4895 modest_ui_actions_create_folder (GTK_WIDGET (dialog), GTK_WIDGET (folder_view));
4897 case GTK_RESPONSE_NONE:
4898 case GTK_RESPONSE_CANCEL:
4899 case GTK_RESPONSE_DELETE_EVENT:
4901 case GTK_RESPONSE_OK:
4902 dst_folder = modest_folder_view_get_selected (folder_view);
4904 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
4905 /* Clean list to move used for filtering */
4906 modest_folder_view_set_list_to_move (folder_view, NULL);
4908 modest_ui_actions_on_main_window_move_to (NULL,
4909 GTK_WIDGET (folder_view),
4911 MODEST_MAIN_WINDOW (parent_win));
4912 #ifdef MODEST_TOOLKIT_HILDON2
4913 } else if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
4914 /* Clean list to move used for filtering */
4915 modest_folder_view_set_list_to_move (folder_view, NULL);
4917 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
4920 GTK_WINDOW (parent_win));
4923 /* if the user selected a root folder
4924 (account) then do not perform any action */
4925 if (TNY_IS_ACCOUNT (dst_folder)) {
4926 g_signal_stop_emission_by_name (dialog, "response");
4930 /* Clean list to move used for filtering */
4931 modest_folder_view_set_list_to_move (folder_view, NULL);
4933 /* Moving from headers window in edit mode */
4934 modest_ui_actions_on_window_move_to (NULL, helper->list,
4936 MODEST_WINDOW (parent_win));
4940 g_object_unref (dst_folder);
4944 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
4947 /* Free the helper and exit */
4949 g_object_unref (helper->list);
4950 g_slice_free (MoveToInfo, helper);
4951 gtk_widget_destroy (GTK_WIDGET (dialog));
4955 create_move_to_dialog (GtkWindow *win,
4956 GtkWidget *folder_view,
4957 TnyList *list_to_move)
4959 GtkWidget *dialog, *tree_view = NULL;
4961 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
4963 #ifndef MODEST_TOOLKIT_HILDON2
4964 /* Track changes in the selection to
4965 * disable the OK button whenever "Move to" is not possible
4966 * disbale NEW button whenever New is not possible */
4967 g_signal_connect (tree_view,
4968 "folder_selection_changed",
4969 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
4973 /* It could happen that we're trying to move a message from a
4974 window (msg window for example) after the main window was
4975 closed, so we can not just get the model of the folder
4977 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4978 const gchar *visible_id = NULL;
4980 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4981 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4982 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4983 MODEST_FOLDER_VIEW(tree_view));
4986 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4988 /* Show the same account than the one that is shown in the main window */
4989 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
4992 const gchar *active_account_name = NULL;
4993 ModestAccountMgr *mgr = NULL;
4994 ModestAccountSettings *settings = NULL;
4995 ModestServerAccountSettings *store_settings = NULL;
4997 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4998 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4999 modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view),
5000 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
5002 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
5003 mgr = modest_runtime_get_account_mgr ();
5004 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
5007 const gchar *store_account_name;
5008 store_settings = modest_account_settings_get_store_settings (settings);
5009 store_account_name = modest_server_account_settings_get_account_name (store_settings);
5011 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
5012 store_account_name);
5013 g_object_unref (store_settings);
5014 g_object_unref (settings);
5018 /* we keep a pointer to the embedded folder view, so we can
5019 * retrieve it with get_folder_view_from_move_to_dialog (see
5020 * above) later (needed for focus handling)
5022 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
5024 /* Hide special folders */
5025 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
5027 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
5028 #ifndef MODEST_TOOLKIT_HILDON2
5029 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5032 gtk_widget_show (GTK_WIDGET (tree_view));
5038 * Shows a confirmation dialog to the user when we're moving messages
5039 * from a remote server to the local storage. Returns the dialog
5040 * response. If it's other kind of movement then it always returns
5043 * This one is used by the next functions:
5044 * modest_ui_actions_on_paste - commented out
5045 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
5048 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
5049 TnyFolder *dest_folder,
5053 gint response = GTK_RESPONSE_OK;
5054 TnyAccount *account = NULL;
5055 TnyFolder *src_folder = NULL;
5056 TnyIterator *iter = NULL;
5057 TnyHeader *header = NULL;
5059 /* return with OK if the destination is a remote folder */
5060 if (modest_tny_folder_is_remote_folder (dest_folder))
5061 return GTK_RESPONSE_OK;
5063 /* Get source folder */
5064 iter = tny_list_create_iterator (headers);
5065 header = TNY_HEADER (tny_iterator_get_current (iter));
5067 src_folder = tny_header_get_folder (header);
5068 g_object_unref (header);
5070 g_object_unref (iter);
5072 /* if no src_folder, message may be an attahcment */
5073 if (src_folder == NULL)
5074 return GTK_RESPONSE_CANCEL;
5076 /* If the source is a local or MMC folder */
5077 if (!modest_tny_folder_is_remote_folder (src_folder)) {
5078 g_object_unref (src_folder);
5079 return GTK_RESPONSE_OK;
5082 /* Get the account */
5083 account = tny_folder_get_account (src_folder);
5085 /* now if offline we ask the user */
5086 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
5087 response = GTK_RESPONSE_OK;
5089 response = GTK_RESPONSE_CANCEL;
5092 g_object_unref (src_folder);
5093 g_object_unref (account);
5099 move_to_helper_destroyer (gpointer user_data)
5101 MoveToHelper *helper = (MoveToHelper *) user_data;
5103 /* Close the "Pasting" information banner */
5104 if (helper->banner) {
5105 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5106 g_object_unref (helper->banner);
5108 if (gtk_tree_row_reference_valid (helper->reference)) {
5109 gtk_tree_row_reference_free (helper->reference);
5110 helper->reference = NULL;
5116 move_to_cb (ModestMailOperation *mail_op,
5119 MoveToHelper *helper = (MoveToHelper *) user_data;
5120 GObject *object = modest_mail_operation_get_source (mail_op);
5122 /* Note that the operation could have failed, in that case do
5124 if (modest_mail_operation_get_status (mail_op) !=
5125 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5128 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5129 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5131 if (!modest_msg_view_window_select_next_message (self) &&
5132 !modest_msg_view_window_select_previous_message (self)) {
5133 /* No more messages to view, so close this window */
5134 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5136 } else if (MODEST_IS_MAIN_WINDOW (object) &&
5137 gtk_tree_row_reference_valid (helper->reference)) {
5138 GtkWidget *header_view;
5140 GtkTreeSelection *sel;
5142 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5143 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5144 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5145 path = gtk_tree_row_reference_get_path (helper->reference);
5146 /* We need to unselect the previous one
5147 because we could be copying instead of
5149 gtk_tree_selection_unselect_all (sel);
5150 gtk_tree_selection_select_path (sel, path);
5151 gtk_tree_path_free (path);
5153 g_object_unref (object);
5156 /* Destroy the helper */
5157 move_to_helper_destroyer (helper);
5161 folder_move_to_cb (ModestMailOperation *mail_op,
5162 TnyFolder *new_folder,
5165 GtkWidget *folder_view;
5168 object = modest_mail_operation_get_source (mail_op);
5169 if (MODEST_IS_MAIN_WINDOW (object)) {
5170 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5171 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5172 g_object_ref (folder_view);
5173 g_object_unref (object);
5174 move_to_cb (mail_op, user_data);
5175 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5176 g_object_unref (folder_view);
5178 move_to_cb (mail_op, user_data);
5183 msgs_move_to_cb (ModestMailOperation *mail_op,
5186 move_to_cb (mail_op, user_data);
5190 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5193 GObject *win = NULL;
5195 #ifndef MODEST_TOOLKIT_HILDON2
5196 ModestWindow *main_window = NULL;
5198 /* Disable next automatic folder selection */
5199 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5200 FALSE); /* don't create */
5202 GtkWidget *folder_view = NULL;
5204 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5205 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5206 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5208 if (user_data && TNY_IS_FOLDER (user_data)) {
5209 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5210 TNY_FOLDER (user_data), FALSE);
5214 /* Show notification dialog only if the main window exists */
5215 win = modest_mail_operation_get_source (mail_op);
5216 modest_platform_run_information_dialog ((GtkWindow *) win,
5217 _("mail_in_ui_folder_move_target_error"),
5220 g_object_unref (win);
5224 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5233 gint pending_purges = 0;
5234 gboolean some_purged = FALSE;
5235 ModestWindow *win = MODEST_WINDOW (user_data);
5236 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5238 /* If there was any error */
5239 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5240 modest_window_mgr_unregister_header (mgr, header);
5244 /* Once the message has been retrieved for purging, we check if
5245 * it's all ok for purging */
5247 parts = tny_simple_list_new ();
5248 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5249 iter = tny_list_create_iterator (parts);
5251 while (!tny_iterator_is_done (iter)) {
5253 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5254 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5255 if (tny_mime_part_is_purged (part))
5262 g_object_unref (part);
5264 tny_iterator_next (iter);
5266 g_object_unref (iter);
5269 if (pending_purges>0) {
5271 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5273 if (response == GTK_RESPONSE_OK) {
5276 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5277 iter = tny_list_create_iterator (parts);
5278 while (!tny_iterator_is_done (iter)) {
5281 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5282 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5283 tny_mime_part_set_purged (part);
5286 g_object_unref (part);
5288 tny_iterator_next (iter);
5290 g_object_unref (iter);
5292 tny_msg_rewrite_cache (msg);
5294 gtk_widget_destroy (info);
5298 modest_window_mgr_unregister_header (mgr, header);
5300 g_object_unref (parts);
5304 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5305 ModestMainWindow *win)
5307 GtkWidget *header_view;
5308 TnyList *header_list;
5310 TnyHeaderFlags flags;
5311 ModestWindow *msg_view_window = NULL;
5314 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5316 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5317 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5319 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5321 g_warning ("%s: no header selected", __FUNCTION__);
5325 if (tny_list_get_length (header_list) == 1) {
5326 TnyIterator *iter = tny_list_create_iterator (header_list);
5327 header = TNY_HEADER (tny_iterator_get_current (iter));
5328 g_object_unref (iter);
5332 if (!header || !TNY_IS_HEADER(header)) {
5333 g_warning ("%s: header is not valid", __FUNCTION__);
5337 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5338 header, &msg_view_window);
5339 flags = tny_header_get_flags (header);
5340 if (!(flags & TNY_HEADER_FLAG_CACHED))
5343 if (msg_view_window != NULL)
5344 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5346 /* do nothing; uid was registered before, so window is probably on it's way */
5347 g_warning ("debug: header %p has already been registered", header);
5350 ModestMailOperation *mail_op = NULL;
5351 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5352 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5353 modest_ui_actions_disk_operations_error_handler,
5355 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5356 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5358 g_object_unref (mail_op);
5361 g_object_unref (header);
5363 g_object_unref (header_list);
5367 * Checks if we need a connection to do the transfer and if the user
5368 * wants to connect to complete it
5371 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5372 TnyFolderStore *src_folder,
5374 TnyFolder *dst_folder,
5375 gboolean delete_originals,
5376 gboolean *need_connection,
5379 TnyAccount *src_account;
5380 gint uncached_msgs = 0;
5382 /* We don't need any further check if
5384 * 1- the source folder is local OR
5385 * 2- the device is already online
5387 if (!modest_tny_folder_store_is_remote (src_folder) ||
5388 tny_device_is_online (modest_runtime_get_device())) {
5389 *need_connection = FALSE;
5394 /* We must ask for a connection when
5396 * - the message(s) is not already cached OR
5397 * - the message(s) is cached but the leave_on_server setting
5398 * is FALSE (because we need to sync the source folder to
5399 * delete the message from the server (for IMAP we could do it
5400 * offline, it'll take place the next time we get a
5403 uncached_msgs = header_list_count_uncached_msgs (headers);
5404 src_account = get_account_from_folder_store (src_folder);
5405 if (uncached_msgs > 0) {
5409 *need_connection = TRUE;
5410 num_headers = tny_list_get_length (headers);
5411 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5413 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5414 GTK_RESPONSE_CANCEL) {
5420 /* The transfer is possible and the user wants to */
5423 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5424 const gchar *account_name;
5425 gboolean leave_on_server;
5427 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5428 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5431 if (leave_on_server == TRUE) {
5432 *need_connection = FALSE;
5434 *need_connection = TRUE;
5437 *need_connection = FALSE;
5442 g_object_unref (src_account);
5446 xfer_messages_error_handler (ModestMailOperation *mail_op,
5450 const GError *error;
5452 win = modest_mail_operation_get_source (mail_op);
5453 error = modest_mail_operation_get_error (mail_op);
5455 if (error && is_memory_full_error ((GError *) error, mail_op))
5456 modest_platform_information_banner ((GtkWidget *) win,
5457 NULL, _KR("cerm_device_memory_full"));
5459 modest_platform_run_information_dialog ((GtkWindow *) win,
5460 _("mail_in_ui_folder_move_target_error"),
5463 g_object_unref (win);
5467 TnyFolderStore *dst_folder;
5472 * Utility function that transfer messages from both the main window
5473 * and the msg view window when using the "Move to" dialog
5476 xfer_messages_performer (gboolean canceled,
5478 GtkWindow *parent_window,
5479 TnyAccount *account,
5482 ModestWindow *win = MODEST_WINDOW (parent_window);
5483 TnyAccount *dst_account = NULL;
5484 gboolean dst_forbids_message_add = FALSE;
5485 XferMsgsHelper *helper;
5486 MoveToHelper *movehelper;
5487 ModestMailOperation *mail_op;
5489 helper = (XferMsgsHelper *) user_data;
5491 if (canceled || err) {
5492 if (!check_memory_full_error ((GtkWidget *) parent_window, err)) {
5493 /* Show the proper error message */
5494 modest_ui_actions_on_account_connection_error (parent_window, account);
5499 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5501 /* tinymail will return NULL for local folders it seems */
5502 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5503 modest_tny_account_get_protocol_type (dst_account),
5504 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_MESSAGE_ADD);
5505 g_object_unref (dst_account);
5507 if (dst_forbids_message_add) {
5508 modest_platform_information_banner (GTK_WIDGET (win),
5510 ngettext("mail_in_ui_folder_move_target_error",
5511 "mail_in_ui_folder_move_targets_error",
5512 tny_list_get_length (helper->headers)));
5516 movehelper = g_new0 (MoveToHelper, 1);
5518 #ifndef MODEST_TOOLKIT_HILDON2
5519 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5520 _CS("ckct_nw_pasting"));
5521 if (movehelper->banner != NULL) {
5522 g_object_ref (movehelper->banner);
5523 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5527 if (MODEST_IS_MAIN_WINDOW (win)) {
5528 GtkWidget *header_view =
5529 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5530 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5531 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5534 /* Perform the mail operation */
5535 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5536 xfer_messages_error_handler,
5538 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5541 modest_mail_operation_xfer_msgs (mail_op,
5543 TNY_FOLDER (helper->dst_folder),
5548 g_object_unref (G_OBJECT (mail_op));
5550 g_object_unref (helper->dst_folder);
5551 g_object_unref (helper->headers);
5552 g_slice_free (XferMsgsHelper, helper);
5556 TnyFolder *src_folder;
5557 TnyFolderStore *dst_folder;
5558 gboolean delete_original;
5559 GtkWidget *folder_view;
5563 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
5564 TnyAccount *account, gpointer user_data)
5566 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5567 GtkTreeSelection *sel;
5568 ModestMailOperation *mail_op = NULL;
5570 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
5571 g_object_unref (G_OBJECT (info->src_folder));
5572 g_object_unref (G_OBJECT (info->dst_folder));
5577 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5578 #ifndef MODEST_TOOLKIT_HILDON2
5579 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5580 _CS("ckct_nw_pasting"));
5581 if (helper->banner != NULL) {
5582 g_object_ref (helper->banner);
5583 gtk_widget_show (GTK_WIDGET(helper->banner));
5586 /* Clean folder on header view before moving it */
5587 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5588 gtk_tree_selection_unselect_all (sel);
5590 /* Let gtk events run. We need that the folder
5591 view frees its reference to the source
5592 folder *before* issuing the mail operation
5593 so we need the signal handler of selection
5594 changed to happen before the mail
5596 while (gtk_events_pending ())
5597 gtk_main_iteration (); */
5600 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5601 modest_ui_actions_move_folder_error_handler,
5602 info->src_folder, NULL);
5603 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5606 /* Select *after* the changes */
5607 /* TODO: this function hangs UI after transfer */
5608 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
5609 /* TNY_FOLDER (src_folder), TRUE); */
5611 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
5612 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5613 TNY_FOLDER (info->dst_folder), TRUE);
5615 modest_mail_operation_xfer_folder (mail_op,
5616 TNY_FOLDER (info->src_folder),
5618 info->delete_original,
5621 g_object_unref (G_OBJECT (info->src_folder));
5623 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5626 /* Unref mail operation */
5627 g_object_unref (G_OBJECT (mail_op));
5628 g_object_unref (G_OBJECT (info->dst_folder));
5633 get_account_from_folder_store (TnyFolderStore *folder_store)
5635 if (TNY_IS_ACCOUNT (folder_store))
5636 return g_object_ref (folder_store);
5638 return tny_folder_get_account (TNY_FOLDER (folder_store));
5642 * UI handler for the "Move to" action when invoked from the
5646 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5647 GtkWidget *folder_view,
5648 TnyFolderStore *dst_folder,
5649 ModestMainWindow *win)
5651 ModestHeaderView *header_view = NULL;
5652 TnyFolderStore *src_folder = NULL;
5654 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5656 /* Get the source folder */
5657 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5659 /* Get header view */
5660 header_view = (ModestHeaderView *)
5661 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5663 /* Get folder or messages to transfer */
5664 if (gtk_widget_is_focus (folder_view)) {
5665 gboolean do_xfer = TRUE;
5667 /* Allow only to transfer folders to the local root folder */
5668 if (TNY_IS_ACCOUNT (dst_folder) &&
5669 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5670 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5672 } else if (!TNY_IS_FOLDER (src_folder)) {
5673 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5678 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5679 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5681 info->src_folder = g_object_ref (src_folder);
5682 info->dst_folder = g_object_ref (dst_folder);
5683 info->delete_original = TRUE;
5684 info->folder_view = folder_view;
5686 connect_info->callback = on_move_folder_cb;
5687 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5688 connect_info->data = info;
5690 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5691 TNY_FOLDER_STORE (src_folder),
5694 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5697 headers = modest_header_view_get_selected_headers(header_view);
5699 /* Transfer the messages */
5700 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
5701 headers, TNY_FOLDER (dst_folder));
5703 g_object_unref (headers);
5707 g_object_unref (src_folder);
5710 #ifdef MODEST_TOOLKIT_HILDON2
5712 * UI handler for the "Move to" action when invoked from the
5713 * ModestFolderWindow
5716 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
5717 TnyFolderStore *dst_folder,
5721 TnyFolderStore *src_folder = NULL;
5722 TnyIterator *iterator;
5724 if (tny_list_get_length (selection) != 1)
5727 iterator = tny_list_create_iterator (selection);
5728 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
5729 g_object_unref (iterator);
5732 gboolean do_xfer = TRUE;
5734 /* Allow only to transfer folders to the local root folder */
5735 if (TNY_IS_ACCOUNT (dst_folder) &&
5736 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5737 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5740 modest_platform_run_information_dialog (win,
5741 _("mail_in_ui_folder_move_target_error"),
5743 } else if (!TNY_IS_FOLDER (src_folder)) {
5744 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5749 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5750 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5752 info->src_folder = g_object_ref (src_folder);
5753 info->dst_folder = g_object_ref (dst_folder);
5754 info->delete_original = TRUE;
5755 info->folder_view = folder_view;
5757 connect_info->callback = on_move_folder_cb;
5758 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5759 connect_info->data = info;
5761 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5762 TNY_FOLDER_STORE (src_folder),
5767 g_object_unref (src_folder);
5773 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
5774 TnyFolder *src_folder,
5776 TnyFolder *dst_folder)
5778 gboolean need_connection = TRUE;
5779 gboolean do_xfer = TRUE;
5780 XferMsgsHelper *helper;
5782 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5783 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5784 g_return_if_fail (TNY_IS_LIST (headers));
5786 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5787 headers, TNY_FOLDER (dst_folder),
5788 TRUE, &need_connection,
5791 /* If we don't want to transfer just return */
5795 /* Create the helper */
5796 helper = g_slice_new (XferMsgsHelper);
5797 helper->dst_folder = g_object_ref (dst_folder);
5798 helper->headers = g_object_ref (headers);
5800 if (need_connection) {
5801 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5802 connect_info->callback = xfer_messages_performer;
5803 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5804 connect_info->data = helper;
5806 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5807 TNY_FOLDER_STORE (src_folder),
5810 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5811 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
5812 src_account, helper);
5813 g_object_unref (src_account);
5818 * UI handler for the "Move to" action when invoked from the
5819 * ModestMsgViewWindow
5822 modest_ui_actions_on_window_move_to (GtkAction *action,
5824 TnyFolderStore *dst_folder,
5827 TnyFolder *src_folder = NULL;
5829 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5832 TnyHeader *header = NULL;
5835 iter = tny_list_create_iterator (headers);
5836 header = (TnyHeader *) tny_iterator_get_current (iter);
5837 src_folder = tny_header_get_folder (header);
5839 /* Transfer the messages */
5840 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
5842 TNY_FOLDER (dst_folder));
5845 g_object_unref (header);
5846 g_object_unref (iter);
5847 g_object_unref (src_folder);
5852 modest_ui_actions_on_move_to (GtkAction *action,
5855 modest_ui_actions_on_edit_mode_move_to (win);
5859 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
5861 GtkWidget *dialog = NULL;
5862 MoveToInfo *helper = NULL;
5863 TnyList *list_to_move;
5865 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
5867 #ifndef MODEST_TOOLKIT_HILDON2
5868 /* Get the main window if exists */
5869 ModestMainWindow *main_window;
5870 if (MODEST_IS_MAIN_WINDOW (win))
5871 main_window = MODEST_MAIN_WINDOW (win);
5874 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5875 FALSE)); /* don't create */
5878 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
5883 if (tny_list_get_length (list_to_move) < 1) {
5884 g_object_unref (list_to_move);
5888 /* Create and run the dialog */
5889 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
5890 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
5891 GTK_WINDOW (dialog),
5895 helper = g_slice_new0 (MoveToInfo);
5896 helper->list = list_to_move;
5899 /* Listen to response signal */
5900 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
5902 /* Show the dialog */
5903 gtk_widget_show (dialog);
5909 * Calls #HeadersFunc for each header already selected in the main
5910 * window or the message currently being shown in the msg view window
5913 do_headers_action (ModestWindow *win,
5917 TnyList *headers_list = NULL;
5918 TnyIterator *iter = NULL;
5919 TnyHeader *header = NULL;
5920 TnyFolder *folder = NULL;
5923 headers_list = get_selected_headers (win);
5927 /* Get the folder */
5928 iter = tny_list_create_iterator (headers_list);
5929 header = TNY_HEADER (tny_iterator_get_current (iter));
5931 folder = tny_header_get_folder (header);
5932 g_object_unref (header);
5935 /* Call the function for each header */
5936 while (!tny_iterator_is_done (iter)) {
5937 header = TNY_HEADER (tny_iterator_get_current (iter));
5938 func (header, win, user_data);
5939 g_object_unref (header);
5940 tny_iterator_next (iter);
5943 /* Trick: do a poke status in order to speed up the signaling
5946 tny_folder_poke_status (folder);
5947 g_object_unref (folder);
5951 g_object_unref (iter);
5952 g_object_unref (headers_list);
5956 modest_ui_actions_view_attachment (GtkAction *action,
5957 ModestWindow *window)
5959 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5960 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5962 /* not supported window for this action */
5963 g_return_if_reached ();
5968 modest_ui_actions_save_attachments (GtkAction *action,
5969 ModestWindow *window)
5971 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5973 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5976 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5978 /* not supported window for this action */
5979 g_return_if_reached ();
5984 modest_ui_actions_remove_attachments (GtkAction *action,
5985 ModestWindow *window)
5987 if (MODEST_IS_MAIN_WINDOW (window)) {
5988 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
5989 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5990 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5992 /* not supported window for this action */
5993 g_return_if_reached ();
5998 modest_ui_actions_on_settings (GtkAction *action,
6003 dialog = modest_platform_get_global_settings_dialog ();
6004 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
6005 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
6006 gtk_widget_show_all (dialog);
6008 gtk_dialog_run (GTK_DIALOG (dialog));
6010 gtk_widget_destroy (dialog);
6014 modest_ui_actions_on_help (GtkAction *action,
6017 /* Help app is not available at all in fremantle */
6018 #ifndef MODEST_TOOLKIT_HILDON2
6019 const gchar *help_id;
6021 g_return_if_fail (win && GTK_IS_WINDOW(win));
6023 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
6026 modest_platform_show_help (GTK_WINDOW (win), help_id);
6031 modest_ui_actions_on_csm_help (GtkAction *action,
6034 /* Help app is not available at all in fremantle */
6035 #ifndef MODEST_TOOLKIT_HILDON2
6037 const gchar* help_id = NULL;
6038 GtkWidget *folder_view;
6039 TnyFolderStore *folder_store;
6041 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
6043 /* Get selected folder */
6044 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
6045 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6046 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6048 /* Switch help_id */
6049 if (folder_store && TNY_IS_FOLDER (folder_store))
6050 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
6053 g_object_unref (folder_store);
6056 modest_platform_show_help (GTK_WINDOW (win), help_id);
6058 modest_ui_actions_on_help (action, win);
6063 retrieve_contents_cb (ModestMailOperation *mail_op,
6070 /* We only need this callback to show an error in case of
6071 memory low condition */
6072 modest_ui_actions_msg_retrieval_check (mail_op, header, msg);
6076 retrieve_msg_contents_performer (gboolean canceled,
6078 GtkWindow *parent_window,
6079 TnyAccount *account,
6082 ModestMailOperation *mail_op;
6083 TnyList *headers = TNY_LIST (user_data);
6085 if (err || canceled) {
6086 check_memory_full_error ((GtkWidget *) parent_window, err);
6090 /* Create mail operation */
6091 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
6092 modest_ui_actions_disk_operations_error_handler,
6094 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
6095 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
6098 g_object_unref (mail_op);
6100 g_object_unref (headers);
6101 g_object_unref (account);
6105 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
6106 ModestWindow *window)
6108 TnyList *headers = NULL;
6109 TnyAccount *account = NULL;
6110 TnyIterator *iter = NULL;
6111 TnyHeader *header = NULL;
6112 TnyFolder *folder = NULL;
6115 headers = get_selected_headers (window);
6119 /* Pick the account */
6120 iter = tny_list_create_iterator (headers);
6121 header = TNY_HEADER (tny_iterator_get_current (iter));
6122 folder = tny_header_get_folder (header);
6123 account = tny_folder_get_account (folder);
6124 g_object_unref (folder);
6125 g_object_unref (header);
6126 g_object_unref (iter);
6128 /* Connect and perform the message retrieval */
6129 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6130 g_object_ref (account),
6131 retrieve_msg_contents_performer,
6132 g_object_ref (headers));
6135 g_object_unref (account);
6136 g_object_unref (headers);
6140 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6142 g_return_if_fail (MODEST_IS_WINDOW (window));
6145 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6149 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6151 g_return_if_fail (MODEST_IS_WINDOW (window));
6154 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6158 modest_ui_actions_on_email_menu_activated (GtkAction *action,
6159 ModestWindow *window)
6161 g_return_if_fail (MODEST_IS_WINDOW (window));
6164 modest_ui_actions_check_menu_dimming_rules (window);
6168 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
6169 ModestWindow *window)
6171 g_return_if_fail (MODEST_IS_WINDOW (window));
6174 modest_ui_actions_check_menu_dimming_rules (window);
6178 modest_ui_actions_on_view_menu_activated (GtkAction *action,
6179 ModestWindow *window)
6181 g_return_if_fail (MODEST_IS_WINDOW (window));
6184 modest_ui_actions_check_menu_dimming_rules (window);
6188 modest_ui_actions_on_format_menu_activated (GtkAction *action,
6189 ModestWindow *window)
6191 g_return_if_fail (MODEST_IS_WINDOW (window));
6194 modest_ui_actions_check_menu_dimming_rules (window);
6198 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
6199 ModestWindow *window)
6201 g_return_if_fail (MODEST_IS_WINDOW (window));
6204 modest_ui_actions_check_menu_dimming_rules (window);
6208 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
6209 ModestWindow *window)
6211 g_return_if_fail (MODEST_IS_WINDOW (window));
6214 modest_ui_actions_check_menu_dimming_rules (window);
6218 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
6219 ModestWindow *window)
6221 g_return_if_fail (MODEST_IS_WINDOW (window));
6224 modest_ui_actions_check_menu_dimming_rules (window);
6228 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
6229 ModestWindow *window)
6231 g_return_if_fail (MODEST_IS_WINDOW (window));
6234 modest_ui_actions_check_menu_dimming_rules (window);
6238 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
6239 ModestWindow *window)
6241 g_return_if_fail (MODEST_IS_WINDOW (window));
6244 modest_ui_actions_check_menu_dimming_rules (window);
6248 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6250 g_return_if_fail (MODEST_IS_WINDOW (window));
6252 /* we check for low-mem; in that case, show a warning, and don't allow
6255 if (modest_platform_check_memory_low (window, TRUE))
6258 modest_platform_show_search_messages (GTK_WINDOW (window));
6262 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6264 g_return_if_fail (MODEST_IS_WINDOW (win));
6267 /* we check for low-mem; in that case, show a warning, and don't allow
6268 * for the addressbook
6270 if (modest_platform_check_memory_low (win, TRUE))
6274 modest_platform_show_addressbook (GTK_WINDOW (win));
6279 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6280 ModestWindow *window)
6283 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6285 if (GTK_IS_TOGGLE_ACTION (action))
6286 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6290 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window),
6295 on_send_receive_finished (ModestMailOperation *mail_op,
6298 GtkWidget *header_view, *folder_view;
6299 TnyFolderStore *folder_store;
6300 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6302 /* Set send/receive operation finished */
6303 modest_main_window_notify_send_receive_completed (main_win);
6305 /* Don't refresh the current folder if there were any errors */
6306 if (modest_mail_operation_get_status (mail_op) !=
6307 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6310 /* Refresh the current folder if we're viewing a window. We do
6311 this because the user won't be able to see the new mails in
6312 the selected folder after a Send&Receive because it only
6313 performs a poke_status, i.e, only the number of read/unread
6314 messages is updated, but the new headers are not
6316 folder_view = modest_main_window_get_child_widget (main_win,
6317 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6321 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6323 /* Do not need to refresh INBOX again because the
6324 update_account does it always automatically */
6325 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6326 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6327 ModestMailOperation *refresh_op;
6329 header_view = modest_main_window_get_child_widget (main_win,
6330 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6332 /* We do not need to set the contents style
6333 because it hasn't changed. We also do not
6334 need to save the widget status. Just force
6336 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6337 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6338 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6339 folder_refreshed_cb, main_win);
6340 g_object_unref (refresh_op);
6344 g_object_unref (folder_store);
6349 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6355 const gchar* server_name = NULL;
6356 TnyTransportAccount *transport;
6357 gchar *message = NULL;
6358 ModestProtocol *protocol;
6360 /* Don't show anything if the user cancelled something or the
6361 * send receive request is not interactive. Authentication
6362 * errors are managed by the account store so no need to show
6363 * a dialog here again */
6364 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6365 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6366 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6370 /* Get the server name. Note that we could be using a
6371 connection specific transport account */
6372 transport = (TnyTransportAccount *)
6373 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
6375 ModestTnyAccountStore *acc_store;
6376 const gchar *acc_name;
6377 TnyTransportAccount *conn_specific;
6379 acc_store = modest_runtime_get_account_store();
6380 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
6381 conn_specific = (TnyTransportAccount *)
6382 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
6383 if (conn_specific) {
6384 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
6385 g_object_unref (conn_specific);
6387 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
6389 g_object_unref (transport);
6393 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
6394 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
6395 tny_account_get_proto (TNY_ACCOUNT (transport)));
6397 g_warning ("%s: Account with no proto", __FUNCTION__);
6401 /* Show the appropriate message text for the GError: */
6402 switch (err->code) {
6403 case TNY_SERVICE_ERROR_CONNECT:
6404 message = modest_protocol_get_translation (protocol,
6405 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
6408 case TNY_SERVICE_ERROR_SEND:
6409 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6411 case TNY_SERVICE_ERROR_UNAVAILABLE:
6412 message = modest_protocol_get_translation (protocol,
6413 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
6417 g_warning ("%s: unexpected ERROR %d",
6418 __FUNCTION__, err->code);
6419 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6423 modest_platform_run_information_dialog (NULL, message, FALSE);
6428 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6433 ModestWindow *top_window = NULL;
6434 ModestWindowMgr *mgr = NULL;
6435 GtkWidget *header_view = NULL;
6436 TnyFolder *selected_folder = NULL;
6437 TnyFolderType folder_type;
6439 mgr = modest_runtime_get_window_mgr ();
6440 top_window = modest_window_mgr_get_current_top (mgr);
6445 #ifndef MODEST_TOOLKIT_HILDON2
6446 if (MODEST_IS_MAIN_WINDOW (top_window)) {
6447 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (top_window),
6448 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6451 if (MODEST_IS_HEADER_WINDOW (top_window)) {
6452 header_view = (GtkWidget *)
6453 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
6457 /* Get selected folder */
6459 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
6460 if (!selected_folder)
6463 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6464 #if GTK_CHECK_VERSION(2, 8, 0)
6465 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
6466 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6467 GtkTreeViewColumn *tree_column;
6469 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6470 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6472 gtk_tree_view_column_queue_resize (tree_column);
6474 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
6475 gtk_widget_queue_draw (header_view);
6478 #ifndef MODEST_TOOLKIT_HILDON2
6479 /* Rerun dimming rules, because the message could become deletable for example */
6480 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6481 MODEST_DIMMING_RULES_TOOLBAR);
6482 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6483 MODEST_DIMMING_RULES_MENU);
6487 g_object_unref (selected_folder);
6491 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6492 TnyAccount *account)
6494 ModestProtocolType protocol_type;
6495 ModestProtocol *protocol;
6496 gchar *error_note = NULL;
6498 protocol_type = modest_tny_account_get_protocol_type (account);
6499 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6502 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6503 if (error_note == NULL) {
6504 g_warning ("%s: This should not be reached", __FUNCTION__);
6506 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6507 g_free (error_note);
6512 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6516 TnyFolderStore *folder = NULL;
6517 TnyAccount *account = NULL;
6518 ModestProtocolType proto;
6519 ModestProtocol *protocol;
6520 TnyHeader *header = NULL;
6522 if (MODEST_IS_MAIN_WINDOW (win)) {
6523 GtkWidget *header_view;
6524 TnyList* headers = NULL;
6526 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6527 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6528 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6529 if (!headers || tny_list_get_length (headers) == 0) {
6531 g_object_unref (headers);
6534 iter = tny_list_create_iterator (headers);
6535 header = TNY_HEADER (tny_iterator_get_current (iter));
6536 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6537 g_object_unref (iter);
6538 g_object_unref (headers);
6539 #ifdef MODEST_TOOLKIT_HILDON2
6540 } else if (MODEST_IS_HEADER_WINDOW (win)) {
6541 GtkWidget *header_view;
6542 TnyList* headers = NULL;
6544 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
6545 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6546 if (!headers || tny_list_get_length (headers) == 0) {
6548 g_object_unref (headers);
6551 iter = tny_list_create_iterator (headers);
6552 header = TNY_HEADER (tny_iterator_get_current (iter));
6553 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6554 g_object_unref (iter);
6555 g_object_unref (headers);
6557 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6558 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6559 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6562 if (!header || !folder)
6565 /* Get the account type */
6566 account = tny_folder_get_account (TNY_FOLDER (folder));
6567 proto = modest_tny_account_get_protocol_type (account);
6568 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6571 subject = tny_header_dup_subject (header);
6572 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6576 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6582 g_object_unref (account);
6584 g_object_unref (folder);
6586 g_object_unref (header);
6592 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6593 const gchar *account_name,
6594 const gchar *account_title)
6596 ModestAccountMgr *account_mgr;
6599 ModestProtocol *protocol;
6600 gboolean removed = FALSE;
6602 g_return_val_if_fail (account_name, FALSE);
6603 g_return_val_if_fail (account_title, FALSE);
6605 account_mgr = modest_runtime_get_account_mgr();
6607 /* The warning text depends on the account type: */
6608 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6609 modest_account_mgr_get_store_protocol (account_mgr,
6611 txt = modest_protocol_get_translation (protocol,
6612 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6615 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6617 response = modest_platform_run_confirmation_dialog (parent_window, txt);
6621 if (response == GTK_RESPONSE_OK) {
6622 /* Remove account. If it succeeds then it also removes
6623 the account from the ModestAccountView: */
6624 gboolean is_default = FALSE;
6625 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6626 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6628 g_free (default_account_name);
6630 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6632 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);