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 ModestWindow *old_win;
243 win = MODEST_WINDOW (modest_accounts_window_new ());
244 if (modest_window_mgr_register_window (mgr, win, NULL)) {
245 gtk_widget_show_all (GTK_WIDGET (win));
247 gtk_widget_destroy (GTK_WIDGET (win));
252 win = MODEST_WINDOW (modest_folder_window_new (NULL));
253 if (modest_window_mgr_register_window (mgr, win, NULL)) {
254 gtk_widget_show_all (GTK_WIDGET (win));
256 gtk_widget_destroy (GTK_WIDGET (win));
260 g_list_free (window_list);
266 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
268 /* make sure the mainwindow is visible. We need to present the
269 wizard again to give it the focus back. show_all are needed
270 in order to get the widgets properly drawn (MainWindow main
271 paned won't be in its right position and the dialog will be
273 #ifndef MODEST_TOOLKIT_HILDON2
274 gtk_widget_show_all (GTK_WIDGET (win));
275 gtk_widget_show_all (GTK_WIDGET (wizard));
276 gtk_window_present (GTK_WINDOW (win));
277 gtk_window_present (GTK_WINDOW (wizard));
280 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
281 gtk_widget_destroy (GTK_WIDGET (wizard));
282 if (gtk_events_pending ())
283 gtk_main_iteration ();
285 if (dialog_response == GTK_RESPONSE_CANCEL) {
288 /* Check whether an account was created: */
289 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
296 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
299 const gchar *authors[] = {
300 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
303 about = gtk_about_dialog_new ();
304 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
305 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
306 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
307 _("Copyright (c) 2006, Nokia Corporation\n"
308 "All rights reserved."));
309 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
310 _("a modest e-mail client\n\n"
311 "design and implementation: Dirk-Jan C. Binnema\n"
312 "contributions from the fine people at KC and Ig\n"
313 "uses the tinymail email framework written by Philip van Hoof"));
314 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
315 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
316 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
317 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
319 gtk_dialog_run (GTK_DIALOG (about));
320 gtk_widget_destroy(about);
324 * Gets the list of currently selected messages. If the win is the
325 * main window, then it returns a newly allocated list of the headers
326 * selected in the header view. If win is the msg view window, then
327 * the value returned is a list with just a single header.
329 * The caller of this funcion must free the list.
332 get_selected_headers (ModestWindow *win)
334 if (MODEST_IS_MAIN_WINDOW(win)) {
335 GtkWidget *header_view;
337 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
338 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
339 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
341 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
342 /* for MsgViewWindows, we simply return a list with one element */
344 TnyList *list = NULL;
346 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
347 if (header != NULL) {
348 list = tny_simple_list_new ();
349 tny_list_prepend (list, G_OBJECT(header));
350 g_object_unref (G_OBJECT(header));
355 #ifdef MODEST_TOOLKIT_HILDON2
356 } else if (MODEST_IS_HEADER_WINDOW (win)) {
357 GtkWidget *header_view;
359 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
360 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
366 static GtkTreeRowReference *
367 get_next_after_selected_headers (ModestHeaderView *header_view)
369 GtkTreeSelection *sel;
370 GList *selected_rows, *node;
372 GtkTreeRowReference *result;
375 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
376 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
377 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
379 if (selected_rows == NULL)
382 node = g_list_last (selected_rows);
383 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
384 gtk_tree_path_next (path);
386 result = gtk_tree_row_reference_new (model, path);
388 gtk_tree_path_free (path);
389 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
390 g_list_free (selected_rows);
396 headers_action_mark_as_read (TnyHeader *header,
400 TnyHeaderFlags flags;
402 g_return_if_fail (TNY_IS_HEADER(header));
404 flags = tny_header_get_flags (header);
405 if (flags & TNY_HEADER_FLAG_SEEN) return;
406 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
410 headers_action_mark_as_unread (TnyHeader *header,
414 TnyHeaderFlags flags;
416 g_return_if_fail (TNY_IS_HEADER(header));
418 flags = tny_header_get_flags (header);
419 if (flags & TNY_HEADER_FLAG_SEEN) {
420 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
424 /** After deleing a message that is currently visible in a window,
425 * show the next message from the list, or close the window if there are no more messages.
428 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
430 /* Close msg view window or select next */
431 if (!modest_msg_view_window_select_next_message (win) &&
432 !modest_msg_view_window_select_previous_message (win)) {
434 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
440 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
442 modest_ui_actions_on_edit_mode_delete_message (win);
446 modest_ui_actions_on_edit_mode_delete_message (ModestWindow *win)
448 TnyList *header_list = NULL;
449 TnyIterator *iter = NULL;
450 TnyHeader *header = NULL;
451 gchar *message = NULL;
454 ModestWindowMgr *mgr;
455 GtkWidget *header_view = NULL;
456 gboolean retval = TRUE;
458 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
460 /* Check first if the header view has the focus */
461 if (MODEST_IS_MAIN_WINDOW (win)) {
463 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
464 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
465 if (!gtk_widget_is_focus (header_view))
469 /* Get the headers, either from the header view (if win is the main window),
470 * or from the message view window: */
471 header_list = get_selected_headers (win);
472 if (!header_list) return FALSE;
474 /* Check if any of the headers are already opened, or in the process of being opened */
475 if (MODEST_IS_MAIN_WINDOW (win)) {
476 gint opened_headers = 0;
478 iter = tny_list_create_iterator (header_list);
479 mgr = modest_runtime_get_window_mgr ();
480 while (!tny_iterator_is_done (iter)) {
481 header = TNY_HEADER (tny_iterator_get_current (iter));
483 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
485 g_object_unref (header);
487 tny_iterator_next (iter);
489 g_object_unref (iter);
491 if (opened_headers > 0) {
494 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
497 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg, FALSE);
500 g_object_unref (header_list);
506 if (tny_list_get_length(header_list) == 1) {
507 iter = tny_list_create_iterator (header_list);
508 header = TNY_HEADER (tny_iterator_get_current (iter));
511 subject = tny_header_dup_subject (header);
513 subject = g_strdup (_("mail_va_no_subject"));
514 desc = g_strdup_printf ("%s", subject);
516 g_object_unref (header);
519 g_object_unref (iter);
521 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
522 tny_list_get_length(header_list)), desc);
524 /* Confirmation dialog */
525 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
529 if (response == GTK_RESPONSE_OK) {
530 ModestWindow *main_window = NULL;
531 ModestWindowMgr *mgr = NULL;
532 GtkTreeModel *model = NULL;
533 GtkTreeSelection *sel = NULL;
534 GList *sel_list = NULL, *tmp = NULL;
535 GtkTreeRowReference *next_row_reference = NULL;
536 GtkTreeRowReference *prev_row_reference = NULL;
537 GtkTreePath *next_path = NULL;
538 GtkTreePath *prev_path = NULL;
539 ModestMailOperation *mail_op = NULL;
541 /* Find last selected row */
542 if (MODEST_IS_MAIN_WINDOW (win)) {
543 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
544 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
545 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
546 for (tmp=sel_list; tmp; tmp=tmp->next) {
547 if (tmp->next == NULL) {
548 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
549 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
551 gtk_tree_path_prev (prev_path);
552 gtk_tree_path_next (next_path);
554 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
555 next_row_reference = gtk_tree_row_reference_new (model, next_path);
560 /* Disable window dimming management */
561 modest_window_disable_dimming (MODEST_WINDOW(win));
563 /* Remove each header. If it's a view window header_view == NULL */
564 mail_op = modest_mail_operation_new ((GObject *) win);
565 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
567 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
568 g_object_unref (mail_op);
570 /* Enable window dimming management */
572 gtk_tree_selection_unselect_all (sel);
574 modest_window_enable_dimming (MODEST_WINDOW(win));
576 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
577 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
579 /* Get main window */
580 mgr = modest_runtime_get_window_mgr ();
581 main_window = modest_window_mgr_get_main_window (mgr, FALSE); /* don't create */
582 } else if (MODEST_IS_MAIN_WINDOW (win)) {
583 /* Move cursor to next row */
586 /* Select next or previous row */
587 if (gtk_tree_row_reference_valid (next_row_reference)) {
588 gtk_tree_selection_select_path (sel, next_path);
590 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
591 gtk_tree_selection_select_path (sel, prev_path);
595 if (gtk_tree_row_reference_valid (next_row_reference))
596 gtk_tree_row_reference_free (next_row_reference);
597 if (next_path != NULL)
598 gtk_tree_path_free (next_path);
599 if (gtk_tree_row_reference_valid (prev_row_reference))
600 gtk_tree_row_reference_free (prev_row_reference);
601 if (prev_path != NULL)
602 gtk_tree_path_free (prev_path);
605 /* Update toolbar dimming state */
607 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
608 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
612 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
613 g_list_free (sel_list);
622 g_object_unref (header_list);
630 /* delete either message or folder, based on where we are */
632 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
634 g_return_if_fail (MODEST_IS_WINDOW(win));
636 /* Check first if the header view has the focus */
637 if (MODEST_IS_MAIN_WINDOW (win)) {
639 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
640 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
641 if (gtk_widget_is_focus (w)) {
642 modest_ui_actions_on_delete_folder (action, MODEST_WINDOW(win));
646 modest_ui_actions_on_delete_message (action, win);
650 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
652 ModestWindowMgr *mgr = NULL;
654 #ifdef MODEST_PLATFORM_MAEMO
655 modest_osso_save_state();
656 #endif /* MODEST_PLATFORM_MAEMO */
658 g_debug ("closing down, clearing %d item(s) from operation queue",
659 modest_mail_operation_queue_num_elements
660 (modest_runtime_get_mail_operation_queue()));
662 /* cancel all outstanding operations */
663 modest_mail_operation_queue_cancel_all
664 (modest_runtime_get_mail_operation_queue());
666 g_debug ("queue has been cleared");
669 /* Check if there are opened editing windows */
670 mgr = modest_runtime_get_window_mgr ();
671 modest_window_mgr_close_all_windows (mgr);
673 /* note: when modest-tny-account-store is finalized,
674 it will automatically set all network connections
677 /* gtk_main_quit (); */
681 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
685 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
687 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
688 /* gtk_widget_destroy (GTK_WIDGET (win)); */
689 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
690 /* gboolean ret_value; */
691 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
692 /* } else if (MODEST_IS_WINDOW (win)) { */
693 /* gtk_widget_destroy (GTK_WIDGET (win)); */
695 /* g_return_if_reached (); */
700 modest_ui_actions_add_to_contacts (GtkAction *action, ModestWindow *win)
702 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
704 modest_msg_view_window_add_to_contacts (MODEST_MSG_VIEW_WINDOW (win));
708 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
710 GtkClipboard *clipboard = NULL;
711 gchar *selection = NULL;
713 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
714 selection = gtk_clipboard_wait_for_text (clipboard);
716 /* Question: why is the clipboard being used here?
717 * It doesn't really make a lot of sense. */
721 modest_address_book_add_address (selection);
727 modest_ui_actions_on_new_account (GtkAction *action,
728 ModestWindow *window)
730 modest_ui_actions_run_account_setup_wizard (window);
734 modest_ui_actions_on_accounts (GtkAction *action,
737 /* This is currently only implemented for Maemo */
738 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
739 if (!modest_ui_actions_run_account_setup_wizard (win))
740 g_debug ("%s: wizard was already running", __FUNCTION__);
744 /* Show the list of accounts */
745 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
747 /* The accounts dialog must be modal */
748 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
749 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
754 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
756 /* This is currently only implemented for Maemo,
757 * because it requires an API (libconic) to detect different connection
760 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
762 /* Create the window if necessary: */
763 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
764 modest_connection_specific_smtp_window_fill_with_connections (
765 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
766 modest_runtime_get_account_mgr());
768 /* Show the window: */
769 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
770 GTK_WINDOW (specific_window), (GtkWindow *) win);
771 gtk_widget_show (specific_window);
772 #endif /* !MODEST_TOOLKIT_GTK */
776 modest_ui_actions_compose_msg(ModestWindow *win,
779 const gchar *bcc_str,
780 const gchar *subject_str,
781 const gchar *body_str,
783 gboolean set_as_modified)
785 gchar *account_name = NULL;
787 TnyAccount *account = NULL;
788 TnyFolder *folder = NULL;
789 gchar *from_str = NULL, *signature = NULL, *body = NULL;
790 gboolean use_signature = FALSE;
791 ModestWindow *msg_win = NULL;
792 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
793 ModestTnyAccountStore *store = modest_runtime_get_account_store();
794 GnomeVFSFileSize total_size, allowed_size;
796 /* we check for low-mem */
797 if (modest_platform_check_memory_low (win, TRUE))
800 #ifdef MODEST_TOOLKIT_HILDON2
801 account_name = g_strdup (modest_window_get_active_account(win));
804 account_name = modest_account_mgr_get_default_account(mgr);
807 g_printerr ("modest: no account found\n");
810 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
812 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
815 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
817 g_printerr ("modest: failed to find Drafts folder\n");
820 from_str = modest_account_mgr_get_from_string (mgr, account_name);
822 g_printerr ("modest: failed get from string for '%s'\n", account_name);
826 signature = modest_account_mgr_get_signature (mgr, account_name, &use_signature);
827 if (body_str != NULL) {
828 body = use_signature ? g_strconcat(body_str, "\n--\n", signature, NULL) : g_strdup(body_str);
830 body = use_signature ? g_strconcat("\n--\n", signature, NULL) : g_strdup("");
833 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, body, NULL, NULL, NULL);
835 g_printerr ("modest: failed to create new msg\n");
839 /* Create and register edit window */
840 /* This is destroyed by TODO. */
842 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
843 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
845 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, win)) {
846 gtk_widget_destroy (GTK_WIDGET (msg_win));
849 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
850 gtk_widget_show_all (GTK_WIDGET (msg_win));
852 while (attachments) {
854 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
855 attachments->data, allowed_size);
857 if (total_size > allowed_size) {
858 g_warning ("%s: total size: %u",
859 __FUNCTION__, (unsigned int)total_size);
862 allowed_size -= total_size;
864 attachments = g_slist_next(attachments);
871 g_free (account_name);
873 g_object_unref (G_OBJECT(account));
875 g_object_unref (G_OBJECT(folder));
877 g_object_unref (G_OBJECT(msg));
881 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
883 /* if there are no accounts yet, just show the wizard */
884 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
885 if (!modest_ui_actions_run_account_setup_wizard (win))
888 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
893 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
897 ModestMailOperationStatus status;
899 /* If there is no message or the operation was not successful */
900 status = modest_mail_operation_get_status (mail_op);
901 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
904 /* If it's a memory low issue, then show a banner */
905 error = modest_mail_operation_get_error (mail_op);
906 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
907 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
908 GObject *source = modest_mail_operation_get_source (mail_op);
909 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
910 _KR("memr_ib_operation_disabled"),
912 g_object_unref (source);
915 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
916 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
917 gchar *subject, *msg, *format = NULL;
919 subject = tny_header_dup_subject (header);
921 subject = g_strdup (_("mail_va_no_subject"));
923 account = modest_mail_operation_get_account (mail_op);
925 ModestProtocol *protocol;
926 ModestProtocolType proto;
927 proto = modest_tny_account_get_protocol_type (account);
928 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), proto);
930 format = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
931 g_object_unref (account);
935 format = g_strdup (_("emev_ni_ui_imap_message_not_available_in_server"));
937 msg = g_strdup_printf (format, subject);
938 modest_platform_run_information_dialog (NULL, msg, FALSE);
944 /* Remove the header from the preregistered uids */
945 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
963 OpenMsgBannerInfo *banner_info;
964 GtkTreeRowReference *rowref;
968 open_msg_banner_idle (gpointer userdata)
970 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
972 gdk_threads_enter ();
973 banner_info->idle_handler = 0;
974 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
976 g_object_ref (banner_info->banner);
978 gdk_threads_leave ();
985 get_header_view_from_window (ModestWindow *window)
987 GtkWidget *header_view;
989 if (MODEST_IS_MAIN_WINDOW (window)) {
990 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
991 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
992 #ifdef MODEST_TOOLKIT_HILDON2
993 } else if (MODEST_IS_HEADER_WINDOW (window)){
994 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
1004 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
1007 gchar *account = NULL;
1008 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
1013 folder = tny_header_get_folder (header);
1014 /* Gets folder type (OUTBOX headers will be opened in edit window */
1015 if (modest_tny_folder_is_local_folder (folder)) {
1016 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1017 if (folder_type == TNY_FOLDER_TYPE_INVALID)
1018 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1021 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
1022 TnyTransportAccount *traccount = NULL;
1023 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
1024 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
1026 ModestTnySendQueue *send_queue = NULL;
1027 ModestTnySendQueueStatus status;
1029 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
1030 TNY_ACCOUNT(traccount)));
1031 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
1032 if (TNY_IS_SEND_QUEUE (send_queue)) {
1033 msg_id = modest_tny_send_queue_get_msg_id (header);
1034 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
1036 /* Only open messages in outbox with the editor if they are in Failed state */
1037 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
1040 #ifdef MODEST_TOOLKIT_HILDON2
1042 /* In Fremantle we can not
1043 open any message from
1044 outbox which is not in
1050 g_object_unref(traccount);
1052 g_warning("Cannot get transport account for message in outbox!!");
1054 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
1055 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
1059 TnyAccount *acc = tny_folder_get_account (folder);
1062 g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (acc));
1063 g_object_unref (acc);
1067 g_object_unref (folder);
1073 open_msg_cb (ModestMailOperation *mail_op,
1080 ModestWindowMgr *mgr = NULL;
1081 ModestWindow *parent_win = NULL;
1082 ModestWindow *win = NULL;
1083 gchar *account = NULL;
1084 gboolean open_in_editor = FALSE;
1086 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1088 /* Do nothing if there was any problem with the mail
1089 operation. The error will be shown by the error_handler of
1090 the mail operation */
1091 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1094 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1096 /* Mark header as read */
1097 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1099 account = get_info_from_header (header, &open_in_editor, &can_open);
1103 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1105 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1107 if (open_in_editor) {
1108 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1109 gchar *from_header = NULL, *acc_name;
1111 from_header = tny_header_dup_from (header);
1113 /* we cannot edit without a valid account... */
1114 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1115 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1116 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1118 g_free (from_header);
1123 acc_name = modest_utils_get_account_name_from_recipient (from_header);
1124 g_free (from_header);
1130 win = modest_msg_edit_window_new (msg, account, TRUE);
1132 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1134 if (helper->rowref && helper->model) {
1135 win = modest_msg_view_window_new_with_header_model (msg, account, (const gchar*) uid,
1136 helper->model, helper->rowref);
1138 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
1143 /* Register and show new window */
1145 mgr = modest_runtime_get_window_mgr ();
1146 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1147 gtk_widget_destroy (GTK_WIDGET (win));
1150 gtk_widget_show_all (GTK_WIDGET(win));
1153 /* Update toolbar dimming state */
1154 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1155 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1161 g_object_unref (parent_win);
1165 is_memory_full_error (GError *error)
1167 gboolean enough_free_space = TRUE;
1168 GnomeVFSURI *cache_dir_uri;
1169 const gchar *cache_dir;
1170 GnomeVFSFileSize free_space;
1172 cache_dir = tny_account_store_get_cache_dir (TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
1173 cache_dir_uri = gnome_vfs_uri_new (cache_dir);
1174 if (gnome_vfs_get_volume_free_space (cache_dir_uri, &free_space) == GNOME_VFS_OK) {
1175 if (free_space < MIN_FREE_SPACE)
1176 enough_free_space = FALSE;
1178 gnome_vfs_uri_unref (cache_dir_uri);
1180 if ((error->code == TNY_SYSTEM_ERROR_MEMORY ||
1181 /* When asking for a mail and no space left on device
1182 tinymail returns this error */
1183 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE ||
1184 /* When the folder summary could not be read or
1186 error->code == TNY_IO_ERROR_WRITE ||
1187 error->code == TNY_IO_ERROR_READ) &&
1188 !enough_free_space) {
1196 check_memory_full_error (GtkWidget *parent_window, GError *err)
1201 if (is_memory_full_error (err))
1202 modest_platform_information_banner (parent_window,
1203 NULL, _KR("cerm_device_memory_full"));
1204 else if (err->code == TNY_SYSTEM_ERROR_MEMORY)
1205 /* If the account was created in memory full
1206 conditions then tinymail won't be able to
1207 connect so it'll return this error code */
1208 modest_platform_information_banner (parent_window,
1209 NULL, _("emev_ui_imap_inbox_select_error"));
1217 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1220 const GError *error;
1221 GObject *win = NULL;
1222 ModestMailOperationStatus status;
1224 win = modest_mail_operation_get_source (mail_op);
1225 error = modest_mail_operation_get_error (mail_op);
1226 status = modest_mail_operation_get_status (mail_op);
1228 /* If the mail op has been cancelled then it's not an error:
1229 don't show any message */
1230 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1231 if (is_memory_full_error ((GError *) error)) {
1232 modest_platform_information_banner ((GtkWidget *) win,
1233 NULL, _KR("cerm_device_memory_full"));
1234 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1235 modest_platform_information_banner ((GtkWidget *) win,
1236 NULL, _("emev_ui_imap_inbox_select_error"));
1237 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1238 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1239 modest_platform_information_banner ((GtkWidget *) win,
1240 NULL, _CS ("sfil_ni_unable_to_open_file_not_found"));
1241 } else if (user_data) {
1242 modest_platform_information_banner ((GtkWidget *) win,
1248 g_object_unref (win);
1252 * Returns the account a list of headers belongs to. It returns a
1253 * *new* reference so don't forget to unref it
1256 get_account_from_header_list (TnyList *headers)
1258 TnyAccount *account = NULL;
1260 if (tny_list_get_length (headers) > 0) {
1261 TnyIterator *iter = tny_list_create_iterator (headers);
1262 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1263 TnyFolder *folder = tny_header_get_folder (header);
1266 g_object_unref (header);
1268 while (!tny_iterator_is_done (iter)) {
1269 header = TNY_HEADER (tny_iterator_get_current (iter));
1270 folder = tny_header_get_folder (header);
1273 g_object_unref (header);
1275 tny_iterator_next (iter);
1280 account = tny_folder_get_account (folder);
1281 g_object_unref (folder);
1285 g_object_unref (header);
1287 g_object_unref (iter);
1293 get_account_from_header (TnyHeader *header)
1295 TnyAccount *account = NULL;
1298 folder = tny_header_get_folder (header);
1301 account = tny_folder_get_account (folder);
1302 g_object_unref (folder);
1308 open_msg_helper_destroyer (gpointer user_data)
1310 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1312 if (helper->banner_info) {
1313 g_free (helper->banner_info->message);
1314 if (helper->banner_info->idle_handler > 0) {
1315 g_source_remove (helper->banner_info->idle_handler);
1316 helper->banner_info->idle_handler = 0;
1318 if (helper->banner_info->banner != NULL) {
1319 gtk_widget_destroy (helper->banner_info->banner);
1320 g_object_unref (helper->banner_info->banner);
1321 helper->banner_info->banner = NULL;
1323 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1324 helper->banner_info = NULL;
1326 g_object_unref (helper->model);
1327 g_object_unref (helper->header);
1328 gtk_tree_row_reference_free (helper->rowref);
1329 g_slice_free (OpenMsgHelper, helper);
1333 open_msg_performer(gboolean canceled,
1335 GtkWindow *parent_window,
1336 TnyAccount *account,
1339 ModestMailOperation *mail_op = NULL;
1341 ModestProtocolType proto;
1342 TnyConnectionStatus status;
1343 OpenMsgHelper *helper = NULL;
1344 ModestProtocol *protocol;
1345 ModestProtocolRegistry *protocol_registry;
1348 helper = (OpenMsgHelper *) user_data;
1350 status = tny_account_get_connection_status (account);
1351 if (err || canceled) {
1352 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1353 /* Free the helper */
1354 open_msg_helper_destroyer (helper);
1356 /* In memory full conditions we could get this error here */
1357 check_memory_full_error ((GtkWidget *) parent_window, err);
1362 /* Get the error message depending on the protocol */
1363 proto = modest_tny_account_get_protocol_type (account);
1364 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1365 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1368 protocol_registry = modest_runtime_get_protocol_registry ();
1369 subject = tny_header_dup_subject (helper->header);
1371 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1372 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1376 if (error_msg == NULL) {
1377 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1380 #ifndef MODEST_TOOLKIT_HILDON2
1381 gboolean show_open_draft = FALSE;
1382 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1384 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1386 TnyFolderType folder_type;
1388 folder = tny_header_get_folder (helper->header);
1389 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1390 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1391 g_object_unref (folder);
1395 #ifdef MODEST_TOOLKIT_HILDON2
1398 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1401 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1402 g_free (account_name);
1403 open_msg_helper_destroyer (helper);
1408 ModestWindow *window;
1409 GtkWidget *header_view;
1412 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1413 uid = modest_tny_folder_get_header_unique_id (helper->header);
1415 window = modest_msg_view_window_new_from_header_view
1416 (MODEST_HEADER_VIEW (header_view), account_name, uid, helper->rowref);
1417 if (window != NULL) {
1418 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1420 gtk_widget_destroy (GTK_WIDGET (window));
1422 gtk_widget_show_all (GTK_WIDGET(window));
1426 g_free (account_name);
1428 open_msg_helper_destroyer (helper);
1431 g_free (account_name);
1433 /* Create the mail operation */
1435 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1436 modest_ui_actions_disk_operations_error_handler,
1438 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1442 #ifndef MODEST_TOOLKIT_HILDON2
1443 if (show_open_draft) {
1444 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1445 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1446 helper->banner_info->banner = NULL;
1447 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1448 helper->banner_info);
1454 headers = TNY_LIST (tny_simple_list_new ());
1455 tny_list_prepend (headers, G_OBJECT (helper->header));
1456 modest_mail_operation_get_msgs_full (mail_op,
1460 open_msg_helper_destroyer);
1461 g_object_unref (headers);
1466 g_object_unref (mail_op);
1467 g_object_unref (account);
1471 * This function is used by both modest_ui_actions_on_open and
1472 * modest_ui_actions_on_header_activated. This way we always do the
1473 * same when trying to open messages.
1476 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1478 ModestWindowMgr *mgr = NULL;
1479 TnyAccount *account;
1480 gboolean cached = FALSE;
1482 GtkWidget *header_view = NULL;
1483 OpenMsgHelper *helper;
1484 ModestWindow *window;
1486 g_return_if_fail (header != NULL && rowref != NULL);
1488 mgr = modest_runtime_get_window_mgr ();
1491 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1492 if (header_view == NULL)
1495 /* Get the account */
1496 account = get_account_from_header (header);
1501 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1503 /* Do not open again the message and present the
1504 window to the user */
1507 #ifndef MODEST_TOOLKIT_HILDON2
1508 gtk_window_present (GTK_WINDOW (window));
1511 /* the header has been registered already, we don't do
1512 * anything but wait for the window to come up*/
1513 g_debug ("header %p already registered, waiting for window", header);
1518 /* Open each message */
1519 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1521 /* Allways download if we are online. */
1522 if (!tny_device_is_online (modest_runtime_get_device ())) {
1525 /* If ask for user permission to download the messages */
1526 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1527 _("mcen_nc_get_msg"));
1529 /* End if the user does not want to continue */
1530 if (response == GTK_RESPONSE_CANCEL) {
1536 /* We register the window for opening */
1537 modest_window_mgr_register_header (mgr, header, NULL);
1539 /* Create the helper. We need to get a reference to the model
1540 here because it could change while the message is readed
1541 (the user could switch between folders) */
1542 helper = g_slice_new (OpenMsgHelper);
1543 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1544 helper->header = g_object_ref (header);
1545 helper->rowref = gtk_tree_row_reference_copy (rowref);
1546 helper->banner_info = NULL;
1548 /* Connect to the account and perform */
1550 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1551 open_msg_performer, helper);
1553 /* Call directly the performer, do not need to connect */
1554 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1555 g_object_ref (account), helper);
1560 g_object_unref (account);
1564 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1571 /* we check for low-mem; in that case, show a warning, and don't allow
1574 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1578 headers = get_selected_headers (win);
1582 headers_count = tny_list_get_length (headers);
1583 if (headers_count != 1) {
1584 if (headers_count > 1) {
1585 /* Don't allow activation if there are more than one message selected */
1586 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1589 g_object_unref (headers);
1593 iter = tny_list_create_iterator (headers);
1594 header = TNY_HEADER (tny_iterator_get_current (iter));
1595 g_object_unref (iter);
1599 open_msg_from_header (header, NULL, win);
1600 g_object_unref (header);
1603 g_object_unref(headers);
1607 rf_helper_window_closed (gpointer data,
1610 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1612 helper->parent_window = NULL;
1615 static ReplyForwardHelper*
1616 create_reply_forward_helper (ReplyForwardAction action,
1618 guint reply_forward_type,
1621 ReplyForwardHelper *rf_helper = NULL;
1622 const gchar *active_acc = modest_window_get_active_account (win);
1624 rf_helper = g_slice_new0 (ReplyForwardHelper);
1625 rf_helper->reply_forward_type = reply_forward_type;
1626 rf_helper->action = action;
1627 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1628 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1629 rf_helper->account_name = (active_acc) ?
1630 g_strdup (active_acc) :
1631 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1633 /* Note that window could be destroyed just AFTER calling
1634 register_window so we must ensure that this pointer does
1635 not hold invalid references */
1636 if (rf_helper->parent_window)
1637 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1638 rf_helper_window_closed, rf_helper);
1644 free_reply_forward_helper (gpointer data)
1646 ReplyForwardHelper *helper;
1648 helper = (ReplyForwardHelper *) data;
1649 g_free (helper->account_name);
1651 g_object_unref (helper->header);
1652 if (helper->parent_window)
1653 g_object_weak_unref (G_OBJECT (helper->parent_window),
1654 rf_helper_window_closed, helper);
1655 g_slice_free (ReplyForwardHelper, helper);
1659 reply_forward_cb (ModestMailOperation *mail_op,
1666 TnyMsg *new_msg = NULL;
1667 ReplyForwardHelper *rf_helper;
1668 ModestWindow *msg_win = NULL;
1669 ModestEditType edit_type;
1671 TnyAccount *account = NULL;
1672 ModestWindowMgr *mgr = NULL;
1673 gchar *signature = NULL;
1674 gboolean use_signature;
1676 /* If there was any error. The mail operation could be NULL,
1677 this means that we already have the message downloaded and
1678 that we didn't do a mail operation to retrieve it */
1679 rf_helper = (ReplyForwardHelper *) user_data;
1680 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1683 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1684 rf_helper->account_name);
1685 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr(),
1686 rf_helper->account_name,
1689 /* Create reply mail */
1690 switch (rf_helper->action) {
1693 modest_tny_msg_create_reply_msg (msg, header, from,
1694 (use_signature) ? signature : NULL,
1695 rf_helper->reply_forward_type,
1696 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1698 case ACTION_REPLY_TO_ALL:
1700 modest_tny_msg_create_reply_msg (msg, header, from,
1701 (use_signature) ? signature : NULL,
1702 rf_helper->reply_forward_type,
1703 MODEST_TNY_MSG_REPLY_MODE_ALL);
1704 edit_type = MODEST_EDIT_TYPE_REPLY;
1706 case ACTION_FORWARD:
1708 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1709 rf_helper->reply_forward_type);
1710 edit_type = MODEST_EDIT_TYPE_FORWARD;
1713 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1715 g_return_if_reached ();
1723 g_warning ("%s: failed to create message\n", __FUNCTION__);
1727 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1728 rf_helper->account_name,
1729 TNY_ACCOUNT_TYPE_STORE);
1731 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1735 /* Create and register the windows */
1736 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1737 mgr = modest_runtime_get_window_mgr ();
1738 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1740 /* Note that register_window could have deleted the account */
1741 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1742 gdouble parent_zoom;
1744 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1745 modest_window_set_zoom (msg_win, parent_zoom);
1748 /* Show edit window */
1749 gtk_widget_show_all (GTK_WIDGET (msg_win));
1752 /* We always unregister the header because the message is
1753 forwarded or replied so the original one is no longer
1755 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1758 g_object_unref (G_OBJECT (new_msg));
1760 g_object_unref (G_OBJECT (account));
1761 free_reply_forward_helper (rf_helper);
1764 /* Checks a list of headers. If any of them are not currently
1765 * downloaded (CACHED) then returns TRUE else returns FALSE.
1768 header_list_count_uncached_msgs (TnyList *header_list)
1771 gint uncached_messages = 0;
1773 iter = tny_list_create_iterator (header_list);
1774 while (!tny_iterator_is_done (iter)) {
1777 header = TNY_HEADER (tny_iterator_get_current (iter));
1779 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1780 uncached_messages ++;
1781 g_object_unref (header);
1784 tny_iterator_next (iter);
1786 g_object_unref (iter);
1788 return uncached_messages;
1791 /* Returns FALSE if the user does not want to download the
1792 * messages. Returns TRUE if the user allowed the download.
1795 connect_to_get_msg (ModestWindow *win,
1796 gint num_of_uncached_msgs,
1797 TnyAccount *account)
1799 GtkResponseType response;
1801 /* Allways download if we are online. */
1802 if (tny_device_is_online (modest_runtime_get_device ()))
1805 /* If offline, then ask for user permission to download the messages */
1806 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1807 ngettext("mcen_nc_get_msg",
1809 num_of_uncached_msgs));
1811 if (response == GTK_RESPONSE_CANCEL)
1814 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1818 reply_forward_performer (gboolean canceled,
1820 GtkWindow *parent_window,
1821 TnyAccount *account,
1824 ReplyForwardHelper *rf_helper = NULL;
1825 ModestMailOperation *mail_op;
1827 rf_helper = (ReplyForwardHelper *) user_data;
1829 if (canceled || err) {
1830 free_reply_forward_helper (rf_helper);
1834 /* Retrieve the message */
1835 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1836 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1837 modest_ui_actions_disk_operations_error_handler,
1839 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1840 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1843 g_object_unref(mail_op);
1847 * Common code for the reply and forward actions
1850 reply_forward (ReplyForwardAction action, ModestWindow *win)
1852 ReplyForwardHelper *rf_helper = NULL;
1853 guint reply_forward_type;
1855 g_return_if_fail (MODEST_IS_WINDOW(win));
1857 /* we check for low-mem; in that case, show a warning, and don't allow
1858 * reply/forward (because it could potentially require a lot of memory */
1859 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1863 /* we need an account when editing */
1864 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1865 if (!modest_ui_actions_run_account_setup_wizard (win))
1869 reply_forward_type =
1870 modest_conf_get_int (modest_runtime_get_conf (),
1871 (action == ACTION_FORWARD) ?
1872 MODEST_CONF_FORWARD_TYPE :
1873 MODEST_CONF_REPLY_TYPE,
1876 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1878 TnyHeader *header = NULL;
1879 /* Get header and message. Do not free them here, the
1880 reply_forward_cb must do it */
1881 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1882 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1884 if (msg && header) {
1886 rf_helper = create_reply_forward_helper (action, win,
1887 reply_forward_type, header);
1888 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1890 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1894 g_object_unref (msg);
1896 g_object_unref (header);
1898 TnyHeader *header = NULL;
1900 gboolean do_retrieve = TRUE;
1901 TnyList *header_list = NULL;
1903 header_list = get_selected_headers (win);
1906 /* Check that only one message is selected for replying */
1907 if (tny_list_get_length (header_list) != 1) {
1908 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1909 NULL, _("mcen_ib_select_one_message"));
1910 g_object_unref (header_list);
1914 /* Only reply/forward to one message */
1915 iter = tny_list_create_iterator (header_list);
1916 header = TNY_HEADER (tny_iterator_get_current (iter));
1917 g_object_unref (iter);
1919 /* Retrieve messages */
1920 do_retrieve = (action == ACTION_FORWARD) ||
1921 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1924 TnyAccount *account = NULL;
1925 TnyFolder *folder = NULL;
1926 gdouble download = TRUE;
1927 guint uncached_msgs = 0;
1929 folder = tny_header_get_folder (header);
1931 goto do_retrieve_frees;
1932 account = tny_folder_get_account (folder);
1934 goto do_retrieve_frees;
1936 uncached_msgs = header_list_count_uncached_msgs (header_list);
1938 if (uncached_msgs > 0) {
1939 /* Allways download if we are online. */
1940 if (!tny_device_is_online (modest_runtime_get_device ())) {
1943 /* If ask for user permission to download the messages */
1944 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1945 ngettext("mcen_nc_get_msg",
1949 /* End if the user does not want to continue */
1950 if (response == GTK_RESPONSE_CANCEL)
1957 rf_helper = create_reply_forward_helper (action, win,
1958 reply_forward_type, header);
1959 if (uncached_msgs > 0) {
1960 modest_platform_connect_and_perform (GTK_WINDOW (win),
1962 reply_forward_performer,
1965 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
1966 account, rf_helper);
1971 g_object_unref (account);
1973 g_object_unref (folder);
1975 reply_forward_cb (NULL, header, FALSE, NULL, NULL, rf_helper);
1978 g_object_unref (header_list);
1979 g_object_unref (header);
1984 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1986 g_return_if_fail (MODEST_IS_WINDOW(win));
1988 reply_forward (ACTION_REPLY, win);
1992 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1994 g_return_if_fail (MODEST_IS_WINDOW(win));
1996 reply_forward (ACTION_FORWARD, win);
2000 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
2002 g_return_if_fail (MODEST_IS_WINDOW(win));
2004 reply_forward (ACTION_REPLY_TO_ALL, win);
2008 modest_ui_actions_on_next (GtkAction *action,
2009 ModestWindow *window)
2011 if (MODEST_IS_MAIN_WINDOW (window)) {
2012 GtkWidget *header_view;
2014 header_view = modest_main_window_get_child_widget (
2015 MODEST_MAIN_WINDOW(window),
2016 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2020 modest_header_view_select_next (
2021 MODEST_HEADER_VIEW(header_view));
2022 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2023 modest_msg_view_window_select_next_message (
2024 MODEST_MSG_VIEW_WINDOW (window));
2026 g_return_if_reached ();
2031 modest_ui_actions_on_prev (GtkAction *action,
2032 ModestWindow *window)
2034 g_return_if_fail (MODEST_IS_WINDOW(window));
2036 if (MODEST_IS_MAIN_WINDOW (window)) {
2037 GtkWidget *header_view;
2038 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2039 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2043 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
2044 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2045 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
2047 g_return_if_reached ();
2052 modest_ui_actions_on_sort (GtkAction *action,
2053 ModestWindow *window)
2055 GtkWidget *header_view = NULL;
2057 g_return_if_fail (MODEST_IS_WINDOW(window));
2059 if (MODEST_IS_MAIN_WINDOW (window)) {
2060 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2061 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2062 #ifdef MODEST_TOOLKIT_HILDON2
2063 } else if (MODEST_IS_HEADER_WINDOW (window)) {
2064 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2069 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
2074 /* Show sorting dialog */
2075 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
2079 new_messages_arrived (ModestMailOperation *self,
2080 TnyList *new_headers,
2084 gboolean show_visual_notifications;
2086 source = modest_mail_operation_get_source (self);
2087 show_visual_notifications = (source) ? FALSE : TRUE;
2089 g_object_unref (source);
2091 /* Notify new messages have been downloaded. If the
2092 send&receive was invoked by the user then do not show any
2093 visual notification, only play a sound and activate the LED
2094 (for the Maemo version) */
2095 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0)
2096 modest_platform_on_new_headers_received (new_headers,
2097 show_visual_notifications);
2102 retrieve_all_messages_cb (GObject *source,
2104 guint retrieve_limit)
2110 window = GTK_WINDOW (source);
2111 msg = g_strdup_printf (_("mail_nc_msg_count_limit_exceeded"),
2112 num_msgs, retrieve_limit);
2114 /* Ask the user if they want to retrieve all the messages */
2116 modest_platform_run_confirmation_dialog_with_buttons (window, msg,
2117 _("mcen_bd_get_all"),
2118 _("mcen_bd_newest_only"));
2119 /* Free and return */
2121 return (response == GTK_RESPONSE_ACCEPT) ? TRUE : FALSE;
2125 TnyAccount *account;
2127 gchar *account_name;
2128 gboolean poke_status;
2129 gboolean interactive;
2130 ModestMailOperation *mail_op;
2134 do_send_receive_performer (gboolean canceled,
2136 GtkWindow *parent_window,
2137 TnyAccount *account,
2140 SendReceiveInfo *info;
2142 info = (SendReceiveInfo *) user_data;
2144 if (err || canceled) {
2145 /* In memory full conditions we could get this error here */
2146 check_memory_full_error ((GtkWidget *) parent_window, err);
2148 if (info->mail_op) {
2149 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2155 /* Set send/receive operation in progress */
2156 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2157 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2160 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2161 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2162 G_CALLBACK (on_send_receive_finished),
2165 /* Send & receive. */
2166 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2167 (info->win) ? retrieve_all_messages_cb : NULL,
2168 new_messages_arrived, info->win);
2173 g_object_unref (G_OBJECT (info->mail_op));
2174 if (info->account_name)
2175 g_free (info->account_name);
2177 g_object_unref (info->win);
2179 g_object_unref (info->account);
2180 g_slice_free (SendReceiveInfo, info);
2184 * This function performs the send & receive required actions. The
2185 * window is used to create the mail operation. Typically it should
2186 * always be the main window, but we pass it as argument in order to
2190 modest_ui_actions_do_send_receive (const gchar *account_name,
2191 gboolean force_connection,
2192 gboolean poke_status,
2193 gboolean interactive,
2196 gchar *acc_name = NULL;
2197 SendReceiveInfo *info;
2198 ModestTnyAccountStore *acc_store;
2200 /* If no account name was provided then get the current account, and if
2201 there is no current account then pick the default one: */
2202 if (!account_name) {
2204 acc_name = g_strdup (modest_window_get_active_account (win));
2206 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2208 g_printerr ("modest: cannot get default account\n");
2212 acc_name = g_strdup (account_name);
2215 acc_store = modest_runtime_get_account_store ();
2217 /* Create the info for the connect and perform */
2218 info = g_slice_new (SendReceiveInfo);
2219 info->account_name = acc_name;
2220 info->win = (win) ? g_object_ref (win) : NULL;
2221 info->poke_status = poke_status;
2222 info->interactive = interactive;
2223 info->account = modest_tny_account_store_get_server_account (acc_store, acc_name,
2224 TNY_ACCOUNT_TYPE_STORE);
2225 /* We need to create the operation here, because otherwise it
2226 could happen that the queue emits the queue-empty signal
2227 while we're trying to connect the account */
2228 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2229 modest_ui_actions_disk_operations_error_handler,
2231 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2233 /* Invoke the connect and perform */
2234 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2235 force_connection, info->account,
2236 do_send_receive_performer, info);
2241 modest_ui_actions_do_cancel_send (const gchar *account_name,
2244 TnyTransportAccount *transport_account;
2245 TnySendQueue *send_queue = NULL;
2246 GError *error = NULL;
2248 /* Get transport account */
2250 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2251 (modest_runtime_get_account_store(),
2253 TNY_ACCOUNT_TYPE_TRANSPORT));
2254 if (!transport_account) {
2255 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2260 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2261 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2262 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2263 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2264 "modest: could not find send queue for account\n");
2266 /* Cancel the current send */
2267 tny_account_cancel (TNY_ACCOUNT (transport_account));
2269 /* Suspend all pending messages */
2270 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2274 if (transport_account != NULL)
2275 g_object_unref (G_OBJECT (transport_account));
2279 modest_ui_actions_cancel_send_all (ModestWindow *win)
2281 GSList *account_names, *iter;
2283 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2286 iter = account_names;
2288 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2289 iter = g_slist_next (iter);
2292 modest_account_mgr_free_account_names (account_names);
2293 account_names = NULL;
2297 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2300 /* Check if accounts exist */
2301 gboolean accounts_exist =
2302 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2304 /* If not, allow the user to create an account before trying to send/receive. */
2305 if (!accounts_exist)
2306 modest_ui_actions_on_accounts (NULL, win);
2308 /* Cancel all sending operaitons */
2309 modest_ui_actions_cancel_send_all (win);
2313 * Refreshes all accounts. This function will be used by automatic
2317 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2318 gboolean force_connection,
2319 gboolean poke_status,
2320 gboolean interactive)
2322 GSList *account_names, *iter;
2324 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2327 iter = account_names;
2329 modest_ui_actions_do_send_receive ((const char*) iter->data,
2331 poke_status, interactive, win);
2332 iter = g_slist_next (iter);
2335 modest_account_mgr_free_account_names (account_names);
2336 account_names = NULL;
2340 * Handler of the click on Send&Receive button in the main toolbar
2343 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2345 /* Check if accounts exist */
2346 gboolean accounts_exist;
2349 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2351 /* If not, allow the user to create an account before trying to send/receive. */
2352 if (!accounts_exist)
2353 modest_ui_actions_on_accounts (NULL, win);
2355 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2356 if (MODEST_IS_MAIN_WINDOW (win)) {
2357 GtkWidget *folder_view;
2358 TnyFolderStore *folder_store;
2361 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2362 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2366 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2369 g_object_unref (folder_store);
2370 /* Refresh the active account. Force the connection if needed
2371 and poke the status of all folders */
2372 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2373 #ifdef MODEST_TOOLKIT_HILDON2
2374 } else if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2375 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2378 const gchar *active_account;
2379 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2381 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2388 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2391 GtkWidget *header_view;
2393 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2395 header_view = modest_main_window_get_child_widget (main_window,
2396 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2400 conf = modest_runtime_get_conf ();
2402 /* what is saved/restored is depending on the style; thus; we save with
2403 * old style, then update the style, and restore for this new style
2405 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2407 if (modest_header_view_get_style
2408 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2409 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2410 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2412 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2413 MODEST_HEADER_VIEW_STYLE_DETAILS);
2415 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2416 MODEST_CONF_HEADER_VIEW_KEY);
2421 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2423 ModestMainWindow *main_window)
2425 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2426 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2428 /* in the case the folder is empty, show the empty folder message and focus
2430 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2431 if (modest_header_view_is_empty (header_view)) {
2432 TnyFolder *folder = modest_header_view_get_folder (header_view);
2433 GtkWidget *folder_view =
2434 modest_main_window_get_child_widget (main_window,
2435 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2436 if (folder != NULL) {
2437 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2438 g_object_unref (folder);
2440 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2444 /* If no header has been selected then exit */
2449 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2450 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2452 /* Update toolbar dimming state */
2453 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2454 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2458 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2461 ModestWindow *window)
2463 GtkWidget *open_widget;
2464 GtkTreeRowReference *rowref;
2466 g_return_if_fail (MODEST_IS_WINDOW(window));
2467 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2468 g_return_if_fail (TNY_IS_HEADER (header));
2470 if (modest_header_view_count_selected_headers (header_view) > 1) {
2471 /* Don't allow activation if there are more than one message selected */
2472 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2476 /* we check for low-mem; in that case, show a warning, and don't allow
2477 * activating headers
2479 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2482 if (MODEST_IS_MAIN_WINDOW (window)) {
2483 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2484 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2485 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2489 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2490 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2491 gtk_tree_row_reference_free (rowref);
2495 set_active_account_from_tny_account (TnyAccount *account,
2496 ModestWindow *window)
2498 const gchar *server_acc_name = tny_account_get_id (account);
2500 /* We need the TnyAccount provided by the
2501 account store because that is the one that
2502 knows the name of the Modest account */
2503 TnyAccount *modest_server_account = modest_server_account =
2504 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2505 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2507 if (!modest_server_account) {
2508 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2512 /* Update active account, but only if it's not a pseudo-account */
2513 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2514 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2515 const gchar *modest_acc_name =
2516 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2517 if (modest_acc_name)
2518 modest_window_set_active_account (window, modest_acc_name);
2521 g_object_unref (modest_server_account);
2526 folder_refreshed_cb (ModestMailOperation *mail_op,
2530 ModestMainWindow *win = NULL;
2531 GtkWidget *folder_view;
2532 const GError *error;
2534 g_return_if_fail (TNY_IS_FOLDER (folder));
2536 win = MODEST_MAIN_WINDOW (user_data);
2538 /* Check if the operation failed due to memory low conditions */
2539 error = modest_mail_operation_get_error (mail_op);
2540 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2541 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2542 modest_platform_run_information_dialog (GTK_WINDOW (win),
2543 _KR("memr_ib_operation_disabled"),
2549 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2552 TnyFolderStore *current_folder;
2554 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2555 if (current_folder) {
2556 gboolean different = ((TnyFolderStore *) folder != current_folder);
2557 g_object_unref (current_folder);
2563 /* Check if folder is empty and set headers view contents style */
2564 if (tny_folder_get_all_count (folder) == 0)
2565 modest_main_window_set_contents_style (win,
2566 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2571 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2572 TnyFolderStore *folder_store,
2574 ModestMainWindow *main_window)
2577 GtkWidget *header_view;
2579 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2581 header_view = modest_main_window_get_child_widget(main_window,
2582 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2586 conf = modest_runtime_get_conf ();
2588 if (TNY_IS_ACCOUNT (folder_store)) {
2590 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2592 /* Show account details */
2593 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2596 if (TNY_IS_FOLDER (folder_store) && selected) {
2597 TnyAccount *account;
2598 const gchar *account_name = NULL;
2600 /* Update the active account */
2601 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2603 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2605 modest_tny_account_get_parent_modest_account_name_for_server_account (account);
2606 g_object_unref (account);
2610 /* Set the header style by default, it could
2611 be changed later by the refresh callback to
2613 modest_main_window_set_contents_style (main_window,
2614 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2616 /* Set folder on header view. This function
2617 will call tny_folder_refresh_async so we
2618 pass a callback that will be called when
2619 finished. We use that callback to set the
2620 empty view if there are no messages */
2621 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2622 TNY_FOLDER (folder_store),
2624 MODEST_WINDOW (main_window),
2625 folder_refreshed_cb,
2628 /* Restore configuration. We need to do this
2629 *after* the set_folder because the widget
2630 memory asks the header view about its
2632 modest_widget_memory_restore (modest_runtime_get_conf (),
2633 G_OBJECT(header_view),
2634 MODEST_CONF_HEADER_VIEW_KEY);
2636 /* No need to save the header view
2637 configuration for Maemo because it only
2638 saves the sorting stuff and that it's
2639 already being done by the sort
2640 dialog. Remove it when the GNOME version
2641 has the same behaviour */
2642 #ifdef MODEST_TOOLKIT_GTK
2643 if (modest_main_window_get_contents_style (main_window) ==
2644 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2645 modest_widget_memory_save (conf, G_OBJECT (header_view),
2646 MODEST_CONF_HEADER_VIEW_KEY);
2648 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2652 /* Update dimming state */
2653 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2654 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2658 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2665 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2667 online = tny_device_is_online (modest_runtime_get_device());
2670 /* already online -- the item is simply not there... */
2671 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2673 GTK_MESSAGE_WARNING,
2675 _("The %s you selected cannot be found"),
2677 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2678 gtk_dialog_run (GTK_DIALOG(dialog));
2680 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2683 _("mcen_bd_dialog_cancel"),
2684 GTK_RESPONSE_REJECT,
2685 _("mcen_bd_dialog_ok"),
2686 GTK_RESPONSE_ACCEPT,
2688 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2689 "Do you want to get online?"), item);
2690 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2691 gtk_label_new (txt), FALSE, FALSE, 0);
2692 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2695 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2696 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2697 /* TODO: Comment about why is this commented out: */
2698 /* modest_platform_connect_and_wait (); */
2701 gtk_widget_destroy (dialog);
2705 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2708 /* g_message ("%s %s", __FUNCTION__, link); */
2713 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2716 modest_platform_activate_uri (link);
2720 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2723 modest_platform_show_uri_popup (link);
2727 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2730 /* we check for low-mem; in that case, show a warning, and don't allow
2731 * viewing attachments
2733 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2736 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2740 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2741 const gchar *address,
2744 /* g_message ("%s %s", __FUNCTION__, address); */
2748 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2749 TnyMsg *saved_draft,
2752 ModestMsgEditWindow *edit_window;
2754 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2755 #ifndef MODEST_TOOLKIT_HILDON2
2756 ModestMainWindow *win;
2758 /* FIXME. Make the header view sensitive again. This is a
2759 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2761 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2762 modest_runtime_get_window_mgr(), FALSE));
2764 GtkWidget *hdrview = modest_main_window_get_child_widget(
2765 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2766 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2770 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2772 /* Set draft is there was no error */
2773 if (!modest_mail_operation_get_error (mail_op))
2774 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2776 g_object_unref(edit_window);
2780 enough_space_for_message (ModestMsgEditWindow *edit_window,
2783 TnyAccountStore *acc_store;
2784 guint64 available_disk, expected_size;
2789 acc_store = TNY_ACCOUNT_STORE (modest_runtime_get_account_store());
2790 available_disk = modest_utils_get_available_space (NULL);
2791 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2792 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2797 /* Double check: memory full condition or message too big */
2798 if (available_disk < MIN_FREE_SPACE ||
2799 expected_size > available_disk) {
2801 modest_platform_information_banner (NULL, NULL,
2802 _KR("cerm_device_memory_full"));
2807 * djcb: if we're in low-memory state, we only allow for
2808 * saving messages smaller than
2809 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2810 * should still allow for sending anything critical...
2812 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2813 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2817 * djcb: we also make sure that the attachments are smaller than the max size
2818 * this is for the case where we'd try to forward a message with attachments
2819 * bigger than our max allowed size, or sending an message from drafts which
2820 * somehow got past our checks when attaching.
2822 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2823 modest_platform_run_information_dialog (
2824 GTK_WINDOW(edit_window),
2825 _KR("memr_ib_operation_disabled"),
2834 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2836 TnyTransportAccount *transport_account;
2837 ModestMailOperation *mail_operation;
2839 gchar *account_name, *from;
2840 ModestAccountMgr *account_mgr;
2841 gboolean had_error = FALSE;
2842 ModestMainWindow *win = NULL;
2844 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2846 data = modest_msg_edit_window_get_msg_data (edit_window);
2849 if (!enough_space_for_message (edit_window, data)) {
2850 modest_msg_edit_window_free_msg_data (edit_window, data);
2854 account_name = g_strdup (data->account_name);
2855 account_mgr = modest_runtime_get_account_mgr();
2857 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2859 account_name = modest_account_mgr_get_default_account (account_mgr);
2860 if (!account_name) {
2861 g_printerr ("modest: no account found\n");
2862 modest_msg_edit_window_free_msg_data (edit_window, data);
2866 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2867 account_name = g_strdup (data->account_name);
2871 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2872 (modest_runtime_get_account_store (),
2874 TNY_ACCOUNT_TYPE_TRANSPORT));
2875 if (!transport_account) {
2876 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2877 g_free (account_name);
2878 modest_msg_edit_window_free_msg_data (edit_window, data);
2881 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2883 /* Create the mail operation */
2884 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
2886 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2888 modest_mail_operation_save_to_drafts (mail_operation,
2900 data->priority_flags,
2901 on_save_to_drafts_cb,
2902 g_object_ref(edit_window));
2904 #ifdef MODEST_TOOLKIT_HILDON2
2905 /* In hildon2 we always show the information banner on saving to drafts.
2906 * It will be a system information banner in this case.
2908 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2909 modest_platform_information_banner (NULL, NULL, text);
2912 /* Use the main window as the parent of the banner, if the
2913 main window does not exist it won't be shown, if the parent
2914 window exists then it's properly shown. We don't use the
2915 editor window because it could be closed (save to drafts
2916 could happen after closing the window */
2917 win = (ModestMainWindow *)
2918 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
2920 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2921 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
2925 modest_msg_edit_window_set_modified (edit_window, FALSE);
2929 g_free (account_name);
2930 g_object_unref (G_OBJECT (transport_account));
2931 g_object_unref (G_OBJECT (mail_operation));
2933 modest_msg_edit_window_free_msg_data (edit_window, data);
2936 * If the drafts folder is selected then make the header view
2937 * insensitive while the message is being saved to drafts
2938 * (it'll be sensitive again in on_save_to_drafts_cb()). This
2939 * is not very clean but it avoids letting the drafts folder
2940 * in an inconsistent state: the user could edit the message
2941 * being saved and undesirable things would happen.
2942 * In the average case the user won't notice anything at
2943 * all. In the worst case (the user is editing a really big
2944 * file from Drafts) the header view will be insensitive
2945 * during the saving process (10 or 20 seconds, depending on
2946 * the message). Anyway this is just a quick workaround: once
2947 * we find a better solution it should be removed
2948 * See NB#65125 (commend #18) for details.
2950 if (!had_error && win != NULL) {
2951 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
2952 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
2954 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
2956 if (modest_tny_folder_is_local_folder(folder)) {
2957 TnyFolderType folder_type;
2958 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
2959 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
2960 GtkWidget *hdrview = modest_main_window_get_child_widget(
2961 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2962 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
2966 if (folder != NULL) g_object_unref(folder);
2973 /* For instance, when clicking the Send toolbar button when editing a message: */
2975 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2977 TnyTransportAccount *transport_account = NULL;
2978 gboolean had_error = FALSE;
2980 ModestAccountMgr *account_mgr;
2981 gchar *account_name;
2983 ModestMailOperation *mail_operation;
2985 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
2987 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2990 data = modest_msg_edit_window_get_msg_data (edit_window);
2993 if (!enough_space_for_message (edit_window, data)) {
2994 modest_msg_edit_window_free_msg_data (edit_window, data);
2998 account_mgr = modest_runtime_get_account_mgr();
2999 account_name = g_strdup (data->account_name);
3001 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3004 account_name = modest_account_mgr_get_default_account (account_mgr);
3006 if (!account_name) {
3007 modest_msg_edit_window_free_msg_data (edit_window, data);
3008 /* Run account setup wizard */
3009 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
3014 /* Get the currently-active transport account for this modest account: */
3015 if (strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
3017 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3018 (modest_runtime_get_account_store (),
3019 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
3022 if (!transport_account) {
3023 modest_msg_edit_window_free_msg_data (edit_window, data);
3024 /* Run account setup wizard */
3025 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
3030 /* Create the mail operation */
3031 from = modest_account_mgr_get_from_string (account_mgr, account_name);
3032 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
3033 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3035 modest_mail_operation_send_new_mail (mail_operation,
3047 data->priority_flags);
3049 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3050 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
3053 if (modest_mail_operation_get_error (mail_operation) != NULL) {
3054 const GError *error = modest_mail_operation_get_error (mail_operation);
3055 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3056 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3057 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3058 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3065 g_free (account_name);
3066 g_object_unref (G_OBJECT (transport_account));
3067 g_object_unref (G_OBJECT (mail_operation));
3069 modest_msg_edit_window_free_msg_data (edit_window, data);
3072 modest_msg_edit_window_set_sent (edit_window, TRUE);
3074 /* Save settings and close the window: */
3075 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3082 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3083 ModestMsgEditWindow *window)
3085 ModestMsgEditFormatState *format_state = NULL;
3087 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3088 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3090 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3093 format_state = modest_msg_edit_window_get_format_state (window);
3094 g_return_if_fail (format_state != NULL);
3096 format_state->bold = gtk_toggle_action_get_active (action);
3097 modest_msg_edit_window_set_format_state (window, format_state);
3098 g_free (format_state);
3103 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3104 ModestMsgEditWindow *window)
3106 ModestMsgEditFormatState *format_state = NULL;
3108 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3109 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3111 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3114 format_state = modest_msg_edit_window_get_format_state (window);
3115 g_return_if_fail (format_state != NULL);
3117 format_state->italics = gtk_toggle_action_get_active (action);
3118 modest_msg_edit_window_set_format_state (window, format_state);
3119 g_free (format_state);
3124 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3125 ModestMsgEditWindow *window)
3127 ModestMsgEditFormatState *format_state = NULL;
3129 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3130 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3132 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3135 format_state = modest_msg_edit_window_get_format_state (window);
3136 g_return_if_fail (format_state != NULL);
3138 format_state->bullet = gtk_toggle_action_get_active (action);
3139 modest_msg_edit_window_set_format_state (window, format_state);
3140 g_free (format_state);
3145 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3146 GtkRadioAction *selected,
3147 ModestMsgEditWindow *window)
3149 ModestMsgEditFormatState *format_state = NULL;
3150 GtkJustification value;
3152 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3154 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3157 value = gtk_radio_action_get_current_value (selected);
3159 format_state = modest_msg_edit_window_get_format_state (window);
3160 g_return_if_fail (format_state != NULL);
3162 format_state->justification = value;
3163 modest_msg_edit_window_set_format_state (window, format_state);
3164 g_free (format_state);
3168 modest_ui_actions_on_select_editor_color (GtkAction *action,
3169 ModestMsgEditWindow *window)
3171 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3172 g_return_if_fail (GTK_IS_ACTION (action));
3174 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3177 modest_msg_edit_window_select_color (window);
3181 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3182 ModestMsgEditWindow *window)
3184 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3185 g_return_if_fail (GTK_IS_ACTION (action));
3187 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3190 modest_msg_edit_window_select_background_color (window);
3194 modest_ui_actions_on_insert_image (GObject *object,
3195 ModestMsgEditWindow *window)
3197 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3200 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3203 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3206 modest_msg_edit_window_insert_image (window);
3210 modest_ui_actions_on_attach_file (GtkAction *action,
3211 ModestMsgEditWindow *window)
3213 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3214 g_return_if_fail (GTK_IS_ACTION (action));
3216 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3219 modest_msg_edit_window_offer_attach_file (window);
3223 modest_ui_actions_on_remove_attachments (GtkAction *action,
3224 ModestMsgEditWindow *window)
3226 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3228 modest_msg_edit_window_remove_attachments (window, NULL);
3232 #ifndef MODEST_TOOLKIT_GTK
3237 TnyFolderStore *folder;
3238 } CreateFolderHelper;
3241 show_create_folder_in_timeout (gpointer data)
3243 CreateFolderHelper *helper = (CreateFolderHelper *) data;
3245 /* Remove the timeout ASAP, we can not wait until the dialog
3246 is shown because it could take a lot of time and so the
3247 timeout could be called twice or more times */
3248 g_source_remove (helper->handler);
3250 gdk_threads_enter ();
3251 do_create_folder (helper->win, helper->folder, helper->name);
3252 gdk_threads_leave ();
3254 g_object_unref (helper->win);
3255 g_object_unref (helper->folder);
3256 g_free (helper->name);
3257 g_slice_free (CreateFolderHelper, helper);
3264 do_create_folder_cb (ModestMailOperation *mail_op,
3265 TnyFolderStore *parent_folder,
3266 TnyFolder *new_folder,
3269 gchar *suggested_name = (gchar *) user_data;
3270 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3272 if (modest_mail_operation_get_error (mail_op)) {
3274 /* Show an error. If there was some problem writing to
3275 disk, show it, otherwise show the generic folder
3276 create error. We do it here and not in an error
3277 handler because the call to do_create_folder will
3278 stop the main loop in a gtk_dialog_run and then,
3279 the message won't be shown until that dialog is
3281 modest_ui_actions_disk_operations_error_handler (mail_op,
3282 _("mail_in_ui_folder_create_error"));
3284 /* Try again. Do *NOT* show any error because the mail
3285 operations system will do it for us because we
3286 created the mail_op with new_with_error_handler */
3287 #ifndef MODEST_TOOLKIT_GTK
3288 CreateFolderHelper *helper;
3289 helper = g_slice_new0 (CreateFolderHelper);
3290 helper->name = g_strdup (suggested_name);
3291 helper->folder = g_object_ref (parent_folder);
3292 helper->win = g_object_ref (source_win);
3294 /* Ugly but neccesary stuff. The problem is that the
3295 dialog when is shown calls a function that destroys
3296 all the temporary windows, so the banner is
3298 helper->handler = g_timeout_add (2000, show_create_folder_in_timeout, helper);
3300 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3303 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3304 * FIXME: any other? */
3305 GtkWidget *folder_view;
3307 if (MODEST_IS_MAIN_WINDOW(source_win))
3309 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3310 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3312 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3313 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3315 /* Select the newly created folder. It could happen
3316 that the widget is no longer there (i.e. the window
3317 has been destroyed, so we need to check this */
3319 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3321 g_object_unref (new_folder);
3323 /* Free. Note that the first time it'll be NULL so noop */
3324 g_free (suggested_name);
3325 g_object_unref (source_win);
3330 TnyFolderStore *parent;
3331 } CreateFolderConnect;
3334 do_create_folder_performer (gboolean canceled,
3336 GtkWindow *parent_window,
3337 TnyAccount *account,
3340 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3341 ModestMailOperation *mail_op;
3343 if (canceled || err) {
3344 /* In memory full conditions we could get this error here */
3345 check_memory_full_error ((GtkWidget *) parent_window, err);
3349 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3350 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3352 modest_mail_operation_create_folder (mail_op,
3354 (const gchar *) helper->folder_name,
3355 do_create_folder_cb,
3356 g_strdup (helper->folder_name));
3357 g_object_unref (mail_op);
3361 g_object_unref (helper->parent);
3362 if (helper->folder_name)
3363 g_free (helper->folder_name);
3364 g_slice_free (CreateFolderConnect, helper);
3369 do_create_folder (GtkWindow *parent_window,
3370 TnyFolderStore *suggested_parent,
3371 const gchar *suggested_name)
3374 gchar *folder_name = NULL;
3375 TnyFolderStore *parent_folder = NULL;
3377 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3379 (gchar *) suggested_name,
3383 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3384 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderHelper);
3385 helper->folder_name = g_strdup (folder_name);
3386 helper->parent = g_object_ref (parent_folder);
3388 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3391 do_create_folder_performer,
3396 g_free (folder_name);
3398 g_object_unref (parent_folder);
3402 modest_ui_actions_create_folder(GtkWidget *parent_window,
3403 GtkWidget *folder_view)
3405 TnyFolderStore *parent_folder;
3407 #ifdef MODEST_TOOLKIT_HILDON2
3408 ModestTnyAccountStore *acc_store;
3410 acc_store = modest_runtime_get_account_store ();
3412 parent_folder = (TnyFolderStore *)
3413 modest_tny_account_store_get_local_folders_account (acc_store);
3415 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3419 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3423 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3426 g_return_if_fail (MODEST_IS_WINDOW(window));
3428 if (MODEST_IS_MAIN_WINDOW (window)) {
3429 GtkWidget *folder_view;
3431 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3432 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3436 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view);
3437 #ifdef MODEST_TOOLKIT_HILDON2
3438 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3439 GtkWidget *folder_view;
3441 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3442 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view);
3445 g_assert_not_reached ();
3450 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3453 const GError *error = NULL;
3454 const gchar *message = NULL;
3456 /* Get error message */
3457 error = modest_mail_operation_get_error (mail_op);
3459 g_return_if_reached ();
3461 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3462 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3463 message = _CS("ckdg_ib_folder_already_exists");
3464 } else if (error->domain == TNY_ERROR_DOMAIN &&
3465 error->code == TNY_SERVICE_ERROR_STATE) {
3466 /* This means that the folder is already in use (a
3467 message is opened for example */
3468 message = _("emev_ni_internal_error");
3470 message = _CS("ckdg_ib_unable_to_rename");
3473 /* We don't set a parent for the dialog because the dialog
3474 will be destroyed so the banner won't appear */
3475 modest_platform_information_banner (NULL, NULL, message);
3479 TnyFolderStore *folder;
3484 on_rename_folder_cb (ModestMailOperation *mail_op,
3485 TnyFolder *new_folder,
3488 ModestFolderView *folder_view;
3490 /* If the window was closed when renaming a folder, or if
3491 * it's not a main window this will happen */
3492 if (!MODEST_IS_FOLDER_VIEW (user_data))
3495 folder_view = MODEST_FOLDER_VIEW (user_data);
3496 /* Note that if the rename fails new_folder will be NULL */
3498 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3500 modest_folder_view_select_first_inbox_or_local (folder_view);
3502 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3506 on_rename_folder_performer (gboolean canceled,
3508 GtkWindow *parent_window,
3509 TnyAccount *account,
3512 ModestMailOperation *mail_op = NULL;
3513 GtkTreeSelection *sel = NULL;
3514 GtkWidget *folder_view = NULL;
3515 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3517 if (canceled || err) {
3518 /* In memory full conditions we could get this error here */
3519 check_memory_full_error ((GtkWidget *) parent_window, err);
3523 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3524 modest_ui_actions_rename_folder_error_handler,
3525 parent_window, NULL);
3527 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3530 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3532 folder_view = modest_main_window_get_child_widget (
3533 MODEST_MAIN_WINDOW (parent_window),
3534 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3536 #ifdef MODEST_TOOLKIT_HILDON2
3537 else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3538 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3539 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3543 /* Clear the folders view */
3544 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3545 gtk_tree_selection_unselect_all (sel);
3547 /* Actually rename the folder */
3548 modest_mail_operation_rename_folder (mail_op,
3549 TNY_FOLDER (data->folder),
3550 (const gchar *) (data->new_name),
3551 on_rename_folder_cb,
3553 g_object_unref (mail_op);
3556 g_object_unref (data->folder);
3557 g_free (data->new_name);
3562 modest_ui_actions_on_rename_folder (GtkAction *action,
3563 ModestWindow *window)
3565 modest_ui_actions_on_edit_mode_rename_folder (window);
3569 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3571 TnyFolderStore *folder;
3572 GtkWidget *folder_view;
3573 gboolean do_rename = TRUE;
3575 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3577 if (MODEST_IS_MAIN_WINDOW (window)) {
3578 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3579 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3583 #ifdef MODEST_TOOLKIT_HILDON2
3584 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3585 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3591 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3596 if (TNY_IS_FOLDER (folder)) {
3597 gchar *folder_name = NULL;
3599 const gchar *current_name;
3600 TnyFolderStore *parent;
3602 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3603 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3604 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
3605 parent, current_name,
3607 g_object_unref (parent);
3609 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3612 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3613 rename_folder_data->folder = g_object_ref (folder);
3614 rename_folder_data->new_name = folder_name;
3615 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
3616 folder, on_rename_folder_performer, rename_folder_data);
3619 g_object_unref (folder);
3624 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3627 GObject *win = modest_mail_operation_get_source (mail_op);
3629 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3630 _("mail_in_ui_folder_delete_error"),
3632 g_object_unref (win);
3636 TnyFolderStore *folder;
3637 gboolean move_to_trash;
3641 on_delete_folder_cb (gboolean canceled,
3643 GtkWindow *parent_window,
3644 TnyAccount *account,
3647 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3648 GtkWidget *folder_view;
3649 ModestMailOperation *mail_op;
3650 GtkTreeSelection *sel;
3652 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
3653 g_object_unref (G_OBJECT (info->folder));
3658 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
3659 folder_view = modest_main_window_get_child_widget (
3660 MODEST_MAIN_WINDOW (parent_window),
3661 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3662 #ifdef MODEST_TOOLKIT_HILDON2
3663 } else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3664 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
3667 g_object_unref (G_OBJECT (info->folder));
3672 /* Unselect the folder before deleting it to free the headers */
3673 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3674 gtk_tree_selection_unselect_all (sel);
3676 /* Create the mail operation */
3678 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3679 modest_ui_actions_delete_folder_error_handler,
3682 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3684 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3686 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3688 g_object_unref (G_OBJECT (mail_op));
3689 g_object_unref (G_OBJECT (info->folder));
3694 delete_folder (ModestWindow *window, gboolean move_to_trash)
3696 TnyFolderStore *folder;
3697 GtkWidget *folder_view;
3701 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3703 if (MODEST_IS_MAIN_WINDOW (window)) {
3705 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3706 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3707 #ifdef MODEST_TOOLKIT_HILDON2
3708 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3709 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3717 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3722 /* Show an error if it's an account */
3723 if (!TNY_IS_FOLDER (folder)) {
3724 modest_platform_run_information_dialog (GTK_WINDOW (window),
3725 _("mail_in_ui_folder_delete_error"),
3727 g_object_unref (G_OBJECT (folder));
3732 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3733 tny_folder_get_name (TNY_FOLDER (folder)));
3734 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
3735 (const gchar *) message);
3738 if (response == GTK_RESPONSE_OK) {
3739 DeleteFolderInfo *info;
3740 info = g_new0(DeleteFolderInfo, 1);
3741 info->folder = folder;
3742 info->move_to_trash = move_to_trash;
3743 g_object_ref (G_OBJECT (info->folder));
3744 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder));
3745 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
3747 TNY_FOLDER_STORE (account),
3748 on_delete_folder_cb, info);
3749 g_object_unref (account);
3754 g_object_unref (G_OBJECT (folder));
3758 modest_ui_actions_on_delete_folder (GtkAction *action,
3759 ModestWindow *window)
3761 modest_ui_actions_on_edit_mode_delete_folder (window);
3765 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
3767 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
3769 return delete_folder (window, FALSE);
3773 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3775 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3777 delete_folder (MODEST_WINDOW (main_window), TRUE);
3781 typedef struct _PasswordDialogFields {
3782 GtkWidget *username;
3783 GtkWidget *password;
3785 } PasswordDialogFields;
3788 password_dialog_check_field (GtkEditable *editable,
3789 PasswordDialogFields *fields)
3792 gboolean any_value_empty = FALSE;
3794 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
3795 if ((value == NULL) || value[0] == '\0') {
3796 any_value_empty = TRUE;
3798 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
3799 if ((value == NULL) || value[0] == '\0') {
3800 any_value_empty = TRUE;
3802 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3806 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3807 const gchar* server_account_name,
3812 ModestMainWindow *main_window)
3814 g_return_if_fail(server_account_name);
3815 gboolean completed = FALSE;
3816 PasswordDialogFields *fields = NULL;
3818 /* Initalize output parameters: */
3825 #ifndef MODEST_TOOLKIT_GTK
3826 /* Maemo uses a different (awkward) button order,
3827 * It should probably just use gtk_alternative_dialog_button_order ().
3829 #ifdef MODEST_TOOLKIT_HILDON2
3831 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3834 _HL("wdgt_bd_done"),
3835 GTK_RESPONSE_ACCEPT,
3839 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3842 _("mcen_bd_dialog_ok"),
3843 GTK_RESPONSE_ACCEPT,
3844 _("mcen_bd_dialog_cancel"),
3845 GTK_RESPONSE_REJECT,
3847 #endif /* MODEST_TOOLKIT_HILDON2 */
3850 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3854 GTK_RESPONSE_REJECT,
3856 GTK_RESPONSE_ACCEPT,
3858 #endif /* MODEST_TOOLKIT_GTK */
3860 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3862 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3863 modest_runtime_get_account_mgr(), server_account_name);
3864 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3865 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3868 gtk_widget_destroy (dialog);
3872 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3873 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
3876 g_free (server_name);
3880 gchar *initial_username = modest_account_mgr_get_server_account_username (
3881 modest_runtime_get_account_mgr(), server_account_name);
3883 GtkWidget *entry_username = gtk_entry_new ();
3884 if (initial_username)
3885 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
3886 /* Dim this if a connection has ever succeeded with this username,
3887 * as per the UI spec: */
3888 /* const gboolean username_known = */
3889 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3890 /* modest_runtime_get_account_mgr(), server_account_name); */
3891 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3893 /* We drop the username sensitive code and disallow changing it here
3894 * as tinymail does not support really changing the username in the callback
3896 gtk_widget_set_sensitive (entry_username, FALSE);
3898 #ifndef MODEST_TOOLKIT_GTK
3899 /* Auto-capitalization is the default, so let's turn it off: */
3900 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3902 /* Create a size group to be used by all captions.
3903 * Note that HildonCaption does not create a default size group if we do not specify one.
3904 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3905 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3907 GtkWidget *caption = hildon_caption_new (sizegroup,
3908 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
3909 gtk_widget_show (entry_username);
3910 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3911 FALSE, FALSE, MODEST_MARGIN_HALF);
3912 gtk_widget_show (caption);
3914 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
3916 #endif /* !MODEST_TOOLKIT_GTK */
3919 GtkWidget *entry_password = gtk_entry_new ();
3920 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3921 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3923 #ifndef MODEST_TOOLKIT_GTK
3924 /* Auto-capitalization is the default, so let's turn it off: */
3925 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3926 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3928 caption = hildon_caption_new (sizegroup,
3929 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
3930 gtk_widget_show (entry_password);
3931 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3932 FALSE, FALSE, MODEST_MARGIN_HALF);
3933 gtk_widget_show (caption);
3934 g_object_unref (sizegroup);
3936 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
3938 #endif /* !MODEST_TOOLKIT_GTK */
3940 if (initial_username != NULL)
3941 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3943 /* This is not in the Maemo UI spec:
3944 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3945 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3949 fields = g_slice_new0 (PasswordDialogFields);
3950 fields->username = entry_username;
3951 fields->password = entry_password;
3952 fields->dialog = dialog;
3954 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3955 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3956 password_dialog_check_field (NULL, fields);
3958 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3960 while (!completed) {
3962 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3964 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
3966 /* Note that an empty field becomes the "" string */
3967 if (*username && strlen (*username) > 0) {
3968 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
3969 server_account_name,
3973 const gboolean username_was_changed =
3974 (strcmp (*username, initial_username) != 0);
3975 if (username_was_changed) {
3976 g_warning ("%s: tinymail does not yet support changing the "
3977 "username in the get_password() callback.\n", __FUNCTION__);
3983 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
3984 _("mcen_ib_username_pw_incorrect"));
3990 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
3992 /* We do not save the password in the configuration,
3993 * because this function is only called for passwords that should
3994 * not be remembered:
3995 modest_server_account_set_password (
3996 modest_runtime_get_account_mgr(), server_account_name,
4003 #ifndef MODEST_TOOLKIT_HILDON2
4004 /* Set parent to NULL or the banner will disappear with its parent dialog */
4005 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
4017 /* This is not in the Maemo UI spec:
4018 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
4024 g_free (initial_username);
4025 gtk_widget_destroy (dialog);
4026 g_slice_free (PasswordDialogFields, fields);
4028 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
4032 modest_ui_actions_on_cut (GtkAction *action,
4033 ModestWindow *window)
4035 GtkWidget *focused_widget;
4036 GtkClipboard *clipboard;
4038 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4039 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4040 if (GTK_IS_EDITABLE (focused_widget)) {
4041 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
4042 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4043 gtk_clipboard_store (clipboard);
4044 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4045 GtkTextBuffer *buffer;
4047 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4048 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4049 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
4050 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4051 gtk_clipboard_store (clipboard);
4053 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4054 TnyList *header_list = modest_header_view_get_selected_headers (
4055 MODEST_HEADER_VIEW (focused_widget));
4056 gboolean continue_download = FALSE;
4057 gint num_of_unc_msgs;
4059 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4061 if (num_of_unc_msgs) {
4062 TnyAccount *account = get_account_from_header_list (header_list);
4064 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4065 g_object_unref (account);
4069 if (num_of_unc_msgs == 0 || continue_download) {
4070 /* modest_platform_information_banner (
4071 NULL, NULL, _CS("mcen_ib_getting_items"));*/
4072 modest_header_view_cut_selection (
4073 MODEST_HEADER_VIEW (focused_widget));
4076 g_object_unref (header_list);
4077 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4078 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4083 modest_ui_actions_on_copy (GtkAction *action,
4084 ModestWindow *window)
4086 GtkClipboard *clipboard;
4087 GtkWidget *focused_widget;
4088 gboolean copied = TRUE;
4090 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4091 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4093 if (GTK_IS_LABEL (focused_widget)) {
4095 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4096 gtk_clipboard_set_text (clipboard, selection, -1);
4098 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4099 gtk_clipboard_store (clipboard);
4100 } else if (GTK_IS_EDITABLE (focused_widget)) {
4101 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4102 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4103 gtk_clipboard_store (clipboard);
4104 } else if (GTK_IS_HTML (focused_widget)) {
4107 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4108 if ((sel == NULL) || (sel[0] == '\0')) {
4111 gtk_html_copy (GTK_HTML (focused_widget));
4112 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4113 gtk_clipboard_store (clipboard);
4115 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4116 GtkTextBuffer *buffer;
4117 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4118 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4119 gtk_text_buffer_copy_clipboard (buffer, clipboard);
4120 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4121 gtk_clipboard_store (clipboard);
4123 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4124 TnyList *header_list = modest_header_view_get_selected_headers (
4125 MODEST_HEADER_VIEW (focused_widget));
4126 gboolean continue_download = FALSE;
4127 gint num_of_unc_msgs;
4129 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4131 if (num_of_unc_msgs) {
4132 TnyAccount *account = get_account_from_header_list (header_list);
4134 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4135 g_object_unref (account);
4139 if (num_of_unc_msgs == 0 || continue_download) {
4140 modest_platform_information_banner (
4141 NULL, NULL, _CS("mcen_ib_getting_items"));
4142 modest_header_view_copy_selection (
4143 MODEST_HEADER_VIEW (focused_widget));
4147 g_object_unref (header_list);
4149 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4150 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4153 /* Show information banner if there was a copy to clipboard */
4155 modest_platform_information_banner (
4156 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4160 modest_ui_actions_on_undo (GtkAction *action,
4161 ModestWindow *window)
4163 ModestEmailClipboard *clipboard = NULL;
4165 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4166 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4167 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4168 /* Clear clipboard source */
4169 clipboard = modest_runtime_get_email_clipboard ();
4170 modest_email_clipboard_clear (clipboard);
4173 g_return_if_reached ();
4178 modest_ui_actions_on_redo (GtkAction *action,
4179 ModestWindow *window)
4181 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4182 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4185 g_return_if_reached ();
4191 destroy_information_note (ModestMailOperation *mail_op,
4194 /* destroy information note */
4195 gtk_widget_destroy (GTK_WIDGET(user_data));
4199 destroy_folder_information_note (ModestMailOperation *mail_op,
4200 TnyFolder *new_folder,
4203 /* destroy information note */
4204 gtk_widget_destroy (GTK_WIDGET(user_data));
4209 paste_as_attachment_free (gpointer data)
4211 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4213 if (helper->banner) {
4214 gtk_widget_destroy (helper->banner);
4215 g_object_unref (helper->banner);
4221 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4226 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4227 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4232 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4237 modest_ui_actions_on_paste (GtkAction *action,
4238 ModestWindow *window)
4240 GtkWidget *focused_widget = NULL;
4241 GtkWidget *inf_note = NULL;
4242 ModestMailOperation *mail_op = NULL;
4244 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4245 if (GTK_IS_EDITABLE (focused_widget)) {
4246 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4247 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4248 ModestEmailClipboard *e_clipboard = NULL;
4249 e_clipboard = modest_runtime_get_email_clipboard ();
4250 if (modest_email_clipboard_cleared (e_clipboard)) {
4251 GtkTextBuffer *buffer;
4252 GtkClipboard *clipboard;
4254 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4255 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4256 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4257 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4258 ModestMailOperation *mail_op;
4259 TnyFolder *src_folder = NULL;
4260 TnyList *data = NULL;
4262 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4263 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4264 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4265 _CS("ckct_nw_pasting"));
4266 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4267 mail_op = modest_mail_operation_new (G_OBJECT (window));
4268 if (helper->banner != NULL) {
4269 g_object_ref (G_OBJECT (helper->banner));
4270 gtk_widget_show (GTK_WIDGET (helper->banner));
4274 modest_mail_operation_get_msgs_full (mail_op,
4276 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4278 paste_as_attachment_free);
4282 g_object_unref (data);
4284 g_object_unref (src_folder);
4287 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4288 ModestEmailClipboard *clipboard = NULL;
4289 TnyFolder *src_folder = NULL;
4290 TnyFolderStore *folder_store = NULL;
4291 TnyList *data = NULL;
4292 gboolean delete = FALSE;
4294 /* Check clipboard source */
4295 clipboard = modest_runtime_get_email_clipboard ();
4296 if (modest_email_clipboard_cleared (clipboard))
4299 /* Get elements to paste */
4300 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4302 /* Create a new mail operation */
4303 mail_op = modest_mail_operation_new (G_OBJECT(window));
4305 /* Get destination folder */
4306 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4308 /* transfer messages */
4312 /* Ask for user confirmation */
4314 modest_ui_actions_msgs_move_to_confirmation (window,
4315 TNY_FOLDER (folder_store),
4319 if (response == GTK_RESPONSE_OK) {
4320 /* Launch notification */
4321 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4322 _CS("ckct_nw_pasting"));
4323 if (inf_note != NULL) {
4324 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4325 gtk_widget_show (GTK_WIDGET(inf_note));
4328 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4329 modest_mail_operation_xfer_msgs (mail_op,
4331 TNY_FOLDER (folder_store),
4333 destroy_information_note,
4336 g_object_unref (mail_op);
4339 } else if (src_folder != NULL) {
4340 /* Launch notification */
4341 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4342 _CS("ckct_nw_pasting"));
4343 if (inf_note != NULL) {
4344 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4345 gtk_widget_show (GTK_WIDGET(inf_note));
4348 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4349 modest_mail_operation_xfer_folder (mail_op,
4353 destroy_folder_information_note,
4359 g_object_unref (data);
4360 if (src_folder != NULL)
4361 g_object_unref (src_folder);
4362 if (folder_store != NULL)
4363 g_object_unref (folder_store);
4369 modest_ui_actions_on_select_all (GtkAction *action,
4370 ModestWindow *window)
4372 GtkWidget *focused_widget;
4374 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4375 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4376 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4377 } else if (GTK_IS_LABEL (focused_widget)) {
4378 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4379 } else if (GTK_IS_EDITABLE (focused_widget)) {
4380 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4381 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4382 GtkTextBuffer *buffer;
4383 GtkTextIter start, end;
4385 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4386 gtk_text_buffer_get_start_iter (buffer, &start);
4387 gtk_text_buffer_get_end_iter (buffer, &end);
4388 gtk_text_buffer_select_range (buffer, &start, &end);
4389 } else if (GTK_IS_HTML (focused_widget)) {
4390 gtk_html_select_all (GTK_HTML (focused_widget));
4391 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4392 GtkWidget *header_view = focused_widget;
4393 GtkTreeSelection *selection = NULL;
4395 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4396 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4397 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4400 /* Disable window dimming management */
4401 modest_window_disable_dimming (MODEST_WINDOW(window));
4403 /* Select all messages */
4404 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4405 gtk_tree_selection_select_all (selection);
4407 /* Set focuse on header view */
4408 gtk_widget_grab_focus (header_view);
4410 /* Enable window dimming management */
4411 modest_window_enable_dimming (MODEST_WINDOW(window));
4412 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4413 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4419 modest_ui_actions_on_mark_as_read (GtkAction *action,
4420 ModestWindow *window)
4422 g_return_if_fail (MODEST_IS_WINDOW(window));
4424 /* Mark each header as read */
4425 do_headers_action (window, headers_action_mark_as_read, NULL);
4429 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4430 ModestWindow *window)
4432 g_return_if_fail (MODEST_IS_WINDOW(window));
4434 /* Mark each header as read */
4435 do_headers_action (window, headers_action_mark_as_unread, NULL);
4439 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4440 GtkRadioAction *selected,
4441 ModestWindow *window)
4445 value = gtk_radio_action_get_current_value (selected);
4446 if (MODEST_IS_WINDOW (window)) {
4447 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4452 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4453 GtkRadioAction *selected,
4454 ModestWindow *window)
4456 TnyHeaderFlags flags;
4457 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4459 flags = gtk_radio_action_get_current_value (selected);
4460 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4464 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4465 GtkRadioAction *selected,
4466 ModestWindow *window)
4470 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4472 file_format = gtk_radio_action_get_current_value (selected);
4473 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4478 modest_ui_actions_on_zoom_plus (GtkAction *action,
4479 ModestWindow *window)
4481 g_return_if_fail (MODEST_IS_WINDOW (window));
4483 modest_window_zoom_plus (MODEST_WINDOW (window));
4487 modest_ui_actions_on_zoom_minus (GtkAction *action,
4488 ModestWindow *window)
4490 g_return_if_fail (MODEST_IS_WINDOW (window));
4492 modest_window_zoom_minus (MODEST_WINDOW (window));
4496 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4497 ModestWindow *window)
4499 ModestWindowMgr *mgr;
4500 gboolean fullscreen, active;
4501 g_return_if_fail (MODEST_IS_WINDOW (window));
4503 mgr = modest_runtime_get_window_mgr ();
4505 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4506 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4508 if (active != fullscreen) {
4509 modest_window_mgr_set_fullscreen_mode (mgr, active);
4510 #ifndef MODEST_TOOLKIT_HILDON2
4511 gtk_window_present (GTK_WINDOW (window));
4517 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4518 ModestWindow *window)
4520 ModestWindowMgr *mgr;
4521 gboolean fullscreen;
4523 g_return_if_fail (MODEST_IS_WINDOW (window));
4525 mgr = modest_runtime_get_window_mgr ();
4526 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4527 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4529 #ifndef MODEST_TOOLKIT_HILDON2
4530 gtk_window_present (GTK_WINDOW (window));
4535 * Used by modest_ui_actions_on_details to call do_headers_action
4538 headers_action_show_details (TnyHeader *header,
4539 ModestWindow *window,
4543 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header);
4547 * Show the header details in a ModestDetailsDialog widget
4550 modest_ui_actions_on_details (GtkAction *action,
4553 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4557 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4561 header = tny_msg_get_header (msg);
4563 headers_action_show_details (header, win, NULL);
4564 g_object_unref (header);
4566 g_object_unref (msg);
4568 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4569 GtkWidget *folder_view, *header_view;
4571 /* Check which widget has the focus */
4572 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4573 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4574 if (gtk_widget_is_focus (folder_view)) {
4575 TnyFolderStore *folder_store
4576 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4577 if (!folder_store) {
4578 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4581 /* Show only when it's a folder */
4582 /* This function should not be called for account items,
4583 * because we dim the menu item for them. */
4584 if (TNY_IS_FOLDER (folder_store)) {
4585 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4586 TNY_FOLDER (folder_store));
4589 g_object_unref (folder_store);
4592 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4593 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4594 /* Show details of each header */
4595 do_headers_action (win, headers_action_show_details, header_view);
4597 #ifdef MODEST_TOOLKIT_HILDON2
4598 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4600 GtkWidget *header_view;
4602 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4603 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4605 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4607 g_object_unref (folder);
4614 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4615 ModestMsgEditWindow *window)
4617 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4619 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4623 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4624 ModestMsgEditWindow *window)
4626 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4628 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4632 modest_ui_actions_toggle_folders_view (GtkAction *action,
4633 ModestMainWindow *main_window)
4635 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4637 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4638 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4640 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4644 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4645 ModestWindow *window)
4647 gboolean active, fullscreen = FALSE;
4648 ModestWindowMgr *mgr;
4650 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4652 /* Check if we want to toggle the toolbar view in fullscreen
4654 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4655 "ViewShowToolbarFullScreen")) {
4659 /* Toggle toolbar */
4660 mgr = modest_runtime_get_window_mgr ();
4661 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4665 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4666 ModestMsgEditWindow *window)
4668 modest_msg_edit_window_select_font (window);
4673 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4674 const gchar *display_name,
4677 /* don't update the display name if it was already set;
4678 * updating the display name apparently is expensive */
4679 const gchar* old_name = gtk_window_get_title (window);
4681 if (display_name == NULL)
4684 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4685 return; /* don't do anything */
4687 /* This is usually used to change the title of the main window, which
4688 * is the one that holds the folder view. Note that this change can
4689 * happen even when the widget doesn't have the focus. */
4690 gtk_window_set_title (window, display_name);
4695 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4697 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4698 modest_msg_edit_window_select_contacts (window);
4702 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4704 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4705 modest_msg_edit_window_check_names (window, FALSE);
4708 #ifndef MODEST_TOOLKIT_HILDON2
4710 * This function is used to track changes in the selection of the
4711 * folder view that is inside the "move to" dialog to enable/disable
4712 * the OK button because we do not want the user to select a disallowed
4713 * destination for a folder.
4714 * The user also not desired to be able to use NEW button on items where
4715 * folder creation is not possibel.
4718 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4719 TnyFolderStore *folder_store,
4723 GtkWidget *dialog = NULL;
4724 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4725 gboolean moving_folder = FALSE;
4726 gboolean is_local_account = TRUE;
4727 GtkWidget *folder_view = NULL;
4728 ModestTnyFolderRules rules;
4730 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
4735 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
4739 /* check if folder_store is an remote account */
4740 if (TNY_IS_ACCOUNT (folder_store)) {
4741 TnyAccount *local_account = NULL;
4742 TnyAccount *mmc_account = NULL;
4743 ModestTnyAccountStore *account_store = NULL;
4745 account_store = modest_runtime_get_account_store ();
4746 local_account = modest_tny_account_store_get_local_folders_account (account_store);
4747 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
4749 if ((gpointer) local_account != (gpointer) folder_store &&
4750 (gpointer) mmc_account != (gpointer) folder_store) {
4751 ModestProtocolType proto;
4752 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
4753 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
4754 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
4756 is_local_account = FALSE;
4757 /* New button should be dimmed on remote
4759 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4761 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
4763 g_object_unref (local_account);
4765 /* It could not exist */
4767 g_object_unref (mmc_account);
4770 /* Check the target folder rules */
4771 if (TNY_IS_FOLDER (folder_store)) {
4772 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
4773 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
4774 ok_sensitive = FALSE;
4775 new_sensitive = FALSE;
4780 /* Check if we're moving a folder */
4781 if (MODEST_IS_MAIN_WINDOW (user_data)) {
4782 /* Get the widgets */
4783 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
4784 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4785 if (gtk_widget_is_focus (folder_view))
4786 moving_folder = TRUE;
4789 if (moving_folder) {
4790 TnyFolderStore *moved_folder = NULL, *parent = NULL;
4792 /* Get the folder to move */
4793 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4795 /* Check that we're not moving to the same folder */
4796 if (TNY_IS_FOLDER (moved_folder)) {
4797 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
4798 if (parent == folder_store)
4799 ok_sensitive = FALSE;
4800 g_object_unref (parent);
4803 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
4804 /* Do not allow to move to an account unless it's the
4805 local folders account */
4806 if (!is_local_account)
4807 ok_sensitive = FALSE;
4810 if (ok_sensitive && (moved_folder == folder_store)) {
4811 /* Do not allow to move to itself */
4812 ok_sensitive = FALSE;
4814 g_object_unref (moved_folder);
4816 TnyFolder *src_folder = NULL;
4818 /* Moving a message */
4819 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
4821 TnyHeader *header = NULL;
4822 header = modest_msg_view_window_get_header
4823 (MODEST_MSG_VIEW_WINDOW (user_data));
4824 if (!TNY_IS_HEADER(header))
4825 g_warning ("%s: could not get source header", __FUNCTION__);
4827 src_folder = tny_header_get_folder (header);
4830 g_object_unref (header);
4833 TNY_FOLDER (modest_folder_view_get_selected
4834 (MODEST_FOLDER_VIEW (folder_view)));
4837 if (TNY_IS_FOLDER(src_folder)) {
4838 /* Do not allow to move the msg to the same folder */
4839 /* Do not allow to move the msg to an account */
4840 if ((gpointer) src_folder == (gpointer) folder_store ||
4841 TNY_IS_ACCOUNT (folder_store))
4842 ok_sensitive = FALSE;
4843 g_object_unref (src_folder);
4845 g_warning ("%s: could not get source folder", __FUNCTION__);
4849 /* Set sensitivity of the OK and NEW button */
4850 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
4851 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
4856 on_move_to_dialog_response (GtkDialog *dialog,
4860 GtkWidget *parent_win, *folder_view;
4861 MoveToInfo *helper = NULL;
4863 helper = (MoveToInfo *) user_data;
4865 parent_win = (GtkWidget *) helper->win;
4866 folder_view = GTK_WIDGET (g_object_get_data (G_OBJECT (dialog),
4867 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4870 TnyFolderStore *dst_folder;
4872 case MODEST_GTK_RESPONSE_NEW_FOLDER:
4873 modest_ui_actions_create_folder (GTK_WIDGET (dialog), folder_view);
4875 case GTK_RESPONSE_NONE:
4876 case GTK_RESPONSE_CANCEL:
4877 case GTK_RESPONSE_DELETE_EVENT:
4879 case GTK_RESPONSE_OK:
4880 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4881 /* Do window specific stuff */
4882 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
4883 modest_ui_actions_on_main_window_move_to (NULL,
4886 MODEST_MAIN_WINDOW (parent_win));
4887 #ifdef MODEST_TOOLKIT_HILDON2
4888 } else if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
4889 modest_ui_actions_on_folder_window_move_to (folder_view,
4892 GTK_WINDOW (parent_win));
4895 /* Moving from headers window in edit mode */
4896 modest_ui_actions_on_window_move_to (NULL, helper->list,
4898 MODEST_WINDOW (parent_win));
4902 g_object_unref (dst_folder);
4906 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
4909 /* Free the helper and exit */
4911 g_object_unref (helper->list);
4912 g_slice_free (MoveToInfo, helper);
4913 gtk_widget_destroy (GTK_WIDGET (dialog));
4917 create_move_to_dialog (GtkWindow *win,
4918 GtkWidget *folder_view)
4920 GtkWidget *dialog, *tree_view = NULL;
4922 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
4924 #ifndef MODEST_TOOLKIT_HILDON2
4925 /* Track changes in the selection to
4926 * disable the OK button whenever "Move to" is not possible
4927 * disbale NEW button whenever New is not possible */
4928 g_signal_connect (tree_view,
4929 "folder_selection_changed",
4930 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
4934 /* It could happen that we're trying to move a message from a
4935 window (msg window for example) after the main window was
4936 closed, so we can not just get the model of the folder
4938 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4939 const gchar *visible_id = NULL;
4941 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4942 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4943 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4944 MODEST_FOLDER_VIEW(tree_view));
4947 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4949 /* Show the same account than the one that is shown in the main window */
4950 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
4953 const gchar *active_account_name = NULL;
4954 ModestAccountMgr *mgr = NULL;
4955 ModestAccountSettings *settings = NULL;
4956 ModestServerAccountSettings *store_settings = NULL;
4958 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4959 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4960 modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view),
4961 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
4963 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4964 mgr = modest_runtime_get_account_mgr ();
4965 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4968 const gchar *store_account_name;
4969 store_settings = modest_account_settings_get_store_settings (settings);
4970 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4972 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
4973 store_account_name);
4974 g_object_unref (store_settings);
4975 g_object_unref (settings);
4979 /* we keep a pointer to the embedded folder view, so we can
4980 * retrieve it with get_folder_view_from_move_to_dialog (see
4981 * above) later (needed for focus handling)
4983 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
4985 /* Hide special folders */
4986 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
4987 #ifndef MODEST_TOOLKIT_HILDON2
4988 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
4991 gtk_widget_show (GTK_WIDGET (tree_view));
4997 * Shows a confirmation dialog to the user when we're moving messages
4998 * from a remote server to the local storage. Returns the dialog
4999 * response. If it's other kind of movement then it always returns
5002 * This one is used by the next functions:
5003 * modest_ui_actions_on_paste - commented out
5004 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
5007 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
5008 TnyFolder *dest_folder,
5012 gint response = GTK_RESPONSE_OK;
5013 TnyAccount *account = NULL;
5014 TnyFolder *src_folder = NULL;
5015 TnyIterator *iter = NULL;
5016 TnyHeader *header = NULL;
5018 /* return with OK if the destination is a remote folder */
5019 if (modest_tny_folder_is_remote_folder (dest_folder))
5020 return GTK_RESPONSE_OK;
5022 /* Get source folder */
5023 iter = tny_list_create_iterator (headers);
5024 header = TNY_HEADER (tny_iterator_get_current (iter));
5026 src_folder = tny_header_get_folder (header);
5027 g_object_unref (header);
5029 g_object_unref (iter);
5031 /* if no src_folder, message may be an attahcment */
5032 if (src_folder == NULL)
5033 return GTK_RESPONSE_CANCEL;
5035 /* If the source is a local or MMC folder */
5036 if (!modest_tny_folder_is_remote_folder (src_folder)) {
5037 g_object_unref (src_folder);
5038 return GTK_RESPONSE_OK;
5041 /* Get the account */
5042 account = tny_folder_get_account (src_folder);
5044 /* now if offline we ask the user */
5045 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
5046 response = GTK_RESPONSE_OK;
5048 response = GTK_RESPONSE_CANCEL;
5051 g_object_unref (src_folder);
5052 g_object_unref (account);
5058 move_to_helper_destroyer (gpointer user_data)
5060 MoveToHelper *helper = (MoveToHelper *) user_data;
5062 /* Close the "Pasting" information banner */
5063 if (helper->banner) {
5064 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5065 g_object_unref (helper->banner);
5067 if (gtk_tree_row_reference_valid (helper->reference)) {
5068 gtk_tree_row_reference_free (helper->reference);
5069 helper->reference = NULL;
5075 move_to_cb (ModestMailOperation *mail_op,
5078 MoveToHelper *helper = (MoveToHelper *) user_data;
5079 GObject *object = modest_mail_operation_get_source (mail_op);
5081 /* Note that the operation could have failed, in that case do
5083 if (modest_mail_operation_get_status (mail_op) !=
5084 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5087 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5088 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5090 if (!modest_msg_view_window_select_next_message (self) &&
5091 !modest_msg_view_window_select_previous_message (self)) {
5092 /* No more messages to view, so close this window */
5093 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5095 } else if (MODEST_IS_MAIN_WINDOW (object) &&
5096 gtk_tree_row_reference_valid (helper->reference)) {
5097 GtkWidget *header_view;
5099 GtkTreeSelection *sel;
5101 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5102 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5103 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5104 path = gtk_tree_row_reference_get_path (helper->reference);
5105 /* We need to unselect the previous one
5106 because we could be copying instead of
5108 gtk_tree_selection_unselect_all (sel);
5109 gtk_tree_selection_select_path (sel, path);
5110 gtk_tree_path_free (path);
5112 g_object_unref (object);
5115 /* Destroy the helper */
5116 move_to_helper_destroyer (helper);
5120 folder_move_to_cb (ModestMailOperation *mail_op,
5121 TnyFolder *new_folder,
5124 GtkWidget *folder_view;
5127 object = modest_mail_operation_get_source (mail_op);
5128 if (MODEST_IS_MAIN_WINDOW (object)) {
5129 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5130 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5131 g_object_ref (folder_view);
5132 g_object_unref (object);
5133 move_to_cb (mail_op, user_data);
5134 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5135 g_object_unref (folder_view);
5137 move_to_cb (mail_op, user_data);
5142 msgs_move_to_cb (ModestMailOperation *mail_op,
5145 move_to_cb (mail_op, user_data);
5149 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5152 GObject *win = NULL;
5154 #ifndef MODEST_TOOLKIT_HILDON2
5155 ModestWindow *main_window = NULL;
5157 /* Disable next automatic folder selection */
5158 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5159 FALSE); /* don't create */
5161 GtkWidget *folder_view = NULL;
5163 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5164 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5165 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5167 if (user_data && TNY_IS_FOLDER (user_data)) {
5168 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5169 TNY_FOLDER (user_data), FALSE);
5173 /* Show notification dialog only if the main window exists */
5174 win = modest_mail_operation_get_source (mail_op);
5175 modest_platform_run_information_dialog ((GtkWindow *) win,
5176 _("mail_in_ui_folder_move_target_error"),
5179 g_object_unref (win);
5183 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5192 gint pending_purges = 0;
5193 gboolean some_purged = FALSE;
5194 ModestWindow *win = MODEST_WINDOW (user_data);
5195 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5197 /* If there was any error */
5198 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5199 modest_window_mgr_unregister_header (mgr, header);
5203 /* Once the message has been retrieved for purging, we check if
5204 * it's all ok for purging */
5206 parts = tny_simple_list_new ();
5207 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5208 iter = tny_list_create_iterator (parts);
5210 while (!tny_iterator_is_done (iter)) {
5212 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5213 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5214 if (tny_mime_part_is_purged (part))
5221 g_object_unref (part);
5223 tny_iterator_next (iter);
5225 g_object_unref (iter);
5228 if (pending_purges>0) {
5230 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5232 if (response == GTK_RESPONSE_OK) {
5235 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5236 iter = tny_list_create_iterator (parts);
5237 while (!tny_iterator_is_done (iter)) {
5240 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5241 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5242 tny_mime_part_set_purged (part);
5245 g_object_unref (part);
5247 tny_iterator_next (iter);
5249 g_object_unref (iter);
5251 tny_msg_rewrite_cache (msg);
5253 gtk_widget_destroy (info);
5257 modest_window_mgr_unregister_header (mgr, header);
5259 g_object_unref (parts);
5263 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5264 ModestMainWindow *win)
5266 GtkWidget *header_view;
5267 TnyList *header_list;
5269 TnyHeaderFlags flags;
5270 ModestWindow *msg_view_window = NULL;
5273 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5275 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5276 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5278 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5280 g_warning ("%s: no header selected", __FUNCTION__);
5284 if (tny_list_get_length (header_list) == 1) {
5285 TnyIterator *iter = tny_list_create_iterator (header_list);
5286 header = TNY_HEADER (tny_iterator_get_current (iter));
5287 g_object_unref (iter);
5291 if (!header || !TNY_IS_HEADER(header)) {
5292 g_warning ("%s: header is not valid", __FUNCTION__);
5296 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5297 header, &msg_view_window);
5298 flags = tny_header_get_flags (header);
5299 if (!(flags & TNY_HEADER_FLAG_CACHED))
5302 if (msg_view_window != NULL)
5303 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5305 /* do nothing; uid was registered before, so window is probably on it's way */
5306 g_warning ("debug: header %p has already been registered", header);
5309 ModestMailOperation *mail_op = NULL;
5310 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5311 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5312 modest_ui_actions_disk_operations_error_handler,
5314 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5315 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5317 g_object_unref (mail_op);
5320 g_object_unref (header);
5322 g_object_unref (header_list);
5326 * Checks if we need a connection to do the transfer and if the user
5327 * wants to connect to complete it
5330 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5331 TnyFolderStore *src_folder,
5333 TnyFolder *dst_folder,
5334 gboolean delete_originals,
5335 gboolean *need_connection,
5338 TnyAccount *src_account;
5339 gint uncached_msgs = 0;
5341 /* We don't need any further check if
5343 * 1- the source folder is local OR
5344 * 2- the device is already online
5346 if (!modest_tny_folder_store_is_remote (src_folder) ||
5347 tny_device_is_online (modest_runtime_get_device())) {
5348 *need_connection = FALSE;
5353 /* We must ask for a connection when
5355 * - the message(s) is not already cached OR
5356 * - the message(s) is cached but the leave_on_server setting
5357 * is FALSE (because we need to sync the source folder to
5358 * delete the message from the server (for IMAP we could do it
5359 * offline, it'll take place the next time we get a
5362 uncached_msgs = header_list_count_uncached_msgs (headers);
5363 src_account = get_account_from_folder_store (src_folder);
5364 if (uncached_msgs > 0) {
5368 *need_connection = TRUE;
5369 num_headers = tny_list_get_length (headers);
5370 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5372 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5373 GTK_RESPONSE_CANCEL) {
5379 /* The transfer is possible and the user wants to */
5382 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5383 const gchar *account_name;
5384 gboolean leave_on_server;
5386 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5387 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5390 if (leave_on_server == TRUE) {
5391 *need_connection = FALSE;
5393 *need_connection = TRUE;
5396 *need_connection = FALSE;
5401 g_object_unref (src_account);
5405 xfer_messages_error_handler (ModestMailOperation *mail_op,
5409 const GError *error;
5411 win = modest_mail_operation_get_source (mail_op);
5412 error = modest_mail_operation_get_error (mail_op);
5414 if (error && is_memory_full_error ((GError *) error))
5415 modest_platform_information_banner ((GtkWidget *) win,
5416 NULL, _KR("cerm_device_memory_full"));
5418 modest_platform_run_information_dialog ((GtkWindow *) win,
5419 _("mail_in_ui_folder_move_target_error"),
5422 g_object_unref (win);
5426 TnyFolderStore *dst_folder;
5431 * Utility function that transfer messages from both the main window
5432 * and the msg view window when using the "Move to" dialog
5435 xfer_messages_performer (gboolean canceled,
5437 GtkWindow *parent_window,
5438 TnyAccount *account,
5441 ModestWindow *win = MODEST_WINDOW (parent_window);
5442 TnyAccount *dst_account = NULL;
5443 gboolean dst_forbids_message_add = FALSE;
5444 XferMsgsHelper *helper;
5445 MoveToHelper *movehelper;
5446 ModestMailOperation *mail_op;
5448 helper = (XferMsgsHelper *) user_data;
5450 if (canceled || err) {
5451 if (!check_memory_full_error ((GtkWidget *) parent_window, err)) {
5452 /* Show the proper error message */
5453 modest_ui_actions_on_account_connection_error (parent_window, account);
5458 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5460 /* tinymail will return NULL for local folders it seems */
5461 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5462 modest_tny_account_get_protocol_type (dst_account),
5463 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_MESSAGE_ADD);
5464 g_object_unref (dst_account);
5466 if (dst_forbids_message_add) {
5467 modest_platform_information_banner (GTK_WIDGET (win),
5469 ngettext("mail_in_ui_folder_move_target_error",
5470 "mail_in_ui_folder_move_targets_error",
5471 tny_list_get_length (helper->headers)));
5475 movehelper = g_new0 (MoveToHelper, 1);
5477 #ifndef MODEST_TOOLKIT_HILDON2
5478 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5479 _CS("ckct_nw_pasting"));
5480 if (movehelper->banner != NULL) {
5481 g_object_ref (movehelper->banner);
5482 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5486 if (MODEST_IS_MAIN_WINDOW (win)) {
5487 GtkWidget *header_view =
5488 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5489 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5490 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5493 /* Perform the mail operation */
5494 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5495 xfer_messages_error_handler,
5497 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5500 modest_mail_operation_xfer_msgs (mail_op,
5502 TNY_FOLDER (helper->dst_folder),
5507 g_object_unref (G_OBJECT (mail_op));
5509 g_object_unref (helper->dst_folder);
5510 g_object_unref (helper->headers);
5511 g_slice_free (XferMsgsHelper, helper);
5515 TnyFolder *src_folder;
5516 TnyFolderStore *dst_folder;
5517 gboolean delete_original;
5518 GtkWidget *folder_view;
5522 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
5523 TnyAccount *account, gpointer user_data)
5525 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5526 GtkTreeSelection *sel;
5527 ModestMailOperation *mail_op = NULL;
5529 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
5530 g_object_unref (G_OBJECT (info->src_folder));
5531 g_object_unref (G_OBJECT (info->dst_folder));
5536 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5537 #ifndef MODEST_TOOLKIT_HILDON2
5538 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5539 _CS("ckct_nw_pasting"));
5540 if (helper->banner != NULL) {
5541 g_object_ref (helper->banner);
5542 gtk_widget_show (GTK_WIDGET(helper->banner));
5545 /* Clean folder on header view before moving it */
5546 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5547 gtk_tree_selection_unselect_all (sel);
5549 /* Let gtk events run. We need that the folder
5550 view frees its reference to the source
5551 folder *before* issuing the mail operation
5552 so we need the signal handler of selection
5553 changed to happen before the mail
5555 while (gtk_events_pending ())
5556 gtk_main_iteration (); */
5559 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5560 modest_ui_actions_move_folder_error_handler,
5561 info->src_folder, NULL);
5562 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5565 /* Select *after* the changes */
5566 /* TODO: this function hangs UI after transfer */
5567 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
5568 /* TNY_FOLDER (src_folder), TRUE); */
5570 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
5571 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5572 TNY_FOLDER (info->dst_folder), TRUE);
5574 modest_mail_operation_xfer_folder (mail_op,
5575 TNY_FOLDER (info->src_folder),
5577 info->delete_original,
5580 g_object_unref (G_OBJECT (info->src_folder));
5582 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5585 /* Unref mail operation */
5586 g_object_unref (G_OBJECT (mail_op));
5587 g_object_unref (G_OBJECT (info->dst_folder));
5592 get_account_from_folder_store (TnyFolderStore *folder_store)
5594 if (TNY_IS_ACCOUNT (folder_store))
5595 return g_object_ref (folder_store);
5597 return tny_folder_get_account (TNY_FOLDER (folder_store));
5601 * UI handler for the "Move to" action when invoked from the
5605 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5606 GtkWidget *folder_view,
5607 TnyFolderStore *dst_folder,
5608 ModestMainWindow *win)
5610 ModestHeaderView *header_view = NULL;
5611 TnyFolderStore *src_folder = NULL;
5613 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5615 /* Get the source folder */
5616 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5618 /* Get header view */
5619 header_view = (ModestHeaderView *)
5620 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5622 /* Get folder or messages to transfer */
5623 if (gtk_widget_is_focus (folder_view)) {
5624 gboolean do_xfer = TRUE;
5626 /* Allow only to transfer folders to the local root folder */
5627 if (TNY_IS_ACCOUNT (dst_folder) &&
5628 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5629 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5631 } else if (!TNY_IS_FOLDER (src_folder)) {
5632 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5637 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5638 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5640 info->src_folder = g_object_ref (src_folder);
5641 info->dst_folder = g_object_ref (dst_folder);
5642 info->delete_original = TRUE;
5643 info->folder_view = folder_view;
5645 connect_info->callback = on_move_folder_cb;
5646 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5647 connect_info->data = info;
5649 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5650 TNY_FOLDER_STORE (src_folder),
5653 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5656 headers = modest_header_view_get_selected_headers(header_view);
5658 /* Transfer the messages */
5659 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
5660 headers, TNY_FOLDER (dst_folder));
5662 g_object_unref (headers);
5666 g_object_unref (src_folder);
5669 #ifdef MODEST_TOOLKIT_HILDON2
5671 * UI handler for the "Move to" action when invoked from the
5672 * ModestFolderWindow
5675 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
5676 TnyFolderStore *dst_folder,
5680 TnyFolderStore *src_folder = NULL;
5681 TnyIterator *iterator;
5683 if (tny_list_get_length (selection) != 1)
5686 iterator = tny_list_create_iterator (selection);
5687 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
5688 g_object_unref (iterator);
5691 gboolean do_xfer = TRUE;
5693 /* Allow only to transfer folders to the local root folder */
5694 if (TNY_IS_ACCOUNT (dst_folder) &&
5695 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5696 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5699 modest_platform_run_information_dialog (win,
5700 _("mail_in_ui_folder_move_target_error"),
5702 } else if (!TNY_IS_FOLDER (src_folder)) {
5703 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5708 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5709 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5711 info->src_folder = g_object_ref (src_folder);
5712 info->dst_folder = g_object_ref (dst_folder);
5713 info->delete_original = TRUE;
5714 info->folder_view = folder_view;
5716 connect_info->callback = on_move_folder_cb;
5717 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5718 connect_info->data = info;
5720 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5721 TNY_FOLDER_STORE (src_folder),
5726 g_object_unref (src_folder);
5732 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
5733 TnyFolder *src_folder,
5735 TnyFolder *dst_folder)
5737 gboolean need_connection = TRUE;
5738 gboolean do_xfer = TRUE;
5739 XferMsgsHelper *helper;
5741 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5742 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5743 g_return_if_fail (TNY_IS_LIST (headers));
5745 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5746 headers, TNY_FOLDER (dst_folder),
5747 TRUE, &need_connection,
5750 /* If we don't want to transfer just return */
5754 /* Create the helper */
5755 helper = g_slice_new (XferMsgsHelper);
5756 helper->dst_folder = g_object_ref (dst_folder);
5757 helper->headers = g_object_ref (headers);
5759 if (need_connection) {
5760 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5761 connect_info->callback = xfer_messages_performer;
5762 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5763 connect_info->data = helper;
5765 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5766 TNY_FOLDER_STORE (src_folder),
5769 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5770 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
5771 src_account, helper);
5772 g_object_unref (src_account);
5777 * UI handler for the "Move to" action when invoked from the
5778 * ModestMsgViewWindow
5781 modest_ui_actions_on_window_move_to (GtkAction *action,
5783 TnyFolderStore *dst_folder,
5786 TnyFolder *src_folder = NULL;
5788 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5791 TnyHeader *header = NULL;
5794 iter = tny_list_create_iterator (headers);
5795 header = (TnyHeader *) tny_iterator_get_current (iter);
5796 src_folder = tny_header_get_folder (header);
5798 /* Transfer the messages */
5799 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
5801 TNY_FOLDER (dst_folder));
5804 g_object_unref (header);
5805 g_object_unref (iter);
5806 g_object_unref (src_folder);
5811 modest_ui_actions_on_move_to (GtkAction *action,
5814 modest_ui_actions_on_edit_mode_move_to (win);
5818 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
5820 GtkWidget *dialog = NULL;
5821 MoveToInfo *helper = NULL;
5822 TnyList *list_to_move;
5824 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
5826 #ifndef MODEST_TOOLKIT_HILDON2
5827 /* Get the main window if exists */
5828 ModestMainWindow *main_window;
5829 if (MODEST_IS_MAIN_WINDOW (win))
5830 main_window = MODEST_MAIN_WINDOW (win);
5833 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5834 FALSE)); /* don't create */
5837 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
5842 if (tny_list_get_length (list_to_move) < 1) {
5843 g_object_unref (list_to_move);
5847 /* Create and run the dialog */
5848 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL);
5849 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
5850 GTK_WINDOW (dialog),
5854 helper = g_slice_new0 (MoveToInfo);
5855 helper->list = list_to_move;
5858 /* Listen to response signal */
5859 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
5861 /* Show the dialog */
5862 gtk_widget_show (dialog);
5868 * Calls #HeadersFunc for each header already selected in the main
5869 * window or the message currently being shown in the msg view window
5872 do_headers_action (ModestWindow *win,
5876 TnyList *headers_list = NULL;
5877 TnyIterator *iter = NULL;
5878 TnyHeader *header = NULL;
5879 TnyFolder *folder = NULL;
5882 headers_list = get_selected_headers (win);
5886 /* Get the folder */
5887 iter = tny_list_create_iterator (headers_list);
5888 header = TNY_HEADER (tny_iterator_get_current (iter));
5890 folder = tny_header_get_folder (header);
5891 g_object_unref (header);
5894 /* Call the function for each header */
5895 while (!tny_iterator_is_done (iter)) {
5896 header = TNY_HEADER (tny_iterator_get_current (iter));
5897 func (header, win, user_data);
5898 g_object_unref (header);
5899 tny_iterator_next (iter);
5902 /* Trick: do a poke status in order to speed up the signaling
5905 tny_folder_poke_status (folder);
5906 g_object_unref (folder);
5910 g_object_unref (iter);
5911 g_object_unref (headers_list);
5915 modest_ui_actions_view_attachment (GtkAction *action,
5916 ModestWindow *window)
5918 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5919 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5921 /* not supported window for this action */
5922 g_return_if_reached ();
5927 modest_ui_actions_save_attachments (GtkAction *action,
5928 ModestWindow *window)
5930 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5932 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5935 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5937 /* not supported window for this action */
5938 g_return_if_reached ();
5943 modest_ui_actions_remove_attachments (GtkAction *action,
5944 ModestWindow *window)
5946 if (MODEST_IS_MAIN_WINDOW (window)) {
5947 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
5948 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5949 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5951 /* not supported window for this action */
5952 g_return_if_reached ();
5957 modest_ui_actions_on_settings (GtkAction *action,
5962 dialog = modest_platform_get_global_settings_dialog ();
5963 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
5964 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5965 gtk_widget_show_all (dialog);
5967 gtk_dialog_run (GTK_DIALOG (dialog));
5969 gtk_widget_destroy (dialog);
5973 modest_ui_actions_on_help (GtkAction *action,
5976 /* Help app is not available at all in fremantle */
5977 #ifndef MODEST_TOOLKIT_HILDON2
5978 const gchar *help_id;
5980 g_return_if_fail (win && GTK_IS_WINDOW(win));
5982 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5985 modest_platform_show_help (GTK_WINDOW (win), help_id);
5990 modest_ui_actions_on_csm_help (GtkAction *action,
5993 /* Help app is not available at all in fremantle */
5994 #ifndef MODEST_TOOLKIT_HILDON2
5996 const gchar* help_id = NULL;
5997 GtkWidget *folder_view;
5998 TnyFolderStore *folder_store;
6000 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
6002 /* Get selected folder */
6003 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
6004 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6005 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6007 /* Switch help_id */
6008 if (folder_store && TNY_IS_FOLDER (folder_store))
6009 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
6012 g_object_unref (folder_store);
6015 modest_platform_show_help (GTK_WINDOW (win), help_id);
6017 modest_ui_actions_on_help (action, win);
6022 retrieve_contents_cb (ModestMailOperation *mail_op,
6029 /* We only need this callback to show an error in case of
6030 memory low condition */
6031 modest_ui_actions_msg_retrieval_check (mail_op, header, msg);
6035 retrieve_msg_contents_performer (gboolean canceled,
6037 GtkWindow *parent_window,
6038 TnyAccount *account,
6041 ModestMailOperation *mail_op;
6042 TnyList *headers = TNY_LIST (user_data);
6044 if (err || canceled) {
6045 check_memory_full_error ((GtkWidget *) parent_window, err);
6049 /* Create mail operation */
6050 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
6051 modest_ui_actions_disk_operations_error_handler,
6053 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
6054 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
6057 g_object_unref (mail_op);
6059 g_object_unref (headers);
6060 g_object_unref (account);
6064 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
6065 ModestWindow *window)
6067 TnyList *headers = NULL;
6068 TnyAccount *account = NULL;
6069 TnyIterator *iter = NULL;
6070 TnyHeader *header = NULL;
6071 TnyFolder *folder = NULL;
6074 headers = get_selected_headers (window);
6078 /* Pick the account */
6079 iter = tny_list_create_iterator (headers);
6080 header = TNY_HEADER (tny_iterator_get_current (iter));
6081 folder = tny_header_get_folder (header);
6082 account = tny_folder_get_account (folder);
6083 g_object_unref (folder);
6084 g_object_unref (header);
6085 g_object_unref (iter);
6087 /* Connect and perform the message retrieval */
6088 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6089 g_object_ref (account),
6090 retrieve_msg_contents_performer,
6091 g_object_ref (headers));
6094 g_object_unref (account);
6095 g_object_unref (headers);
6099 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6101 g_return_if_fail (MODEST_IS_WINDOW (window));
6104 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6108 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6110 g_return_if_fail (MODEST_IS_WINDOW (window));
6113 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6117 modest_ui_actions_on_email_menu_activated (GtkAction *action,
6118 ModestWindow *window)
6120 g_return_if_fail (MODEST_IS_WINDOW (window));
6123 modest_ui_actions_check_menu_dimming_rules (window);
6127 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
6128 ModestWindow *window)
6130 g_return_if_fail (MODEST_IS_WINDOW (window));
6133 modest_ui_actions_check_menu_dimming_rules (window);
6137 modest_ui_actions_on_view_menu_activated (GtkAction *action,
6138 ModestWindow *window)
6140 g_return_if_fail (MODEST_IS_WINDOW (window));
6143 modest_ui_actions_check_menu_dimming_rules (window);
6147 modest_ui_actions_on_format_menu_activated (GtkAction *action,
6148 ModestWindow *window)
6150 g_return_if_fail (MODEST_IS_WINDOW (window));
6153 modest_ui_actions_check_menu_dimming_rules (window);
6157 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
6158 ModestWindow *window)
6160 g_return_if_fail (MODEST_IS_WINDOW (window));
6163 modest_ui_actions_check_menu_dimming_rules (window);
6167 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
6168 ModestWindow *window)
6170 g_return_if_fail (MODEST_IS_WINDOW (window));
6173 modest_ui_actions_check_menu_dimming_rules (window);
6177 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
6178 ModestWindow *window)
6180 g_return_if_fail (MODEST_IS_WINDOW (window));
6183 modest_ui_actions_check_menu_dimming_rules (window);
6187 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
6188 ModestWindow *window)
6190 g_return_if_fail (MODEST_IS_WINDOW (window));
6193 modest_ui_actions_check_menu_dimming_rules (window);
6197 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
6198 ModestWindow *window)
6200 g_return_if_fail (MODEST_IS_WINDOW (window));
6203 modest_ui_actions_check_menu_dimming_rules (window);
6207 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6209 g_return_if_fail (MODEST_IS_WINDOW (window));
6211 /* we check for low-mem; in that case, show a warning, and don't allow
6214 if (modest_platform_check_memory_low (window, TRUE))
6217 modest_platform_show_search_messages (GTK_WINDOW (window));
6221 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6223 g_return_if_fail (MODEST_IS_WINDOW (win));
6226 /* we check for low-mem; in that case, show a warning, and don't allow
6227 * for the addressbook
6229 if (modest_platform_check_memory_low (win, TRUE))
6233 modest_platform_show_addressbook (GTK_WINDOW (win));
6238 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6239 ModestWindow *window)
6242 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6244 if (GTK_IS_TOGGLE_ACTION (action))
6245 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6249 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window),
6254 on_send_receive_finished (ModestMailOperation *mail_op,
6257 GtkWidget *header_view, *folder_view;
6258 TnyFolderStore *folder_store;
6259 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6261 /* Set send/receive operation finished */
6262 modest_main_window_notify_send_receive_completed (main_win);
6264 /* Don't refresh the current folder if there were any errors */
6265 if (modest_mail_operation_get_status (mail_op) !=
6266 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6269 /* Refresh the current folder if we're viewing a window. We do
6270 this because the user won't be able to see the new mails in
6271 the selected folder after a Send&Receive because it only
6272 performs a poke_status, i.e, only the number of read/unread
6273 messages is updated, but the new headers are not
6275 folder_view = modest_main_window_get_child_widget (main_win,
6276 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6280 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6282 /* Do not need to refresh INBOX again because the
6283 update_account does it always automatically */
6284 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6285 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6286 ModestMailOperation *refresh_op;
6288 header_view = modest_main_window_get_child_widget (main_win,
6289 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6291 /* We do not need to set the contents style
6292 because it hasn't changed. We also do not
6293 need to save the widget status. Just force
6295 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6296 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6297 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6298 folder_refreshed_cb, main_win);
6299 g_object_unref (refresh_op);
6303 g_object_unref (folder_store);
6308 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6314 const gchar* server_name = NULL;
6315 TnyTransportAccount *server_account;
6316 gchar *message = NULL;
6318 /* Don't show anything if the user cancelled something or the
6319 * send receive request is not interactive. Authentication
6320 * errors are managed by the account store so no need to show
6321 * a dialog here again */
6322 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6323 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6324 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6328 /* Get the server name: */
6330 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
6332 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
6334 g_return_if_reached ();
6336 /* Show the appropriate message text for the GError: */
6337 switch (err->code) {
6338 case TNY_SERVICE_ERROR_CONNECT:
6339 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6341 case TNY_SERVICE_ERROR_SEND:
6342 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6344 case TNY_SERVICE_ERROR_UNAVAILABLE:
6345 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6348 g_warning ("%s: unexpected ERROR %d",
6349 __FUNCTION__, err->code);
6350 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6354 modest_platform_run_information_dialog (NULL, message, FALSE);
6356 g_object_unref (server_account);
6360 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6365 ModestWindow *top_window = NULL;
6366 ModestWindowMgr *mgr = NULL;
6367 GtkWidget *header_view = NULL;
6368 TnyFolder *selected_folder = NULL;
6369 TnyFolderType folder_type;
6371 mgr = modest_runtime_get_window_mgr ();
6372 top_window = modest_window_mgr_get_current_top (mgr);
6377 #ifndef MODEST_TOOLKIT_HILDON2
6378 if (MODEST_IS_MAIN_WINDOW (top_window)) {
6379 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (top_window),
6380 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6383 if (MODEST_IS_HEADER_WINDOW (top_window)) {
6384 header_view = (GtkWidget *)
6385 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
6389 /* Get selected folder */
6390 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
6391 if (!selected_folder)
6394 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6395 #if GTK_CHECK_VERSION(2, 8, 0)
6396 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
6397 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6398 GtkTreeViewColumn *tree_column;
6400 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6401 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6403 gtk_tree_view_column_queue_resize (tree_column);
6405 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
6406 gtk_widget_queue_draw (header_view);
6409 #ifndef MODEST_TOOLKIT_HILDON2
6410 /* Rerun dimming rules, because the message could become deletable for example */
6411 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6412 MODEST_DIMMING_RULES_TOOLBAR);
6413 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6414 MODEST_DIMMING_RULES_MENU);
6418 g_object_unref (selected_folder);
6422 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6423 TnyAccount *account)
6425 ModestProtocolType protocol_type;
6426 ModestProtocol *protocol;
6427 gchar *error_note = NULL;
6429 protocol_type = modest_tny_account_get_protocol_type (account);
6430 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6433 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6434 if (error_note == NULL) {
6435 g_warning ("%s: This should not be reached", __FUNCTION__);
6437 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6438 g_free (error_note);
6443 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6447 TnyFolderStore *folder = NULL;
6448 TnyAccount *account = NULL;
6449 ModestProtocolType proto;
6450 ModestProtocol *protocol;
6451 TnyHeader *header = NULL;
6453 if (MODEST_IS_MAIN_WINDOW (win)) {
6454 GtkWidget *header_view;
6455 TnyList* headers = NULL;
6457 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6458 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6459 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6460 if (!headers || tny_list_get_length (headers) == 0) {
6462 g_object_unref (headers);
6465 iter = tny_list_create_iterator (headers);
6466 header = TNY_HEADER (tny_iterator_get_current (iter));
6467 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6468 g_object_unref (iter);
6469 g_object_unref (headers);
6470 #ifdef MODEST_TOOLKIT_HILDON2
6471 } else if (MODEST_IS_HEADER_WINDOW (win)) {
6472 GtkWidget *header_view;
6473 TnyList* headers = NULL;
6475 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
6476 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6477 if (!headers || tny_list_get_length (headers) == 0) {
6479 g_object_unref (headers);
6482 iter = tny_list_create_iterator (headers);
6483 header = TNY_HEADER (tny_iterator_get_current (iter));
6484 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6485 g_object_unref (iter);
6486 g_object_unref (headers);
6488 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6489 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6490 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6493 /* Get the account type */
6494 account = tny_folder_get_account (TNY_FOLDER (folder));
6495 proto = modest_tny_account_get_protocol_type (account);
6496 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6499 subject = tny_header_dup_subject (header);
6500 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6504 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6508 g_object_unref (account);
6509 g_object_unref (folder);
6510 g_object_unref (header);
6516 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6517 const gchar *account_name,
6518 const gchar *account_title)
6520 ModestAccountMgr *account_mgr;
6523 ModestProtocol *protocol;
6524 gboolean removed = FALSE;
6526 g_return_val_if_fail (account_name, FALSE);
6527 g_return_val_if_fail (account_title, FALSE);
6529 account_mgr = modest_runtime_get_account_mgr();
6531 /* The warning text depends on the account type: */
6532 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6533 modest_account_mgr_get_store_protocol (account_mgr,
6535 txt = modest_protocol_get_translation (protocol,
6536 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6539 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6541 response = modest_platform_run_confirmation_dialog (parent_window, txt);
6545 if (response == GTK_RESPONSE_OK) {
6546 /* Remove account. If it succeeds then it also removes
6547 the account from the ModestAccountView: */
6548 gboolean is_default = FALSE;
6549 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6550 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6552 g_free (default_account_name);
6554 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6556 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);