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-tny-folder.h>
39 #include <modest-tny-msg.h>
40 #include <modest-tny-account.h>
41 #include <modest-address-book.h>
42 #include "modest-error.h"
43 #include "modest-ui-actions.h"
44 #include "modest-tny-platform-factory.h"
45 #include "modest-platform.h"
46 #include "modest-debug.h"
47 #include <tny-mime-part.h>
48 #include <tny-camel-folder.h>
49 #include <tny-camel-imap-folder.h>
50 #include <tny-camel-pop-folder.h>
51 #ifdef MODEST_TOOLKIT_HILDON2
52 #include <modest-accounts-window.h>
53 #include <hildon/hildon-pannable-area.h>
54 #include <hildon/hildon-gtk.h>
55 #include <modest-header-window.h>
56 #include <modest-folder-window.h>
59 #ifdef MODEST_PLATFORM_MAEMO
60 #include "maemo/modest-osso-state-saving.h"
61 #endif /* MODEST_PLATFORM_MAEMO */
62 #ifndef MODEST_TOOLKIT_GTK
63 #include "maemo/modest-hildon-includes.h"
64 #include "maemo/modest-connection-specific-smtp-window.h"
65 #endif /* !MODEST_TOOLKIT_GTK */
66 #include <modest-utils.h>
68 #include "widgets/modest-ui-constants.h"
69 #include <widgets/modest-main-window.h>
70 #include <widgets/modest-msg-view-window.h>
71 #include <widgets/modest-account-view-window.h>
72 #include <widgets/modest-details-dialog.h>
73 #include <widgets/modest-attachments-view.h>
74 #include "widgets/modest-folder-view.h"
75 #include "widgets/modest-global-settings-dialog.h"
76 #include "modest-account-mgr-helpers.h"
77 #include "modest-mail-operation.h"
78 #include "modest-text-utils.h"
79 #include <modest-widget-memory.h>
80 #include <tny-error.h>
81 #include <tny-simple-list.h>
82 #include <tny-msg-view.h>
83 #include <tny-device.h>
84 #include <tny-merge-folder.h>
86 #include <gtkhtml/gtkhtml.h>
88 #define MIN_FREE_SPACE 5 * 1024 * 1024
89 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
91 typedef struct _GetMsgAsyncHelper {
93 ModestMailOperation *mail_op;
100 typedef enum _ReplyForwardAction {
104 } ReplyForwardAction;
106 typedef struct _ReplyForwardHelper {
107 guint reply_forward_type;
108 ReplyForwardAction action;
110 GtkWidget *parent_window;
112 } ReplyForwardHelper;
114 typedef struct _MoveToHelper {
115 GtkTreeRowReference *reference;
119 typedef struct _PasteAsAttachmentHelper {
120 ModestMsgEditWindow *window;
122 } PasteAsAttachmentHelper;
130 * The do_headers_action uses this kind of functions to perform some
131 * action to each member of a list of headers
133 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
135 static void do_headers_action (ModestWindow *win,
139 static void open_msg_cb (ModestMailOperation *mail_op,
146 static void reply_forward_cb (ModestMailOperation *mail_op,
153 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
155 static void folder_refreshed_cb (ModestMailOperation *mail_op,
159 static void on_send_receive_finished (ModestMailOperation *mail_op,
162 static gint header_list_count_uncached_msgs (TnyList *header_list);
164 static gboolean connect_to_get_msg (ModestWindow *win,
165 gint num_of_uncached_msgs,
166 TnyAccount *account);
168 static gboolean remote_folder_has_leave_on_server (TnyFolderStore *folder);
170 static void do_create_folder (GtkWindow *window,
171 TnyFolderStore *parent_folder,
172 const gchar *suggested_name);
174 static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store);
176 static void modest_ui_actions_on_main_window_move_to (GtkAction *action,
177 GtkWidget *folder_view,
178 TnyFolderStore *dst_folder,
179 ModestMainWindow *win);
180 #ifdef MODEST_TOOLKIT_HILDON2
181 static void modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
182 TnyFolderStore *dst_folder,
187 static void modest_ui_actions_on_window_move_to (GtkAction *action,
188 TnyList *list_to_move,
189 TnyFolderStore *dst_folder,
193 * This function checks whether a TnyFolderStore is a pop account
196 remote_folder_has_leave_on_server (TnyFolderStore *folder)
201 g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
203 account = get_account_from_folder_store (folder);
204 result = (modest_protocol_registry_protocol_type_has_leave_on_server (modest_runtime_get_protocol_registry (),
205 modest_tny_account_get_protocol_type (account)));
206 g_object_unref (account);
211 /* FIXME: this should be merged with the similar code in modest-account-view-window */
212 /* Show the account creation wizard dialog.
213 * returns: TRUE if an account was created. FALSE if the user cancelled.
216 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
218 gboolean result = FALSE;
220 gint dialog_response;
222 /* there is no such wizard yet */
223 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
224 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (wizard), (GtkWindow *) win);
226 #ifndef MODEST_TOOLKIT_HILDON2
227 /* always present a main window in the background
228 * we do it here, so we cannot end up with two wizards (as this
229 * function might be called in modest_window_mgr_get_main_window as well */
231 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
232 TRUE); /* create if not existent */
236 ModestWindowMgr *mgr;
238 mgr = modest_runtime_get_window_mgr ();
240 window_list = modest_window_mgr_get_window_list (mgr);
241 if (window_list == NULL) {
242 win = MODEST_WINDOW (modest_accounts_window_new ());
243 if (modest_window_mgr_register_window (mgr, win, NULL))
244 gtk_widget_show_all (GTK_WIDGET (win));
246 gtk_widget_destroy (GTK_WIDGET (win));
248 win = MODEST_WINDOW (modest_folder_window_new (NULL));
249 if (modest_window_mgr_register_window (mgr, win, NULL))
250 gtk_widget_show_all (GTK_WIDGET (win));
252 gtk_widget_destroy (GTK_WIDGET (win));
254 g_list_free (window_list);
260 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
262 /* make sure the mainwindow is visible. We need to present the
263 wizard again to give it the focus back. show_all are needed
264 in order to get the widgets properly drawn (MainWindow main
265 paned won't be in its right position and the dialog will be
267 #ifndef MODEST_TOOLKIT_HILDON2
268 gtk_widget_show_all (GTK_WIDGET (win));
269 gtk_widget_show_all (GTK_WIDGET (wizard));
270 gtk_window_present (GTK_WINDOW (win));
271 gtk_window_present (GTK_WINDOW (wizard));
274 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
275 gtk_widget_destroy (GTK_WIDGET (wizard));
276 if (gtk_events_pending ())
277 gtk_main_iteration ();
279 if (dialog_response == GTK_RESPONSE_CANCEL) {
282 /* Check whether an account was created: */
283 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
290 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
293 const gchar *authors[] = {
294 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
297 about = gtk_about_dialog_new ();
298 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
299 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
300 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
301 _("Copyright (c) 2006, Nokia Corporation\n"
302 "All rights reserved."));
303 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
304 _("a modest e-mail client\n\n"
305 "design and implementation: Dirk-Jan C. Binnema\n"
306 "contributions from the fine people at KC and Ig\n"
307 "uses the tinymail email framework written by Philip van Hoof"));
308 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
309 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
310 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
311 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
313 gtk_dialog_run (GTK_DIALOG (about));
314 gtk_widget_destroy(about);
318 * Gets the list of currently selected messages. If the win is the
319 * main window, then it returns a newly allocated list of the headers
320 * selected in the header view. If win is the msg view window, then
321 * the value returned is a list with just a single header.
323 * The caller of this funcion must free the list.
326 get_selected_headers (ModestWindow *win)
328 if (MODEST_IS_MAIN_WINDOW(win)) {
329 GtkWidget *header_view;
331 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
332 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
333 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
335 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
336 /* for MsgViewWindows, we simply return a list with one element */
338 TnyList *list = NULL;
340 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
341 if (header != NULL) {
342 list = tny_simple_list_new ();
343 tny_list_prepend (list, G_OBJECT(header));
344 g_object_unref (G_OBJECT(header));
349 #ifdef MODEST_TOOLKIT_HILDON2
350 } else if (MODEST_IS_HEADER_WINDOW (win)) {
351 GtkWidget *header_view;
353 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
354 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
360 static GtkTreeRowReference *
361 get_next_after_selected_headers (ModestHeaderView *header_view)
363 GtkTreeSelection *sel;
364 GList *selected_rows, *node;
366 GtkTreeRowReference *result;
369 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
370 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
371 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
373 if (selected_rows == NULL)
376 node = g_list_last (selected_rows);
377 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
378 gtk_tree_path_next (path);
380 result = gtk_tree_row_reference_new (model, path);
382 gtk_tree_path_free (path);
383 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
384 g_list_free (selected_rows);
390 headers_action_mark_as_read (TnyHeader *header,
394 TnyHeaderFlags flags;
396 g_return_if_fail (TNY_IS_HEADER(header));
398 flags = tny_header_get_flags (header);
399 if (flags & TNY_HEADER_FLAG_SEEN) return;
400 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
404 headers_action_mark_as_unread (TnyHeader *header,
408 TnyHeaderFlags flags;
410 g_return_if_fail (TNY_IS_HEADER(header));
412 flags = tny_header_get_flags (header);
413 if (flags & TNY_HEADER_FLAG_SEEN) {
414 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
418 /** After deleing a message that is currently visible in a window,
419 * show the next message from the list, or close the window if there are no more messages.
422 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
424 /* Close msg view window or select next */
425 if (!modest_msg_view_window_select_next_message (win) &&
426 !modest_msg_view_window_select_previous_message (win)) {
428 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
434 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
436 modest_ui_actions_on_edit_mode_delete_message (win);
440 modest_ui_actions_on_edit_mode_delete_message (ModestWindow *win)
442 TnyList *header_list = NULL;
443 TnyIterator *iter = NULL;
444 TnyHeader *header = NULL;
445 gchar *message = NULL;
448 ModestWindowMgr *mgr;
449 GtkWidget *header_view = NULL;
450 gboolean retval = TRUE;
452 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
454 /* Check first if the header view has the focus */
455 if (MODEST_IS_MAIN_WINDOW (win)) {
457 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
458 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
459 if (!gtk_widget_is_focus (header_view))
463 /* Get the headers, either from the header view (if win is the main window),
464 * or from the message view window: */
465 header_list = get_selected_headers (win);
466 if (!header_list) return FALSE;
468 /* Check if any of the headers are already opened, or in the process of being opened */
469 if (MODEST_IS_MAIN_WINDOW (win)) {
470 gint opened_headers = 0;
472 iter = tny_list_create_iterator (header_list);
473 mgr = modest_runtime_get_window_mgr ();
474 while (!tny_iterator_is_done (iter)) {
475 header = TNY_HEADER (tny_iterator_get_current (iter));
477 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
479 g_object_unref (header);
481 tny_iterator_next (iter);
483 g_object_unref (iter);
485 if (opened_headers > 0) {
488 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
491 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg, FALSE);
494 g_object_unref (header_list);
500 if (tny_list_get_length(header_list) == 1) {
501 iter = tny_list_create_iterator (header_list);
502 header = TNY_HEADER (tny_iterator_get_current (iter));
505 subject = tny_header_dup_subject (header);
507 subject = g_strdup (_("mail_va_no_subject"));
508 desc = g_strdup_printf ("%s", subject);
510 g_object_unref (header);
513 g_object_unref (iter);
515 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
516 tny_list_get_length(header_list)), desc);
518 /* Confirmation dialog */
519 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
523 if (response == GTK_RESPONSE_OK) {
524 ModestWindow *main_window = NULL;
525 ModestWindowMgr *mgr = NULL;
526 GtkTreeModel *model = NULL;
527 GtkTreeSelection *sel = NULL;
528 GList *sel_list = NULL, *tmp = NULL;
529 GtkTreeRowReference *next_row_reference = NULL;
530 GtkTreeRowReference *prev_row_reference = NULL;
531 GtkTreePath *next_path = NULL;
532 GtkTreePath *prev_path = NULL;
533 ModestMailOperation *mail_op = NULL;
535 /* Find last selected row */
536 if (MODEST_IS_MAIN_WINDOW (win)) {
537 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
538 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
539 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
540 for (tmp=sel_list; tmp; tmp=tmp->next) {
541 if (tmp->next == NULL) {
542 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
543 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
545 gtk_tree_path_prev (prev_path);
546 gtk_tree_path_next (next_path);
548 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
549 next_row_reference = gtk_tree_row_reference_new (model, next_path);
554 /* Disable window dimming management */
555 modest_window_disable_dimming (MODEST_WINDOW(win));
557 /* Remove each header. If it's a view window header_view == NULL */
558 mail_op = modest_mail_operation_new ((GObject *) win);
559 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
561 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
562 g_object_unref (mail_op);
564 /* Enable window dimming management */
566 gtk_tree_selection_unselect_all (sel);
568 modest_window_enable_dimming (MODEST_WINDOW(win));
570 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
571 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
573 /* Get main window */
574 mgr = modest_runtime_get_window_mgr ();
575 main_window = modest_window_mgr_get_main_window (mgr, FALSE); /* don't create */
576 } else if (MODEST_IS_MAIN_WINDOW (win)) {
577 /* Move cursor to next row */
580 /* Select next or previous row */
581 if (gtk_tree_row_reference_valid (next_row_reference)) {
582 gtk_tree_selection_select_path (sel, next_path);
584 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
585 gtk_tree_selection_select_path (sel, prev_path);
589 if (gtk_tree_row_reference_valid (next_row_reference))
590 gtk_tree_row_reference_free (next_row_reference);
591 if (next_path != NULL)
592 gtk_tree_path_free (next_path);
593 if (gtk_tree_row_reference_valid (prev_row_reference))
594 gtk_tree_row_reference_free (prev_row_reference);
595 if (prev_path != NULL)
596 gtk_tree_path_free (prev_path);
599 /* Update toolbar dimming state */
601 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
602 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
606 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
607 g_list_free (sel_list);
616 g_object_unref (header_list);
624 /* delete either message or folder, based on where we are */
626 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
628 g_return_if_fail (MODEST_IS_WINDOW(win));
630 /* Check first if the header view has the focus */
631 if (MODEST_IS_MAIN_WINDOW (win)) {
633 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
634 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
635 if (gtk_widget_is_focus (w)) {
636 modest_ui_actions_on_delete_folder (action, MODEST_WINDOW(win));
640 modest_ui_actions_on_delete_message (action, win);
644 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
646 ModestWindowMgr *mgr = NULL;
648 #ifdef MODEST_PLATFORM_MAEMO
649 modest_osso_save_state();
650 #endif /* MODEST_PLATFORM_MAEMO */
652 g_debug ("closing down, clearing %d item(s) from operation queue",
653 modest_mail_operation_queue_num_elements
654 (modest_runtime_get_mail_operation_queue()));
656 /* cancel all outstanding operations */
657 modest_mail_operation_queue_cancel_all
658 (modest_runtime_get_mail_operation_queue());
660 g_debug ("queue has been cleared");
663 /* Check if there are opened editing windows */
664 mgr = modest_runtime_get_window_mgr ();
665 modest_window_mgr_close_all_windows (mgr);
667 /* note: when modest-tny-account-store is finalized,
668 it will automatically set all network connections
671 /* gtk_main_quit (); */
675 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
679 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
681 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
682 /* gtk_widget_destroy (GTK_WIDGET (win)); */
683 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
684 /* gboolean ret_value; */
685 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
686 /* } else if (MODEST_IS_WINDOW (win)) { */
687 /* gtk_widget_destroy (GTK_WIDGET (win)); */
689 /* g_return_if_reached (); */
694 modest_ui_actions_add_to_contacts (GtkAction *action, ModestWindow *win)
696 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
698 modest_msg_view_window_add_to_contacts (MODEST_MSG_VIEW_WINDOW (win));
702 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
704 GtkClipboard *clipboard = NULL;
705 gchar *selection = NULL;
707 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
708 selection = gtk_clipboard_wait_for_text (clipboard);
710 /* Question: why is the clipboard being used here?
711 * It doesn't really make a lot of sense. */
715 modest_address_book_add_address (selection);
721 modest_ui_actions_on_new_account (GtkAction *action,
722 ModestWindow *window)
724 modest_ui_actions_run_account_setup_wizard (window);
728 modest_ui_actions_on_accounts (GtkAction *action,
731 /* This is currently only implemented for Maemo */
732 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
733 if (!modest_ui_actions_run_account_setup_wizard (win))
734 g_debug ("%s: wizard was already running", __FUNCTION__);
738 /* Show the list of accounts */
739 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
741 /* The accounts dialog must be modal */
742 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
743 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
748 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
750 /* This is currently only implemented for Maemo,
751 * because it requires an API (libconic) to detect different connection
754 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
756 /* Create the window if necessary: */
757 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
758 modest_connection_specific_smtp_window_fill_with_connections (
759 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
760 modest_runtime_get_account_mgr());
762 /* Show the window: */
763 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
764 GTK_WINDOW (specific_window), (GtkWindow *) win);
765 gtk_widget_show (specific_window);
766 #endif /* !MODEST_TOOLKIT_GTK */
770 modest_ui_actions_compose_msg(ModestWindow *win,
773 const gchar *bcc_str,
774 const gchar *subject_str,
775 const gchar *body_str,
777 gboolean set_as_modified)
779 gchar *account_name = NULL;
781 TnyAccount *account = NULL;
782 TnyFolder *folder = NULL;
783 gchar *from_str = NULL, *signature = NULL, *body = NULL;
784 gboolean use_signature = FALSE;
785 ModestWindow *msg_win = NULL;
786 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
787 ModestTnyAccountStore *store = modest_runtime_get_account_store();
788 GnomeVFSFileSize total_size, allowed_size;
790 /* we check for low-mem */
791 if (modest_platform_check_memory_low (win, TRUE))
794 #ifdef MODEST_TOOLKIT_HILDON2
795 account_name = g_strdup (modest_window_get_active_account(win));
798 account_name = modest_account_mgr_get_default_account(mgr);
801 g_printerr ("modest: no account found\n");
804 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
806 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
809 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
811 g_printerr ("modest: failed to find Drafts folder\n");
814 from_str = modest_account_mgr_get_from_string (mgr, account_name);
816 g_printerr ("modest: failed get from string for '%s'\n", account_name);
820 signature = modest_account_mgr_get_signature (mgr, account_name, &use_signature);
821 if (body_str != NULL) {
822 body = use_signature ? g_strconcat(body_str, "\n--\n", signature, NULL) : g_strdup(body_str);
824 body = use_signature ? g_strconcat("\n--\n", signature, NULL) : g_strdup("");
827 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, body, NULL, NULL, NULL);
829 g_printerr ("modest: failed to create new msg\n");
833 /* Create and register edit window */
834 /* This is destroyed by TODO. */
836 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
837 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
839 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, win)) {
840 gtk_widget_destroy (GTK_WIDGET (msg_win));
843 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
844 gtk_widget_show_all (GTK_WIDGET (msg_win));
846 while (attachments) {
848 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
849 attachments->data, allowed_size);
851 if (total_size > allowed_size) {
852 g_warning ("%s: total size: %u",
853 __FUNCTION__, (unsigned int)total_size);
856 allowed_size -= total_size;
858 attachments = g_slist_next(attachments);
865 g_free (account_name);
867 g_object_unref (G_OBJECT(account));
869 g_object_unref (G_OBJECT(folder));
871 g_object_unref (G_OBJECT(msg));
875 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
877 /* if there are no accounts yet, just show the wizard */
878 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
879 if (!modest_ui_actions_run_account_setup_wizard (win))
882 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
887 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
891 ModestMailOperationStatus status;
893 /* If there is no message or the operation was not successful */
894 status = modest_mail_operation_get_status (mail_op);
895 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
898 /* If it's a memory low issue, then show a banner */
899 error = modest_mail_operation_get_error (mail_op);
900 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
901 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
902 GObject *source = modest_mail_operation_get_source (mail_op);
903 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
904 _KR("memr_ib_operation_disabled"),
906 g_object_unref (source);
909 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
910 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
911 gchar *subject, *msg, *format = NULL;
913 subject = tny_header_dup_subject (header);
915 subject = g_strdup (_("mail_va_no_subject"));
917 account = modest_mail_operation_get_account (mail_op);
919 ModestProtocol *protocol;
920 ModestProtocolType proto;
921 proto = modest_tny_account_get_protocol_type (account);
922 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), proto);
924 format = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
925 g_object_unref (account);
929 format = g_strdup (_("emev_ni_ui_imap_message_not_available_in_server"));
931 msg = g_strdup_printf (format, subject);
932 modest_platform_run_information_dialog (NULL, msg, FALSE);
938 /* Remove the header from the preregistered uids */
939 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
957 OpenMsgBannerInfo *banner_info;
958 GtkTreeRowReference *rowref;
962 open_msg_banner_idle (gpointer userdata)
964 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
966 gdk_threads_enter ();
967 banner_info->idle_handler = 0;
968 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
970 g_object_ref (banner_info->banner);
972 gdk_threads_leave ();
979 get_header_view_from_window (ModestWindow *window)
981 GtkWidget *header_view;
983 if (MODEST_IS_MAIN_WINDOW (window)) {
984 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
985 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
986 #ifdef MODEST_TOOLKIT_HILDON2
987 } else if (MODEST_IS_HEADER_WINDOW (window)){
988 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
998 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
1001 gchar *account = NULL;
1002 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
1007 folder = tny_header_get_folder (header);
1008 /* Gets folder type (OUTBOX headers will be opened in edit window */
1009 if (modest_tny_folder_is_local_folder (folder)) {
1010 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1011 if (folder_type == TNY_FOLDER_TYPE_INVALID)
1012 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1015 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
1016 TnyTransportAccount *traccount = NULL;
1017 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
1018 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
1020 ModestTnySendQueue *send_queue = NULL;
1021 ModestTnySendQueueStatus status;
1023 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
1024 TNY_ACCOUNT(traccount)));
1025 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
1026 if (TNY_IS_SEND_QUEUE (send_queue)) {
1027 msg_id = modest_tny_send_queue_get_msg_id (header);
1028 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
1030 /* Only open messages in outbox with the editor if they are in Failed state */
1031 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
1034 #ifdef MODEST_TOOLKIT_HILDON2
1036 /* In Fremantle we can not
1037 open any message from
1038 outbox which is not in
1044 g_object_unref(traccount);
1046 g_warning("Cannot get transport account for message in outbox!!");
1048 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
1049 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
1053 TnyAccount *acc = tny_folder_get_account (folder);
1056 g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (acc));
1057 g_object_unref (acc);
1061 g_object_unref (folder);
1067 open_msg_cb (ModestMailOperation *mail_op,
1074 ModestWindowMgr *mgr = NULL;
1075 ModestWindow *parent_win = NULL;
1076 ModestWindow *win = NULL;
1077 gchar *account = NULL;
1078 gboolean open_in_editor = FALSE;
1080 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1082 /* Do nothing if there was any problem with the mail
1083 operation. The error will be shown by the error_handler of
1084 the mail operation */
1085 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1088 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1090 /* Mark header as read */
1091 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1093 account = get_info_from_header (header, &open_in_editor, &can_open);
1097 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1099 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1101 if (open_in_editor) {
1102 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1103 gchar *from_header = NULL, *acc_name;
1105 from_header = tny_header_dup_from (header);
1107 /* we cannot edit without a valid account... */
1108 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1109 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1110 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1112 g_free (from_header);
1117 acc_name = modest_utils_get_account_name_from_recipient (from_header);
1118 g_free (from_header);
1124 win = modest_msg_edit_window_new (msg, account, TRUE);
1126 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1128 if (helper->rowref && helper->model) {
1129 win = modest_msg_view_window_new_with_header_model (msg, account, (const gchar*) uid,
1130 helper->model, helper->rowref);
1132 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
1137 /* Register and show new window */
1139 mgr = modest_runtime_get_window_mgr ();
1140 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1141 gtk_widget_destroy (GTK_WIDGET (win));
1144 gtk_widget_show_all (GTK_WIDGET(win));
1147 /* Update toolbar dimming state */
1148 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1149 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1155 g_object_unref (parent_win);
1159 is_memory_full_error (GError *error)
1161 gboolean enough_free_space = TRUE;
1162 GnomeVFSURI *cache_dir_uri;
1163 const gchar *cache_dir;
1164 GnomeVFSFileSize free_space;
1166 cache_dir = tny_account_store_get_cache_dir (TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
1167 cache_dir_uri = gnome_vfs_uri_new (cache_dir);
1168 if (gnome_vfs_get_volume_free_space (cache_dir_uri, &free_space) == GNOME_VFS_OK) {
1169 if (free_space < MIN_FREE_SPACE)
1170 enough_free_space = FALSE;
1172 gnome_vfs_uri_unref (cache_dir_uri);
1174 if ((error->code == TNY_SYSTEM_ERROR_MEMORY ||
1175 /* When asking for a mail and no space left on device
1176 tinymail returns this error */
1177 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE ||
1178 /* When the folder summary could not be read or
1180 error->code == TNY_IO_ERROR_WRITE ||
1181 error->code == TNY_IO_ERROR_READ) &&
1182 !enough_free_space) {
1190 check_memory_full_error (GtkWidget *parent_window, GError *err)
1195 if (is_memory_full_error (err))
1196 modest_platform_information_banner (parent_window,
1197 NULL, _KR("cerm_device_memory_full"));
1198 else if (err->code == TNY_SYSTEM_ERROR_MEMORY)
1199 /* If the account was created in memory full
1200 conditions then tinymail won't be able to
1201 connect so it'll return this error code */
1202 modest_platform_information_banner (parent_window,
1203 NULL, _("emev_ui_imap_inbox_select_error"));
1211 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1214 const GError *error;
1215 GObject *win = NULL;
1216 ModestMailOperationStatus status;
1218 win = modest_mail_operation_get_source (mail_op);
1219 error = modest_mail_operation_get_error (mail_op);
1220 status = modest_mail_operation_get_status (mail_op);
1222 /* If the mail op has been cancelled then it's not an error:
1223 don't show any message */
1224 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1225 if (is_memory_full_error ((GError *) error)) {
1226 modest_platform_information_banner ((GtkWidget *) win,
1227 NULL, _KR("cerm_device_memory_full"));
1228 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1229 modest_platform_information_banner ((GtkWidget *) win,
1230 NULL, _("emev_ui_imap_inbox_select_error"));
1231 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1232 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1233 modest_platform_information_banner ((GtkWidget *) win,
1234 NULL, _CS ("sfil_ni_unable_to_open_file_not_found"));
1235 } else if (user_data) {
1236 modest_platform_information_banner ((GtkWidget *) win,
1242 g_object_unref (win);
1246 * Returns the account a list of headers belongs to. It returns a
1247 * *new* reference so don't forget to unref it
1250 get_account_from_header_list (TnyList *headers)
1252 TnyAccount *account = NULL;
1254 if (tny_list_get_length (headers) > 0) {
1255 TnyIterator *iter = tny_list_create_iterator (headers);
1256 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1257 TnyFolder *folder = tny_header_get_folder (header);
1260 g_object_unref (header);
1262 while (!tny_iterator_is_done (iter)) {
1263 header = TNY_HEADER (tny_iterator_get_current (iter));
1264 folder = tny_header_get_folder (header);
1267 g_object_unref (header);
1269 tny_iterator_next (iter);
1274 account = tny_folder_get_account (folder);
1275 g_object_unref (folder);
1279 g_object_unref (header);
1281 g_object_unref (iter);
1287 get_account_from_header (TnyHeader *header)
1289 TnyAccount *account = NULL;
1292 folder = tny_header_get_folder (header);
1295 account = tny_folder_get_account (folder);
1296 g_object_unref (folder);
1302 open_msg_helper_destroyer (gpointer user_data)
1304 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1306 if (helper->banner_info) {
1307 g_free (helper->banner_info->message);
1308 if (helper->banner_info->idle_handler > 0) {
1309 g_source_remove (helper->banner_info->idle_handler);
1310 helper->banner_info->idle_handler = 0;
1312 if (helper->banner_info->banner != NULL) {
1313 gtk_widget_destroy (helper->banner_info->banner);
1314 g_object_unref (helper->banner_info->banner);
1315 helper->banner_info->banner = NULL;
1317 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1318 helper->banner_info = NULL;
1320 g_object_unref (helper->model);
1321 g_object_unref (helper->header);
1322 gtk_tree_row_reference_free (helper->rowref);
1323 g_slice_free (OpenMsgHelper, helper);
1327 open_msg_performer(gboolean canceled,
1329 GtkWindow *parent_window,
1330 TnyAccount *account,
1333 ModestMailOperation *mail_op = NULL;
1335 ModestProtocolType proto;
1336 TnyConnectionStatus status;
1337 OpenMsgHelper *helper = NULL;
1338 ModestProtocol *protocol;
1339 ModestProtocolRegistry *protocol_registry;
1342 helper = (OpenMsgHelper *) user_data;
1344 status = tny_account_get_connection_status (account);
1345 if (err || canceled) {
1346 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1347 /* Free the helper */
1348 open_msg_helper_destroyer (helper);
1350 /* In memory full conditions we could get this error here */
1351 check_memory_full_error ((GtkWidget *) parent_window, err);
1356 /* Get the error message depending on the protocol */
1357 proto = modest_tny_account_get_protocol_type (account);
1358 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1359 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1362 protocol_registry = modest_runtime_get_protocol_registry ();
1363 subject = tny_header_dup_subject (helper->header);
1365 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1366 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1370 if (error_msg == NULL) {
1371 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1374 #ifndef MODEST_TOOLKIT_HILDON2
1375 gboolean show_open_draft = FALSE;
1376 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1378 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1380 TnyFolderType folder_type;
1382 folder = tny_header_get_folder (helper->header);
1383 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1384 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1385 g_object_unref (folder);
1389 #ifdef MODEST_TOOLKIT_HILDON2
1392 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1395 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1396 g_free (account_name);
1397 open_msg_helper_destroyer (helper);
1402 ModestWindow *window;
1403 GtkWidget *header_view;
1406 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1407 uid = modest_tny_folder_get_header_unique_id (helper->header);
1409 window = modest_msg_view_window_new_from_header_view
1410 (MODEST_HEADER_VIEW (header_view), account_name, uid, helper->rowref);
1411 if (window != NULL) {
1412 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1414 gtk_widget_destroy (GTK_WIDGET (window));
1416 gtk_widget_show_all (GTK_WIDGET(window));
1420 g_free (account_name);
1422 open_msg_helper_destroyer (helper);
1425 g_free (account_name);
1427 /* Create the mail operation */
1429 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1430 modest_ui_actions_disk_operations_error_handler,
1432 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1436 #ifndef MODEST_TOOLKIT_HILDON2
1437 if (show_open_draft) {
1438 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1439 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1440 helper->banner_info->banner = NULL;
1441 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1442 helper->banner_info);
1448 headers = TNY_LIST (tny_simple_list_new ());
1449 tny_list_prepend (headers, G_OBJECT (helper->header));
1450 modest_mail_operation_get_msgs_full (mail_op,
1454 open_msg_helper_destroyer);
1455 g_object_unref (headers);
1460 g_object_unref (mail_op);
1461 g_object_unref (account);
1465 * This function is used by both modest_ui_actions_on_open and
1466 * modest_ui_actions_on_header_activated. This way we always do the
1467 * same when trying to open messages.
1470 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1472 ModestWindowMgr *mgr = NULL;
1473 TnyAccount *account;
1474 gboolean cached = FALSE;
1476 GtkWidget *header_view = NULL;
1477 OpenMsgHelper *helper;
1478 ModestWindow *window;
1480 g_return_if_fail (header != NULL && rowref != NULL);
1482 mgr = modest_runtime_get_window_mgr ();
1485 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1486 if (header_view == NULL)
1489 /* Get the account */
1490 account = get_account_from_header (header);
1495 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1497 /* Do not open again the message and present the
1498 window to the user */
1501 #ifndef MODEST_TOOLKIT_HILDON2
1502 gtk_window_present (GTK_WINDOW (window));
1505 /* the header has been registered already, we don't do
1506 * anything but wait for the window to come up*/
1507 g_debug ("header %p already registered, waiting for window", header);
1512 /* Open each message */
1513 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1515 /* Allways download if we are online. */
1516 if (!tny_device_is_online (modest_runtime_get_device ())) {
1519 /* If ask for user permission to download the messages */
1520 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1521 _("mcen_nc_get_msg"));
1523 /* End if the user does not want to continue */
1524 if (response == GTK_RESPONSE_CANCEL) {
1530 /* We register the window for opening */
1531 modest_window_mgr_register_header (mgr, header, NULL);
1533 /* Create the helper. We need to get a reference to the model
1534 here because it could change while the message is readed
1535 (the user could switch between folders) */
1536 helper = g_slice_new (OpenMsgHelper);
1537 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1538 helper->header = g_object_ref (header);
1539 helper->rowref = gtk_tree_row_reference_copy (rowref);
1540 helper->banner_info = NULL;
1542 /* Connect to the account and perform */
1544 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1545 open_msg_performer, helper);
1547 /* Call directly the performer, do not need to connect */
1548 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1549 g_object_ref (account), helper);
1554 g_object_unref (account);
1558 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1565 /* we check for low-mem; in that case, show a warning, and don't allow
1568 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1572 headers = get_selected_headers (win);
1576 headers_count = tny_list_get_length (headers);
1577 if (headers_count != 1) {
1578 if (headers_count > 1) {
1579 /* Don't allow activation if there are more than one message selected */
1580 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1583 g_object_unref (headers);
1587 iter = tny_list_create_iterator (headers);
1588 header = TNY_HEADER (tny_iterator_get_current (iter));
1589 g_object_unref (iter);
1593 open_msg_from_header (header, NULL, win);
1594 g_object_unref (header);
1597 g_object_unref(headers);
1601 rf_helper_window_closed (gpointer data,
1604 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1606 helper->parent_window = NULL;
1609 static ReplyForwardHelper*
1610 create_reply_forward_helper (ReplyForwardAction action,
1612 guint reply_forward_type,
1615 ReplyForwardHelper *rf_helper = NULL;
1616 const gchar *active_acc = modest_window_get_active_account (win);
1618 rf_helper = g_slice_new0 (ReplyForwardHelper);
1619 rf_helper->reply_forward_type = reply_forward_type;
1620 rf_helper->action = action;
1621 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1622 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1623 rf_helper->account_name = (active_acc) ?
1624 g_strdup (active_acc) :
1625 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1627 /* Note that window could be destroyed just AFTER calling
1628 register_window so we must ensure that this pointer does
1629 not hold invalid references */
1630 if (rf_helper->parent_window)
1631 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1632 rf_helper_window_closed, rf_helper);
1638 free_reply_forward_helper (gpointer data)
1640 ReplyForwardHelper *helper;
1642 helper = (ReplyForwardHelper *) data;
1643 g_free (helper->account_name);
1645 g_object_unref (helper->header);
1646 if (helper->parent_window)
1647 g_object_weak_unref (G_OBJECT (helper->parent_window),
1648 rf_helper_window_closed, helper);
1649 g_slice_free (ReplyForwardHelper, helper);
1653 reply_forward_cb (ModestMailOperation *mail_op,
1660 TnyMsg *new_msg = NULL;
1661 ReplyForwardHelper *rf_helper;
1662 ModestWindow *msg_win = NULL;
1663 ModestEditType edit_type;
1665 TnyAccount *account = NULL;
1666 ModestWindowMgr *mgr = NULL;
1667 gchar *signature = NULL;
1668 gboolean use_signature;
1670 /* If there was any error. The mail operation could be NULL,
1671 this means that we already have the message downloaded and
1672 that we didn't do a mail operation to retrieve it */
1673 rf_helper = (ReplyForwardHelper *) user_data;
1674 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1677 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1678 rf_helper->account_name);
1679 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr(),
1680 rf_helper->account_name,
1683 /* Create reply mail */
1684 switch (rf_helper->action) {
1687 modest_tny_msg_create_reply_msg (msg, header, from,
1688 (use_signature) ? signature : NULL,
1689 rf_helper->reply_forward_type,
1690 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1692 case ACTION_REPLY_TO_ALL:
1694 modest_tny_msg_create_reply_msg (msg, header, from,
1695 (use_signature) ? signature : NULL,
1696 rf_helper->reply_forward_type,
1697 MODEST_TNY_MSG_REPLY_MODE_ALL);
1698 edit_type = MODEST_EDIT_TYPE_REPLY;
1700 case ACTION_FORWARD:
1702 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1703 rf_helper->reply_forward_type);
1704 edit_type = MODEST_EDIT_TYPE_FORWARD;
1707 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1709 g_return_if_reached ();
1717 g_warning ("%s: failed to create message\n", __FUNCTION__);
1721 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1722 rf_helper->account_name,
1723 TNY_ACCOUNT_TYPE_STORE);
1725 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1729 /* Create and register the windows */
1730 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1731 mgr = modest_runtime_get_window_mgr ();
1732 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1734 /* Note that register_window could have deleted the account */
1735 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1736 gdouble parent_zoom;
1738 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1739 modest_window_set_zoom (msg_win, parent_zoom);
1742 /* Show edit window */
1743 gtk_widget_show_all (GTK_WIDGET (msg_win));
1746 /* We always unregister the header because the message is
1747 forwarded or replied so the original one is no longer
1749 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1752 g_object_unref (G_OBJECT (new_msg));
1754 g_object_unref (G_OBJECT (account));
1755 free_reply_forward_helper (rf_helper);
1758 /* Checks a list of headers. If any of them are not currently
1759 * downloaded (CACHED) then returns TRUE else returns FALSE.
1762 header_list_count_uncached_msgs (TnyList *header_list)
1765 gint uncached_messages = 0;
1767 iter = tny_list_create_iterator (header_list);
1768 while (!tny_iterator_is_done (iter)) {
1771 header = TNY_HEADER (tny_iterator_get_current (iter));
1773 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1774 uncached_messages ++;
1775 g_object_unref (header);
1778 tny_iterator_next (iter);
1780 g_object_unref (iter);
1782 return uncached_messages;
1785 /* Returns FALSE if the user does not want to download the
1786 * messages. Returns TRUE if the user allowed the download.
1789 connect_to_get_msg (ModestWindow *win,
1790 gint num_of_uncached_msgs,
1791 TnyAccount *account)
1793 GtkResponseType response;
1795 /* Allways download if we are online. */
1796 if (tny_device_is_online (modest_runtime_get_device ()))
1799 /* If offline, then ask for user permission to download the messages */
1800 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1801 ngettext("mcen_nc_get_msg",
1803 num_of_uncached_msgs));
1805 if (response == GTK_RESPONSE_CANCEL)
1808 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1812 reply_forward_performer (gboolean canceled,
1814 GtkWindow *parent_window,
1815 TnyAccount *account,
1818 ReplyForwardHelper *rf_helper = NULL;
1819 ModestMailOperation *mail_op;
1821 rf_helper = (ReplyForwardHelper *) user_data;
1823 if (canceled || err) {
1824 free_reply_forward_helper (rf_helper);
1828 /* Retrieve the message */
1829 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1830 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1831 modest_ui_actions_disk_operations_error_handler,
1833 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1834 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1837 g_object_unref(mail_op);
1841 * Common code for the reply and forward actions
1844 reply_forward (ReplyForwardAction action, ModestWindow *win)
1846 ReplyForwardHelper *rf_helper = NULL;
1847 guint reply_forward_type;
1849 g_return_if_fail (MODEST_IS_WINDOW(win));
1851 /* we check for low-mem; in that case, show a warning, and don't allow
1852 * reply/forward (because it could potentially require a lot of memory */
1853 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1857 /* we need an account when editing */
1858 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1859 if (!modest_ui_actions_run_account_setup_wizard (win))
1863 reply_forward_type =
1864 modest_conf_get_int (modest_runtime_get_conf (),
1865 (action == ACTION_FORWARD) ?
1866 MODEST_CONF_FORWARD_TYPE :
1867 MODEST_CONF_REPLY_TYPE,
1870 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1872 TnyHeader *header = NULL;
1873 /* Get header and message. Do not free them here, the
1874 reply_forward_cb must do it */
1875 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1876 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1878 if (msg && header) {
1880 rf_helper = create_reply_forward_helper (action, win,
1881 reply_forward_type, header);
1882 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1884 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1888 g_object_unref (msg);
1890 g_object_unref (header);
1892 TnyHeader *header = NULL;
1894 gboolean do_retrieve = TRUE;
1895 TnyList *header_list = NULL;
1897 header_list = get_selected_headers (win);
1900 /* Check that only one message is selected for replying */
1901 if (tny_list_get_length (header_list) != 1) {
1902 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1903 NULL, _("mcen_ib_select_one_message"));
1904 g_object_unref (header_list);
1908 /* Only reply/forward to one message */
1909 iter = tny_list_create_iterator (header_list);
1910 header = TNY_HEADER (tny_iterator_get_current (iter));
1911 g_object_unref (iter);
1913 /* Retrieve messages */
1914 do_retrieve = (action == ACTION_FORWARD) ||
1915 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1918 TnyAccount *account = NULL;
1919 TnyFolder *folder = NULL;
1920 gdouble download = TRUE;
1921 guint uncached_msgs = 0;
1923 folder = tny_header_get_folder (header);
1925 goto do_retrieve_frees;
1926 account = tny_folder_get_account (folder);
1928 goto do_retrieve_frees;
1930 uncached_msgs = header_list_count_uncached_msgs (header_list);
1932 if (uncached_msgs > 0) {
1933 /* Allways download if we are online. */
1934 if (!tny_device_is_online (modest_runtime_get_device ())) {
1937 /* If ask for user permission to download the messages */
1938 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1939 ngettext("mcen_nc_get_msg",
1943 /* End if the user does not want to continue */
1944 if (response == GTK_RESPONSE_CANCEL)
1951 rf_helper = create_reply_forward_helper (action, win,
1952 reply_forward_type, header);
1953 if (uncached_msgs > 0) {
1954 modest_platform_connect_and_perform (GTK_WINDOW (win),
1956 reply_forward_performer,
1959 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
1960 account, rf_helper);
1965 g_object_unref (account);
1967 g_object_unref (folder);
1969 reply_forward_cb (NULL, header, FALSE, NULL, NULL, rf_helper);
1972 g_object_unref (header_list);
1973 g_object_unref (header);
1978 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1980 g_return_if_fail (MODEST_IS_WINDOW(win));
1982 reply_forward (ACTION_REPLY, win);
1986 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1988 g_return_if_fail (MODEST_IS_WINDOW(win));
1990 reply_forward (ACTION_FORWARD, win);
1994 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1996 g_return_if_fail (MODEST_IS_WINDOW(win));
1998 reply_forward (ACTION_REPLY_TO_ALL, win);
2002 modest_ui_actions_on_next (GtkAction *action,
2003 ModestWindow *window)
2005 if (MODEST_IS_MAIN_WINDOW (window)) {
2006 GtkWidget *header_view;
2008 header_view = modest_main_window_get_child_widget (
2009 MODEST_MAIN_WINDOW(window),
2010 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2014 modest_header_view_select_next (
2015 MODEST_HEADER_VIEW(header_view));
2016 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2017 modest_msg_view_window_select_next_message (
2018 MODEST_MSG_VIEW_WINDOW (window));
2020 g_return_if_reached ();
2025 modest_ui_actions_on_prev (GtkAction *action,
2026 ModestWindow *window)
2028 g_return_if_fail (MODEST_IS_WINDOW(window));
2030 if (MODEST_IS_MAIN_WINDOW (window)) {
2031 GtkWidget *header_view;
2032 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2033 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2037 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
2038 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2039 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
2041 g_return_if_reached ();
2046 modest_ui_actions_on_sort (GtkAction *action,
2047 ModestWindow *window)
2049 GtkWidget *header_view = NULL;
2051 g_return_if_fail (MODEST_IS_WINDOW(window));
2053 if (MODEST_IS_MAIN_WINDOW (window)) {
2054 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2055 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2056 #ifdef MODEST_TOOLKIT_HILDON2
2057 } else if (MODEST_IS_HEADER_WINDOW (window)) {
2058 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2063 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
2068 /* Show sorting dialog */
2069 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
2073 new_messages_arrived (ModestMailOperation *self,
2074 TnyList *new_headers,
2078 gboolean show_visual_notifications;
2080 source = modest_mail_operation_get_source (self);
2081 show_visual_notifications = (source) ? FALSE : TRUE;
2083 g_object_unref (source);
2085 /* Notify new messages have been downloaded. If the
2086 send&receive was invoked by the user then do not show any
2087 visual notification, only play a sound and activate the LED
2088 (for the Maemo version) */
2089 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0)
2090 modest_platform_on_new_headers_received (new_headers,
2091 show_visual_notifications);
2096 retrieve_all_messages_cb (GObject *source,
2098 guint retrieve_limit)
2104 window = GTK_WINDOW (source);
2105 msg = g_strdup_printf (_("mail_nc_msg_count_limit_exceeded"),
2106 num_msgs, retrieve_limit);
2108 /* Ask the user if they want to retrieve all the messages */
2110 modest_platform_run_confirmation_dialog_with_buttons (window, msg,
2111 _("mcen_bd_get_all"),
2112 _("mcen_bd_newest_only"));
2113 /* Free and return */
2115 return (response == GTK_RESPONSE_ACCEPT) ? TRUE : FALSE;
2119 TnyAccount *account;
2121 gchar *account_name;
2122 gboolean poke_status;
2123 gboolean interactive;
2124 ModestMailOperation *mail_op;
2128 do_send_receive_performer (gboolean canceled,
2130 GtkWindow *parent_window,
2131 TnyAccount *account,
2134 SendReceiveInfo *info;
2136 info = (SendReceiveInfo *) user_data;
2138 if (err || canceled) {
2139 /* In memory full conditions we could get this error here */
2140 check_memory_full_error ((GtkWidget *) parent_window, err);
2142 if (info->mail_op) {
2143 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2149 /* Set send/receive operation in progress */
2150 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2151 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2154 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2155 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2156 G_CALLBACK (on_send_receive_finished),
2159 /* Send & receive. */
2160 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2161 (info->win) ? retrieve_all_messages_cb : NULL,
2162 new_messages_arrived, info->win);
2167 g_object_unref (G_OBJECT (info->mail_op));
2168 if (info->account_name)
2169 g_free (info->account_name);
2171 g_object_unref (info->win);
2173 g_object_unref (info->account);
2174 g_slice_free (SendReceiveInfo, info);
2178 * This function performs the send & receive required actions. The
2179 * window is used to create the mail operation. Typically it should
2180 * always be the main window, but we pass it as argument in order to
2184 modest_ui_actions_do_send_receive (const gchar *account_name,
2185 gboolean force_connection,
2186 gboolean poke_status,
2187 gboolean interactive,
2190 gchar *acc_name = NULL;
2191 SendReceiveInfo *info;
2192 ModestTnyAccountStore *acc_store;
2194 /* If no account name was provided then get the current account, and if
2195 there is no current account then pick the default one: */
2196 if (!account_name) {
2198 acc_name = g_strdup (modest_window_get_active_account (win));
2200 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2202 g_printerr ("modest: cannot get default account\n");
2206 acc_name = g_strdup (account_name);
2209 acc_store = modest_runtime_get_account_store ();
2211 /* Create the info for the connect and perform */
2212 info = g_slice_new (SendReceiveInfo);
2213 info->account_name = acc_name;
2214 info->win = (win) ? g_object_ref (win) : NULL;
2215 info->poke_status = poke_status;
2216 info->interactive = interactive;
2217 info->account = modest_tny_account_store_get_server_account (acc_store, acc_name,
2218 TNY_ACCOUNT_TYPE_STORE);
2219 /* We need to create the operation here, because otherwise it
2220 could happen that the queue emits the queue-empty signal
2221 while we're trying to connect the account */
2222 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2223 modest_ui_actions_disk_operations_error_handler,
2225 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2227 /* Invoke the connect and perform */
2228 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2229 force_connection, info->account,
2230 do_send_receive_performer, info);
2235 modest_ui_actions_do_cancel_send (const gchar *account_name,
2238 TnyTransportAccount *transport_account;
2239 TnySendQueue *send_queue = NULL;
2240 GError *error = NULL;
2242 /* Get transport account */
2244 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2245 (modest_runtime_get_account_store(),
2247 TNY_ACCOUNT_TYPE_TRANSPORT));
2248 if (!transport_account) {
2249 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2254 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2255 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2256 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2257 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2258 "modest: could not find send queue for account\n");
2260 /* Cancel the current send */
2261 tny_account_cancel (TNY_ACCOUNT (transport_account));
2263 /* Suspend all pending messages */
2264 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2268 if (transport_account != NULL)
2269 g_object_unref (G_OBJECT (transport_account));
2273 modest_ui_actions_cancel_send_all (ModestWindow *win)
2275 GSList *account_names, *iter;
2277 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2280 iter = account_names;
2282 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2283 iter = g_slist_next (iter);
2286 modest_account_mgr_free_account_names (account_names);
2287 account_names = NULL;
2291 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2294 /* Check if accounts exist */
2295 gboolean accounts_exist =
2296 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2298 /* If not, allow the user to create an account before trying to send/receive. */
2299 if (!accounts_exist)
2300 modest_ui_actions_on_accounts (NULL, win);
2302 /* Cancel all sending operaitons */
2303 modest_ui_actions_cancel_send_all (win);
2307 * Refreshes all accounts. This function will be used by automatic
2311 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2312 gboolean force_connection,
2313 gboolean poke_status,
2314 gboolean interactive)
2316 GSList *account_names, *iter;
2318 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2321 iter = account_names;
2323 modest_ui_actions_do_send_receive ((const char*) iter->data,
2325 poke_status, interactive, win);
2326 iter = g_slist_next (iter);
2329 modest_account_mgr_free_account_names (account_names);
2330 account_names = NULL;
2334 * Handler of the click on Send&Receive button in the main toolbar
2337 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2339 /* Check if accounts exist */
2340 gboolean accounts_exist;
2343 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2345 /* If not, allow the user to create an account before trying to send/receive. */
2346 if (!accounts_exist)
2347 modest_ui_actions_on_accounts (NULL, win);
2349 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2350 if (MODEST_IS_MAIN_WINDOW (win)) {
2351 GtkWidget *folder_view;
2352 TnyFolderStore *folder_store;
2355 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2356 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2360 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2363 g_object_unref (folder_store);
2364 /* Refresh the active account. Force the connection if needed
2365 and poke the status of all folders */
2366 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2367 #ifdef MODEST_TOOLKIT_HILDON2
2368 } else if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2369 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2372 const gchar *active_account;
2373 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2375 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2382 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2385 GtkWidget *header_view;
2387 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2389 header_view = modest_main_window_get_child_widget (main_window,
2390 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2394 conf = modest_runtime_get_conf ();
2396 /* what is saved/restored is depending on the style; thus; we save with
2397 * old style, then update the style, and restore for this new style
2399 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2401 if (modest_header_view_get_style
2402 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2403 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2404 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2406 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2407 MODEST_HEADER_VIEW_STYLE_DETAILS);
2409 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2410 MODEST_CONF_HEADER_VIEW_KEY);
2415 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2417 ModestMainWindow *main_window)
2419 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2420 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2422 /* in the case the folder is empty, show the empty folder message and focus
2424 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2425 if (modest_header_view_is_empty (header_view)) {
2426 TnyFolder *folder = modest_header_view_get_folder (header_view);
2427 GtkWidget *folder_view =
2428 modest_main_window_get_child_widget (main_window,
2429 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2430 if (folder != NULL) {
2431 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2432 g_object_unref (folder);
2434 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2438 /* If no header has been selected then exit */
2443 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2444 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2446 /* Update toolbar dimming state */
2447 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2448 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2452 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2455 ModestWindow *window)
2457 GtkWidget *open_widget;
2458 GtkTreeRowReference *rowref;
2460 g_return_if_fail (MODEST_IS_WINDOW(window));
2461 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2462 g_return_if_fail (TNY_IS_HEADER (header));
2464 if (modest_header_view_count_selected_headers (header_view) > 1) {
2465 /* Don't allow activation if there are more than one message selected */
2466 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2470 /* we check for low-mem; in that case, show a warning, and don't allow
2471 * activating headers
2473 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2476 if (MODEST_IS_MAIN_WINDOW (window)) {
2477 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2478 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2479 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2483 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2484 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2485 gtk_tree_row_reference_free (rowref);
2489 set_active_account_from_tny_account (TnyAccount *account,
2490 ModestWindow *window)
2492 const gchar *server_acc_name = tny_account_get_id (account);
2494 /* We need the TnyAccount provided by the
2495 account store because that is the one that
2496 knows the name of the Modest account */
2497 TnyAccount *modest_server_account = modest_server_account =
2498 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2499 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2501 if (!modest_server_account) {
2502 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2506 /* Update active account, but only if it's not a pseudo-account */
2507 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2508 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2509 const gchar *modest_acc_name =
2510 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2511 if (modest_acc_name)
2512 modest_window_set_active_account (window, modest_acc_name);
2515 g_object_unref (modest_server_account);
2520 folder_refreshed_cb (ModestMailOperation *mail_op,
2524 ModestMainWindow *win = NULL;
2525 GtkWidget *folder_view;
2526 const GError *error;
2528 g_return_if_fail (TNY_IS_FOLDER (folder));
2530 win = MODEST_MAIN_WINDOW (user_data);
2532 /* Check if the operation failed due to memory low conditions */
2533 error = modest_mail_operation_get_error (mail_op);
2534 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2535 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2536 modest_platform_run_information_dialog (GTK_WINDOW (win),
2537 _KR("memr_ib_operation_disabled"),
2543 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2546 TnyFolderStore *current_folder;
2548 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2549 if (current_folder) {
2550 gboolean different = ((TnyFolderStore *) folder != current_folder);
2551 g_object_unref (current_folder);
2557 /* Check if folder is empty and set headers view contents style */
2558 if (tny_folder_get_all_count (folder) == 0)
2559 modest_main_window_set_contents_style (win,
2560 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2565 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2566 TnyFolderStore *folder_store,
2568 ModestMainWindow *main_window)
2571 GtkWidget *header_view;
2573 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2575 header_view = modest_main_window_get_child_widget(main_window,
2576 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2580 conf = modest_runtime_get_conf ();
2582 if (TNY_IS_ACCOUNT (folder_store)) {
2584 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2586 /* Show account details */
2587 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2590 if (TNY_IS_FOLDER (folder_store) && selected) {
2591 TnyAccount *account;
2592 const gchar *account_name = NULL;
2594 /* Update the active account */
2595 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2597 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2599 modest_tny_account_get_parent_modest_account_name_for_server_account (account);
2600 g_object_unref (account);
2604 /* Set the header style by default, it could
2605 be changed later by the refresh callback to
2607 modest_main_window_set_contents_style (main_window,
2608 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2610 /* Set folder on header view. This function
2611 will call tny_folder_refresh_async so we
2612 pass a callback that will be called when
2613 finished. We use that callback to set the
2614 empty view if there are no messages */
2615 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2616 TNY_FOLDER (folder_store),
2618 MODEST_WINDOW (main_window),
2619 folder_refreshed_cb,
2622 /* Restore configuration. We need to do this
2623 *after* the set_folder because the widget
2624 memory asks the header view about its
2626 modest_widget_memory_restore (modest_runtime_get_conf (),
2627 G_OBJECT(header_view),
2628 MODEST_CONF_HEADER_VIEW_KEY);
2630 /* No need to save the header view
2631 configuration for Maemo because it only
2632 saves the sorting stuff and that it's
2633 already being done by the sort
2634 dialog. Remove it when the GNOME version
2635 has the same behaviour */
2636 #ifdef MODEST_TOOLKIT_GTK
2637 if (modest_main_window_get_contents_style (main_window) ==
2638 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2639 modest_widget_memory_save (conf, G_OBJECT (header_view),
2640 MODEST_CONF_HEADER_VIEW_KEY);
2642 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2646 /* Update dimming state */
2647 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2648 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2652 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2659 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2661 online = tny_device_is_online (modest_runtime_get_device());
2664 /* already online -- the item is simply not there... */
2665 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2667 GTK_MESSAGE_WARNING,
2669 _("The %s you selected cannot be found"),
2671 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2672 gtk_dialog_run (GTK_DIALOG(dialog));
2674 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2677 _("mcen_bd_dialog_cancel"),
2678 GTK_RESPONSE_REJECT,
2679 _("mcen_bd_dialog_ok"),
2680 GTK_RESPONSE_ACCEPT,
2682 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2683 "Do you want to get online?"), item);
2684 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2685 gtk_label_new (txt), FALSE, FALSE, 0);
2686 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2689 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2690 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2691 /* TODO: Comment about why is this commented out: */
2692 /* modest_platform_connect_and_wait (); */
2695 gtk_widget_destroy (dialog);
2699 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2702 /* g_message ("%s %s", __FUNCTION__, link); */
2707 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2710 modest_platform_activate_uri (link);
2714 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2717 modest_platform_show_uri_popup (link);
2721 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2724 /* we check for low-mem; in that case, show a warning, and don't allow
2725 * viewing attachments
2727 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2730 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2734 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2735 const gchar *address,
2738 /* g_message ("%s %s", __FUNCTION__, address); */
2742 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2743 TnyMsg *saved_draft,
2746 ModestMsgEditWindow *edit_window;
2748 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2749 #ifndef MODEST_TOOLKIT_HILDON2
2750 ModestMainWindow *win;
2752 /* FIXME. Make the header view sensitive again. This is a
2753 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2755 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2756 modest_runtime_get_window_mgr(), FALSE));
2758 GtkWidget *hdrview = modest_main_window_get_child_widget(
2759 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2760 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2764 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2766 /* Set draft is there was no error */
2767 if (!modest_mail_operation_get_error (mail_op))
2768 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2770 g_object_unref(edit_window);
2774 enough_space_for_message (ModestMsgEditWindow *edit_window,
2777 TnyAccountStore *acc_store;
2778 guint64 available_disk, expected_size;
2783 acc_store = TNY_ACCOUNT_STORE (modest_runtime_get_account_store());
2784 available_disk = modest_utils_get_available_space (NULL);
2785 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2786 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2791 /* Double check: memory full condition or message too big */
2792 if (available_disk < MIN_FREE_SPACE ||
2793 expected_size > available_disk) {
2795 modest_platform_information_banner (NULL, NULL,
2796 _KR("cerm_device_memory_full"));
2801 * djcb: if we're in low-memory state, we only allow for
2802 * saving messages smaller than
2803 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2804 * should still allow for sending anything critical...
2806 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2807 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2811 * djcb: we also make sure that the attachments are smaller than the max size
2812 * this is for the case where we'd try to forward a message with attachments
2813 * bigger than our max allowed size, or sending an message from drafts which
2814 * somehow got past our checks when attaching.
2816 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2817 modest_platform_run_information_dialog (
2818 GTK_WINDOW(edit_window),
2819 _KR("memr_ib_operation_disabled"),
2828 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2830 TnyTransportAccount *transport_account;
2831 ModestMailOperation *mail_operation;
2833 gchar *account_name, *from;
2834 ModestAccountMgr *account_mgr;
2835 gboolean had_error = FALSE;
2836 ModestMainWindow *win = NULL;
2838 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2840 data = modest_msg_edit_window_get_msg_data (edit_window);
2843 if (!enough_space_for_message (edit_window, data)) {
2844 modest_msg_edit_window_free_msg_data (edit_window, data);
2848 account_name = g_strdup (data->account_name);
2849 account_mgr = modest_runtime_get_account_mgr();
2851 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2853 account_name = modest_account_mgr_get_default_account (account_mgr);
2854 if (!account_name) {
2855 g_printerr ("modest: no account found\n");
2856 modest_msg_edit_window_free_msg_data (edit_window, data);
2860 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2861 account_name = g_strdup (data->account_name);
2865 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2866 (modest_runtime_get_account_store (),
2868 TNY_ACCOUNT_TYPE_TRANSPORT));
2869 if (!transport_account) {
2870 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2871 g_free (account_name);
2872 modest_msg_edit_window_free_msg_data (edit_window, data);
2875 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2877 /* Create the mail operation */
2878 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
2880 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2882 modest_mail_operation_save_to_drafts (mail_operation,
2894 data->priority_flags,
2895 on_save_to_drafts_cb,
2896 g_object_ref(edit_window));
2898 #ifdef MODEST_TOOLKIT_HILDON2
2899 /* In hildon2 we always show the information banner on saving to drafts.
2900 * It will be a system information banner in this case.
2902 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2903 modest_platform_information_banner (NULL, NULL, text);
2906 /* Use the main window as the parent of the banner, if the
2907 main window does not exist it won't be shown, if the parent
2908 window exists then it's properly shown. We don't use the
2909 editor window because it could be closed (save to drafts
2910 could happen after closing the window */
2911 win = (ModestMainWindow *)
2912 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
2914 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2915 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
2919 modest_msg_edit_window_set_modified (edit_window, FALSE);
2923 g_free (account_name);
2924 g_object_unref (G_OBJECT (transport_account));
2925 g_object_unref (G_OBJECT (mail_operation));
2927 modest_msg_edit_window_free_msg_data (edit_window, data);
2930 * If the drafts folder is selected then make the header view
2931 * insensitive while the message is being saved to drafts
2932 * (it'll be sensitive again in on_save_to_drafts_cb()). This
2933 * is not very clean but it avoids letting the drafts folder
2934 * in an inconsistent state: the user could edit the message
2935 * being saved and undesirable things would happen.
2936 * In the average case the user won't notice anything at
2937 * all. In the worst case (the user is editing a really big
2938 * file from Drafts) the header view will be insensitive
2939 * during the saving process (10 or 20 seconds, depending on
2940 * the message). Anyway this is just a quick workaround: once
2941 * we find a better solution it should be removed
2942 * See NB#65125 (commend #18) for details.
2944 if (!had_error && win != NULL) {
2945 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
2946 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
2948 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
2950 if (modest_tny_folder_is_local_folder(folder)) {
2951 TnyFolderType folder_type;
2952 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
2953 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
2954 GtkWidget *hdrview = modest_main_window_get_child_widget(
2955 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2956 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
2960 if (folder != NULL) g_object_unref(folder);
2967 /* For instance, when clicking the Send toolbar button when editing a message: */
2969 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2971 TnyTransportAccount *transport_account = NULL;
2972 gboolean had_error = FALSE;
2974 ModestAccountMgr *account_mgr;
2975 gchar *account_name;
2977 ModestMailOperation *mail_operation;
2979 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
2981 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2984 data = modest_msg_edit_window_get_msg_data (edit_window);
2987 if (!enough_space_for_message (edit_window, data)) {
2988 modest_msg_edit_window_free_msg_data (edit_window, data);
2992 account_mgr = modest_runtime_get_account_mgr();
2993 account_name = g_strdup (data->account_name);
2995 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2998 account_name = modest_account_mgr_get_default_account (account_mgr);
3000 if (!account_name) {
3001 modest_msg_edit_window_free_msg_data (edit_window, data);
3002 /* Run account setup wizard */
3003 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
3008 /* Get the currently-active transport account for this modest account: */
3009 if (strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
3011 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3012 (modest_runtime_get_account_store (),
3013 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
3016 if (!transport_account) {
3017 modest_msg_edit_window_free_msg_data (edit_window, data);
3018 /* Run account setup wizard */
3019 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
3024 /* Create the mail operation */
3025 from = modest_account_mgr_get_from_string (account_mgr, account_name);
3026 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
3027 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3029 modest_mail_operation_send_new_mail (mail_operation,
3041 data->priority_flags);
3043 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3044 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
3047 if (modest_mail_operation_get_error (mail_operation) != NULL) {
3048 const GError *error = modest_mail_operation_get_error (mail_operation);
3049 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3050 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3051 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3052 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3059 g_free (account_name);
3060 g_object_unref (G_OBJECT (transport_account));
3061 g_object_unref (G_OBJECT (mail_operation));
3063 modest_msg_edit_window_free_msg_data (edit_window, data);
3066 modest_msg_edit_window_set_sent (edit_window, TRUE);
3068 /* Save settings and close the window: */
3069 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3076 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3077 ModestMsgEditWindow *window)
3079 ModestMsgEditFormatState *format_state = NULL;
3081 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3082 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3084 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3087 format_state = modest_msg_edit_window_get_format_state (window);
3088 g_return_if_fail (format_state != NULL);
3090 format_state->bold = gtk_toggle_action_get_active (action);
3091 modest_msg_edit_window_set_format_state (window, format_state);
3092 g_free (format_state);
3097 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3098 ModestMsgEditWindow *window)
3100 ModestMsgEditFormatState *format_state = NULL;
3102 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3103 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3105 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3108 format_state = modest_msg_edit_window_get_format_state (window);
3109 g_return_if_fail (format_state != NULL);
3111 format_state->italics = gtk_toggle_action_get_active (action);
3112 modest_msg_edit_window_set_format_state (window, format_state);
3113 g_free (format_state);
3118 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3119 ModestMsgEditWindow *window)
3121 ModestMsgEditFormatState *format_state = NULL;
3123 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3124 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3126 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3129 format_state = modest_msg_edit_window_get_format_state (window);
3130 g_return_if_fail (format_state != NULL);
3132 format_state->bullet = gtk_toggle_action_get_active (action);
3133 modest_msg_edit_window_set_format_state (window, format_state);
3134 g_free (format_state);
3139 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3140 GtkRadioAction *selected,
3141 ModestMsgEditWindow *window)
3143 ModestMsgEditFormatState *format_state = NULL;
3144 GtkJustification value;
3146 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3148 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3151 value = gtk_radio_action_get_current_value (selected);
3153 format_state = modest_msg_edit_window_get_format_state (window);
3154 g_return_if_fail (format_state != NULL);
3156 format_state->justification = value;
3157 modest_msg_edit_window_set_format_state (window, format_state);
3158 g_free (format_state);
3162 modest_ui_actions_on_select_editor_color (GtkAction *action,
3163 ModestMsgEditWindow *window)
3165 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3166 g_return_if_fail (GTK_IS_ACTION (action));
3168 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3171 modest_msg_edit_window_select_color (window);
3175 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3176 ModestMsgEditWindow *window)
3178 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3179 g_return_if_fail (GTK_IS_ACTION (action));
3181 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3184 modest_msg_edit_window_select_background_color (window);
3188 modest_ui_actions_on_insert_image (GObject *object,
3189 ModestMsgEditWindow *window)
3191 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3194 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3197 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3200 modest_msg_edit_window_insert_image (window);
3204 modest_ui_actions_on_attach_file (GtkAction *action,
3205 ModestMsgEditWindow *window)
3207 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3208 g_return_if_fail (GTK_IS_ACTION (action));
3210 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3213 modest_msg_edit_window_offer_attach_file (window);
3217 modest_ui_actions_on_remove_attachments (GtkAction *action,
3218 ModestMsgEditWindow *window)
3220 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3222 modest_msg_edit_window_remove_attachments (window, NULL);
3226 #ifndef MODEST_TOOLKIT_GTK
3231 TnyFolderStore *folder;
3232 } CreateFolderHelper;
3235 show_create_folder_in_timeout (gpointer data)
3237 CreateFolderHelper *helper = (CreateFolderHelper *) data;
3239 /* Remove the timeout ASAP, we can not wait until the dialog
3240 is shown because it could take a lot of time and so the
3241 timeout could be called twice or more times */
3242 g_source_remove (helper->handler);
3244 gdk_threads_enter ();
3245 do_create_folder (helper->win, helper->folder, helper->name);
3246 gdk_threads_leave ();
3248 g_object_unref (helper->win);
3249 g_object_unref (helper->folder);
3250 g_free (helper->name);
3251 g_slice_free (CreateFolderHelper, helper);
3258 do_create_folder_cb (ModestMailOperation *mail_op,
3259 TnyFolderStore *parent_folder,
3260 TnyFolder *new_folder,
3263 gchar *suggested_name = (gchar *) user_data;
3264 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3266 if (modest_mail_operation_get_error (mail_op)) {
3268 /* Show an error. If there was some problem writing to
3269 disk, show it, otherwise show the generic folder
3270 create error. We do it here and not in an error
3271 handler because the call to do_create_folder will
3272 stop the main loop in a gtk_dialog_run and then,
3273 the message won't be shown until that dialog is
3275 modest_ui_actions_disk_operations_error_handler (mail_op,
3276 _("mail_in_ui_folder_create_error"));
3278 /* Try again. Do *NOT* show any error because the mail
3279 operations system will do it for us because we
3280 created the mail_op with new_with_error_handler */
3281 #ifndef MODEST_TOOLKIT_GTK
3282 CreateFolderHelper *helper;
3283 helper = g_slice_new0 (CreateFolderHelper);
3284 helper->name = g_strdup (suggested_name);
3285 helper->folder = g_object_ref (parent_folder);
3286 helper->win = g_object_ref (source_win);
3288 /* Ugly but neccesary stuff. The problem is that the
3289 dialog when is shown calls a function that destroys
3290 all the temporary windows, so the banner is
3292 helper->handler = g_timeout_add (2000, show_create_folder_in_timeout, helper);
3294 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3297 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3298 * FIXME: any other? */
3299 GtkWidget *folder_view;
3301 if (MODEST_IS_MAIN_WINDOW(source_win))
3303 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3304 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3306 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3307 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3309 /* Select the newly created folder. It could happen
3310 that the widget is no longer there (i.e. the window
3311 has been destroyed, so we need to check this */
3313 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3315 g_object_unref (new_folder);
3317 /* Free. Note that the first time it'll be NULL so noop */
3318 g_free (suggested_name);
3319 g_object_unref (source_win);
3324 TnyFolderStore *parent;
3325 } CreateFolderConnect;
3328 do_create_folder_performer (gboolean canceled,
3330 GtkWindow *parent_window,
3331 TnyAccount *account,
3334 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3335 ModestMailOperation *mail_op;
3337 if (canceled || err) {
3338 /* In memory full conditions we could get this error here */
3339 check_memory_full_error ((GtkWidget *) parent_window, err);
3343 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3344 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3346 modest_mail_operation_create_folder (mail_op,
3348 (const gchar *) helper->folder_name,
3349 do_create_folder_cb,
3350 g_strdup (helper->folder_name));
3351 g_object_unref (mail_op);
3355 g_object_unref (helper->parent);
3356 if (helper->folder_name)
3357 g_free (helper->folder_name);
3358 g_slice_free (CreateFolderConnect, helper);
3363 do_create_folder (GtkWindow *parent_window,
3364 TnyFolderStore *suggested_parent,
3365 const gchar *suggested_name)
3368 gchar *folder_name = NULL;
3369 TnyFolderStore *parent_folder = NULL;
3371 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3373 (gchar *) suggested_name,
3377 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3378 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderHelper);
3379 helper->folder_name = g_strdup (folder_name);
3380 helper->parent = g_object_ref (parent_folder);
3382 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3385 do_create_folder_performer,
3390 g_free (folder_name);
3392 g_object_unref (parent_folder);
3396 modest_ui_actions_create_folder(GtkWidget *parent_window,
3397 GtkWidget *folder_view)
3399 TnyFolderStore *parent_folder;
3401 #ifdef MODEST_TOOLKIT_HILDON2
3402 ModestTnyAccountStore *acc_store;
3404 acc_store = modest_runtime_get_account_store ();
3406 parent_folder = (TnyFolderStore *)
3407 modest_tny_account_store_get_local_folders_account (acc_store);
3409 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3413 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3417 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3420 g_return_if_fail (MODEST_IS_WINDOW(window));
3422 if (MODEST_IS_MAIN_WINDOW (window)) {
3423 GtkWidget *folder_view;
3425 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3426 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3430 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view);
3431 #ifdef MODEST_TOOLKIT_HILDON2
3432 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3433 GtkWidget *folder_view;
3435 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3436 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view);
3439 g_assert_not_reached ();
3444 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3447 const GError *error = NULL;
3448 const gchar *message = NULL;
3450 /* Get error message */
3451 error = modest_mail_operation_get_error (mail_op);
3453 g_return_if_reached ();
3455 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3456 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3457 message = _CS("ckdg_ib_folder_already_exists");
3458 } else if (error->domain == TNY_ERROR_DOMAIN &&
3459 error->code == TNY_SERVICE_ERROR_STATE) {
3460 /* This means that the folder is already in use (a
3461 message is opened for example */
3462 message = _("emev_ni_internal_error");
3464 message = _CS("ckdg_ib_unable_to_rename");
3467 /* We don't set a parent for the dialog because the dialog
3468 will be destroyed so the banner won't appear */
3469 modest_platform_information_banner (NULL, NULL, message);
3473 TnyFolderStore *folder;
3478 on_rename_folder_cb (ModestMailOperation *mail_op,
3479 TnyFolder *new_folder,
3482 ModestFolderView *folder_view;
3484 /* If the window was closed when renaming a folder, or if
3485 * it's not a main window this will happen */
3486 if (!MODEST_IS_FOLDER_VIEW (user_data))
3489 folder_view = MODEST_FOLDER_VIEW (user_data);
3490 /* Note that if the rename fails new_folder will be NULL */
3492 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3494 modest_folder_view_select_first_inbox_or_local (folder_view);
3496 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3500 on_rename_folder_performer (gboolean canceled,
3502 GtkWindow *parent_window,
3503 TnyAccount *account,
3506 ModestMailOperation *mail_op = NULL;
3507 GtkTreeSelection *sel = NULL;
3508 GtkWidget *folder_view = NULL;
3509 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3511 if (canceled || err) {
3512 /* In memory full conditions we could get this error here */
3513 check_memory_full_error ((GtkWidget *) parent_window, err);
3517 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3518 modest_ui_actions_rename_folder_error_handler,
3519 parent_window, NULL);
3521 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3524 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3526 folder_view = modest_main_window_get_child_widget (
3527 MODEST_MAIN_WINDOW (parent_window),
3528 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3530 #ifdef MODEST_TOOLKIT_HILDON2
3531 else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3532 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3533 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3537 /* Clear the folders view */
3538 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3539 gtk_tree_selection_unselect_all (sel);
3541 /* Actually rename the folder */
3542 modest_mail_operation_rename_folder (mail_op,
3543 TNY_FOLDER (data->folder),
3544 (const gchar *) (data->new_name),
3545 on_rename_folder_cb,
3547 g_object_unref (mail_op);
3550 g_object_unref (data->folder);
3551 g_free (data->new_name);
3556 modest_ui_actions_on_rename_folder (GtkAction *action,
3557 ModestWindow *window)
3559 modest_ui_actions_on_edit_mode_rename_folder (window);
3563 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3565 TnyFolderStore *folder;
3566 GtkWidget *folder_view;
3567 gboolean do_rename = TRUE;
3569 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3571 if (MODEST_IS_MAIN_WINDOW (window)) {
3572 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3573 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3577 #ifdef MODEST_TOOLKIT_HILDON2
3578 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3579 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3585 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3590 if (TNY_IS_FOLDER (folder)) {
3591 gchar *folder_name = NULL;
3593 const gchar *current_name;
3594 TnyFolderStore *parent;
3596 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3597 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3598 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
3599 parent, current_name,
3601 g_object_unref (parent);
3603 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3606 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3607 rename_folder_data->folder = g_object_ref (folder);
3608 rename_folder_data->new_name = folder_name;
3609 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
3610 folder, on_rename_folder_performer, rename_folder_data);
3613 g_object_unref (folder);
3618 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3621 GObject *win = modest_mail_operation_get_source (mail_op);
3623 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3624 _("mail_in_ui_folder_delete_error"),
3626 g_object_unref (win);
3630 TnyFolderStore *folder;
3631 gboolean move_to_trash;
3635 on_delete_folder_cb (gboolean canceled,
3637 GtkWindow *parent_window,
3638 TnyAccount *account,
3641 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3642 GtkWidget *folder_view;
3643 ModestMailOperation *mail_op;
3644 GtkTreeSelection *sel;
3646 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
3647 g_object_unref (G_OBJECT (info->folder));
3652 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
3653 folder_view = modest_main_window_get_child_widget (
3654 MODEST_MAIN_WINDOW (parent_window),
3655 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3656 #ifdef MODEST_TOOLKIT_HILDON2
3657 } else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3658 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
3661 g_object_unref (G_OBJECT (info->folder));
3666 /* Unselect the folder before deleting it to free the headers */
3667 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3668 gtk_tree_selection_unselect_all (sel);
3670 /* Create the mail operation */
3672 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3673 modest_ui_actions_delete_folder_error_handler,
3676 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3678 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3680 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3682 g_object_unref (G_OBJECT (mail_op));
3683 g_object_unref (G_OBJECT (info->folder));
3688 delete_folder (ModestWindow *window, gboolean move_to_trash)
3690 TnyFolderStore *folder;
3691 GtkWidget *folder_view;
3695 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3697 if (MODEST_IS_MAIN_WINDOW (window)) {
3699 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3700 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3701 #ifdef MODEST_TOOLKIT_HILDON2
3702 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3703 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3711 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3716 /* Show an error if it's an account */
3717 if (!TNY_IS_FOLDER (folder)) {
3718 modest_platform_run_information_dialog (GTK_WINDOW (window),
3719 _("mail_in_ui_folder_delete_error"),
3721 g_object_unref (G_OBJECT (folder));
3726 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3727 tny_folder_get_name (TNY_FOLDER (folder)));
3728 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
3729 (const gchar *) message);
3732 if (response == GTK_RESPONSE_OK) {
3733 DeleteFolderInfo *info;
3734 info = g_new0(DeleteFolderInfo, 1);
3735 info->folder = folder;
3736 info->move_to_trash = move_to_trash;
3737 g_object_ref (G_OBJECT (info->folder));
3738 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder));
3739 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
3741 TNY_FOLDER_STORE (account),
3742 on_delete_folder_cb, info);
3743 g_object_unref (account);
3748 g_object_unref (G_OBJECT (folder));
3752 modest_ui_actions_on_delete_folder (GtkAction *action,
3753 ModestWindow *window)
3755 modest_ui_actions_on_edit_mode_delete_folder (window);
3759 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
3761 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
3763 return delete_folder (window, FALSE);
3767 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3769 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3771 delete_folder (MODEST_WINDOW (main_window), TRUE);
3775 typedef struct _PasswordDialogFields {
3776 GtkWidget *username;
3777 GtkWidget *password;
3779 } PasswordDialogFields;
3782 password_dialog_check_field (GtkEditable *editable,
3783 PasswordDialogFields *fields)
3786 gboolean any_value_empty = FALSE;
3788 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
3789 if ((value == NULL) || value[0] == '\0') {
3790 any_value_empty = TRUE;
3792 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
3793 if ((value == NULL) || value[0] == '\0') {
3794 any_value_empty = TRUE;
3796 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3800 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3801 const gchar* server_account_name,
3806 ModestMainWindow *main_window)
3808 g_return_if_fail(server_account_name);
3809 gboolean completed = FALSE;
3810 PasswordDialogFields *fields = NULL;
3812 /* Initalize output parameters: */
3819 #ifndef MODEST_TOOLKIT_GTK
3820 /* Maemo uses a different (awkward) button order,
3821 * It should probably just use gtk_alternative_dialog_button_order ().
3823 #ifdef MODEST_TOOLKIT_HILDON2
3825 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3828 _HL("wdgt_bd_done"),
3829 GTK_RESPONSE_ACCEPT,
3833 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3836 _("mcen_bd_dialog_ok"),
3837 GTK_RESPONSE_ACCEPT,
3838 _("mcen_bd_dialog_cancel"),
3839 GTK_RESPONSE_REJECT,
3841 #endif /* MODEST_TOOLKIT_HILDON2 */
3844 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3848 GTK_RESPONSE_REJECT,
3850 GTK_RESPONSE_ACCEPT,
3852 #endif /* MODEST_TOOLKIT_GTK */
3854 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3856 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3857 modest_runtime_get_account_mgr(), server_account_name);
3858 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3859 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3862 gtk_widget_destroy (dialog);
3866 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3867 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
3870 g_free (server_name);
3874 gchar *initial_username = modest_account_mgr_get_server_account_username (
3875 modest_runtime_get_account_mgr(), server_account_name);
3877 GtkWidget *entry_username = gtk_entry_new ();
3878 if (initial_username)
3879 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
3880 /* Dim this if a connection has ever succeeded with this username,
3881 * as per the UI spec: */
3882 /* const gboolean username_known = */
3883 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3884 /* modest_runtime_get_account_mgr(), server_account_name); */
3885 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3887 /* We drop the username sensitive code and disallow changing it here
3888 * as tinymail does not support really changing the username in the callback
3890 gtk_widget_set_sensitive (entry_username, FALSE);
3892 #ifndef MODEST_TOOLKIT_GTK
3893 /* Auto-capitalization is the default, so let's turn it off: */
3894 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3896 /* Create a size group to be used by all captions.
3897 * Note that HildonCaption does not create a default size group if we do not specify one.
3898 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3899 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3901 GtkWidget *caption = hildon_caption_new (sizegroup,
3902 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
3903 gtk_widget_show (entry_username);
3904 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3905 FALSE, FALSE, MODEST_MARGIN_HALF);
3906 gtk_widget_show (caption);
3908 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
3910 #endif /* !MODEST_TOOLKIT_GTK */
3913 GtkWidget *entry_password = gtk_entry_new ();
3914 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3915 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3917 #ifndef MODEST_TOOLKIT_GTK
3918 /* Auto-capitalization is the default, so let's turn it off: */
3919 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3920 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3922 caption = hildon_caption_new (sizegroup,
3923 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
3924 gtk_widget_show (entry_password);
3925 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3926 FALSE, FALSE, MODEST_MARGIN_HALF);
3927 gtk_widget_show (caption);
3928 g_object_unref (sizegroup);
3930 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
3932 #endif /* !MODEST_TOOLKIT_GTK */
3934 if (initial_username != NULL)
3935 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3937 /* This is not in the Maemo UI spec:
3938 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3939 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3943 fields = g_slice_new0 (PasswordDialogFields);
3944 fields->username = entry_username;
3945 fields->password = entry_password;
3946 fields->dialog = dialog;
3948 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3949 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3950 password_dialog_check_field (NULL, fields);
3952 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3954 while (!completed) {
3956 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3958 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
3960 /* Note that an empty field becomes the "" string */
3961 if (*username && strlen (*username) > 0) {
3962 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
3963 server_account_name,
3967 const gboolean username_was_changed =
3968 (strcmp (*username, initial_username) != 0);
3969 if (username_was_changed) {
3970 g_warning ("%s: tinymail does not yet support changing the "
3971 "username in the get_password() callback.\n", __FUNCTION__);
3977 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
3978 _("mcen_ib_username_pw_incorrect"));
3984 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
3986 /* We do not save the password in the configuration,
3987 * because this function is only called for passwords that should
3988 * not be remembered:
3989 modest_server_account_set_password (
3990 modest_runtime_get_account_mgr(), server_account_name,
3997 #ifndef MODEST_TOOLKIT_HILDON2
3998 /* Set parent to NULL or the banner will disappear with its parent dialog */
3999 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
4011 /* This is not in the Maemo UI spec:
4012 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
4018 g_free (initial_username);
4019 gtk_widget_destroy (dialog);
4020 g_slice_free (PasswordDialogFields, fields);
4022 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
4026 modest_ui_actions_on_cut (GtkAction *action,
4027 ModestWindow *window)
4029 GtkWidget *focused_widget;
4030 GtkClipboard *clipboard;
4032 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4033 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4034 if (GTK_IS_EDITABLE (focused_widget)) {
4035 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
4036 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4037 gtk_clipboard_store (clipboard);
4038 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4039 GtkTextBuffer *buffer;
4041 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4042 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4043 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
4044 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4045 gtk_clipboard_store (clipboard);
4047 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4048 TnyList *header_list = modest_header_view_get_selected_headers (
4049 MODEST_HEADER_VIEW (focused_widget));
4050 gboolean continue_download = FALSE;
4051 gint num_of_unc_msgs;
4053 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4055 if (num_of_unc_msgs) {
4056 TnyAccount *account = get_account_from_header_list (header_list);
4058 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4059 g_object_unref (account);
4063 if (num_of_unc_msgs == 0 || continue_download) {
4064 /* modest_platform_information_banner (
4065 NULL, NULL, _CS("mcen_ib_getting_items"));*/
4066 modest_header_view_cut_selection (
4067 MODEST_HEADER_VIEW (focused_widget));
4070 g_object_unref (header_list);
4071 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4072 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4077 modest_ui_actions_on_copy (GtkAction *action,
4078 ModestWindow *window)
4080 GtkClipboard *clipboard;
4081 GtkWidget *focused_widget;
4082 gboolean copied = TRUE;
4084 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4085 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4087 if (GTK_IS_LABEL (focused_widget)) {
4089 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4090 gtk_clipboard_set_text (clipboard, selection, -1);
4092 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4093 gtk_clipboard_store (clipboard);
4094 } else if (GTK_IS_EDITABLE (focused_widget)) {
4095 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4096 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4097 gtk_clipboard_store (clipboard);
4098 } else if (GTK_IS_HTML (focused_widget)) {
4101 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4102 if ((sel == NULL) || (sel[0] == '\0')) {
4105 gtk_html_copy (GTK_HTML (focused_widget));
4106 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4107 gtk_clipboard_store (clipboard);
4109 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4110 GtkTextBuffer *buffer;
4111 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4112 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4113 gtk_text_buffer_copy_clipboard (buffer, clipboard);
4114 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4115 gtk_clipboard_store (clipboard);
4117 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4118 TnyList *header_list = modest_header_view_get_selected_headers (
4119 MODEST_HEADER_VIEW (focused_widget));
4120 gboolean continue_download = FALSE;
4121 gint num_of_unc_msgs;
4123 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4125 if (num_of_unc_msgs) {
4126 TnyAccount *account = get_account_from_header_list (header_list);
4128 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4129 g_object_unref (account);
4133 if (num_of_unc_msgs == 0 || continue_download) {
4134 modest_platform_information_banner (
4135 NULL, NULL, _CS("mcen_ib_getting_items"));
4136 modest_header_view_copy_selection (
4137 MODEST_HEADER_VIEW (focused_widget));
4141 g_object_unref (header_list);
4143 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4144 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4147 /* Show information banner if there was a copy to clipboard */
4149 modest_platform_information_banner (
4150 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4154 modest_ui_actions_on_undo (GtkAction *action,
4155 ModestWindow *window)
4157 ModestEmailClipboard *clipboard = NULL;
4159 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4160 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4161 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4162 /* Clear clipboard source */
4163 clipboard = modest_runtime_get_email_clipboard ();
4164 modest_email_clipboard_clear (clipboard);
4167 g_return_if_reached ();
4172 modest_ui_actions_on_redo (GtkAction *action,
4173 ModestWindow *window)
4175 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4176 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4179 g_return_if_reached ();
4185 destroy_information_note (ModestMailOperation *mail_op,
4188 /* destroy information note */
4189 gtk_widget_destroy (GTK_WIDGET(user_data));
4193 destroy_folder_information_note (ModestMailOperation *mail_op,
4194 TnyFolder *new_folder,
4197 /* destroy information note */
4198 gtk_widget_destroy (GTK_WIDGET(user_data));
4203 paste_as_attachment_free (gpointer data)
4205 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4207 if (helper->banner) {
4208 gtk_widget_destroy (helper->banner);
4209 g_object_unref (helper->banner);
4215 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4220 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4221 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4226 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4231 modest_ui_actions_on_paste (GtkAction *action,
4232 ModestWindow *window)
4234 GtkWidget *focused_widget = NULL;
4235 GtkWidget *inf_note = NULL;
4236 ModestMailOperation *mail_op = NULL;
4238 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4239 if (GTK_IS_EDITABLE (focused_widget)) {
4240 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4241 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4242 ModestEmailClipboard *e_clipboard = NULL;
4243 e_clipboard = modest_runtime_get_email_clipboard ();
4244 if (modest_email_clipboard_cleared (e_clipboard)) {
4245 GtkTextBuffer *buffer;
4246 GtkClipboard *clipboard;
4248 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4249 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4250 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4251 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4252 ModestMailOperation *mail_op;
4253 TnyFolder *src_folder = NULL;
4254 TnyList *data = NULL;
4256 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4257 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4258 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4259 _CS("ckct_nw_pasting"));
4260 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4261 mail_op = modest_mail_operation_new (G_OBJECT (window));
4262 if (helper->banner != NULL) {
4263 g_object_ref (G_OBJECT (helper->banner));
4264 gtk_widget_show (GTK_WIDGET (helper->banner));
4268 modest_mail_operation_get_msgs_full (mail_op,
4270 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4272 paste_as_attachment_free);
4276 g_object_unref (data);
4278 g_object_unref (src_folder);
4281 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4282 ModestEmailClipboard *clipboard = NULL;
4283 TnyFolder *src_folder = NULL;
4284 TnyFolderStore *folder_store = NULL;
4285 TnyList *data = NULL;
4286 gboolean delete = FALSE;
4288 /* Check clipboard source */
4289 clipboard = modest_runtime_get_email_clipboard ();
4290 if (modest_email_clipboard_cleared (clipboard))
4293 /* Get elements to paste */
4294 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4296 /* Create a new mail operation */
4297 mail_op = modest_mail_operation_new (G_OBJECT(window));
4299 /* Get destination folder */
4300 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4302 /* transfer messages */
4306 /* Ask for user confirmation */
4308 modest_ui_actions_msgs_move_to_confirmation (window,
4309 TNY_FOLDER (folder_store),
4313 if (response == GTK_RESPONSE_OK) {
4314 /* Launch notification */
4315 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4316 _CS("ckct_nw_pasting"));
4317 if (inf_note != NULL) {
4318 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4319 gtk_widget_show (GTK_WIDGET(inf_note));
4322 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4323 modest_mail_operation_xfer_msgs (mail_op,
4325 TNY_FOLDER (folder_store),
4327 destroy_information_note,
4330 g_object_unref (mail_op);
4333 } else if (src_folder != NULL) {
4334 /* Launch notification */
4335 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4336 _CS("ckct_nw_pasting"));
4337 if (inf_note != NULL) {
4338 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4339 gtk_widget_show (GTK_WIDGET(inf_note));
4342 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4343 modest_mail_operation_xfer_folder (mail_op,
4347 destroy_folder_information_note,
4353 g_object_unref (data);
4354 if (src_folder != NULL)
4355 g_object_unref (src_folder);
4356 if (folder_store != NULL)
4357 g_object_unref (folder_store);
4363 modest_ui_actions_on_select_all (GtkAction *action,
4364 ModestWindow *window)
4366 GtkWidget *focused_widget;
4368 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4369 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4370 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4371 } else if (GTK_IS_LABEL (focused_widget)) {
4372 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4373 } else if (GTK_IS_EDITABLE (focused_widget)) {
4374 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4375 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4376 GtkTextBuffer *buffer;
4377 GtkTextIter start, end;
4379 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4380 gtk_text_buffer_get_start_iter (buffer, &start);
4381 gtk_text_buffer_get_end_iter (buffer, &end);
4382 gtk_text_buffer_select_range (buffer, &start, &end);
4383 } else if (GTK_IS_HTML (focused_widget)) {
4384 gtk_html_select_all (GTK_HTML (focused_widget));
4385 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4386 GtkWidget *header_view = focused_widget;
4387 GtkTreeSelection *selection = NULL;
4389 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4390 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4391 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4394 /* Disable window dimming management */
4395 modest_window_disable_dimming (MODEST_WINDOW(window));
4397 /* Select all messages */
4398 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4399 gtk_tree_selection_select_all (selection);
4401 /* Set focuse on header view */
4402 gtk_widget_grab_focus (header_view);
4404 /* Enable window dimming management */
4405 modest_window_enable_dimming (MODEST_WINDOW(window));
4406 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4407 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4413 modest_ui_actions_on_mark_as_read (GtkAction *action,
4414 ModestWindow *window)
4416 g_return_if_fail (MODEST_IS_WINDOW(window));
4418 /* Mark each header as read */
4419 do_headers_action (window, headers_action_mark_as_read, NULL);
4423 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4424 ModestWindow *window)
4426 g_return_if_fail (MODEST_IS_WINDOW(window));
4428 /* Mark each header as read */
4429 do_headers_action (window, headers_action_mark_as_unread, NULL);
4433 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4434 GtkRadioAction *selected,
4435 ModestWindow *window)
4439 value = gtk_radio_action_get_current_value (selected);
4440 if (MODEST_IS_WINDOW (window)) {
4441 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4446 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4447 GtkRadioAction *selected,
4448 ModestWindow *window)
4450 TnyHeaderFlags flags;
4451 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4453 flags = gtk_radio_action_get_current_value (selected);
4454 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4458 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4459 GtkRadioAction *selected,
4460 ModestWindow *window)
4464 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4466 file_format = gtk_radio_action_get_current_value (selected);
4467 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4472 modest_ui_actions_on_zoom_plus (GtkAction *action,
4473 ModestWindow *window)
4475 g_return_if_fail (MODEST_IS_WINDOW (window));
4477 modest_window_zoom_plus (MODEST_WINDOW (window));
4481 modest_ui_actions_on_zoom_minus (GtkAction *action,
4482 ModestWindow *window)
4484 g_return_if_fail (MODEST_IS_WINDOW (window));
4486 modest_window_zoom_minus (MODEST_WINDOW (window));
4490 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4491 ModestWindow *window)
4493 ModestWindowMgr *mgr;
4494 gboolean fullscreen, active;
4495 g_return_if_fail (MODEST_IS_WINDOW (window));
4497 mgr = modest_runtime_get_window_mgr ();
4499 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4500 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4502 if (active != fullscreen) {
4503 modest_window_mgr_set_fullscreen_mode (mgr, active);
4504 #ifndef MODEST_TOOLKIT_HILDON2
4505 gtk_window_present (GTK_WINDOW (window));
4511 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4512 ModestWindow *window)
4514 ModestWindowMgr *mgr;
4515 gboolean fullscreen;
4517 g_return_if_fail (MODEST_IS_WINDOW (window));
4519 mgr = modest_runtime_get_window_mgr ();
4520 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4521 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4523 #ifndef MODEST_TOOLKIT_HILDON2
4524 gtk_window_present (GTK_WINDOW (window));
4529 * Used by modest_ui_actions_on_details to call do_headers_action
4532 headers_action_show_details (TnyHeader *header,
4533 ModestWindow *window,
4537 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header);
4541 * Show the header details in a ModestDetailsDialog widget
4544 modest_ui_actions_on_details (GtkAction *action,
4547 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4551 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4555 header = tny_msg_get_header (msg);
4557 headers_action_show_details (header, win, NULL);
4558 g_object_unref (header);
4560 g_object_unref (msg);
4562 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4563 GtkWidget *folder_view, *header_view;
4565 /* Check which widget has the focus */
4566 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4567 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4568 if (gtk_widget_is_focus (folder_view)) {
4569 TnyFolderStore *folder_store
4570 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4571 if (!folder_store) {
4572 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4575 /* Show only when it's a folder */
4576 /* This function should not be called for account items,
4577 * because we dim the menu item for them. */
4578 if (TNY_IS_FOLDER (folder_store)) {
4579 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4580 TNY_FOLDER (folder_store));
4583 g_object_unref (folder_store);
4586 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4587 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4588 /* Show details of each header */
4589 do_headers_action (win, headers_action_show_details, header_view);
4591 #ifdef MODEST_TOOLKIT_HILDON2
4592 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4594 GtkWidget *header_view;
4596 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4597 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4599 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4601 g_object_unref (folder);
4608 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4609 ModestMsgEditWindow *window)
4611 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4613 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4617 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4618 ModestMsgEditWindow *window)
4620 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4622 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4626 modest_ui_actions_toggle_folders_view (GtkAction *action,
4627 ModestMainWindow *main_window)
4629 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4631 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4632 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4634 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4638 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4639 ModestWindow *window)
4641 gboolean active, fullscreen = FALSE;
4642 ModestWindowMgr *mgr;
4644 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4646 /* Check if we want to toggle the toolbar view in fullscreen
4648 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4649 "ViewShowToolbarFullScreen")) {
4653 /* Toggle toolbar */
4654 mgr = modest_runtime_get_window_mgr ();
4655 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4659 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4660 ModestMsgEditWindow *window)
4662 modest_msg_edit_window_select_font (window);
4667 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4668 const gchar *display_name,
4671 /* don't update the display name if it was already set;
4672 * updating the display name apparently is expensive */
4673 const gchar* old_name = gtk_window_get_title (window);
4675 if (display_name == NULL)
4678 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4679 return; /* don't do anything */
4681 /* This is usually used to change the title of the main window, which
4682 * is the one that holds the folder view. Note that this change can
4683 * happen even when the widget doesn't have the focus. */
4684 gtk_window_set_title (window, display_name);
4689 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4691 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4692 modest_msg_edit_window_select_contacts (window);
4696 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4698 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4699 modest_msg_edit_window_check_names (window, FALSE);
4702 #ifndef MODEST_TOOLKIT_HILDON2
4704 * This function is used to track changes in the selection of the
4705 * folder view that is inside the "move to" dialog to enable/disable
4706 * the OK button because we do not want the user to select a disallowed
4707 * destination for a folder.
4708 * The user also not desired to be able to use NEW button on items where
4709 * folder creation is not possibel.
4712 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4713 TnyFolderStore *folder_store,
4717 GtkWidget *dialog = NULL;
4718 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4719 gboolean moving_folder = FALSE;
4720 gboolean is_local_account = TRUE;
4721 GtkWidget *folder_view = NULL;
4722 ModestTnyFolderRules rules;
4724 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
4729 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
4733 /* check if folder_store is an remote account */
4734 if (TNY_IS_ACCOUNT (folder_store)) {
4735 TnyAccount *local_account = NULL;
4736 TnyAccount *mmc_account = NULL;
4737 ModestTnyAccountStore *account_store = NULL;
4739 account_store = modest_runtime_get_account_store ();
4740 local_account = modest_tny_account_store_get_local_folders_account (account_store);
4741 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
4743 if ((gpointer) local_account != (gpointer) folder_store &&
4744 (gpointer) mmc_account != (gpointer) folder_store) {
4745 ModestProtocolType proto;
4746 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
4747 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
4748 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
4750 is_local_account = FALSE;
4751 /* New button should be dimmed on remote
4753 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4755 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
4757 g_object_unref (local_account);
4759 /* It could not exist */
4761 g_object_unref (mmc_account);
4764 /* Check the target folder rules */
4765 if (TNY_IS_FOLDER (folder_store)) {
4766 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
4767 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
4768 ok_sensitive = FALSE;
4769 new_sensitive = FALSE;
4774 /* Check if we're moving a folder */
4775 if (MODEST_IS_MAIN_WINDOW (user_data)) {
4776 /* Get the widgets */
4777 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
4778 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4779 if (gtk_widget_is_focus (folder_view))
4780 moving_folder = TRUE;
4783 if (moving_folder) {
4784 TnyFolderStore *moved_folder = NULL, *parent = NULL;
4786 /* Get the folder to move */
4787 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4789 /* Check that we're not moving to the same folder */
4790 if (TNY_IS_FOLDER (moved_folder)) {
4791 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
4792 if (parent == folder_store)
4793 ok_sensitive = FALSE;
4794 g_object_unref (parent);
4797 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
4798 /* Do not allow to move to an account unless it's the
4799 local folders account */
4800 if (!is_local_account)
4801 ok_sensitive = FALSE;
4804 if (ok_sensitive && (moved_folder == folder_store)) {
4805 /* Do not allow to move to itself */
4806 ok_sensitive = FALSE;
4808 g_object_unref (moved_folder);
4810 TnyFolder *src_folder = NULL;
4812 /* Moving a message */
4813 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
4815 TnyHeader *header = NULL;
4816 header = modest_msg_view_window_get_header
4817 (MODEST_MSG_VIEW_WINDOW (user_data));
4818 if (!TNY_IS_HEADER(header))
4819 g_warning ("%s: could not get source header", __FUNCTION__);
4821 src_folder = tny_header_get_folder (header);
4824 g_object_unref (header);
4827 TNY_FOLDER (modest_folder_view_get_selected
4828 (MODEST_FOLDER_VIEW (folder_view)));
4831 if (TNY_IS_FOLDER(src_folder)) {
4832 /* Do not allow to move the msg to the same folder */
4833 /* Do not allow to move the msg to an account */
4834 if ((gpointer) src_folder == (gpointer) folder_store ||
4835 TNY_IS_ACCOUNT (folder_store))
4836 ok_sensitive = FALSE;
4837 g_object_unref (src_folder);
4839 g_warning ("%s: could not get source folder", __FUNCTION__);
4843 /* Set sensitivity of the OK and NEW button */
4844 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
4845 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
4850 on_move_to_dialog_response (GtkDialog *dialog,
4854 GtkWidget *parent_win, *folder_view;
4855 MoveToInfo *helper = NULL;
4857 helper = (MoveToInfo *) user_data;
4859 parent_win = (GtkWidget *) helper->win;
4860 folder_view = GTK_WIDGET (g_object_get_data (G_OBJECT (dialog),
4861 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4864 TnyFolderStore *dst_folder;
4866 case MODEST_GTK_RESPONSE_NEW_FOLDER:
4867 modest_ui_actions_create_folder (GTK_WIDGET (dialog), folder_view);
4869 case GTK_RESPONSE_NONE:
4870 case GTK_RESPONSE_CANCEL:
4871 case GTK_RESPONSE_DELETE_EVENT:
4873 case GTK_RESPONSE_OK:
4874 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4875 /* Do window specific stuff */
4876 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
4877 modest_ui_actions_on_main_window_move_to (NULL,
4880 MODEST_MAIN_WINDOW (parent_win));
4881 #ifdef MODEST_TOOLKIT_HILDON2
4882 } else if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
4883 modest_ui_actions_on_folder_window_move_to (folder_view,
4886 GTK_WINDOW (parent_win));
4889 /* Moving from headers window in edit mode */
4890 modest_ui_actions_on_window_move_to (NULL, helper->list,
4892 MODEST_WINDOW (parent_win));
4896 g_object_unref (dst_folder);
4900 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
4903 /* Free the helper and exit */
4905 g_object_unref (helper->list);
4906 g_slice_free (MoveToInfo, helper);
4907 gtk_widget_destroy (GTK_WIDGET (dialog));
4911 create_move_to_dialog (GtkWindow *win,
4912 GtkWidget *folder_view)
4914 GtkWidget *dialog, *tree_view = NULL;
4916 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
4918 #ifndef MODEST_TOOLKIT_HILDON2
4919 /* Track changes in the selection to
4920 * disable the OK button whenever "Move to" is not possible
4921 * disbale NEW button whenever New is not possible */
4922 g_signal_connect (tree_view,
4923 "folder_selection_changed",
4924 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
4928 /* It could happen that we're trying to move a message from a
4929 window (msg window for example) after the main window was
4930 closed, so we can not just get the model of the folder
4932 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4933 const gchar *visible_id = NULL;
4935 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4936 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4937 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4938 MODEST_FOLDER_VIEW(tree_view));
4941 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4943 /* Show the same account than the one that is shown in the main window */
4944 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
4947 const gchar *active_account_name = NULL;
4948 ModestAccountMgr *mgr = NULL;
4949 ModestAccountSettings *settings = NULL;
4950 ModestServerAccountSettings *store_settings = NULL;
4952 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4953 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4954 modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view),
4955 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
4957 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4958 mgr = modest_runtime_get_account_mgr ();
4959 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4962 const gchar *store_account_name;
4963 store_settings = modest_account_settings_get_store_settings (settings);
4964 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4966 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
4967 store_account_name);
4968 g_object_unref (store_settings);
4969 g_object_unref (settings);
4973 /* we keep a pointer to the embedded folder view, so we can
4974 * retrieve it with get_folder_view_from_move_to_dialog (see
4975 * above) later (needed for focus handling)
4977 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
4979 /* Hide special folders */
4980 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
4981 #ifndef MODEST_TOOLKIT_HILDON2
4982 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
4985 gtk_widget_show (GTK_WIDGET (tree_view));
4991 * Shows a confirmation dialog to the user when we're moving messages
4992 * from a remote server to the local storage. Returns the dialog
4993 * response. If it's other kind of movement then it always returns
4996 * This one is used by the next functions:
4997 * modest_ui_actions_on_paste - commented out
4998 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
5001 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
5002 TnyFolder *dest_folder,
5006 gint response = GTK_RESPONSE_OK;
5007 TnyAccount *account = NULL;
5008 TnyFolder *src_folder = NULL;
5009 TnyIterator *iter = NULL;
5010 TnyHeader *header = NULL;
5012 /* return with OK if the destination is a remote folder */
5013 if (modest_tny_folder_is_remote_folder (dest_folder))
5014 return GTK_RESPONSE_OK;
5016 /* Get source folder */
5017 iter = tny_list_create_iterator (headers);
5018 header = TNY_HEADER (tny_iterator_get_current (iter));
5020 src_folder = tny_header_get_folder (header);
5021 g_object_unref (header);
5023 g_object_unref (iter);
5025 /* if no src_folder, message may be an attahcment */
5026 if (src_folder == NULL)
5027 return GTK_RESPONSE_CANCEL;
5029 /* If the source is a local or MMC folder */
5030 if (!modest_tny_folder_is_remote_folder (src_folder)) {
5031 g_object_unref (src_folder);
5032 return GTK_RESPONSE_OK;
5035 /* Get the account */
5036 account = tny_folder_get_account (src_folder);
5038 /* now if offline we ask the user */
5039 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
5040 response = GTK_RESPONSE_OK;
5042 response = GTK_RESPONSE_CANCEL;
5045 g_object_unref (src_folder);
5046 g_object_unref (account);
5052 move_to_helper_destroyer (gpointer user_data)
5054 MoveToHelper *helper = (MoveToHelper *) user_data;
5056 /* Close the "Pasting" information banner */
5057 if (helper->banner) {
5058 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5059 g_object_unref (helper->banner);
5061 if (gtk_tree_row_reference_valid (helper->reference)) {
5062 gtk_tree_row_reference_free (helper->reference);
5063 helper->reference = NULL;
5069 move_to_cb (ModestMailOperation *mail_op,
5072 MoveToHelper *helper = (MoveToHelper *) user_data;
5073 GObject *object = modest_mail_operation_get_source (mail_op);
5075 /* Note that the operation could have failed, in that case do
5077 if (modest_mail_operation_get_status (mail_op) !=
5078 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5081 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5082 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5084 if (!modest_msg_view_window_select_next_message (self) &&
5085 !modest_msg_view_window_select_previous_message (self)) {
5086 /* No more messages to view, so close this window */
5087 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5089 } else if (MODEST_IS_MAIN_WINDOW (object) &&
5090 gtk_tree_row_reference_valid (helper->reference)) {
5091 GtkWidget *header_view;
5093 GtkTreeSelection *sel;
5095 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5096 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5097 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5098 path = gtk_tree_row_reference_get_path (helper->reference);
5099 /* We need to unselect the previous one
5100 because we could be copying instead of
5102 gtk_tree_selection_unselect_all (sel);
5103 gtk_tree_selection_select_path (sel, path);
5104 gtk_tree_path_free (path);
5106 g_object_unref (object);
5109 /* Destroy the helper */
5110 move_to_helper_destroyer (helper);
5114 folder_move_to_cb (ModestMailOperation *mail_op,
5115 TnyFolder *new_folder,
5118 GtkWidget *folder_view;
5121 object = modest_mail_operation_get_source (mail_op);
5122 if (MODEST_IS_MAIN_WINDOW (object)) {
5123 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5124 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5125 g_object_ref (folder_view);
5126 g_object_unref (object);
5127 move_to_cb (mail_op, user_data);
5128 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5129 g_object_unref (folder_view);
5131 move_to_cb (mail_op, user_data);
5136 msgs_move_to_cb (ModestMailOperation *mail_op,
5139 move_to_cb (mail_op, user_data);
5143 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5146 GObject *win = NULL;
5148 #ifndef MODEST_TOOLKIT_HILDON2
5149 ModestWindow *main_window = NULL;
5151 /* Disable next automatic folder selection */
5152 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5153 FALSE); /* don't create */
5155 GtkWidget *folder_view = NULL;
5157 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5158 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5159 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5161 if (user_data && TNY_IS_FOLDER (user_data)) {
5162 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5163 TNY_FOLDER (user_data), FALSE);
5167 /* Show notification dialog only if the main window exists */
5168 win = modest_mail_operation_get_source (mail_op);
5169 modest_platform_run_information_dialog ((GtkWindow *) win,
5170 _("mail_in_ui_folder_move_target_error"),
5173 g_object_unref (win);
5177 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5186 gint pending_purges = 0;
5187 gboolean some_purged = FALSE;
5188 ModestWindow *win = MODEST_WINDOW (user_data);
5189 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5191 /* If there was any error */
5192 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5193 modest_window_mgr_unregister_header (mgr, header);
5197 /* Once the message has been retrieved for purging, we check if
5198 * it's all ok for purging */
5200 parts = tny_simple_list_new ();
5201 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5202 iter = tny_list_create_iterator (parts);
5204 while (!tny_iterator_is_done (iter)) {
5206 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5207 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5208 if (tny_mime_part_is_purged (part))
5215 g_object_unref (part);
5217 tny_iterator_next (iter);
5219 g_object_unref (iter);
5222 if (pending_purges>0) {
5224 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5226 if (response == GTK_RESPONSE_OK) {
5229 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5230 iter = tny_list_create_iterator (parts);
5231 while (!tny_iterator_is_done (iter)) {
5234 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5235 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5236 tny_mime_part_set_purged (part);
5239 g_object_unref (part);
5241 tny_iterator_next (iter);
5243 g_object_unref (iter);
5245 tny_msg_rewrite_cache (msg);
5247 gtk_widget_destroy (info);
5251 modest_window_mgr_unregister_header (mgr, header);
5253 g_object_unref (parts);
5257 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5258 ModestMainWindow *win)
5260 GtkWidget *header_view;
5261 TnyList *header_list;
5263 TnyHeaderFlags flags;
5264 ModestWindow *msg_view_window = NULL;
5267 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5269 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5270 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5272 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5274 g_warning ("%s: no header selected", __FUNCTION__);
5278 if (tny_list_get_length (header_list) == 1) {
5279 TnyIterator *iter = tny_list_create_iterator (header_list);
5280 header = TNY_HEADER (tny_iterator_get_current (iter));
5281 g_object_unref (iter);
5285 if (!header || !TNY_IS_HEADER(header)) {
5286 g_warning ("%s: header is not valid", __FUNCTION__);
5290 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5291 header, &msg_view_window);
5292 flags = tny_header_get_flags (header);
5293 if (!(flags & TNY_HEADER_FLAG_CACHED))
5296 if (msg_view_window != NULL)
5297 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5299 /* do nothing; uid was registered before, so window is probably on it's way */
5300 g_warning ("debug: header %p has already been registered", header);
5303 ModestMailOperation *mail_op = NULL;
5304 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5305 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5306 modest_ui_actions_disk_operations_error_handler,
5308 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5309 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5311 g_object_unref (mail_op);
5314 g_object_unref (header);
5316 g_object_unref (header_list);
5320 * Checks if we need a connection to do the transfer and if the user
5321 * wants to connect to complete it
5324 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5325 TnyFolderStore *src_folder,
5327 TnyFolder *dst_folder,
5328 gboolean delete_originals,
5329 gboolean *need_connection,
5332 TnyAccount *src_account;
5333 gint uncached_msgs = 0;
5335 /* We don't need any further check if
5337 * 1- the source folder is local OR
5338 * 2- the device is already online
5340 if (!modest_tny_folder_store_is_remote (src_folder) ||
5341 tny_device_is_online (modest_runtime_get_device())) {
5342 *need_connection = FALSE;
5347 /* We must ask for a connection when
5349 * - the message(s) is not already cached OR
5350 * - the message(s) is cached but the leave_on_server setting
5351 * is FALSE (because we need to sync the source folder to
5352 * delete the message from the server (for IMAP we could do it
5353 * offline, it'll take place the next time we get a
5356 uncached_msgs = header_list_count_uncached_msgs (headers);
5357 src_account = get_account_from_folder_store (src_folder);
5358 if (uncached_msgs > 0) {
5362 *need_connection = TRUE;
5363 num_headers = tny_list_get_length (headers);
5364 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5366 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5367 GTK_RESPONSE_CANCEL) {
5373 /* The transfer is possible and the user wants to */
5376 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5377 const gchar *account_name;
5378 gboolean leave_on_server;
5380 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5381 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5384 if (leave_on_server == TRUE) {
5385 *need_connection = FALSE;
5387 *need_connection = TRUE;
5390 *need_connection = FALSE;
5395 g_object_unref (src_account);
5399 xfer_messages_error_handler (ModestMailOperation *mail_op,
5403 const GError *error;
5405 win = modest_mail_operation_get_source (mail_op);
5406 error = modest_mail_operation_get_error (mail_op);
5408 if (error && is_memory_full_error ((GError *) error))
5409 modest_platform_information_banner ((GtkWidget *) win,
5410 NULL, _KR("cerm_device_memory_full"));
5412 modest_platform_run_information_dialog ((GtkWindow *) win,
5413 _("mail_in_ui_folder_move_target_error"),
5416 g_object_unref (win);
5420 TnyFolderStore *dst_folder;
5425 * Utility function that transfer messages from both the main window
5426 * and the msg view window when using the "Move to" dialog
5429 xfer_messages_performer (gboolean canceled,
5431 GtkWindow *parent_window,
5432 TnyAccount *account,
5435 ModestWindow *win = MODEST_WINDOW (parent_window);
5436 TnyAccount *dst_account = NULL;
5437 gboolean dst_forbids_message_add = FALSE;
5438 XferMsgsHelper *helper;
5439 MoveToHelper *movehelper;
5440 ModestMailOperation *mail_op;
5442 helper = (XferMsgsHelper *) user_data;
5444 if (canceled || err) {
5445 if (!check_memory_full_error ((GtkWidget *) parent_window, err)) {
5446 /* Show the proper error message */
5447 modest_ui_actions_on_account_connection_error (parent_window, account);
5452 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5454 /* tinymail will return NULL for local folders it seems */
5455 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5456 modest_tny_account_get_protocol_type (dst_account),
5457 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_MESSAGE_ADD);
5458 g_object_unref (dst_account);
5460 if (dst_forbids_message_add) {
5461 modest_platform_information_banner (GTK_WIDGET (win),
5463 ngettext("mail_in_ui_folder_move_target_error",
5464 "mail_in_ui_folder_move_targets_error",
5465 tny_list_get_length (helper->headers)));
5469 movehelper = g_new0 (MoveToHelper, 1);
5471 #ifndef MODEST_TOOLKIT_HILDON2
5472 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5473 _CS("ckct_nw_pasting"));
5474 if (movehelper->banner != NULL) {
5475 g_object_ref (movehelper->banner);
5476 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5480 if (MODEST_IS_MAIN_WINDOW (win)) {
5481 GtkWidget *header_view =
5482 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5483 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5484 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5487 /* Perform the mail operation */
5488 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5489 xfer_messages_error_handler,
5491 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5494 modest_mail_operation_xfer_msgs (mail_op,
5496 TNY_FOLDER (helper->dst_folder),
5501 g_object_unref (G_OBJECT (mail_op));
5503 g_object_unref (helper->dst_folder);
5504 g_object_unref (helper->headers);
5505 g_slice_free (XferMsgsHelper, helper);
5509 TnyFolder *src_folder;
5510 TnyFolderStore *dst_folder;
5511 gboolean delete_original;
5512 GtkWidget *folder_view;
5516 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
5517 TnyAccount *account, gpointer user_data)
5519 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5520 GtkTreeSelection *sel;
5521 ModestMailOperation *mail_op = NULL;
5523 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
5524 g_object_unref (G_OBJECT (info->src_folder));
5525 g_object_unref (G_OBJECT (info->dst_folder));
5530 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5531 #ifndef MODEST_TOOLKIT_HILDON2
5532 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5533 _CS("ckct_nw_pasting"));
5534 if (helper->banner != NULL) {
5535 g_object_ref (helper->banner);
5536 gtk_widget_show (GTK_WIDGET(helper->banner));
5539 /* Clean folder on header view before moving it */
5540 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5541 gtk_tree_selection_unselect_all (sel);
5543 /* Let gtk events run. We need that the folder
5544 view frees its reference to the source
5545 folder *before* issuing the mail operation
5546 so we need the signal handler of selection
5547 changed to happen before the mail
5549 while (gtk_events_pending ())
5550 gtk_main_iteration (); */
5553 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5554 modest_ui_actions_move_folder_error_handler,
5555 info->src_folder, NULL);
5556 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5559 /* Select *after* the changes */
5560 /* TODO: this function hangs UI after transfer */
5561 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
5562 /* TNY_FOLDER (src_folder), TRUE); */
5564 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
5565 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5566 TNY_FOLDER (info->dst_folder), TRUE);
5568 modest_mail_operation_xfer_folder (mail_op,
5569 TNY_FOLDER (info->src_folder),
5571 info->delete_original,
5574 g_object_unref (G_OBJECT (info->src_folder));
5576 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5579 /* Unref mail operation */
5580 g_object_unref (G_OBJECT (mail_op));
5581 g_object_unref (G_OBJECT (info->dst_folder));
5586 get_account_from_folder_store (TnyFolderStore *folder_store)
5588 if (TNY_IS_ACCOUNT (folder_store))
5589 return g_object_ref (folder_store);
5591 return tny_folder_get_account (TNY_FOLDER (folder_store));
5595 * UI handler for the "Move to" action when invoked from the
5599 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5600 GtkWidget *folder_view,
5601 TnyFolderStore *dst_folder,
5602 ModestMainWindow *win)
5604 ModestHeaderView *header_view = NULL;
5605 TnyFolderStore *src_folder = NULL;
5607 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5609 /* Get the source folder */
5610 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5612 /* Get header view */
5613 header_view = (ModestHeaderView *)
5614 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5616 /* Get folder or messages to transfer */
5617 if (gtk_widget_is_focus (folder_view)) {
5618 gboolean do_xfer = TRUE;
5620 /* Allow only to transfer folders to the local root folder */
5621 if (TNY_IS_ACCOUNT (dst_folder) &&
5622 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5623 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5625 } else if (!TNY_IS_FOLDER (src_folder)) {
5626 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5631 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5632 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5634 info->src_folder = g_object_ref (src_folder);
5635 info->dst_folder = g_object_ref (dst_folder);
5636 info->delete_original = TRUE;
5637 info->folder_view = folder_view;
5639 connect_info->callback = on_move_folder_cb;
5640 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5641 connect_info->data = info;
5643 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5644 TNY_FOLDER_STORE (src_folder),
5647 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5650 headers = modest_header_view_get_selected_headers(header_view);
5652 /* Transfer the messages */
5653 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
5654 headers, TNY_FOLDER (dst_folder));
5656 g_object_unref (headers);
5660 g_object_unref (src_folder);
5663 #ifdef MODEST_TOOLKIT_HILDON2
5665 * UI handler for the "Move to" action when invoked from the
5666 * ModestFolderWindow
5669 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
5670 TnyFolderStore *dst_folder,
5674 TnyFolderStore *src_folder = NULL;
5675 TnyIterator *iterator;
5677 if (tny_list_get_length (selection) != 1)
5680 iterator = tny_list_create_iterator (selection);
5681 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
5682 g_object_unref (iterator);
5685 gboolean do_xfer = TRUE;
5687 /* Allow only to transfer folders to the local root folder */
5688 if (TNY_IS_ACCOUNT (dst_folder) &&
5689 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5690 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5693 modest_platform_run_information_dialog (win,
5694 _("mail_in_ui_folder_move_target_error"),
5696 } else if (!TNY_IS_FOLDER (src_folder)) {
5697 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5702 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5703 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5705 info->src_folder = g_object_ref (src_folder);
5706 info->dst_folder = g_object_ref (dst_folder);
5707 info->delete_original = TRUE;
5708 info->folder_view = folder_view;
5710 connect_info->callback = on_move_folder_cb;
5711 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5712 connect_info->data = info;
5714 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5715 TNY_FOLDER_STORE (src_folder),
5720 g_object_unref (src_folder);
5726 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
5727 TnyFolder *src_folder,
5729 TnyFolder *dst_folder)
5731 gboolean need_connection = TRUE;
5732 gboolean do_xfer = TRUE;
5733 XferMsgsHelper *helper;
5735 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5736 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5737 g_return_if_fail (TNY_IS_LIST (headers));
5739 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5740 headers, TNY_FOLDER (dst_folder),
5741 TRUE, &need_connection,
5744 /* If we don't want to transfer just return */
5748 /* Create the helper */
5749 helper = g_slice_new (XferMsgsHelper);
5750 helper->dst_folder = g_object_ref (dst_folder);
5751 helper->headers = g_object_ref (headers);
5753 if (need_connection) {
5754 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5755 connect_info->callback = xfer_messages_performer;
5756 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5757 connect_info->data = helper;
5759 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5760 TNY_FOLDER_STORE (src_folder),
5763 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5764 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
5765 src_account, helper);
5766 g_object_unref (src_account);
5771 * UI handler for the "Move to" action when invoked from the
5772 * ModestMsgViewWindow
5775 modest_ui_actions_on_window_move_to (GtkAction *action,
5777 TnyFolderStore *dst_folder,
5780 TnyFolder *src_folder = NULL;
5782 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5785 TnyHeader *header = NULL;
5788 iter = tny_list_create_iterator (headers);
5789 header = (TnyHeader *) tny_iterator_get_current (iter);
5790 src_folder = tny_header_get_folder (header);
5792 /* Transfer the messages */
5793 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
5795 TNY_FOLDER (dst_folder));
5798 g_object_unref (header);
5799 g_object_unref (iter);
5800 g_object_unref (src_folder);
5805 modest_ui_actions_on_move_to (GtkAction *action,
5808 modest_ui_actions_on_edit_mode_move_to (win);
5812 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
5814 GtkWidget *dialog = NULL;
5815 MoveToInfo *helper = NULL;
5816 TnyList *list_to_move;
5818 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
5820 #ifndef MODEST_TOOLKIT_HILDON2
5821 /* Get the main window if exists */
5822 ModestMainWindow *main_window;
5823 if (MODEST_IS_MAIN_WINDOW (win))
5824 main_window = MODEST_MAIN_WINDOW (win);
5827 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5828 FALSE)); /* don't create */
5831 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
5836 if (tny_list_get_length (list_to_move) < 1) {
5837 g_object_unref (list_to_move);
5841 /* Create and run the dialog */
5842 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL);
5843 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
5844 GTK_WINDOW (dialog),
5848 helper = g_slice_new0 (MoveToInfo);
5849 helper->list = list_to_move;
5852 /* Listen to response signal */
5853 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
5855 /* Show the dialog */
5856 gtk_widget_show (dialog);
5862 * Calls #HeadersFunc for each header already selected in the main
5863 * window or the message currently being shown in the msg view window
5866 do_headers_action (ModestWindow *win,
5870 TnyList *headers_list = NULL;
5871 TnyIterator *iter = NULL;
5872 TnyHeader *header = NULL;
5873 TnyFolder *folder = NULL;
5876 headers_list = get_selected_headers (win);
5880 /* Get the folder */
5881 iter = tny_list_create_iterator (headers_list);
5882 header = TNY_HEADER (tny_iterator_get_current (iter));
5884 folder = tny_header_get_folder (header);
5885 g_object_unref (header);
5888 /* Call the function for each header */
5889 while (!tny_iterator_is_done (iter)) {
5890 header = TNY_HEADER (tny_iterator_get_current (iter));
5891 func (header, win, user_data);
5892 g_object_unref (header);
5893 tny_iterator_next (iter);
5896 /* Trick: do a poke status in order to speed up the signaling
5899 tny_folder_poke_status (folder);
5900 g_object_unref (folder);
5904 g_object_unref (iter);
5905 g_object_unref (headers_list);
5909 modest_ui_actions_view_attachment (GtkAction *action,
5910 ModestWindow *window)
5912 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5913 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5915 /* not supported window for this action */
5916 g_return_if_reached ();
5921 modest_ui_actions_save_attachments (GtkAction *action,
5922 ModestWindow *window)
5924 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5926 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5929 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5931 /* not supported window for this action */
5932 g_return_if_reached ();
5937 modest_ui_actions_remove_attachments (GtkAction *action,
5938 ModestWindow *window)
5940 if (MODEST_IS_MAIN_WINDOW (window)) {
5941 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
5942 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5943 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5945 /* not supported window for this action */
5946 g_return_if_reached ();
5951 modest_ui_actions_on_settings (GtkAction *action,
5956 dialog = modest_platform_get_global_settings_dialog ();
5957 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
5958 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5959 gtk_widget_show_all (dialog);
5961 gtk_dialog_run (GTK_DIALOG (dialog));
5963 gtk_widget_destroy (dialog);
5967 modest_ui_actions_on_help (GtkAction *action,
5970 /* Help app is not available at all in fremantle */
5971 #ifndef MODEST_TOOLKIT_HILDON2
5972 const gchar *help_id;
5974 g_return_if_fail (win && GTK_IS_WINDOW(win));
5976 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5979 modest_platform_show_help (GTK_WINDOW (win), help_id);
5984 modest_ui_actions_on_csm_help (GtkAction *action,
5987 /* Help app is not available at all in fremantle */
5988 #ifndef MODEST_TOOLKIT_HILDON2
5990 const gchar* help_id = NULL;
5991 GtkWidget *folder_view;
5992 TnyFolderStore *folder_store;
5994 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
5996 /* Get selected folder */
5997 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5998 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5999 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6001 /* Switch help_id */
6002 if (folder_store && TNY_IS_FOLDER (folder_store))
6003 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
6006 g_object_unref (folder_store);
6009 modest_platform_show_help (GTK_WINDOW (win), help_id);
6011 modest_ui_actions_on_help (action, win);
6016 retrieve_contents_cb (ModestMailOperation *mail_op,
6023 /* We only need this callback to show an error in case of
6024 memory low condition */
6025 modest_ui_actions_msg_retrieval_check (mail_op, header, msg);
6029 retrieve_msg_contents_performer (gboolean canceled,
6031 GtkWindow *parent_window,
6032 TnyAccount *account,
6035 ModestMailOperation *mail_op;
6036 TnyList *headers = TNY_LIST (user_data);
6038 if (err || canceled) {
6039 check_memory_full_error ((GtkWidget *) parent_window, err);
6043 /* Create mail operation */
6044 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
6045 modest_ui_actions_disk_operations_error_handler,
6047 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
6048 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
6051 g_object_unref (mail_op);
6053 g_object_unref (headers);
6054 g_object_unref (account);
6058 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
6059 ModestWindow *window)
6061 TnyList *headers = NULL;
6062 TnyAccount *account = NULL;
6063 TnyIterator *iter = NULL;
6064 TnyHeader *header = NULL;
6065 TnyFolder *folder = NULL;
6068 headers = get_selected_headers (window);
6072 /* Pick the account */
6073 iter = tny_list_create_iterator (headers);
6074 header = TNY_HEADER (tny_iterator_get_current (iter));
6075 folder = tny_header_get_folder (header);
6076 account = tny_folder_get_account (folder);
6077 g_object_unref (folder);
6078 g_object_unref (header);
6079 g_object_unref (iter);
6081 /* Connect and perform the message retrieval */
6082 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6083 g_object_ref (account),
6084 retrieve_msg_contents_performer,
6085 g_object_ref (headers));
6088 g_object_unref (account);
6089 g_object_unref (headers);
6093 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6095 g_return_if_fail (MODEST_IS_WINDOW (window));
6098 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6102 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6104 g_return_if_fail (MODEST_IS_WINDOW (window));
6107 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6111 modest_ui_actions_on_email_menu_activated (GtkAction *action,
6112 ModestWindow *window)
6114 g_return_if_fail (MODEST_IS_WINDOW (window));
6117 modest_ui_actions_check_menu_dimming_rules (window);
6121 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
6122 ModestWindow *window)
6124 g_return_if_fail (MODEST_IS_WINDOW (window));
6127 modest_ui_actions_check_menu_dimming_rules (window);
6131 modest_ui_actions_on_view_menu_activated (GtkAction *action,
6132 ModestWindow *window)
6134 g_return_if_fail (MODEST_IS_WINDOW (window));
6137 modest_ui_actions_check_menu_dimming_rules (window);
6141 modest_ui_actions_on_format_menu_activated (GtkAction *action,
6142 ModestWindow *window)
6144 g_return_if_fail (MODEST_IS_WINDOW (window));
6147 modest_ui_actions_check_menu_dimming_rules (window);
6151 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
6152 ModestWindow *window)
6154 g_return_if_fail (MODEST_IS_WINDOW (window));
6157 modest_ui_actions_check_menu_dimming_rules (window);
6161 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
6162 ModestWindow *window)
6164 g_return_if_fail (MODEST_IS_WINDOW (window));
6167 modest_ui_actions_check_menu_dimming_rules (window);
6171 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
6172 ModestWindow *window)
6174 g_return_if_fail (MODEST_IS_WINDOW (window));
6177 modest_ui_actions_check_menu_dimming_rules (window);
6181 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
6182 ModestWindow *window)
6184 g_return_if_fail (MODEST_IS_WINDOW (window));
6187 modest_ui_actions_check_menu_dimming_rules (window);
6191 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
6192 ModestWindow *window)
6194 g_return_if_fail (MODEST_IS_WINDOW (window));
6197 modest_ui_actions_check_menu_dimming_rules (window);
6201 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6203 g_return_if_fail (MODEST_IS_WINDOW (window));
6205 /* we check for low-mem; in that case, show a warning, and don't allow
6208 if (modest_platform_check_memory_low (window, TRUE))
6211 modest_platform_show_search_messages (GTK_WINDOW (window));
6215 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6217 g_return_if_fail (MODEST_IS_WINDOW (win));
6220 /* we check for low-mem; in that case, show a warning, and don't allow
6221 * for the addressbook
6223 if (modest_platform_check_memory_low (win, TRUE))
6227 modest_platform_show_addressbook (GTK_WINDOW (win));
6232 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6233 ModestWindow *window)
6236 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6238 if (GTK_IS_TOGGLE_ACTION (action))
6239 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6243 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window),
6248 on_send_receive_finished (ModestMailOperation *mail_op,
6251 GtkWidget *header_view, *folder_view;
6252 TnyFolderStore *folder_store;
6253 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6255 /* Set send/receive operation finished */
6256 modest_main_window_notify_send_receive_completed (main_win);
6258 /* Don't refresh the current folder if there were any errors */
6259 if (modest_mail_operation_get_status (mail_op) !=
6260 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6263 /* Refresh the current folder if we're viewing a window. We do
6264 this because the user won't be able to see the new mails in
6265 the selected folder after a Send&Receive because it only
6266 performs a poke_status, i.e, only the number of read/unread
6267 messages is updated, but the new headers are not
6269 folder_view = modest_main_window_get_child_widget (main_win,
6270 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6274 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6276 /* Do not need to refresh INBOX again because the
6277 update_account does it always automatically */
6278 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6279 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6280 ModestMailOperation *refresh_op;
6282 header_view = modest_main_window_get_child_widget (main_win,
6283 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6285 /* We do not need to set the contents style
6286 because it hasn't changed. We also do not
6287 need to save the widget status. Just force
6289 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6290 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6291 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6292 folder_refreshed_cb, main_win);
6293 g_object_unref (refresh_op);
6297 g_object_unref (folder_store);
6302 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6308 const gchar* server_name = NULL;
6309 TnyTransportAccount *server_account;
6310 gchar *message = NULL;
6312 /* Don't show anything if the user cancelled something or the
6313 * send receive request is not interactive. Authentication
6314 * errors are managed by the account store so no need to show
6315 * a dialog here again */
6316 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6317 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6318 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6322 /* Get the server name: */
6324 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
6326 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
6328 g_return_if_reached ();
6330 /* Show the appropriate message text for the GError: */
6331 switch (err->code) {
6332 case TNY_SERVICE_ERROR_CONNECT:
6333 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6335 case TNY_SERVICE_ERROR_SEND:
6336 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6338 case TNY_SERVICE_ERROR_UNAVAILABLE:
6339 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6342 g_warning ("%s: unexpected ERROR %d",
6343 __FUNCTION__, err->code);
6344 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6348 modest_platform_run_information_dialog (NULL, message, FALSE);
6350 g_object_unref (server_account);
6354 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6359 ModestWindow *top_window = NULL;
6360 ModestWindowMgr *mgr = NULL;
6361 GtkWidget *header_view = NULL;
6362 TnyFolder *selected_folder = NULL;
6363 TnyFolderType folder_type;
6365 mgr = modest_runtime_get_window_mgr ();
6366 top_window = modest_window_mgr_get_current_top (mgr);
6371 #ifndef MODEST_TOOLKIT_HILDON2
6372 if (MODEST_IS_MAIN_WINDOW (top_window)) {
6373 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (top_window),
6374 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6377 if (MODEST_IS_HEADER_WINDOW (top_window)) {
6378 header_view = (GtkWidget *)
6379 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
6383 /* Get selected folder */
6384 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
6385 if (!selected_folder)
6388 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6389 #if GTK_CHECK_VERSION(2, 8, 0)
6390 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
6391 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6392 GtkTreeViewColumn *tree_column;
6394 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6395 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6397 gtk_tree_view_column_queue_resize (tree_column);
6399 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
6400 gtk_widget_queue_draw (header_view);
6403 #ifndef MODEST_TOOLKIT_HILDON2
6404 /* Rerun dimming rules, because the message could become deletable for example */
6405 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6406 MODEST_DIMMING_RULES_TOOLBAR);
6407 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6408 MODEST_DIMMING_RULES_MENU);
6412 g_object_unref (selected_folder);
6416 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6417 TnyAccount *account)
6419 ModestProtocolType protocol_type;
6420 ModestProtocol *protocol;
6421 gchar *error_note = NULL;
6423 protocol_type = modest_tny_account_get_protocol_type (account);
6424 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6427 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6428 if (error_note == NULL) {
6429 g_warning ("%s: This should not be reached", __FUNCTION__);
6431 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6432 g_free (error_note);
6437 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6441 TnyFolderStore *folder = NULL;
6442 TnyAccount *account = NULL;
6443 ModestProtocolType proto;
6444 ModestProtocol *protocol;
6445 TnyHeader *header = NULL;
6447 if (MODEST_IS_MAIN_WINDOW (win)) {
6448 GtkWidget *header_view;
6449 TnyList* headers = NULL;
6451 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6452 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6453 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6454 if (!headers || tny_list_get_length (headers) == 0) {
6456 g_object_unref (headers);
6459 iter = tny_list_create_iterator (headers);
6460 header = TNY_HEADER (tny_iterator_get_current (iter));
6461 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6462 g_object_unref (iter);
6463 g_object_unref (headers);
6464 #ifdef MODEST_TOOLKIT_HILDON2
6465 } else if (MODEST_IS_HEADER_WINDOW (win)) {
6466 GtkWidget *header_view;
6467 TnyList* headers = NULL;
6469 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
6470 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6471 if (!headers || tny_list_get_length (headers) == 0) {
6473 g_object_unref (headers);
6476 iter = tny_list_create_iterator (headers);
6477 header = TNY_HEADER (tny_iterator_get_current (iter));
6478 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6479 g_object_unref (iter);
6480 g_object_unref (headers);
6482 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6483 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6484 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6487 /* Get the account type */
6488 account = tny_folder_get_account (TNY_FOLDER (folder));
6489 proto = modest_tny_account_get_protocol_type (account);
6490 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6493 subject = tny_header_dup_subject (header);
6494 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6498 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6502 g_object_unref (account);
6503 g_object_unref (folder);
6504 g_object_unref (header);
6510 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6511 const gchar *account_name,
6512 const gchar *account_title)
6514 ModestAccountMgr *account_mgr;
6517 ModestProtocol *protocol;
6518 gboolean removed = FALSE;
6520 g_return_val_if_fail (account_name, FALSE);
6521 g_return_val_if_fail (account_title, FALSE);
6523 account_mgr = modest_runtime_get_account_mgr();
6525 /* The warning text depends on the account type: */
6526 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6527 modest_account_mgr_get_store_protocol (account_mgr,
6529 txt = modest_protocol_get_translation (protocol,
6530 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6533 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6535 response = modest_platform_run_confirmation_dialog (parent_window, txt);
6539 if (response == GTK_RESPONSE_OK) {
6540 /* Remove account. If it succeeds then it also removes
6541 the account from the ModestAccountView: */
6542 gboolean is_default = FALSE;
6543 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6544 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6546 g_free (default_account_name);
6548 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6550 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);