1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #endif /*HAVE_CONFIG_H*/
34 #include <glib/gi18n.h>
35 #include <glib/gprintf.h>
37 #include <modest-runtime.h>
38 #include <modest-defs.h>
39 #include <modest-tny-folder.h>
40 #include <modest-tny-msg.h>
41 #include <modest-tny-account.h>
42 #include <modest-address-book.h>
43 #include "modest-error.h"
44 #include "modest-ui-actions.h"
45 #include "modest-tny-platform-factory.h"
46 #include "modest-platform.h"
47 #include "modest-debug.h"
48 #include <tny-mime-part.h>
49 #include <tny-error.h>
50 #include <tny-camel-folder.h>
51 #include <tny-camel-imap-folder.h>
52 #include <tny-camel-pop-folder.h>
53 #ifdef MODEST_TOOLKIT_HILDON2
54 #include <modest-accounts-window.h>
55 #include <hildon/hildon-pannable-area.h>
56 #include <hildon/hildon-gtk.h>
57 #include <modest-header-window.h>
58 #include <modest-folder-window.h>
59 #include <modest-maemo-utils.h>
62 #ifdef MODEST_PLATFORM_MAEMO
63 #include "maemo/modest-osso-state-saving.h"
64 #endif /* MODEST_PLATFORM_MAEMO */
65 #ifndef MODEST_TOOLKIT_GTK
66 #include "maemo/modest-hildon-includes.h"
67 #include "maemo/modest-connection-specific-smtp-window.h"
68 #endif /* !MODEST_TOOLKIT_GTK */
70 #include <modest-utils.h>
71 #include "widgets/modest-ui-constants.h"
72 #include <widgets/modest-main-window.h>
73 #include <widgets/modest-msg-view-window.h>
74 #include <widgets/modest-account-view-window.h>
75 #include <widgets/modest-details-dialog.h>
76 #include <widgets/modest-attachments-view.h>
77 #include "widgets/modest-folder-view.h"
78 #include "widgets/modest-global-settings-dialog.h"
79 #include "modest-account-mgr-helpers.h"
80 #include "modest-mail-operation.h"
81 #include "modest-text-utils.h"
82 #include <modest-widget-memory.h>
83 #include <tny-error.h>
84 #include <tny-simple-list.h>
85 #include <tny-msg-view.h>
86 #include <tny-device.h>
87 #include <tny-merge-folder.h>
88 #include <tny-camel-bs-msg.h>
89 #include <tny-camel-bs-mime-part.h>
92 #include <gtkhtml/gtkhtml.h>
94 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
96 typedef struct _GetMsgAsyncHelper {
98 ModestMailOperation *mail_op;
105 typedef enum _ReplyForwardAction {
109 } ReplyForwardAction;
111 typedef struct _ReplyForwardHelper {
112 guint reply_forward_type;
113 ReplyForwardAction action;
116 GtkWidget *parent_window;
118 TnyHeader *top_header;
121 } ReplyForwardHelper;
123 typedef struct _MoveToHelper {
124 GtkTreeRowReference *reference;
128 typedef struct _PasteAsAttachmentHelper {
129 ModestMsgEditWindow *window;
131 } PasteAsAttachmentHelper;
139 * The do_headers_action uses this kind of functions to perform some
140 * action to each member of a list of headers
142 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
144 static void do_headers_action (ModestWindow *win,
148 static void open_msg_cb (ModestMailOperation *mail_op,
155 static void reply_forward_cb (ModestMailOperation *mail_op,
162 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
164 static void folder_refreshed_cb (ModestMailOperation *mail_op,
168 static void on_send_receive_finished (ModestMailOperation *mail_op,
171 static gint header_list_count_uncached_msgs (TnyList *header_list);
173 static gboolean connect_to_get_msg (ModestWindow *win,
174 gint num_of_uncached_msgs,
175 TnyAccount *account);
177 static gboolean remote_folder_has_leave_on_server (TnyFolderStore *folder);
179 static void do_create_folder (GtkWindow *window,
180 TnyFolderStore *parent_folder,
181 const gchar *suggested_name);
183 static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store);
185 static void modest_ui_actions_on_main_window_move_to (GtkAction *action,
186 GtkWidget *folder_view,
187 TnyFolderStore *dst_folder,
188 ModestMainWindow *win);
189 #ifdef MODEST_TOOLKIT_HILDON2
190 static void modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
191 TnyFolderStore *dst_folder,
196 static void modest_ui_actions_on_window_move_to (GtkAction *action,
197 TnyList *list_to_move,
198 TnyFolderStore *dst_folder,
202 * This function checks whether a TnyFolderStore is a pop account
205 remote_folder_has_leave_on_server (TnyFolderStore *folder)
210 g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
212 account = get_account_from_folder_store (folder);
213 result = (modest_protocol_registry_protocol_type_has_leave_on_server (modest_runtime_get_protocol_registry (),
214 modest_tny_account_get_protocol_type (account)));
215 g_object_unref (account);
220 /* FIXME: this should be merged with the similar code in modest-account-view-window */
221 /* Show the account creation wizard dialog.
222 * returns: TRUE if an account was created. FALSE if the user cancelled.
225 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
227 gboolean result = FALSE;
229 gint dialog_response;
231 /* there is no such wizard yet */
232 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
233 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (wizard), (GtkWindow *) win);
235 #ifndef MODEST_TOOLKIT_HILDON2
236 /* always present a main window in the background
237 * we do it here, so we cannot end up with two wizards (as this
238 * function might be called in modest_window_mgr_get_main_window as well */
240 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
241 TRUE); /* create if not existent */
245 ModestWindowMgr *mgr;
247 mgr = modest_runtime_get_window_mgr ();
249 window_list = modest_window_mgr_get_window_list (mgr);
250 if (window_list == NULL) {
251 win = MODEST_WINDOW (modest_accounts_window_new ());
252 if (modest_window_mgr_register_window (mgr, win, NULL)) {
253 gtk_widget_show_all (GTK_WIDGET (win));
255 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 ModestWindowMgr *mgr = NULL;
531 GtkTreeModel *model = NULL;
532 GtkTreeSelection *sel = NULL;
533 GList *sel_list = NULL, *tmp = NULL;
534 GtkTreeRowReference *next_row_reference = NULL;
535 GtkTreeRowReference *prev_row_reference = NULL;
536 GtkTreePath *next_path = NULL;
537 GtkTreePath *prev_path = NULL;
538 ModestMailOperation *mail_op = NULL;
540 /* Find last selected row */
541 if (MODEST_IS_MAIN_WINDOW (win)) {
542 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
543 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
544 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
545 for (tmp=sel_list; tmp; tmp=tmp->next) {
546 if (tmp->next == NULL) {
547 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
548 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
550 gtk_tree_path_prev (prev_path);
551 gtk_tree_path_next (next_path);
553 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
554 next_row_reference = gtk_tree_row_reference_new (model, next_path);
559 /* Disable window dimming management */
560 modest_window_disable_dimming (win);
562 /* Remove each header. If it's a view window header_view == NULL */
563 mail_op = modest_mail_operation_new ((GObject *) win);
564 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
566 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
567 g_object_unref (mail_op);
569 /* Enable window dimming management */
571 gtk_tree_selection_unselect_all (sel);
573 modest_window_enable_dimming (win);
575 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
576 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
578 /* Get main window */
579 mgr = modest_runtime_get_window_mgr ();
580 } else if (MODEST_IS_MAIN_WINDOW (win)) {
581 /* Select next or previous row */
582 if (gtk_tree_row_reference_valid (next_row_reference)) {
583 gtk_tree_selection_select_path (sel, next_path);
585 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
586 gtk_tree_selection_select_path (sel, prev_path);
590 if (gtk_tree_row_reference_valid (next_row_reference))
591 gtk_tree_row_reference_free (next_row_reference);
592 if (next_path != NULL)
593 gtk_tree_path_free (next_path);
594 if (gtk_tree_row_reference_valid (prev_row_reference))
595 gtk_tree_row_reference_free (prev_row_reference);
596 if (prev_path != NULL)
597 gtk_tree_path_free (prev_path);
600 /* Update toolbar dimming state */
601 modest_ui_actions_check_menu_dimming_rules (win);
602 modest_ui_actions_check_toolbar_dimming_rules (win);
605 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
606 g_list_free (sel_list);
615 g_object_unref (header_list);
623 /* delete either message or folder, based on where we are */
625 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
627 g_return_if_fail (MODEST_IS_WINDOW(win));
629 /* Check first if the header view has the focus */
630 if (MODEST_IS_MAIN_WINDOW (win)) {
632 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
633 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
634 if (gtk_widget_is_focus (w)) {
635 modest_ui_actions_on_delete_folder (action, MODEST_WINDOW(win));
639 modest_ui_actions_on_delete_message (action, win);
643 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
645 ModestWindowMgr *mgr = NULL;
647 #ifdef MODEST_PLATFORM_MAEMO
648 modest_window_mgr_save_state_for_all_windows (modest_runtime_get_window_mgr ());
649 #endif /* MODEST_PLATFORM_MAEMO */
651 g_debug ("closing down, clearing %d item(s) from operation queue",
652 modest_mail_operation_queue_num_elements
653 (modest_runtime_get_mail_operation_queue()));
655 /* cancel all outstanding operations */
656 modest_mail_operation_queue_cancel_all
657 (modest_runtime_get_mail_operation_queue());
659 g_debug ("queue has been cleared");
662 /* Check if there are opened editing windows */
663 mgr = modest_runtime_get_window_mgr ();
664 modest_window_mgr_close_all_windows (mgr);
666 /* note: when modest-tny-account-store is finalized,
667 it will automatically set all network connections
670 /* gtk_main_quit (); */
674 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
678 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
680 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
681 /* gtk_widget_destroy (GTK_WIDGET (win)); */
682 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
683 /* gboolean ret_value; */
684 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
685 /* } else if (MODEST_IS_WINDOW (win)) { */
686 /* gtk_widget_destroy (GTK_WIDGET (win)); */
688 /* g_return_if_reached (); */
693 modest_ui_actions_add_to_contacts (GtkAction *action, ModestWindow *win)
695 if (MODEST_IS_MSG_VIEW_WINDOW (win))
696 modest_msg_view_window_add_to_contacts (MODEST_MSG_VIEW_WINDOW (win));
697 else if (MODEST_IS_MSG_EDIT_WINDOW (win))
698 modest_msg_edit_window_add_to_contacts (MODEST_MSG_EDIT_WINDOW (win));
702 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
704 GtkClipboard *clipboard = NULL;
705 gchar *selection = NULL;
707 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
708 selection = gtk_clipboard_wait_for_text (clipboard);
711 modest_address_book_add_address (selection, (GtkWindow *) win);
717 modest_ui_actions_on_new_account (GtkAction *action,
718 ModestWindow *window)
720 if (!modest_ui_actions_run_account_setup_wizard (window)) {
721 g_debug ("%s: wizard was already running", __FUNCTION__);
726 modest_ui_actions_on_accounts (GtkAction *action,
729 /* This is currently only implemented for Maemo */
730 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
731 if (!modest_ui_actions_run_account_setup_wizard (win))
732 g_debug ("%s: wizard was already running", __FUNCTION__);
736 /* Show the list of accounts */
737 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
739 /* The accounts dialog must be modal */
740 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
741 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
746 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
748 /* This is currently only implemented for Maemo,
749 * because it requires an API (libconic) to detect different connection
752 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
754 /* Create the window if necessary: */
755 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
756 modest_connection_specific_smtp_window_fill_with_connections (
757 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
758 modest_runtime_get_account_mgr());
760 /* Show the window: */
761 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
762 GTK_WINDOW (specific_window), (GtkWindow *) win);
763 gtk_widget_show (specific_window);
764 #endif /* !MODEST_TOOLKIT_GTK */
768 count_part_size (const gchar *part)
770 GnomeVFSURI *vfs_uri;
771 gchar *escaped_filename;
773 GnomeVFSFileInfo *info;
776 /* Estimation of attachment size if we cannot get it from file info */
779 vfs_uri = gnome_vfs_uri_new (part);
781 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
782 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
783 g_free (escaped_filename);
784 gnome_vfs_uri_unref (vfs_uri);
786 info = gnome_vfs_file_info_new ();
788 if (gnome_vfs_get_file_info (part,
790 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
792 if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) {
797 gnome_vfs_file_info_unref (info);
803 count_parts_size (GSList *parts)
808 for (node = parts; node != NULL; node = g_slist_next (node)) {
809 result += count_part_size ((const gchar *) node->data);
816 modest_ui_actions_compose_msg(ModestWindow *win,
819 const gchar *bcc_str,
820 const gchar *subject_str,
821 const gchar *body_str,
823 gboolean set_as_modified)
825 gchar *account_name = NULL;
826 const gchar *mailbox;
828 TnyAccount *account = NULL;
829 TnyFolder *folder = NULL;
830 gchar *from_str = NULL, *signature = NULL, *body = NULL;
831 gchar *recipient = NULL;
832 gboolean use_signature = FALSE;
833 ModestWindow *msg_win = NULL;
834 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
835 ModestTnyAccountStore *store = modest_runtime_get_account_store();
836 GnomeVFSFileSize total_size, allowed_size;
837 guint64 available_disk, expected_size, parts_size;
840 /* we check for low-mem */
841 if (modest_platform_check_memory_low (win, TRUE))
844 available_disk = modest_utils_get_available_space (NULL);
845 parts_count = g_slist_length (attachments);
846 parts_size = count_parts_size (attachments);
847 expected_size = modest_tny_msg_estimate_size (body, NULL, parts_count, parts_size);
849 /* Double check: disk full condition or message too big */
850 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
851 expected_size > available_disk) {
852 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
853 modest_platform_system_banner (NULL, NULL, msg);
859 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
860 modest_platform_run_information_dialog (
862 _("mail_ib_error_attachment_size"),
868 #ifdef MODEST_TOOLKIT_HILDON2
870 account_name = g_strdup (modest_window_get_active_account(win));
873 account_name = modest_account_mgr_get_default_account(mgr);
876 g_printerr ("modest: no account found\n");
881 mailbox = modest_window_get_active_mailbox (win);
884 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
886 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
889 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
891 g_printerr ("modest: failed to find Drafts folder\n");
894 from_str = modest_account_mgr_get_from_string (mgr, account_name, mailbox);
896 g_printerr ("modest: failed get from string for '%s'\n", account_name);
900 recipient = modest_text_utils_get_email_address (from_str);
901 signature = modest_account_mgr_get_signature_from_recipient (mgr, recipient, &use_signature);
903 if (body_str != NULL) {
904 body = use_signature ? g_strconcat(body_str, "\n",
905 MODEST_TEXT_UTILS_SIGNATURE_MARKER,
906 "\n", signature, NULL) : g_strdup(body_str);
909 gchar *gray_color_markup = NULL, *color_begin = NULL, *color_end = NULL;
912 if (win && gtk_style_lookup_color (gtk_widget_get_style ((GtkWidget *) win),
913 "SecondaryTextColor", &color))
914 gray_color_markup = modest_text_utils_get_color_string (&color);
915 if (!gray_color_markup)
916 gray_color_markup = g_strdup ("#babababababa");
918 color_begin = g_strdup_printf ("<font color=\"%s\">", gray_color_markup);
919 color_end = "</font>";
921 body = use_signature ? g_strconcat("<br/>\n", color_begin,
922 MODEST_TEXT_UTILS_SIGNATURE_MARKER, "<br/>\n",
923 signature, color_end, NULL) : g_strdup("");
925 g_free (gray_color_markup);
926 g_free (color_begin);
929 msg = modest_tny_msg_new_html_plain (to_str, from_str, cc_str, bcc_str, subject_str,
930 NULL, NULL, body, NULL, NULL, NULL, NULL, NULL);
932 g_printerr ("modest: failed to create new msg\n");
936 /* Create and register edit window */
937 /* This is destroyed by TODO. */
939 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
940 msg_win = modest_msg_edit_window_new (msg, account_name, mailbox, FALSE);
942 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, win)) {
943 gtk_widget_destroy (GTK_WIDGET (msg_win));
946 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
947 gtk_widget_show_all (GTK_WIDGET (msg_win));
949 while (attachments) {
950 GnomeVFSFileSize att_size;
952 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
953 attachments->data, allowed_size);
954 total_size += att_size;
956 if (att_size > allowed_size) {
957 g_debug ("%s: total size: %u",
958 __FUNCTION__, (unsigned int)total_size);
961 allowed_size -= att_size;
963 attachments = g_slist_next(attachments);
970 g_free (account_name);
972 g_object_unref (G_OBJECT(account));
974 g_object_unref (G_OBJECT(folder));
976 g_object_unref (G_OBJECT(msg));
980 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
982 /* if there are no accounts yet, just show the wizard */
983 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
984 if (!modest_ui_actions_run_account_setup_wizard (win))
987 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
992 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
996 ModestMailOperationStatus status;
998 /* If there is no message or the operation was not successful */
999 status = modest_mail_operation_get_status (mail_op);
1000 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
1001 const GError *error;
1003 /* If it's a memory low issue, then show a banner */
1004 error = modest_mail_operation_get_error (mail_op);
1005 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
1006 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
1007 GObject *source = modest_mail_operation_get_source (mail_op);
1008 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
1009 _KR("memr_ib_operation_disabled"),
1011 g_object_unref (source);
1014 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
1015 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
1016 gchar *subject, *msg, *format = NULL;
1017 TnyAccount *account;
1019 subject = (header) ? tny_header_dup_subject (header) : NULL;
1021 subject = g_strdup (_("mail_va_no_subject"));
1023 account = modest_mail_operation_get_account (mail_op);
1025 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
1026 ModestProtocol *protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), proto);
1029 if (tny_account_get_connection_status (account) ==
1030 TNY_CONNECTION_STATUS_CONNECTED) {
1032 format = modest_protocol_get_translation (protocol,
1033 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE,
1036 format = modest_protocol_get_translation (protocol,
1037 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE_LOST_HEADER);
1040 format = g_strdup_printf (_("mail_ib_backend_server_invalid"),
1041 tny_account_get_hostname (account));
1044 g_object_unref (account);
1049 format = g_strdup (_("emev_ni_ui_imap_message_not_available_in_server"));
1051 format = g_strdup (_("emev_ni_ui_pop3_msg_recv_error"));
1055 msg = g_strdup_printf (format, subject);
1056 modest_platform_run_information_dialog (NULL, msg, FALSE);
1062 /* Remove the header from the preregistered uids */
1063 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1076 } OpenMsgBannerInfo;
1079 GtkTreeModel *model;
1081 ModestWindow *caller_window;
1082 OpenMsgBannerInfo *banner_info;
1083 GtkTreeRowReference *rowref;
1087 open_msg_banner_idle (gpointer userdata)
1089 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
1091 gdk_threads_enter ();
1092 banner_info->idle_handler = 0;
1093 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
1094 if (banner_info->banner)
1095 g_object_ref (banner_info->banner);
1097 gdk_threads_leave ();
1103 get_header_view_from_window (ModestWindow *window)
1105 GtkWidget *header_view;
1107 if (MODEST_IS_MAIN_WINDOW (window)) {
1108 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
1109 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1110 #ifdef MODEST_TOOLKIT_HILDON2
1111 } else if (MODEST_IS_HEADER_WINDOW (window)){
1112 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
1122 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
1125 gchar *account = NULL;
1126 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
1131 folder = tny_header_get_folder (header);
1132 /* Gets folder type (OUTBOX headers will be opened in edit window */
1133 if (modest_tny_folder_is_local_folder (folder)) {
1134 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1135 if (folder_type == TNY_FOLDER_TYPE_INVALID)
1136 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1139 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
1140 TnyTransportAccount *traccount = NULL;
1141 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
1142 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
1144 ModestTnySendQueue *send_queue = NULL;
1145 ModestTnySendQueueStatus status;
1147 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
1148 TNY_ACCOUNT(traccount)));
1149 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
1150 if (TNY_IS_SEND_QUEUE (send_queue)) {
1151 msg_id = modest_tny_send_queue_get_msg_id (header);
1152 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
1154 /* Only open messages in outbox with the editor if they are in Failed state */
1155 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
1158 #ifdef MODEST_TOOLKIT_HILDON2
1160 /* In Fremantle we can not
1161 open any message from
1162 outbox which is not in
1168 g_object_unref(traccount);
1170 g_warning("Cannot get transport account for message in outbox!!");
1172 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
1173 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
1177 TnyAccount *acc = tny_folder_get_account (folder);
1180 g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (acc));
1181 g_object_unref (acc);
1185 g_object_unref (folder);
1191 open_msg_cb (ModestMailOperation *mail_op,
1198 ModestWindowMgr *mgr = NULL;
1199 ModestWindow *parent_win = NULL;
1200 ModestWindow *win = NULL;
1201 gchar *account = NULL;
1202 gboolean open_in_editor = FALSE;
1204 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1206 /* Do nothing if there was any problem with the mail
1207 operation. The error will be shown by the error_handler of
1208 the mail operation */
1209 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1212 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1214 /* Mark header as read */
1215 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1217 account = get_info_from_header (header, &open_in_editor, &can_open);
1221 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1223 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1225 if (open_in_editor) {
1226 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1227 gchar *from_header = NULL, *acc_name;
1228 gchar *mailbox = NULL;
1230 from_header = tny_header_dup_from (header);
1232 /* we cannot edit without a valid account... */
1233 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1234 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1235 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1237 g_free (from_header);
1242 acc_name = modest_utils_get_account_name_from_recipient (from_header, &mailbox);
1243 g_free (from_header);
1249 win = modest_msg_edit_window_new (msg, account, mailbox, TRUE);
1253 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1254 const gchar *mailbox = NULL;
1256 if (parent_win && MODEST_IS_WINDOW (parent_win))
1257 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_win));
1259 if (helper->rowref && helper->model) {
1260 win = modest_msg_view_window_new_with_header_model (msg, account, mailbox, (const gchar*) uid,
1261 helper->model, helper->rowref);
1263 win = modest_msg_view_window_new_for_attachment (msg, NULL, account, mailbox, (const gchar*) uid);
1268 /* Register and show new window */
1270 mgr = modest_runtime_get_window_mgr ();
1271 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1272 gtk_widget_destroy (GTK_WIDGET (win));
1275 gtk_widget_show_all (GTK_WIDGET(win));
1278 /* Update toolbar dimming state */
1279 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1280 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1286 g_object_unref (parent_win);
1290 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1293 const GError *error;
1294 GObject *win = NULL;
1295 ModestMailOperationStatus status;
1297 win = modest_mail_operation_get_source (mail_op);
1298 error = modest_mail_operation_get_error (mail_op);
1299 status = modest_mail_operation_get_status (mail_op);
1301 /* If the mail op has been cancelled then it's not an error:
1302 don't show any message */
1303 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1304 TnyAccount *account = modest_mail_operation_get_account (mail_op);
1305 if (modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
1306 (GError *) error, account)) {
1307 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
1308 modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
1310 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1311 modest_platform_information_banner ((GtkWidget *) win,
1312 NULL, _("emev_ui_imap_inbox_select_error"));
1313 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1314 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1315 modest_platform_information_banner ((GtkWidget *) win,
1316 NULL, _CS ("sfil_ni_unable_to_open_file_not_found"));
1317 } else if (user_data) {
1318 modest_platform_information_banner ((GtkWidget *) win,
1322 g_object_unref (account);
1326 g_object_unref (win);
1330 * Returns the account a list of headers belongs to. It returns a
1331 * *new* reference so don't forget to unref it
1334 get_account_from_header_list (TnyList *headers)
1336 TnyAccount *account = NULL;
1338 if (tny_list_get_length (headers) > 0) {
1339 TnyIterator *iter = tny_list_create_iterator (headers);
1340 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1341 TnyFolder *folder = tny_header_get_folder (header);
1344 g_object_unref (header);
1346 while (!tny_iterator_is_done (iter)) {
1347 header = TNY_HEADER (tny_iterator_get_current (iter));
1348 folder = tny_header_get_folder (header);
1351 g_object_unref (header);
1353 tny_iterator_next (iter);
1358 account = tny_folder_get_account (folder);
1359 g_object_unref (folder);
1363 g_object_unref (header);
1365 g_object_unref (iter);
1371 get_account_from_header (TnyHeader *header)
1373 TnyAccount *account = NULL;
1376 folder = tny_header_get_folder (header);
1379 account = tny_folder_get_account (folder);
1380 g_object_unref (folder);
1386 caller_win_destroyed (OpenMsgHelper *helper, GObject *object)
1388 if (helper->caller_window)
1389 helper->caller_window = NULL;
1393 open_msg_helper_destroyer (gpointer user_data)
1395 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1397 if (helper->caller_window) {
1398 g_object_weak_unref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1399 helper->caller_window = NULL;
1402 if (helper->banner_info) {
1403 g_free (helper->banner_info->message);
1404 if (helper->banner_info->idle_handler > 0) {
1405 g_source_remove (helper->banner_info->idle_handler);
1406 helper->banner_info->idle_handler = 0;
1408 if (helper->banner_info->banner != NULL) {
1409 gtk_widget_destroy (helper->banner_info->banner);
1410 g_object_unref (helper->banner_info->banner);
1411 helper->banner_info->banner = NULL;
1413 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1414 helper->banner_info = NULL;
1416 g_object_unref (helper->model);
1417 g_object_unref (helper->header);
1418 gtk_tree_row_reference_free (helper->rowref);
1419 g_slice_free (OpenMsgHelper, helper);
1423 open_msg_performer(gboolean canceled,
1425 GtkWindow *parent_window,
1426 TnyAccount *account,
1429 ModestMailOperation *mail_op = NULL;
1430 gchar *error_msg = NULL;
1431 ModestProtocolType proto;
1432 TnyConnectionStatus status;
1433 OpenMsgHelper *helper = NULL;
1434 ModestProtocol *protocol;
1435 ModestProtocolRegistry *protocol_registry;
1438 helper = (OpenMsgHelper *) user_data;
1440 status = tny_account_get_connection_status (account);
1441 if (err || canceled || helper->caller_window == NULL) {
1442 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1443 /* Free the helper */
1444 open_msg_helper_destroyer (helper);
1446 /* In disk full conditions we could get this error here */
1447 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
1448 (GtkWidget *) parent_window, err,
1454 /* Get the error message depending on the protocol */
1455 proto = modest_tny_account_get_protocol_type (account);
1456 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1457 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1460 protocol_registry = modest_runtime_get_protocol_registry ();
1461 subject = tny_header_dup_subject (helper->header);
1463 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1464 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1468 if (error_msg == NULL) {
1469 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1472 #ifndef MODEST_TOOLKIT_HILDON2
1473 gboolean show_open_draft = FALSE;
1474 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1476 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1478 TnyFolderType folder_type;
1480 folder = tny_header_get_folder (helper->header);
1481 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1482 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1483 g_object_unref (folder);
1487 #ifdef MODEST_TOOLKIT_HILDON2
1490 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1492 if (!g_strcmp0 (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) ||
1493 !g_strcmp0 (account_name, MODEST_MMC_ACCOUNT_ID)) {
1494 g_free (account_name);
1495 account_name = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_window)));
1499 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1500 g_free (account_name);
1501 open_msg_helper_destroyer (helper);
1506 ModestWindow *window;
1507 GtkWidget *header_view;
1510 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1511 uid = modest_tny_folder_get_header_unique_id (helper->header);
1513 const gchar *mailbox = NULL;
1514 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_window));
1515 window = modest_msg_view_window_new_from_header_view
1516 (MODEST_HEADER_VIEW (header_view), account_name, mailbox, uid, helper->rowref);
1517 if (window != NULL) {
1518 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1520 gtk_widget_destroy (GTK_WIDGET (window));
1522 gtk_widget_show_all (GTK_WIDGET(window));
1526 g_free (account_name);
1528 open_msg_helper_destroyer (helper);
1531 g_free (account_name);
1533 /* Create the mail operation */
1535 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1536 modest_ui_actions_disk_operations_error_handler,
1537 g_strdup (error_msg), g_free);
1538 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1542 #ifndef MODEST_TOOLKIT_HILDON2
1543 if (show_open_draft) {
1544 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1545 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1546 helper->banner_info->banner = NULL;
1547 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1548 helper->banner_info);
1554 headers = TNY_LIST (tny_simple_list_new ());
1555 tny_list_prepend (headers, G_OBJECT (helper->header));
1556 modest_mail_operation_get_msgs_full (mail_op,
1560 open_msg_helper_destroyer);
1561 g_object_unref (headers);
1568 g_object_unref (mail_op);
1569 g_object_unref (account);
1573 * This function is used by both modest_ui_actions_on_open and
1574 * modest_ui_actions_on_header_activated. This way we always do the
1575 * same when trying to open messages.
1578 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1580 ModestWindowMgr *mgr = NULL;
1581 TnyAccount *account;
1582 gboolean cached = FALSE;
1584 GtkWidget *header_view = NULL;
1585 OpenMsgHelper *helper;
1586 ModestWindow *window;
1588 g_return_if_fail (header != NULL && rowref != NULL && gtk_tree_row_reference_valid (rowref));
1590 mgr = modest_runtime_get_window_mgr ();
1593 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1594 if (header_view == NULL)
1597 /* Get the account */
1598 account = get_account_from_header (header);
1603 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1605 /* Do not open again the message and present the
1606 window to the user */
1609 #ifndef MODEST_TOOLKIT_HILDON2
1610 gtk_window_present (GTK_WINDOW (window));
1613 /* the header has been registered already, we don't do
1614 * anything but wait for the window to come up*/
1615 g_debug ("header %p already registered, waiting for window", header);
1620 /* Open each message */
1621 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1623 /* Allways download if we are online. */
1624 if (!tny_device_is_online (modest_runtime_get_device ())) {
1627 /* If ask for user permission to download the messages */
1628 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1629 _("mcen_nc_get_msg"));
1631 /* End if the user does not want to continue */
1632 if (response == GTK_RESPONSE_CANCEL) {
1638 /* We register the window for opening */
1639 modest_window_mgr_register_header (mgr, header, NULL);
1641 /* Create the helper. We need to get a reference to the model
1642 here because it could change while the message is readed
1643 (the user could switch between folders) */
1644 helper = g_slice_new (OpenMsgHelper);
1645 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1646 helper->caller_window = win;
1647 g_object_weak_ref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1648 helper->header = g_object_ref (header);
1649 helper->rowref = gtk_tree_row_reference_copy (rowref);
1650 helper->banner_info = NULL;
1652 /* Connect to the account and perform */
1654 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1655 open_msg_performer, helper);
1657 /* Call directly the performer, do not need to connect */
1658 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1659 g_object_ref (account), helper);
1664 g_object_unref (account);
1668 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1675 /* we check for low-mem; in that case, show a warning, and don't allow
1678 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1682 headers = get_selected_headers (win);
1686 headers_count = tny_list_get_length (headers);
1687 if (headers_count != 1) {
1688 if (headers_count > 1) {
1689 /* Don't allow activation if there are more than one message selected */
1690 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1693 g_object_unref (headers);
1697 iter = tny_list_create_iterator (headers);
1698 header = TNY_HEADER (tny_iterator_get_current (iter));
1699 g_object_unref (iter);
1703 open_msg_from_header (header, NULL, win);
1704 g_object_unref (header);
1707 g_object_unref(headers);
1711 rf_helper_window_closed (gpointer data,
1714 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1716 helper->parent_window = NULL;
1719 static ReplyForwardHelper*
1720 create_reply_forward_helper (ReplyForwardAction action,
1722 guint reply_forward_type,
1725 TnyHeader *top_header,
1728 ReplyForwardHelper *rf_helper = NULL;
1729 const gchar *active_acc = modest_window_get_active_account (win);
1730 const gchar *active_mailbox = modest_window_get_active_mailbox (win);
1732 rf_helper = g_slice_new0 (ReplyForwardHelper);
1733 rf_helper->reply_forward_type = reply_forward_type;
1734 rf_helper->action = action;
1735 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1736 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1737 rf_helper->top_header = (top_header) ? g_object_ref (top_header) : NULL;
1738 rf_helper->msg_part = (msg_part) ? g_object_ref (msg_part) : NULL;
1739 rf_helper->account_name = (active_acc) ?
1740 g_strdup (active_acc) :
1741 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1742 rf_helper->mailbox = g_strdup (active_mailbox);
1744 rf_helper->parts = g_object_ref (parts);
1746 rf_helper->parts = NULL;
1748 /* Note that window could be destroyed just AFTER calling
1749 register_window so we must ensure that this pointer does
1750 not hold invalid references */
1751 if (rf_helper->parent_window)
1752 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1753 rf_helper_window_closed, rf_helper);
1759 free_reply_forward_helper (gpointer data)
1761 ReplyForwardHelper *helper;
1763 helper = (ReplyForwardHelper *) data;
1764 g_free (helper->account_name);
1765 g_free (helper->mailbox);
1767 g_object_unref (helper->header);
1768 if (helper->top_header)
1769 g_object_unref (helper->top_header);
1770 if (helper->msg_part)
1771 g_object_unref (helper->msg_part);
1773 g_object_unref (helper->parts);
1774 if (helper->parent_window)
1775 g_object_weak_unref (G_OBJECT (helper->parent_window),
1776 rf_helper_window_closed, helper);
1777 g_slice_free (ReplyForwardHelper, helper);
1781 reply_forward_cb (ModestMailOperation *mail_op,
1788 TnyMsg *new_msg = NULL;
1789 ReplyForwardHelper *rf_helper;
1790 ModestWindow *msg_win = NULL;
1791 ModestEditType edit_type;
1793 TnyAccount *account = NULL;
1794 ModestWindowMgr *mgr = NULL;
1795 gchar *signature = NULL;
1796 gboolean use_signature;
1799 /* If there was any error. The mail operation could be NULL,
1800 this means that we already have the message downloaded and
1801 that we didn't do a mail operation to retrieve it */
1802 rf_helper = (ReplyForwardHelper *) user_data;
1803 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1806 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1807 rf_helper->account_name, rf_helper->mailbox);
1808 recipient = modest_text_utils_get_email_address (from);
1809 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr(),
1814 /* Create reply mail */
1815 switch (rf_helper->action) {
1816 /* Use the msg_header to ensure that we have all the
1817 information. The summary can lack some data */
1818 TnyHeader *msg_header;
1820 msg_header = tny_msg_get_header (rf_helper->msg_part?rf_helper->msg_part:msg);
1822 modest_tny_msg_create_reply_msg (rf_helper->msg_part?rf_helper->msg_part:msg, msg_header, from,
1823 (use_signature) ? signature : NULL,
1824 rf_helper->reply_forward_type,
1825 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1826 g_object_unref (msg_header);
1828 case ACTION_REPLY_TO_ALL:
1829 msg_header = tny_msg_get_header (rf_helper->msg_part?rf_helper->msg_part:msg);
1831 modest_tny_msg_create_reply_msg (rf_helper->msg_part?rf_helper->msg_part:msg, msg_header, from,
1832 (use_signature) ? signature : NULL,
1833 rf_helper->reply_forward_type,
1834 MODEST_TNY_MSG_REPLY_MODE_ALL);
1835 edit_type = MODEST_EDIT_TYPE_REPLY;
1836 g_object_unref (msg_header);
1838 case ACTION_FORWARD:
1840 modest_tny_msg_create_forward_msg (rf_helper->msg_part?rf_helper->msg_part:msg, from,
1841 (use_signature) ? signature : NULL,
1842 rf_helper->reply_forward_type);
1843 edit_type = MODEST_EDIT_TYPE_FORWARD;
1846 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1848 g_return_if_reached ();
1856 g_warning ("%s: failed to create message\n", __FUNCTION__);
1860 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1861 rf_helper->account_name,
1862 TNY_ACCOUNT_TYPE_STORE);
1864 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1868 /* Create and register the windows */
1869 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, rf_helper->mailbox, FALSE);
1870 mgr = modest_runtime_get_window_mgr ();
1871 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1873 /* Note that register_window could have deleted the account */
1874 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1875 gdouble parent_zoom;
1877 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1878 modest_window_set_zoom (msg_win, parent_zoom);
1881 /* Show edit window */
1882 gtk_widget_show_all (GTK_WIDGET (msg_win));
1885 /* We always unregister the header because the message is
1886 forwarded or replied so the original one is no longer
1888 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1891 g_object_unref (G_OBJECT (new_msg));
1893 g_object_unref (G_OBJECT (account));
1894 free_reply_forward_helper (rf_helper);
1897 /* Checks a list of headers. If any of them are not currently
1898 * downloaded (CACHED) then returns TRUE else returns FALSE.
1901 header_list_count_uncached_msgs (TnyList *header_list)
1904 gint uncached_messages = 0;
1906 iter = tny_list_create_iterator (header_list);
1907 while (!tny_iterator_is_done (iter)) {
1910 header = TNY_HEADER (tny_iterator_get_current (iter));
1912 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1913 uncached_messages ++;
1914 g_object_unref (header);
1917 tny_iterator_next (iter);
1919 g_object_unref (iter);
1921 return uncached_messages;
1924 /* Returns FALSE if the user does not want to download the
1925 * messages. Returns TRUE if the user allowed the download.
1928 connect_to_get_msg (ModestWindow *win,
1929 gint num_of_uncached_msgs,
1930 TnyAccount *account)
1932 GtkResponseType response;
1934 /* Allways download if we are online. */
1935 if (tny_device_is_online (modest_runtime_get_device ()))
1938 /* If offline, then ask for user permission to download the messages */
1939 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1940 ngettext("mcen_nc_get_msg",
1942 num_of_uncached_msgs));
1944 if (response == GTK_RESPONSE_CANCEL)
1947 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1951 reply_forward_performer (gboolean canceled,
1953 GtkWindow *parent_window,
1954 TnyAccount *account,
1957 ReplyForwardHelper *rf_helper = NULL;
1958 ModestMailOperation *mail_op;
1960 rf_helper = (ReplyForwardHelper *) user_data;
1962 if (canceled || err) {
1963 free_reply_forward_helper (rf_helper);
1967 /* Retrieve the message */
1968 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1969 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1970 modest_ui_actions_disk_operations_error_handler,
1972 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1973 modest_mail_operation_get_msg_and_parts (mail_op, rf_helper->top_header, rf_helper->parts, TRUE, reply_forward_cb, rf_helper);
1976 g_object_unref(mail_op);
1980 all_parts_retrieved (TnyMimePart *part)
1982 if (!TNY_IS_CAMEL_BS_MIME_PART (part)) {
1985 TnyList *pending_parts;
1986 TnyIterator *iterator;
1987 gboolean all_retrieved = TRUE;
1989 pending_parts = TNY_LIST (tny_simple_list_new ());
1990 tny_mime_part_get_parts (part, pending_parts);
1991 iterator = tny_list_create_iterator (pending_parts);
1992 while (all_retrieved && !tny_iterator_is_done (iterator)) {
1995 child = TNY_MIME_PART (tny_iterator_get_current (iterator));
1997 if (tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (child))) {
1998 all_retrieved = all_parts_retrieved (TNY_MIME_PART (child));
2000 all_retrieved = FALSE;
2003 g_object_unref (child);
2004 tny_iterator_next (iterator);
2006 g_object_unref (iterator);
2007 g_object_unref (pending_parts);
2008 return all_retrieved;
2013 forward_pending_parts_helper (TnyMimePart *part, TnyList *list)
2016 TnyIterator *iterator;
2018 if (!tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (part))) {
2019 tny_list_append (list, G_OBJECT (part));
2021 parts = TNY_LIST (tny_simple_list_new ());
2022 tny_mime_part_get_parts (part, parts);
2023 for (iterator = tny_list_create_iterator (parts);
2024 !tny_iterator_is_done (iterator);
2025 tny_iterator_next (iterator)) {
2028 child = TNY_MIME_PART (tny_iterator_get_current (iterator));
2029 forward_pending_parts_helper (child, list);
2030 g_object_unref (child);
2032 g_object_unref (iterator);
2033 g_object_unref (parts);
2037 forward_pending_parts (TnyMsg *msg)
2039 TnyList *result = TNY_LIST (tny_simple_list_new ());
2040 if (TNY_IS_CAMEL_BS_MIME_PART (msg)) {
2041 forward_pending_parts_helper (TNY_MIME_PART (msg), result);
2048 * Common code for the reply and forward actions
2051 reply_forward (ReplyForwardAction action, ModestWindow *win)
2053 ReplyForwardHelper *rf_helper = NULL;
2054 guint reply_forward_type;
2056 g_return_if_fail (win && MODEST_IS_WINDOW(win));
2058 /* we check for low-mem; in that case, show a warning, and don't allow
2059 * reply/forward (because it could potentially require a lot of memory */
2060 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2064 /* we need an account when editing */
2065 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
2066 if (!modest_ui_actions_run_account_setup_wizard (win))
2070 reply_forward_type =
2071 modest_conf_get_int (modest_runtime_get_conf (),
2072 (action == ACTION_FORWARD) ?
2073 MODEST_CONF_FORWARD_TYPE :
2074 MODEST_CONF_REPLY_TYPE,
2077 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2079 TnyMsg *top_msg = NULL;
2080 TnyHeader *header = NULL;
2081 /* Get header and message. Do not free them here, the
2082 reply_forward_cb must do it */
2083 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
2084 top_msg = modest_msg_view_window_get_top_message (MODEST_MSG_VIEW_WINDOW(win));
2085 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
2087 if (msg && header && (action != ACTION_FORWARD || all_parts_retrieved (TNY_MIME_PART (msg)))) {
2089 rf_helper = create_reply_forward_helper (action, win,
2090 reply_forward_type, header, NULL, NULL, NULL);
2091 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
2093 gboolean do_download = TRUE;
2095 if (msg && header && action == ACTION_FORWARD) {
2096 if (top_msg == NULL)
2097 top_msg = g_object_ref (msg);
2098 /* Not all parts retrieved. Then we have to retrieve them all before
2099 * creating the forward message */
2100 if (!tny_device_is_online (modest_runtime_get_device ())) {
2103 /* If ask for user permission to download the messages */
2104 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2105 ngettext("mcen_nc_get_msg",
2109 /* End if the user does not want to continue */
2110 if (response == GTK_RESPONSE_CANCEL)
2111 do_download = FALSE;
2115 TnyList *pending_parts;
2117 TnyAccount *account;
2118 TnyHeader *top_header;
2121 top_header = tny_msg_get_header (top_msg);
2122 pending_parts = forward_pending_parts (top_msg);
2123 rf_helper = create_reply_forward_helper (action, win,
2124 reply_forward_type, header, msg, top_header, pending_parts);
2125 g_object_unref (pending_parts);
2127 folder = tny_header_get_folder (top_header);
2128 account = tny_folder_get_account (folder);
2129 modest_platform_connect_and_perform (GTK_WINDOW (win),
2131 reply_forward_performer,
2133 if (folder) g_object_unref (folder);
2134 g_object_unref (account);
2135 if (top_header) g_object_unref (top_header);
2139 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
2144 g_object_unref (msg);
2146 g_object_unref (top_msg);
2148 g_object_unref (header);
2150 TnyHeader *header = NULL;
2152 gboolean do_retrieve = TRUE;
2153 TnyList *header_list = NULL;
2155 header_list = get_selected_headers (win);
2158 /* Check that only one message is selected for replying */
2159 if (tny_list_get_length (header_list) != 1) {
2160 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
2161 NULL, _("mcen_ib_select_one_message"));
2162 g_object_unref (header_list);
2166 /* Only reply/forward to one message */
2167 iter = tny_list_create_iterator (header_list);
2168 header = TNY_HEADER (tny_iterator_get_current (iter));
2169 g_object_unref (iter);
2171 /* Retrieve messages */
2172 do_retrieve = (action == ACTION_FORWARD) ||
2173 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
2176 TnyAccount *account = NULL;
2177 TnyFolder *folder = NULL;
2178 gdouble download = TRUE;
2179 guint uncached_msgs = 0;
2181 folder = tny_header_get_folder (header);
2183 goto do_retrieve_frees;
2184 account = tny_folder_get_account (folder);
2186 goto do_retrieve_frees;
2188 uncached_msgs = header_list_count_uncached_msgs (header_list);
2190 if (uncached_msgs > 0) {
2191 /* Allways download if we are online. */
2192 if (!tny_device_is_online (modest_runtime_get_device ())) {
2195 /* If ask for user permission to download the messages */
2196 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2197 ngettext("mcen_nc_get_msg",
2201 /* End if the user does not want to continue */
2202 if (response == GTK_RESPONSE_CANCEL)
2209 rf_helper = create_reply_forward_helper (action, win,
2210 reply_forward_type, header, NULL, NULL, NULL);
2211 if (uncached_msgs > 0) {
2212 modest_platform_connect_and_perform (GTK_WINDOW (win),
2214 reply_forward_performer,
2217 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
2218 account, rf_helper);
2223 g_object_unref (account);
2225 g_object_unref (folder);
2227 reply_forward_cb (NULL, header, FALSE, NULL, NULL, NULL);
2230 g_object_unref (header_list);
2231 g_object_unref (header);
2236 modest_ui_actions_reply_calendar (ModestWindow *win, TnyMsg *msg, TnyList *header_pairs)
2241 gboolean use_signature;
2244 gdouble parent_zoom;
2245 const gchar *account_name;
2246 const gchar *mailbox;
2247 TnyHeader *msg_header;
2248 ModestWindowMgr *mgr;
2250 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW(win));
2252 /* we check for low-mem; in that case, show a warning, and don't allow
2253 * reply/forward (because it could potentially require a lot of memory */
2254 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2257 account_name = modest_window_get_active_account (MODEST_WINDOW (win));
2258 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (win));
2259 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
2260 account_name, mailbox);
2261 recipient = modest_text_utils_get_email_address (from);
2262 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr(),
2267 msg_header = tny_msg_get_header (msg);
2269 modest_tny_msg_create_reply_calendar_msg (msg, msg_header, from,
2270 (use_signature) ? signature : NULL,
2272 g_object_unref (msg_header);
2278 g_warning ("%s: failed to create message\n", __FUNCTION__);
2282 msg_win = (GtkWidget *) modest_msg_edit_window_new (new_msg, account_name, mailbox, FALSE);
2283 mgr = modest_runtime_get_window_mgr ();
2284 modest_window_mgr_register_window (mgr, MODEST_WINDOW (msg_win), (ModestWindow *) win);
2286 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (win));
2287 modest_window_set_zoom (MODEST_WINDOW (msg_win), parent_zoom);
2289 /* Show edit window */
2290 gtk_widget_show_all (GTK_WIDGET (msg_win));
2294 g_object_unref (G_OBJECT (new_msg));
2298 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
2300 g_return_if_fail (MODEST_IS_WINDOW(win));
2302 reply_forward (ACTION_REPLY, win);
2306 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
2308 g_return_if_fail (MODEST_IS_WINDOW(win));
2310 reply_forward (ACTION_FORWARD, win);
2314 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
2316 g_return_if_fail (MODEST_IS_WINDOW(win));
2318 reply_forward (ACTION_REPLY_TO_ALL, win);
2322 modest_ui_actions_on_next (GtkAction *action,
2323 ModestWindow *window)
2325 if (MODEST_IS_MAIN_WINDOW (window)) {
2326 GtkWidget *header_view;
2328 header_view = modest_main_window_get_child_widget (
2329 MODEST_MAIN_WINDOW(window),
2330 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2334 modest_header_view_select_next (
2335 MODEST_HEADER_VIEW(header_view));
2336 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2337 modest_msg_view_window_select_next_message (
2338 MODEST_MSG_VIEW_WINDOW (window));
2340 g_return_if_reached ();
2345 modest_ui_actions_on_prev (GtkAction *action,
2346 ModestWindow *window)
2348 g_return_if_fail (MODEST_IS_WINDOW(window));
2350 if (MODEST_IS_MAIN_WINDOW (window)) {
2351 GtkWidget *header_view;
2352 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2353 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2357 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
2358 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2359 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
2361 g_return_if_reached ();
2366 modest_ui_actions_on_sort (GtkAction *action,
2367 ModestWindow *window)
2369 GtkWidget *header_view = NULL;
2371 g_return_if_fail (MODEST_IS_WINDOW(window));
2373 if (MODEST_IS_MAIN_WINDOW (window)) {
2374 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2375 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2376 #ifdef MODEST_TOOLKIT_HILDON2
2377 } else if (MODEST_IS_HEADER_WINDOW (window)) {
2378 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2383 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
2388 /* Show sorting dialog */
2389 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
2393 sync_folder_cb (ModestMailOperation *mail_op,
2397 ModestHeaderView *header_view = (ModestHeaderView *) user_data;
2399 if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
2400 ModestWindow *parent = (ModestWindow *) modest_mail_operation_get_source (mail_op);
2402 /* We must clear first, because otherwise set_folder will ignore */
2403 /* the change as the folders are the same */
2404 modest_header_view_clear (header_view);
2405 modest_header_view_set_folder (header_view, folder, TRUE, parent, NULL, NULL);
2407 g_object_unref (parent);
2410 g_object_unref (header_view);
2414 idle_refresh_folder (gpointer source)
2416 ModestHeaderView *header_view = NULL;
2418 /* If the window still exists */
2419 if (!GTK_IS_WIDGET (source) ||
2420 !GTK_WIDGET_VISIBLE (source))
2423 /* Refresh the current view */
2424 #ifdef MODEST_TOOLKIT_HILDON2
2425 if (MODEST_IS_HEADER_WINDOW (source))
2426 header_view = modest_header_window_get_header_view ((ModestHeaderWindow *) source);
2428 if (MODEST_IS_MAIN_WINDOW (source))
2429 header_view = MODEST_HEADER_VIEW (modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source),
2430 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
2433 TnyFolder *folder = modest_header_view_get_folder (header_view);
2435 /* Sync the folder status */
2436 ModestMailOperation *mail_op = modest_mail_operation_new (source);
2437 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2438 modest_mail_operation_sync_folder (mail_op, folder, FALSE, sync_folder_cb, g_object_ref (header_view));
2439 g_object_unref (folder);
2440 g_object_unref (mail_op);
2448 update_account_cb (ModestMailOperation *self,
2449 TnyList *new_headers,
2453 gboolean show_visual_notifications;
2455 top = modest_window_mgr_get_current_top (modest_runtime_get_window_mgr ());
2456 show_visual_notifications = (top) ? FALSE : TRUE;
2458 /* Notify new messages have been downloaded. If the
2459 send&receive was invoked by the user then do not show any
2460 visual notification, only play a sound and activate the LED
2461 (for the Maemo version) */
2462 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0) {
2464 /* We only notify about really new messages (not seen) we get */
2465 TnyList *actually_new_list;
2466 TnyIterator *iterator;
2467 actually_new_list = TNY_LIST (tny_simple_list_new ());
2468 for (iterator = tny_list_create_iterator (new_headers);
2469 !tny_iterator_is_done (iterator);
2470 tny_iterator_next (iterator)) {
2472 TnyHeaderFlags flags;
2473 header = TNY_HEADER (tny_iterator_get_current (iterator));
2474 flags = tny_header_get_flags (header);
2476 if (!(flags & TNY_HEADER_FLAG_SEEN)) {
2477 /* Messages are ordered from most
2478 recent to oldest. But we want to
2479 show notifications starting from
2480 the oldest message. That's why we
2482 tny_list_prepend (actually_new_list, G_OBJECT (header));
2484 g_object_unref (header);
2486 g_object_unref (iterator);
2488 if (tny_list_get_length (actually_new_list) > 0) {
2489 GList *new_headers_list = NULL;
2491 new_headers_list = modest_utils_create_notification_list_from_header_list (actually_new_list);
2493 /* Send notifications */
2494 if (new_headers_list) {
2495 modest_platform_on_new_headers_received (new_headers_list,
2496 show_visual_notifications);
2498 modest_utils_free_notification_list (new_headers_list);
2501 g_object_unref (actually_new_list);
2505 /* Refresh the current folder in an idle. We do this
2506 in order to avoid refresh cancelations if the
2507 currently viewed folder is the inbox */
2508 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
2509 idle_refresh_folder,
2516 TnyAccount *account;
2518 gchar *account_name;
2519 gboolean poke_status;
2520 gboolean interactive;
2521 ModestMailOperation *mail_op;
2525 do_send_receive_performer (gboolean canceled,
2527 GtkWindow *parent_window,
2528 TnyAccount *account,
2531 SendReceiveInfo *info;
2533 info = (SendReceiveInfo *) user_data;
2535 if (err || canceled) {
2536 /* In disk full conditions we could get this error here */
2537 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
2538 (GtkWidget *) parent_window, err,
2541 if (info->mail_op) {
2542 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2548 /* Set send/receive operation in progress */
2549 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2550 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2553 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2554 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2555 G_CALLBACK (on_send_receive_finished),
2558 /* Send & receive. */
2559 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2560 update_account_cb, info->win);
2565 g_object_unref (G_OBJECT (info->mail_op));
2566 if (info->account_name)
2567 g_free (info->account_name);
2569 g_object_unref (info->win);
2571 g_object_unref (info->account);
2572 g_slice_free (SendReceiveInfo, info);
2576 * This function performs the send & receive required actions. The
2577 * window is used to create the mail operation. Typically it should
2578 * always be the main window, but we pass it as argument in order to
2582 modest_ui_actions_do_send_receive (const gchar *account_name,
2583 gboolean force_connection,
2584 gboolean poke_status,
2585 gboolean interactive,
2588 gchar *acc_name = NULL;
2589 SendReceiveInfo *info;
2590 ModestTnyAccountStore *acc_store;
2591 TnyAccount *account;
2593 /* If no account name was provided then get the current account, and if
2594 there is no current account then pick the default one: */
2595 if (!account_name) {
2597 acc_name = g_strdup (modest_window_get_active_account (win));
2599 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2601 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2605 acc_name = g_strdup (account_name);
2608 acc_store = modest_runtime_get_account_store ();
2609 account = modest_tny_account_store_get_server_account (acc_store, acc_name, TNY_ACCOUNT_TYPE_STORE);
2613 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2617 /* Do not automatically refresh accounts that are flagged as
2618 NO_AUTO_UPDATE. This could be useful for accounts that
2619 handle their own update times */
2621 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
2622 if (proto != MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
2623 const gchar *tag = MODEST_PROTOCOL_REGISTRY_NO_AUTO_UPDATE_PROTOCOLS;
2624 ModestProtocolRegistry *registry = modest_runtime_get_protocol_registry ();
2626 if (modest_protocol_registry_protocol_type_has_tag (registry, proto, tag)) {
2627 g_debug ("%s no auto update allowed for account %s", __FUNCTION__, account_name);
2628 g_object_unref (account);
2635 /* Create the info for the connect and perform */
2636 info = g_slice_new (SendReceiveInfo);
2637 info->account_name = acc_name;
2638 info->win = (win) ? g_object_ref (win) : NULL;
2639 info->poke_status = poke_status;
2640 info->interactive = interactive;
2641 info->account = account;
2642 /* We need to create the operation here, because otherwise it
2643 could happen that the queue emits the queue-empty signal
2644 while we're trying to connect the account */
2645 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2646 modest_ui_actions_disk_operations_error_handler,
2648 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2650 /* Invoke the connect and perform */
2651 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2652 force_connection, info->account,
2653 do_send_receive_performer, info);
2658 modest_ui_actions_do_cancel_send (const gchar *account_name,
2661 TnyTransportAccount *transport_account;
2662 TnySendQueue *send_queue = NULL;
2663 GError *error = NULL;
2665 /* Get transport account */
2667 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2668 (modest_runtime_get_account_store(),
2670 TNY_ACCOUNT_TYPE_TRANSPORT));
2671 if (!transport_account) {
2672 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2677 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2678 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2679 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2680 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2681 "modest: could not find send queue for account\n");
2683 /* Cancel the current send */
2684 tny_account_cancel (TNY_ACCOUNT (transport_account));
2686 /* Suspend all pending messages */
2687 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2691 if (transport_account != NULL)
2692 g_object_unref (G_OBJECT (transport_account));
2696 modest_ui_actions_cancel_send_all (ModestWindow *win)
2698 GSList *account_names, *iter;
2700 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2703 iter = account_names;
2705 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2706 iter = g_slist_next (iter);
2709 modest_account_mgr_free_account_names (account_names);
2710 account_names = NULL;
2714 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2717 /* Check if accounts exist */
2718 gboolean accounts_exist =
2719 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2721 /* If not, allow the user to create an account before trying to send/receive. */
2722 if (!accounts_exist)
2723 modest_ui_actions_on_accounts (NULL, win);
2725 /* Cancel all sending operaitons */
2726 modest_ui_actions_cancel_send_all (win);
2730 * Refreshes all accounts. This function will be used by automatic
2734 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2735 gboolean force_connection,
2736 gboolean poke_status,
2737 gboolean interactive)
2739 GSList *account_names, *iter;
2741 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2744 iter = account_names;
2746 modest_ui_actions_do_send_receive ((const char*) iter->data,
2748 poke_status, interactive, win);
2749 iter = g_slist_next (iter);
2752 modest_account_mgr_free_account_names (account_names);
2753 account_names = NULL;
2757 * Handler of the click on Send&Receive button in the main toolbar
2760 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2762 /* Check if accounts exist */
2763 gboolean accounts_exist;
2766 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2768 /* If not, allow the user to create an account before trying to send/receive. */
2769 if (!accounts_exist)
2770 modest_ui_actions_on_accounts (NULL, win);
2772 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2773 if (MODEST_IS_MAIN_WINDOW (win)) {
2774 GtkWidget *folder_view;
2775 TnyFolderStore *folder_store;
2778 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2779 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2783 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2786 g_object_unref (folder_store);
2787 /* Refresh the active account. Force the connection if needed
2788 and poke the status of all folders */
2789 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2790 #ifdef MODEST_TOOLKIT_HILDON2
2791 } else if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2792 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2795 const gchar *active_account;
2796 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2798 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2805 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2808 GtkWidget *header_view;
2810 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2812 header_view = modest_main_window_get_child_widget (main_window,
2813 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2817 conf = modest_runtime_get_conf ();
2819 /* what is saved/restored is depending on the style; thus; we save with
2820 * old style, then update the style, and restore for this new style
2822 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2824 if (modest_header_view_get_style
2825 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2826 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2827 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2829 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2830 MODEST_HEADER_VIEW_STYLE_DETAILS);
2832 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2833 MODEST_CONF_HEADER_VIEW_KEY);
2838 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2840 ModestMainWindow *main_window)
2842 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2843 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2845 /* in the case the folder is empty, show the empty folder message and focus
2847 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2848 if (modest_header_view_is_empty (header_view)) {
2849 TnyFolder *folder = modest_header_view_get_folder (header_view);
2850 GtkWidget *folder_view =
2851 modest_main_window_get_child_widget (main_window,
2852 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2853 if (folder != NULL) {
2854 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2855 g_object_unref (folder);
2857 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2861 /* If no header has been selected then exit */
2866 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2867 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2869 /* Update toolbar dimming state */
2870 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2871 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2875 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2878 ModestWindow *window)
2880 GtkWidget *open_widget;
2881 GtkTreeRowReference *rowref;
2883 g_return_if_fail (MODEST_IS_WINDOW(window));
2884 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2885 g_return_if_fail (TNY_IS_HEADER (header));
2887 if (modest_header_view_count_selected_headers (header_view) > 1) {
2888 /* Don't allow activation if there are more than one message selected */
2889 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2893 /* we check for low-mem; in that case, show a warning, and don't allow
2894 * activating headers
2896 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2899 if (MODEST_IS_MAIN_WINDOW (window)) {
2900 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2901 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2902 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2906 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2907 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2908 gtk_tree_row_reference_free (rowref);
2912 set_active_account_from_tny_account (TnyAccount *account,
2913 ModestWindow *window)
2915 const gchar *server_acc_name = tny_account_get_id (account);
2917 /* We need the TnyAccount provided by the
2918 account store because that is the one that
2919 knows the name of the Modest account */
2920 TnyAccount *modest_server_account =
2921 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2922 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2924 if (!modest_server_account) {
2925 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2929 /* Update active account, but only if it's not a pseudo-account */
2930 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2931 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2932 const gchar *modest_acc_name =
2933 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2934 if (modest_acc_name)
2935 modest_window_set_active_account (window, modest_acc_name);
2938 g_object_unref (modest_server_account);
2943 folder_refreshed_cb (ModestMailOperation *mail_op,
2947 ModestMainWindow *win = NULL;
2948 GtkWidget *folder_view, *header_view;
2949 const GError *error;
2951 g_return_if_fail (TNY_IS_FOLDER (folder));
2953 win = MODEST_MAIN_WINDOW (user_data);
2955 /* Check if the operation failed due to memory low conditions */
2956 error = modest_mail_operation_get_error (mail_op);
2957 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2958 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2959 modest_platform_run_information_dialog (GTK_WINDOW (win),
2960 _KR("memr_ib_operation_disabled"),
2966 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2968 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2971 TnyFolderStore *current_folder;
2973 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2974 if (current_folder) {
2975 gboolean different = ((TnyFolderStore *) folder != current_folder);
2976 g_object_unref (current_folder);
2982 /* Check if folder is empty and set headers view contents style */
2983 if ((tny_folder_get_all_count (folder) == 0) ||
2984 modest_header_view_is_empty (MODEST_HEADER_VIEW (header_view)))
2985 modest_main_window_set_contents_style (win,
2986 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2990 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2991 TnyFolderStore *folder_store,
2993 ModestMainWindow *main_window)
2995 GtkWidget *header_view;
2997 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2999 header_view = modest_main_window_get_child_widget(main_window,
3000 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3005 if (TNY_IS_ACCOUNT (folder_store)) {
3007 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
3009 /* Show account details */
3010 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
3013 if (TNY_IS_FOLDER (folder_store) && selected) {
3014 TnyAccount *account;
3016 /* Update the active account */
3017 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
3019 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
3020 g_object_unref (account);
3024 /* Set the header style by default, it could
3025 be changed later by the refresh callback to
3027 modest_main_window_set_contents_style (main_window,
3028 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
3030 /* Set folder on header view. This function
3031 will call tny_folder_refresh_async so we
3032 pass a callback that will be called when
3033 finished. We use that callback to set the
3034 empty view if there are no messages */
3035 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
3036 TNY_FOLDER (folder_store),
3038 MODEST_WINDOW (main_window),
3039 folder_refreshed_cb,
3042 /* Restore configuration. We need to do this
3043 *after* the set_folder because the widget
3044 memory asks the header view about its
3046 modest_widget_memory_restore (modest_runtime_get_conf (),
3047 G_OBJECT(header_view),
3048 MODEST_CONF_HEADER_VIEW_KEY);
3050 /* No need to save the header view
3051 configuration for Maemo because it only
3052 saves the sorting stuff and that it's
3053 already being done by the sort
3054 dialog. Remove it when the GNOME version
3055 has the same behaviour */
3056 #ifdef MODEST_TOOLKIT_GTK
3057 if (modest_main_window_get_contents_style (main_window) ==
3058 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
3059 modest_widget_memory_save (modest_runtime_get_conf (),
3060 G_OBJECT (header_view),
3061 MODEST_CONF_HEADER_VIEW_KEY);
3063 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
3067 /* Update dimming state */
3068 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
3069 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
3073 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
3080 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
3082 online = tny_device_is_online (modest_runtime_get_device());
3085 /* already online -- the item is simply not there... */
3086 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
3088 GTK_MESSAGE_WARNING,
3090 _("The %s you selected cannot be found"),
3092 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
3093 gtk_dialog_run (GTK_DIALOG(dialog));
3095 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
3098 _("mcen_bd_dialog_cancel"),
3099 GTK_RESPONSE_REJECT,
3100 _("mcen_bd_dialog_ok"),
3101 GTK_RESPONSE_ACCEPT,
3103 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
3104 "Do you want to get online?"), item);
3105 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
3106 gtk_label_new (txt), FALSE, FALSE, 0);
3107 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3110 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
3111 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3112 /* TODO: Comment about why is this commented out: */
3113 /* modest_platform_connect_and_wait (); */
3116 gtk_widget_destroy (dialog);
3120 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
3123 /* g_debug ("%s %s", __FUNCTION__, link); */
3128 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
3131 modest_platform_activate_uri (link);
3135 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
3138 modest_platform_show_uri_popup (link);
3142 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
3145 /* we check for low-mem; in that case, show a warning, and don't allow
3146 * viewing attachments
3148 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
3151 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
3155 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
3156 const gchar *address,
3159 /* g_debug ("%s %s", __FUNCTION__, address); */
3163 on_save_to_drafts_cb (ModestMailOperation *mail_op,
3164 TnyMsg *saved_draft,
3167 ModestMsgEditWindow *edit_window;
3169 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
3170 #ifndef MODEST_TOOLKIT_HILDON2
3171 ModestMainWindow *win;
3173 /* FIXME. Make the header view sensitive again. This is a
3174 * temporary hack. See modest_ui_actions_on_save_to_drafts()
3176 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
3177 modest_runtime_get_window_mgr(), FALSE));
3179 GtkWidget *hdrview = modest_main_window_get_child_widget(
3180 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3181 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
3185 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
3187 /* Set draft is there was no error */
3188 if (!modest_mail_operation_get_error (mail_op))
3189 modest_msg_edit_window_set_draft (edit_window, saved_draft);
3191 g_object_unref(edit_window);
3195 enough_space_for_message (ModestMsgEditWindow *edit_window,
3198 guint64 available_disk, expected_size;
3203 available_disk = modest_utils_get_available_space (NULL);
3204 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
3205 expected_size = modest_tny_msg_estimate_size (data->plain_body,
3210 /* Double check: disk full condition or message too big */
3211 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
3212 expected_size > available_disk) {
3213 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3214 modest_platform_information_banner (NULL, NULL, msg);
3221 * djcb: if we're in low-memory state, we only allow for
3222 * saving messages smaller than
3223 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
3224 * should still allow for sending anything critical...
3226 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
3227 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
3231 * djcb: we also make sure that the attachments are smaller than the max size
3232 * this is for the case where we'd try to forward a message with attachments
3233 * bigger than our max allowed size, or sending an message from drafts which
3234 * somehow got past our checks when attaching.
3236 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
3237 modest_platform_run_information_dialog (
3238 GTK_WINDOW(edit_window),
3239 _("mail_ib_error_attachment_size"),
3248 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3250 TnyTransportAccount *transport_account;
3251 ModestMailOperation *mail_operation;
3253 gchar *account_name;
3254 ModestAccountMgr *account_mgr;
3255 gboolean had_error = FALSE;
3256 ModestMainWindow *win = NULL;
3258 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
3260 data = modest_msg_edit_window_get_msg_data (edit_window);
3263 if (!enough_space_for_message (edit_window, data)) {
3264 modest_msg_edit_window_free_msg_data (edit_window, data);
3268 account_name = g_strdup (data->account_name);
3269 account_mgr = modest_runtime_get_account_mgr();
3271 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3273 account_name = modest_account_mgr_get_default_account (account_mgr);
3274 if (!account_name) {
3275 g_printerr ("modest: no account found\n");
3276 modest_msg_edit_window_free_msg_data (edit_window, data);
3280 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
3281 account_name = g_strdup (data->account_name);
3285 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3286 (modest_runtime_get_account_store (),
3288 TNY_ACCOUNT_TYPE_TRANSPORT));
3289 if (!transport_account) {
3290 g_printerr ("modest: no transport account found for '%s'\n", account_name);
3291 g_free (account_name);
3292 modest_msg_edit_window_free_msg_data (edit_window, data);
3296 /* Create the mail operation */
3297 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
3299 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3301 modest_mail_operation_save_to_drafts (mail_operation,
3313 data->priority_flags,
3316 on_save_to_drafts_cb,
3317 g_object_ref(edit_window));
3319 #ifdef MODEST_TOOLKIT_HILDON2
3320 /* In hildon2 we always show the information banner on saving to drafts.
3321 * It will be a system information banner in this case.
3323 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3324 modest_platform_information_banner (NULL, NULL, text);
3327 /* Use the main window as the parent of the banner, if the
3328 main window does not exist it won't be shown, if the parent
3329 window exists then it's properly shown. We don't use the
3330 editor window because it could be closed (save to drafts
3331 could happen after closing the window */
3332 win = (ModestMainWindow *)
3333 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
3335 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3336 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
3340 modest_msg_edit_window_set_modified (edit_window, FALSE);
3343 g_free (account_name);
3344 g_object_unref (G_OBJECT (transport_account));
3345 g_object_unref (G_OBJECT (mail_operation));
3347 modest_msg_edit_window_free_msg_data (edit_window, data);
3350 * If the drafts folder is selected then make the header view
3351 * insensitive while the message is being saved to drafts
3352 * (it'll be sensitive again in on_save_to_drafts_cb()). This
3353 * is not very clean but it avoids letting the drafts folder
3354 * in an inconsistent state: the user could edit the message
3355 * being saved and undesirable things would happen.
3356 * In the average case the user won't notice anything at
3357 * all. In the worst case (the user is editing a really big
3358 * file from Drafts) the header view will be insensitive
3359 * during the saving process (10 or 20 seconds, depending on
3360 * the message). Anyway this is just a quick workaround: once
3361 * we find a better solution it should be removed
3362 * See NB#65125 (commend #18) for details.
3364 if (!had_error && win != NULL) {
3365 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
3366 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
3368 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
3370 if (modest_tny_folder_is_local_folder(folder)) {
3371 TnyFolderType folder_type;
3372 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
3373 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
3374 GtkWidget *hdrview = modest_main_window_get_child_widget(
3375 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3376 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
3380 if (folder != NULL) g_object_unref(folder);
3387 /* For instance, when clicking the Send toolbar button when editing a message: */
3389 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3391 TnyTransportAccount *transport_account = NULL;
3392 gboolean had_error = FALSE, add_to_contacts;
3394 ModestAccountMgr *account_mgr;
3395 gchar *account_name;
3396 ModestMailOperation *mail_operation;
3399 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
3401 /* Check whether to automatically add new contacts to addressbook or not */
3402 add_to_contacts = modest_conf_get_bool (modest_runtime_get_conf (),
3403 MODEST_CONF_AUTO_ADD_TO_CONTACTS, NULL);
3404 if (!modest_msg_edit_window_check_names (edit_window, add_to_contacts))
3407 data = modest_msg_edit_window_get_msg_data (edit_window);
3409 recipients = g_strconcat (data->to?data->to:"",
3410 data->cc?data->cc:"",
3411 data->bcc?data->bcc:"",
3413 if (recipients == NULL || recipients[0] == '\0') {
3414 /* Empty subject -> no send */
3415 g_free (recipients);
3416 modest_msg_edit_window_free_msg_data (edit_window, data);
3419 g_free (recipients);
3422 if (!enough_space_for_message (edit_window, data)) {
3423 modest_msg_edit_window_free_msg_data (edit_window, data);
3427 account_mgr = modest_runtime_get_account_mgr();
3428 account_name = g_strdup (data->account_name);
3430 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3433 account_name = modest_account_mgr_get_default_account (account_mgr);
3435 if (!account_name) {
3436 modest_msg_edit_window_free_msg_data (edit_window, data);
3437 /* Run account setup wizard */
3438 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
3443 /* Get the currently-active transport account for this modest account: */
3444 if (account_name && strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
3446 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3447 (modest_runtime_get_account_store (),
3448 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
3451 if (!transport_account) {
3452 modest_msg_edit_window_free_msg_data (edit_window, data);
3453 /* Run account setup wizard */
3454 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
3459 /* Create the mail operation */
3460 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
3461 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3463 modest_mail_operation_send_new_mail (mail_operation,
3477 data->priority_flags);
3479 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3480 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
3482 if (modest_mail_operation_get_error (mail_operation) != NULL) {
3483 const GError *error = modest_mail_operation_get_error (mail_operation);
3484 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3485 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3486 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3487 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3493 g_free (account_name);
3494 g_object_unref (G_OBJECT (transport_account));
3495 g_object_unref (G_OBJECT (mail_operation));
3497 modest_msg_edit_window_free_msg_data (edit_window, data);
3500 modest_msg_edit_window_set_sent (edit_window, TRUE);
3502 /* Save settings and close the window: */
3503 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3510 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3511 ModestMsgEditWindow *window)
3513 ModestMsgEditFormatState *format_state = NULL;
3515 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3516 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3518 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3521 format_state = modest_msg_edit_window_get_format_state (window);
3522 g_return_if_fail (format_state != NULL);
3524 format_state->bold = gtk_toggle_action_get_active (action);
3525 modest_msg_edit_window_set_format_state (window, format_state);
3526 g_free (format_state);
3531 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3532 ModestMsgEditWindow *window)
3534 ModestMsgEditFormatState *format_state = NULL;
3536 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3537 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3539 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3542 format_state = modest_msg_edit_window_get_format_state (window);
3543 g_return_if_fail (format_state != NULL);
3545 format_state->italics = gtk_toggle_action_get_active (action);
3546 modest_msg_edit_window_set_format_state (window, format_state);
3547 g_free (format_state);
3552 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3553 ModestMsgEditWindow *window)
3555 ModestMsgEditFormatState *format_state = NULL;
3557 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3558 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3560 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3563 format_state = modest_msg_edit_window_get_format_state (window);
3564 g_return_if_fail (format_state != NULL);
3566 format_state->bullet = gtk_toggle_action_get_active (action);
3567 modest_msg_edit_window_set_format_state (window, format_state);
3568 g_free (format_state);
3573 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3574 GtkRadioAction *selected,
3575 ModestMsgEditWindow *window)
3577 ModestMsgEditFormatState *format_state = NULL;
3578 GtkJustification value;
3580 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3582 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3585 value = gtk_radio_action_get_current_value (selected);
3587 format_state = modest_msg_edit_window_get_format_state (window);
3588 g_return_if_fail (format_state != NULL);
3590 format_state->justification = value;
3591 modest_msg_edit_window_set_format_state (window, format_state);
3592 g_free (format_state);
3596 modest_ui_actions_on_select_editor_color (GtkAction *action,
3597 ModestMsgEditWindow *window)
3599 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3600 g_return_if_fail (GTK_IS_ACTION (action));
3602 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3605 modest_msg_edit_window_select_color (window);
3609 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3610 ModestMsgEditWindow *window)
3612 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3613 g_return_if_fail (GTK_IS_ACTION (action));
3615 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3618 modest_msg_edit_window_select_background_color (window);
3622 modest_ui_actions_on_insert_image (GObject *object,
3623 ModestMsgEditWindow *window)
3625 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3628 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3631 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3634 modest_msg_edit_window_insert_image (window);
3638 modest_ui_actions_on_attach_file (GtkAction *action,
3639 ModestMsgEditWindow *window)
3641 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3642 g_return_if_fail (GTK_IS_ACTION (action));
3644 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3647 modest_msg_edit_window_offer_attach_file (window);
3651 modest_ui_actions_on_remove_attachments (GtkAction *action,
3652 ModestMsgEditWindow *window)
3654 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3656 modest_msg_edit_window_remove_attachments (window, NULL);
3660 do_create_folder_cb (ModestMailOperation *mail_op,
3661 TnyFolderStore *parent_folder,
3662 TnyFolder *new_folder,
3665 gchar *suggested_name = (gchar *) user_data;
3666 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3667 const GError *error;
3669 error = modest_mail_operation_get_error (mail_op);
3671 gboolean disk_full = FALSE;
3672 TnyAccount *account;
3673 /* Show an error. If there was some problem writing to
3674 disk, show it, otherwise show the generic folder
3675 create error. We do it here and not in an error
3676 handler because the call to do_create_folder will
3677 stop the main loop in a gtk_dialog_run and then,
3678 the message won't be shown until that dialog is
3680 account = modest_mail_operation_get_account (mail_op);
3683 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3684 (GtkWidget *) source_win,
3687 _("mail_in_ui_folder_create_error_memory"));
3688 g_object_unref (account);
3691 /* Show an error and try again if there is no
3692 full memory condition */
3693 modest_platform_information_banner ((GtkWidget *) source_win, NULL,
3694 _("mail_in_ui_folder_create_error"));
3695 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3699 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3700 * FIXME: any other? */
3701 GtkWidget *folder_view;
3703 if (MODEST_IS_MAIN_WINDOW(source_win))
3705 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3706 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3708 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3709 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3711 /* Select the newly created folder. It could happen
3712 that the widget is no longer there (i.e. the window
3713 has been destroyed, so we need to check this */
3715 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3717 g_object_unref (new_folder);
3719 /* Free. Note that the first time it'll be NULL so noop */
3720 g_free (suggested_name);
3721 g_object_unref (source_win);
3726 TnyFolderStore *parent;
3727 } CreateFolderConnect;
3730 do_create_folder_performer (gboolean canceled,
3732 GtkWindow *parent_window,
3733 TnyAccount *account,
3736 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3737 ModestMailOperation *mail_op;
3739 if (canceled || err) {
3740 /* In disk full conditions we could get this error here */
3741 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3742 (GtkWidget *) parent_window, err,
3743 NULL, _("mail_in_ui_folder_create_error_memory"));
3745 /* This happens if we have selected the outbox folder
3747 if (err && err->code == TNY_SERVICE_ERROR_UNKNOWN &&
3748 TNY_IS_MERGE_FOLDER (helper->parent)) {
3749 /* Show an error and retry */
3750 modest_platform_information_banner ((GtkWidget *) parent_window,
3752 _("mail_in_ui_folder_create_error"));
3754 do_create_folder (parent_window, helper->parent, helper->folder_name);
3760 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3761 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3763 modest_mail_operation_create_folder (mail_op,
3765 (const gchar *) helper->folder_name,
3766 do_create_folder_cb,
3767 g_strdup (helper->folder_name));
3768 g_object_unref (mail_op);
3772 g_object_unref (helper->parent);
3773 if (helper->folder_name)
3774 g_free (helper->folder_name);
3775 g_slice_free (CreateFolderConnect, helper);
3780 do_create_folder (GtkWindow *parent_window,
3781 TnyFolderStore *suggested_parent,
3782 const gchar *suggested_name)
3785 gchar *folder_name = NULL;
3786 TnyFolderStore *parent_folder = NULL;
3788 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3790 (gchar *) suggested_name,
3794 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3795 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3796 helper->folder_name = g_strdup (folder_name);
3797 helper->parent = g_object_ref (parent_folder);
3799 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3802 do_create_folder_performer,
3807 g_free (folder_name);
3809 g_object_unref (parent_folder);
3813 modest_ui_actions_create_folder(GtkWidget *parent_window,
3814 GtkWidget *folder_view,
3815 TnyFolderStore *parent_folder)
3817 if (!parent_folder) {
3818 #ifdef MODEST_TOOLKIT_HILDON2
3819 ModestTnyAccountStore *acc_store;
3821 acc_store = modest_runtime_get_account_store ();
3823 parent_folder = (TnyFolderStore *)
3824 modest_tny_account_store_get_local_folders_account (acc_store);
3826 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3830 if (parent_folder) {
3831 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3832 g_object_unref (parent_folder);
3837 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3840 g_return_if_fail (MODEST_IS_WINDOW(window));
3842 if (MODEST_IS_MAIN_WINDOW (window)) {
3843 GtkWidget *folder_view;
3845 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3846 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3850 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3851 #ifdef MODEST_TOOLKIT_HILDON2
3852 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3853 GtkWidget *folder_view;
3855 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3856 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3859 g_assert_not_reached ();
3864 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3867 const GError *error = NULL;
3868 gchar *message = NULL;
3870 TnyAccount *account = modest_mail_operation_get_account (mail_op);
3872 /* Get error message */
3873 error = modest_mail_operation_get_error (mail_op);
3875 g_return_if_reached ();
3877 mem_full = modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
3878 (GError *) error, account);
3880 message = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3881 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3882 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3883 message = _CS("ckdg_ib_folder_already_exists");
3884 } else if (error->domain == TNY_ERROR_DOMAIN &&
3885 error->code == TNY_SERVICE_ERROR_STATE) {
3886 /* This means that the folder is already in use (a
3887 message is opened for example */
3888 message = _("emev_ni_internal_error");
3890 message = _CS("ckdg_ib_unable_to_rename");
3893 /* We don't set a parent for the dialog because the dialog
3894 will be destroyed so the banner won't appear */
3895 modest_platform_information_banner (NULL, NULL, message);
3898 g_object_unref (account);
3904 TnyFolderStore *folder;
3909 on_rename_folder_cb (ModestMailOperation *mail_op,
3910 TnyFolder *new_folder,
3913 ModestFolderView *folder_view;
3915 /* If the window was closed when renaming a folder, or if
3916 * it's not a main window this will happen */
3917 if (!MODEST_IS_FOLDER_VIEW (user_data))
3920 folder_view = MODEST_FOLDER_VIEW (user_data);
3921 /* Note that if the rename fails new_folder will be NULL */
3923 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3925 modest_folder_view_select_first_inbox_or_local (folder_view);
3927 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3931 on_rename_folder_performer (gboolean canceled,
3933 GtkWindow *parent_window,
3934 TnyAccount *account,
3937 ModestMailOperation *mail_op = NULL;
3938 GtkTreeSelection *sel = NULL;
3939 GtkWidget *folder_view = NULL;
3940 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3942 if (canceled || err) {
3943 /* In disk full conditions we could get this error here */
3944 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3945 (GtkWidget *) parent_window, err,
3950 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3951 modest_ui_actions_rename_folder_error_handler,
3952 parent_window, NULL);
3954 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3957 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3959 folder_view = modest_main_window_get_child_widget (
3960 MODEST_MAIN_WINDOW (parent_window),
3961 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3963 #ifdef MODEST_TOOLKIT_HILDON2
3964 else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3965 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3966 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3970 /* Clear the folders view */
3971 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3972 gtk_tree_selection_unselect_all (sel);
3974 /* Actually rename the folder */
3975 modest_mail_operation_rename_folder (mail_op,
3976 TNY_FOLDER (data->folder),
3977 (const gchar *) (data->new_name),
3978 on_rename_folder_cb,
3980 g_object_unref (mail_op);
3983 g_object_unref (data->folder);
3984 g_free (data->new_name);
3989 modest_ui_actions_on_rename_folder (GtkAction *action,
3990 ModestWindow *window)
3992 modest_ui_actions_on_edit_mode_rename_folder (window);
3996 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3998 TnyFolderStore *folder;
3999 GtkWidget *folder_view;
4000 gboolean do_rename = TRUE;
4002 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
4004 if (MODEST_IS_MAIN_WINDOW (window)) {
4005 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4006 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4010 #ifdef MODEST_TOOLKIT_HILDON2
4011 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
4012 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
4018 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
4023 if (TNY_IS_FOLDER (folder)) {
4024 gchar *folder_name = NULL;
4026 const gchar *current_name;
4027 TnyFolderStore *parent;
4029 current_name = tny_folder_get_name (TNY_FOLDER (folder));
4030 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
4031 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
4032 parent, current_name,
4034 g_object_unref (parent);
4036 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
4039 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
4040 rename_folder_data->folder = g_object_ref (folder);
4041 rename_folder_data->new_name = folder_name;
4042 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
4043 folder, on_rename_folder_performer, rename_folder_data);
4046 g_object_unref (folder);
4051 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
4054 GObject *win = modest_mail_operation_get_source (mail_op);
4056 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
4057 _("mail_in_ui_folder_delete_error"),
4059 g_object_unref (win);
4063 TnyFolderStore *folder;
4064 gboolean move_to_trash;
4068 on_delete_folder_cb (gboolean canceled,
4070 GtkWindow *parent_window,
4071 TnyAccount *account,
4074 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
4075 GtkWidget *folder_view;
4076 ModestMailOperation *mail_op;
4077 GtkTreeSelection *sel;
4079 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
4080 /* Note that the connection process can fail due to
4081 memory low conditions as it can not successfully
4082 store the summary */
4083 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4084 (GtkWidget*) parent_window, err,
4086 g_debug ("Error connecting when trying to delete a folder");
4087 g_object_unref (G_OBJECT (info->folder));
4092 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
4093 folder_view = modest_main_window_get_child_widget (
4094 MODEST_MAIN_WINDOW (parent_window),
4095 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4096 #ifdef MODEST_TOOLKIT_HILDON2
4097 } else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
4098 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
4101 g_object_unref (G_OBJECT (info->folder));
4106 /* Unselect the folder before deleting it to free the headers */
4107 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
4108 gtk_tree_selection_unselect_all (sel);
4110 /* Create the mail operation */
4112 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
4113 modest_ui_actions_delete_folder_error_handler,
4116 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4118 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
4120 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
4122 g_object_unref (mail_op);
4123 g_object_unref (info->folder);
4128 delete_folder (ModestWindow *window, gboolean move_to_trash)
4130 TnyFolderStore *folder;
4131 GtkWidget *folder_view;
4135 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
4137 if (MODEST_IS_MAIN_WINDOW (window)) {
4139 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4140 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4141 #ifdef MODEST_TOOLKIT_HILDON2
4142 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
4143 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
4151 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4156 /* Show an error if it's an account */
4157 if (!TNY_IS_FOLDER (folder)) {
4158 modest_platform_run_information_dialog (GTK_WINDOW (window),
4159 _("mail_in_ui_folder_delete_error"),
4161 g_object_unref (G_OBJECT (folder));
4166 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
4167 tny_folder_get_name (TNY_FOLDER (folder)));
4168 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
4169 (const gchar *) message);
4172 if (response == GTK_RESPONSE_OK) {
4173 TnyAccount *account = NULL;
4174 DeleteFolderInfo *info = NULL;
4175 info = g_new0(DeleteFolderInfo, 1);
4176 info->folder = g_object_ref (folder);
4177 info->move_to_trash = move_to_trash;
4179 account = tny_folder_get_account (TNY_FOLDER (folder));
4180 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
4182 TNY_FOLDER_STORE (account),
4183 on_delete_folder_cb, info);
4184 g_object_unref (account);
4185 g_object_unref (folder);
4193 modest_ui_actions_on_delete_folder (GtkAction *action,
4194 ModestWindow *window)
4196 modest_ui_actions_on_edit_mode_delete_folder (window);
4200 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
4202 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
4204 return delete_folder (window, FALSE);
4208 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
4210 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4212 delete_folder (MODEST_WINDOW (main_window), TRUE);
4216 typedef struct _PasswordDialogFields {
4217 GtkWidget *username;
4218 GtkWidget *password;
4220 } PasswordDialogFields;
4223 password_dialog_check_field (GtkEditable *editable,
4224 PasswordDialogFields *fields)
4227 gboolean any_value_empty = FALSE;
4229 #ifdef MODEST_TOOLKIT_HILDON2
4230 value = hildon_entry_get_text (HILDON_ENTRY (fields->username));
4232 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
4234 if ((value == NULL) || value[0] == '\0') {
4235 any_value_empty = TRUE;
4237 #ifdef MODEST_TOOLKIT_HILDON2
4238 value = hildon_entry_get_text (HILDON_ENTRY (fields->password));
4240 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
4242 if ((value == NULL) || value[0] == '\0') {
4243 any_value_empty = TRUE;
4245 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
4249 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
4250 const gchar* server_account_name,
4255 ModestMainWindow *main_window)
4257 g_return_if_fail(server_account_name);
4258 gboolean completed = FALSE;
4259 PasswordDialogFields *fields = NULL;
4261 /* Initalize output parameters: */
4268 #ifndef MODEST_TOOLKIT_GTK
4269 /* Maemo uses a different (awkward) button order,
4270 * It should probably just use gtk_alternative_dialog_button_order ().
4272 #ifdef MODEST_TOOLKIT_HILDON2
4274 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4277 _HL("wdgt_bd_done"),
4278 GTK_RESPONSE_ACCEPT,
4280 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
4281 HILDON_MARGIN_DOUBLE);
4284 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4287 _("mcen_bd_dialog_ok"),
4288 GTK_RESPONSE_ACCEPT,
4289 _("mcen_bd_dialog_cancel"),
4290 GTK_RESPONSE_REJECT,
4292 #endif /* MODEST_TOOLKIT_HILDON2 */
4295 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4299 GTK_RESPONSE_REJECT,
4301 GTK_RESPONSE_ACCEPT,
4303 #endif /* MODEST_TOOLKIT_GTK */
4305 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
4307 gchar *server_name = modest_account_mgr_get_server_account_hostname (
4308 modest_runtime_get_account_mgr(), server_account_name);
4309 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
4310 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
4313 gtk_widget_destroy (dialog);
4317 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
4318 GtkWidget *label = gtk_label_new (txt);
4319 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
4321 g_free (server_name);
4322 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
4327 gchar *initial_username = modest_account_mgr_get_server_account_username (
4328 modest_runtime_get_account_mgr(), server_account_name);
4330 #ifdef MODEST_TOOLKIT_HILDON2
4331 GtkWidget *entry_username = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4332 if (initial_username)
4333 hildon_entry_set_text (HILDON_ENTRY (entry_username), initial_username);
4335 GtkWidget *entry_username = gtk_entry_new ();
4336 if (initial_username)
4337 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
4339 /* Dim this if a connection has ever succeeded with this username,
4340 * as per the UI spec: */
4341 /* const gboolean username_known = */
4342 /* modest_account_mgr_get_server_account_username_has_succeeded( */
4343 /* modest_runtime_get_account_mgr(), server_account_name); */
4344 /* gtk_widget_set_sensitive (entry_username, !username_known); */
4346 /* We drop the username sensitive code and disallow changing it here
4347 * as tinymail does not support really changing the username in the callback
4349 gtk_widget_set_sensitive (entry_username, FALSE);
4351 #ifndef MODEST_TOOLKIT_GTK
4352 /* Auto-capitalization is the default, so let's turn it off: */
4353 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
4355 /* Create a size group to be used by all captions.
4356 * Note that HildonCaption does not create a default size group if we do not specify one.
4357 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
4358 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
4360 #ifdef MODEST_TOOLKIT_HILDON2
4361 GtkWidget *caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4362 _("mail_fi_username"), FALSE,
4365 GtkWidget *caption = hildon_caption_new (sizegroup,
4366 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
4368 gtk_widget_show (entry_username);
4369 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4370 FALSE, FALSE, MODEST_MARGIN_HALF);
4371 gtk_widget_show (caption);
4373 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
4375 #endif /* !MODEST_TOOLKIT_GTK */
4378 #ifdef MODEST_TOOLKIT_HILDON2
4379 GtkWidget *entry_password = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4381 GtkWidget *entry_password = gtk_entry_new ();
4383 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
4384 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
4386 #ifndef MODEST_TOOLKIT_GTK
4387 /* Auto-capitalization is the default, so let's turn it off: */
4388 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
4389 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
4391 #ifdef MODEST_TOOLKIT_HILDON2
4392 caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4393 _("mail_fi_password"), FALSE,
4396 caption = hildon_caption_new (sizegroup,
4397 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
4399 gtk_widget_show (entry_password);
4400 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4401 FALSE, FALSE, MODEST_MARGIN_HALF);
4402 gtk_widget_show (caption);
4403 g_object_unref (sizegroup);
4405 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
4407 #endif /* !MODEST_TOOLKIT_GTK */
4409 if (initial_username != NULL)
4410 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
4412 /* This is not in the Maemo UI spec:
4413 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
4414 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
4418 fields = g_slice_new0 (PasswordDialogFields);
4419 fields->username = entry_username;
4420 fields->password = entry_password;
4421 fields->dialog = dialog;
4423 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
4424 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
4425 password_dialog_check_field (NULL, fields);
4427 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4429 while (!completed) {
4431 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
4433 #ifdef MODEST_TOOLKIT_HILDON2
4434 *username = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_username)));
4436 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
4439 /* Note that an empty field becomes the "" string */
4440 if (*username && strlen (*username) > 0) {
4441 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
4442 server_account_name,
4446 const gboolean username_was_changed =
4447 (strcmp (*username, initial_username) != 0);
4448 if (username_was_changed) {
4449 g_warning ("%s: tinymail does not yet support changing the "
4450 "username in the get_password() callback.\n", __FUNCTION__);
4456 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
4457 _("mcen_ib_username_pw_incorrect"));
4463 #ifdef MODEST_TOOLKIT_HILDON2
4464 *password = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_password)));
4466 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
4469 /* We do not save the password in the configuration,
4470 * because this function is only called for passwords that should
4471 * not be remembered:
4472 modest_server_account_set_password (
4473 modest_runtime_get_account_mgr(), server_account_name,
4480 #ifndef MODEST_TOOLKIT_HILDON2
4481 /* Set parent to NULL or the banner will disappear with its parent dialog */
4482 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
4494 /* This is not in the Maemo UI spec:
4495 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
4501 g_free (initial_username);
4502 gtk_widget_destroy (dialog);
4503 g_slice_free (PasswordDialogFields, fields);
4505 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
4509 modest_ui_actions_on_cut (GtkAction *action,
4510 ModestWindow *window)
4512 GtkWidget *focused_widget;
4513 GtkClipboard *clipboard;
4515 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4516 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4517 if (GTK_IS_EDITABLE (focused_widget)) {
4518 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
4519 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4520 gtk_clipboard_store (clipboard);
4521 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4522 GtkTextBuffer *buffer;
4524 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4525 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4526 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
4527 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4528 gtk_clipboard_store (clipboard);
4530 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4531 TnyList *header_list = modest_header_view_get_selected_headers (
4532 MODEST_HEADER_VIEW (focused_widget));
4533 gboolean continue_download = FALSE;
4534 gint num_of_unc_msgs;
4536 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4538 if (num_of_unc_msgs) {
4539 TnyAccount *account = get_account_from_header_list (header_list);
4541 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4542 g_object_unref (account);
4546 if (num_of_unc_msgs == 0 || continue_download) {
4547 /* modest_platform_information_banner (
4548 NULL, NULL, _CS("mcen_ib_getting_items"));*/
4549 modest_header_view_cut_selection (
4550 MODEST_HEADER_VIEW (focused_widget));
4553 g_object_unref (header_list);
4554 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4555 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4560 modest_ui_actions_on_copy (GtkAction *action,
4561 ModestWindow *window)
4563 GtkClipboard *clipboard;
4564 GtkWidget *focused_widget;
4565 gboolean copied = TRUE;
4567 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4568 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4570 if (GTK_IS_LABEL (focused_widget)) {
4572 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4573 gtk_clipboard_set_text (clipboard, selection, -1);
4575 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4576 gtk_clipboard_store (clipboard);
4577 } else if (GTK_IS_EDITABLE (focused_widget)) {
4578 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4579 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4580 gtk_clipboard_store (clipboard);
4581 } else if (GTK_IS_HTML (focused_widget)) {
4584 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4585 if ((sel == NULL) || (sel[0] == '\0')) {
4588 gtk_html_copy (GTK_HTML (focused_widget));
4589 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4590 gtk_clipboard_store (clipboard);
4592 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4593 GtkTextBuffer *buffer;
4594 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4595 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4596 gtk_text_buffer_copy_clipboard (buffer, clipboard);
4597 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4598 gtk_clipboard_store (clipboard);
4600 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4601 TnyList *header_list = modest_header_view_get_selected_headers (
4602 MODEST_HEADER_VIEW (focused_widget));
4603 gboolean continue_download = FALSE;
4604 gint num_of_unc_msgs;
4606 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4608 if (num_of_unc_msgs) {
4609 TnyAccount *account = get_account_from_header_list (header_list);
4611 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4612 g_object_unref (account);
4616 if (num_of_unc_msgs == 0 || continue_download) {
4617 modest_platform_information_banner (
4618 NULL, NULL, _CS("mcen_ib_getting_items"));
4619 modest_header_view_copy_selection (
4620 MODEST_HEADER_VIEW (focused_widget));
4624 g_object_unref (header_list);
4626 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4627 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4630 /* Show information banner if there was a copy to clipboard */
4632 modest_platform_information_banner (
4633 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4637 modest_ui_actions_on_undo (GtkAction *action,
4638 ModestWindow *window)
4640 ModestEmailClipboard *clipboard = NULL;
4642 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4643 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4644 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4645 /* Clear clipboard source */
4646 clipboard = modest_runtime_get_email_clipboard ();
4647 modest_email_clipboard_clear (clipboard);
4650 g_return_if_reached ();
4655 modest_ui_actions_on_redo (GtkAction *action,
4656 ModestWindow *window)
4658 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4659 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4662 g_return_if_reached ();
4668 destroy_information_note (ModestMailOperation *mail_op,
4671 /* destroy information note */
4672 gtk_widget_destroy (GTK_WIDGET(user_data));
4676 destroy_folder_information_note (ModestMailOperation *mail_op,
4677 TnyFolder *new_folder,
4680 /* destroy information note */
4681 gtk_widget_destroy (GTK_WIDGET(user_data));
4686 paste_as_attachment_free (gpointer data)
4688 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4690 if (helper->banner) {
4691 gtk_widget_destroy (helper->banner);
4692 g_object_unref (helper->banner);
4698 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4703 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4704 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4709 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4714 modest_ui_actions_on_paste (GtkAction *action,
4715 ModestWindow *window)
4717 GtkWidget *focused_widget = NULL;
4718 GtkWidget *inf_note = NULL;
4719 ModestMailOperation *mail_op = NULL;
4721 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4722 if (GTK_IS_EDITABLE (focused_widget)) {
4723 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4724 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4725 ModestEmailClipboard *e_clipboard = NULL;
4726 e_clipboard = modest_runtime_get_email_clipboard ();
4727 if (modest_email_clipboard_cleared (e_clipboard)) {
4728 GtkTextBuffer *buffer;
4729 GtkClipboard *clipboard;
4731 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4732 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4733 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4734 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4735 ModestMailOperation *mail_op;
4736 TnyFolder *src_folder = NULL;
4737 TnyList *data = NULL;
4739 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4740 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4741 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4742 _CS("ckct_nw_pasting"));
4743 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4744 mail_op = modest_mail_operation_new (G_OBJECT (window));
4745 if (helper->banner != NULL) {
4746 g_object_ref (G_OBJECT (helper->banner));
4747 gtk_widget_show (GTK_WIDGET (helper->banner));
4751 modest_mail_operation_get_msgs_full (mail_op,
4753 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4755 paste_as_attachment_free);
4759 g_object_unref (data);
4761 g_object_unref (src_folder);
4764 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4765 ModestEmailClipboard *clipboard = NULL;
4766 TnyFolder *src_folder = NULL;
4767 TnyFolderStore *folder_store = NULL;
4768 TnyList *data = NULL;
4769 gboolean delete = FALSE;
4771 /* Check clipboard source */
4772 clipboard = modest_runtime_get_email_clipboard ();
4773 if (modest_email_clipboard_cleared (clipboard))
4776 /* Get elements to paste */
4777 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4779 /* Create a new mail operation */
4780 mail_op = modest_mail_operation_new (G_OBJECT(window));
4782 /* Get destination folder */
4783 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4785 /* transfer messages */
4789 /* Ask for user confirmation */
4791 modest_ui_actions_msgs_move_to_confirmation (window,
4792 TNY_FOLDER (folder_store),
4796 if (response == GTK_RESPONSE_OK) {
4797 /* Launch notification */
4798 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4799 _CS("ckct_nw_pasting"));
4800 if (inf_note != NULL) {
4801 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4802 gtk_widget_show (GTK_WIDGET(inf_note));
4805 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4806 modest_mail_operation_xfer_msgs (mail_op,
4808 TNY_FOLDER (folder_store),
4810 destroy_information_note,
4813 g_object_unref (mail_op);
4816 } else if (src_folder != NULL) {
4817 /* Launch notification */
4818 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4819 _CS("ckct_nw_pasting"));
4820 if (inf_note != NULL) {
4821 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4822 gtk_widget_show (GTK_WIDGET(inf_note));
4825 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4826 modest_mail_operation_xfer_folder (mail_op,
4830 destroy_folder_information_note,
4836 g_object_unref (data);
4837 if (src_folder != NULL)
4838 g_object_unref (src_folder);
4839 if (folder_store != NULL)
4840 g_object_unref (folder_store);
4846 modest_ui_actions_on_select_all (GtkAction *action,
4847 ModestWindow *window)
4849 GtkWidget *focused_widget;
4851 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4852 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4853 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4854 } else if (GTK_IS_LABEL (focused_widget)) {
4855 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4856 } else if (GTK_IS_EDITABLE (focused_widget)) {
4857 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4858 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4859 GtkTextBuffer *buffer;
4860 GtkTextIter start, end;
4862 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4863 gtk_text_buffer_get_start_iter (buffer, &start);
4864 gtk_text_buffer_get_end_iter (buffer, &end);
4865 gtk_text_buffer_select_range (buffer, &start, &end);
4866 } else if (GTK_IS_HTML (focused_widget)) {
4867 gtk_html_select_all (GTK_HTML (focused_widget));
4868 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4869 GtkWidget *header_view = focused_widget;
4870 GtkTreeSelection *selection = NULL;
4872 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4873 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4874 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4877 /* Disable window dimming management */
4878 modest_window_disable_dimming (MODEST_WINDOW(window));
4880 /* Select all messages */
4881 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4882 gtk_tree_selection_select_all (selection);
4884 /* Set focuse on header view */
4885 gtk_widget_grab_focus (header_view);
4887 /* Enable window dimming management */
4888 modest_window_enable_dimming (MODEST_WINDOW(window));
4889 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4890 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4896 modest_ui_actions_on_mark_as_read (GtkAction *action,
4897 ModestWindow *window)
4899 g_return_if_fail (MODEST_IS_WINDOW(window));
4901 /* Mark each header as read */
4902 do_headers_action (window, headers_action_mark_as_read, NULL);
4906 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4907 ModestWindow *window)
4909 g_return_if_fail (MODEST_IS_WINDOW(window));
4911 /* Mark each header as read */
4912 do_headers_action (window, headers_action_mark_as_unread, NULL);
4916 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4917 GtkRadioAction *selected,
4918 ModestWindow *window)
4922 value = gtk_radio_action_get_current_value (selected);
4923 if (MODEST_IS_WINDOW (window)) {
4924 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4929 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4930 GtkRadioAction *selected,
4931 ModestWindow *window)
4933 TnyHeaderFlags flags;
4934 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4936 flags = gtk_radio_action_get_current_value (selected);
4937 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4941 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4942 GtkRadioAction *selected,
4943 ModestWindow *window)
4947 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4949 file_format = gtk_radio_action_get_current_value (selected);
4950 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4955 modest_ui_actions_on_zoom_plus (GtkAction *action,
4956 ModestWindow *window)
4958 g_return_if_fail (MODEST_IS_WINDOW (window));
4960 modest_window_zoom_plus (MODEST_WINDOW (window));
4964 modest_ui_actions_on_zoom_minus (GtkAction *action,
4965 ModestWindow *window)
4967 g_return_if_fail (MODEST_IS_WINDOW (window));
4969 modest_window_zoom_minus (MODEST_WINDOW (window));
4973 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4974 ModestWindow *window)
4976 ModestWindowMgr *mgr;
4977 gboolean fullscreen, active;
4978 g_return_if_fail (MODEST_IS_WINDOW (window));
4980 mgr = modest_runtime_get_window_mgr ();
4982 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4983 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4985 if (active != fullscreen) {
4986 modest_window_mgr_set_fullscreen_mode (mgr, active);
4987 #ifndef MODEST_TOOLKIT_HILDON2
4988 gtk_window_present (GTK_WINDOW (window));
4994 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4995 ModestWindow *window)
4997 ModestWindowMgr *mgr;
4998 gboolean fullscreen;
5000 g_return_if_fail (MODEST_IS_WINDOW (window));
5002 mgr = modest_runtime_get_window_mgr ();
5003 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
5004 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
5006 #ifndef MODEST_TOOLKIT_HILDON2
5007 gtk_window_present (GTK_WINDOW (window));
5012 * Used by modest_ui_actions_on_details to call do_headers_action
5015 headers_action_show_details (TnyHeader *header,
5016 ModestWindow *window,
5020 gboolean async_retrieval;
5023 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5024 async_retrieval = TRUE;
5025 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
5026 async_retrieval = !TNY_IS_CAMEL_BS_MSG (msg);
5028 async_retrieval = FALSE;
5030 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header, async_retrieval, msg);
5032 g_object_unref (msg);
5036 * Show the header details in a ModestDetailsDialog widget
5039 modest_ui_actions_on_details (GtkAction *action,
5042 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
5046 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
5050 header = tny_msg_get_header (msg);
5052 headers_action_show_details (header, win, NULL);
5053 g_object_unref (header);
5055 g_object_unref (msg);
5057 } else if (MODEST_IS_MAIN_WINDOW (win)) {
5058 GtkWidget *folder_view, *header_view;
5060 /* Check which widget has the focus */
5061 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5062 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5063 if (gtk_widget_is_focus (folder_view)) {
5064 TnyFolderStore *folder_store
5065 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5066 if (!folder_store) {
5067 g_warning ("%s: No item was selected.\n", __FUNCTION__);
5070 /* Show only when it's a folder */
5071 /* This function should not be called for account items,
5072 * because we dim the menu item for them. */
5073 if (TNY_IS_FOLDER (folder_store)) {
5074 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
5075 TNY_FOLDER (folder_store));
5078 g_object_unref (folder_store);
5081 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5082 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5083 /* Show details of each header */
5084 do_headers_action (win, headers_action_show_details, header_view);
5086 #ifdef MODEST_TOOLKIT_HILDON2
5087 } else if (MODEST_IS_HEADER_WINDOW (win)) {
5089 GtkWidget *header_view;
5091 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
5092 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
5094 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
5096 g_object_unref (folder);
5103 modest_ui_actions_on_limit_error (GtkAction *action,
5106 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
5108 modest_platform_information_banner ((GtkWidget *) win, NULL, _CS("ckdg_ib_maximum_characters_reached"));
5113 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
5114 ModestMsgEditWindow *window)
5116 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5118 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
5122 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
5123 ModestMsgEditWindow *window)
5125 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5127 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
5131 modest_ui_actions_toggle_folders_view (GtkAction *action,
5132 ModestMainWindow *main_window)
5134 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
5136 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
5137 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
5139 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
5143 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
5144 ModestWindow *window)
5146 gboolean active, fullscreen = FALSE;
5147 ModestWindowMgr *mgr;
5149 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
5151 /* Check if we want to toggle the toolbar view in fullscreen
5153 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
5154 "ViewShowToolbarFullScreen")) {
5158 /* Toggle toolbar */
5159 mgr = modest_runtime_get_window_mgr ();
5160 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
5164 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
5165 ModestMsgEditWindow *window)
5167 modest_msg_edit_window_select_font (window);
5172 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
5173 const gchar *display_name,
5176 /* don't update the display name if it was already set;
5177 * updating the display name apparently is expensive */
5178 const gchar* old_name = gtk_window_get_title (window);
5180 if (display_name == NULL)
5183 if (old_name && display_name && strcmp (old_name, display_name) == 0)
5184 return; /* don't do anything */
5186 /* This is usually used to change the title of the main window, which
5187 * is the one that holds the folder view. Note that this change can
5188 * happen even when the widget doesn't have the focus. */
5189 gtk_window_set_title (window, display_name);
5194 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
5196 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5197 modest_msg_edit_window_select_contacts (window);
5201 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
5203 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5204 modest_msg_edit_window_check_names (window, FALSE);
5207 #ifndef MODEST_TOOLKIT_HILDON2
5209 * This function is used to track changes in the selection of the
5210 * folder view that is inside the "move to" dialog to enable/disable
5211 * the OK button because we do not want the user to select a disallowed
5212 * destination for a folder.
5213 * The user also not desired to be able to use NEW button on items where
5214 * folder creation is not possibel.
5217 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
5218 TnyFolderStore *folder_store,
5222 GtkWidget *dialog = NULL;
5223 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
5224 gboolean moving_folder = FALSE;
5225 gboolean is_local_account = TRUE;
5226 GtkWidget *folder_view = NULL;
5227 ModestTnyFolderRules rules;
5229 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
5234 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
5238 /* check if folder_store is an remote account */
5239 if (TNY_IS_ACCOUNT (folder_store)) {
5240 TnyAccount *local_account = NULL;
5241 TnyAccount *mmc_account = NULL;
5242 ModestTnyAccountStore *account_store = NULL;
5244 account_store = modest_runtime_get_account_store ();
5245 local_account = modest_tny_account_store_get_local_folders_account (account_store);
5246 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
5248 if ((gpointer) local_account != (gpointer) folder_store &&
5249 (gpointer) mmc_account != (gpointer) folder_store) {
5250 ModestProtocolType proto;
5251 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
5252 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
5253 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
5255 is_local_account = FALSE;
5256 /* New button should be dimmed on remote
5258 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5260 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
5262 g_object_unref (local_account);
5264 /* It could not exist */
5266 g_object_unref (mmc_account);
5269 /* Check the target folder rules */
5270 if (TNY_IS_FOLDER (folder_store)) {
5271 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
5272 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
5273 ok_sensitive = FALSE;
5274 new_sensitive = FALSE;
5279 /* Check if we're moving a folder */
5280 if (MODEST_IS_MAIN_WINDOW (user_data)) {
5281 /* Get the widgets */
5282 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
5283 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5284 if (gtk_widget_is_focus (folder_view))
5285 moving_folder = TRUE;
5288 if (moving_folder) {
5289 TnyFolderStore *moved_folder = NULL, *parent = NULL;
5291 /* Get the folder to move */
5292 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5294 /* Check that we're not moving to the same folder */
5295 if (TNY_IS_FOLDER (moved_folder)) {
5296 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
5297 if (parent == folder_store)
5298 ok_sensitive = FALSE;
5299 g_object_unref (parent);
5302 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
5303 /* Do not allow to move to an account unless it's the
5304 local folders account */
5305 if (!is_local_account)
5306 ok_sensitive = FALSE;
5309 if (ok_sensitive && (moved_folder == folder_store)) {
5310 /* Do not allow to move to itself */
5311 ok_sensitive = FALSE;
5313 g_object_unref (moved_folder);
5315 TnyFolder *src_folder = NULL;
5317 /* Moving a message */
5318 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
5320 TnyHeader *header = NULL;
5321 header = modest_msg_view_window_get_header
5322 (MODEST_MSG_VIEW_WINDOW (user_data));
5323 if (!TNY_IS_HEADER(header))
5324 g_warning ("%s: could not get source header", __FUNCTION__);
5326 src_folder = tny_header_get_folder (header);
5329 g_object_unref (header);
5332 TNY_FOLDER (modest_folder_view_get_selected
5333 (MODEST_FOLDER_VIEW (folder_view)));
5336 if (TNY_IS_FOLDER(src_folder)) {
5337 /* Do not allow to move the msg to the same folder */
5338 /* Do not allow to move the msg to an account */
5339 if ((gpointer) src_folder == (gpointer) folder_store ||
5340 TNY_IS_ACCOUNT (folder_store))
5341 ok_sensitive = FALSE;
5342 g_object_unref (src_folder);
5344 g_warning ("%s: could not get source folder", __FUNCTION__);
5348 /* Set sensitivity of the OK and NEW button */
5349 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
5350 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
5355 on_move_to_dialog_response (GtkDialog *dialog,
5359 GtkWidget *parent_win;
5360 MoveToInfo *helper = NULL;
5361 ModestFolderView *folder_view;
5362 gboolean unset_edit_mode = FALSE;
5364 helper = (MoveToInfo *) user_data;
5366 parent_win = (GtkWidget *) helper->win;
5367 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
5368 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
5370 TnyFolderStore *dst_folder;
5371 TnyFolderStore *selected;
5373 case MODEST_GTK_RESPONSE_NEW_FOLDER:
5374 selected = modest_folder_view_get_selected (folder_view);
5375 modest_ui_actions_create_folder (GTK_WIDGET (dialog), GTK_WIDGET (folder_view), selected);
5376 g_object_unref (selected);
5378 case GTK_RESPONSE_NONE:
5379 case GTK_RESPONSE_CANCEL:
5380 case GTK_RESPONSE_DELETE_EVENT:
5382 case GTK_RESPONSE_OK:
5383 dst_folder = modest_folder_view_get_selected (folder_view);
5385 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
5386 /* Clean list to move used for filtering */
5387 modest_folder_view_set_list_to_move (folder_view, NULL);
5389 modest_ui_actions_on_main_window_move_to (NULL,
5390 GTK_WIDGET (folder_view),
5392 MODEST_MAIN_WINDOW (parent_win));
5393 #ifdef MODEST_TOOLKIT_HILDON2
5394 } else if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
5395 /* Clean list to move used for filtering */
5396 modest_folder_view_set_list_to_move (folder_view, NULL);
5398 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
5401 GTK_WINDOW (parent_win));
5404 /* if the user selected a root folder
5405 (account) then do not perform any action */
5406 if (TNY_IS_ACCOUNT (dst_folder)) {
5407 g_signal_stop_emission_by_name (dialog, "response");
5411 /* Clean list to move used for filtering */
5412 modest_folder_view_set_list_to_move (folder_view, NULL);
5414 /* Moving from headers window in edit mode */
5415 modest_ui_actions_on_window_move_to (NULL, helper->list,
5417 MODEST_WINDOW (parent_win));
5421 g_object_unref (dst_folder);
5423 unset_edit_mode = TRUE;
5426 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
5429 /* Free the helper and exit */
5431 g_object_unref (helper->list);
5432 if (unset_edit_mode) {
5433 #ifdef MODEST_TOOLKIT_HILDON2
5434 modest_hildon2_window_unset_edit_mode (MODEST_HILDON2_WINDOW (helper->win));
5437 g_slice_free (MoveToInfo, helper);
5438 gtk_widget_destroy (GTK_WIDGET (dialog));
5442 create_move_to_dialog (GtkWindow *win,
5443 GtkWidget *folder_view,
5444 TnyList *list_to_move)
5446 GtkWidget *dialog, *tree_view = NULL;
5448 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
5450 #ifndef MODEST_TOOLKIT_HILDON2
5451 /* Track changes in the selection to
5452 * disable the OK button whenever "Move to" is not possible
5453 * disbale NEW button whenever New is not possible */
5454 g_signal_connect (tree_view,
5455 "folder_selection_changed",
5456 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
5460 /* It could happen that we're trying to move a message from a
5461 window (msg window for example) after the main window was
5462 closed, so we can not just get the model of the folder
5464 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
5465 const gchar *visible_id = NULL;
5467 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5468 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5469 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
5470 MODEST_FOLDER_VIEW(tree_view));
5473 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
5475 /* Show the same account than the one that is shown in the main window */
5476 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
5479 const gchar *active_account_name = NULL;
5480 ModestAccountMgr *mgr = NULL;
5481 ModestAccountSettings *settings = NULL;
5482 ModestServerAccountSettings *store_settings = NULL;
5484 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5485 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5487 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
5488 mgr = modest_runtime_get_account_mgr ();
5489 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
5492 const gchar *store_account_name;
5493 store_settings = modest_account_settings_get_store_settings (settings);
5494 store_account_name = modest_server_account_settings_get_account_name (store_settings);
5496 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
5497 store_account_name);
5498 g_object_unref (store_settings);
5499 g_object_unref (settings);
5503 /* we keep a pointer to the embedded folder view, so we can
5504 * retrieve it with get_folder_view_from_move_to_dialog (see
5505 * above) later (needed for focus handling)
5507 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
5509 /* Hide special folders */
5510 #ifndef MODEST_TOOLKIT_HILDON2
5511 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
5514 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
5515 #ifndef MODEST_TOOLKIT_HILDON2
5516 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5519 gtk_widget_show (GTK_WIDGET (tree_view));
5525 * Shows a confirmation dialog to the user when we're moving messages
5526 * from a remote server to the local storage. Returns the dialog
5527 * response. If it's other kind of movement then it always returns
5530 * This one is used by the next functions:
5531 * modest_ui_actions_on_paste - commented out
5532 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
5535 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
5536 TnyFolder *dest_folder,
5540 gint response = GTK_RESPONSE_OK;
5541 TnyAccount *account = NULL;
5542 TnyFolder *src_folder = NULL;
5543 TnyIterator *iter = NULL;
5544 TnyHeader *header = NULL;
5546 /* return with OK if the destination is a remote folder */
5547 if (modest_tny_folder_is_remote_folder (dest_folder))
5548 return GTK_RESPONSE_OK;
5550 /* Get source folder */
5551 iter = tny_list_create_iterator (headers);
5552 header = TNY_HEADER (tny_iterator_get_current (iter));
5554 src_folder = tny_header_get_folder (header);
5555 g_object_unref (header);
5557 g_object_unref (iter);
5559 /* if no src_folder, message may be an attahcment */
5560 if (src_folder == NULL)
5561 return GTK_RESPONSE_CANCEL;
5563 /* If the source is a local or MMC folder */
5564 if (!modest_tny_folder_is_remote_folder (src_folder)) {
5565 g_object_unref (src_folder);
5566 return GTK_RESPONSE_OK;
5569 /* Get the account */
5570 account = tny_folder_get_account (src_folder);
5572 /* now if offline we ask the user */
5573 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
5574 response = GTK_RESPONSE_OK;
5576 response = GTK_RESPONSE_CANCEL;
5579 g_object_unref (src_folder);
5580 g_object_unref (account);
5586 move_to_helper_destroyer (gpointer user_data)
5588 MoveToHelper *helper = (MoveToHelper *) user_data;
5590 /* Close the "Pasting" information banner */
5591 if (helper->banner) {
5592 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5593 g_object_unref (helper->banner);
5595 if (gtk_tree_row_reference_valid (helper->reference)) {
5596 gtk_tree_row_reference_free (helper->reference);
5597 helper->reference = NULL;
5603 move_to_cb (ModestMailOperation *mail_op,
5606 MoveToHelper *helper = (MoveToHelper *) user_data;
5607 GObject *object = modest_mail_operation_get_source (mail_op);
5609 /* Note that the operation could have failed, in that case do
5611 if (modest_mail_operation_get_status (mail_op) !=
5612 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5615 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5616 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5618 if (!modest_msg_view_window_select_next_message (self) &&
5619 !modest_msg_view_window_select_previous_message (self)) {
5620 /* No more messages to view, so close this window */
5621 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5623 } else if (MODEST_IS_MAIN_WINDOW (object) &&
5624 gtk_tree_row_reference_valid (helper->reference)) {
5625 GtkWidget *header_view;
5627 GtkTreeSelection *sel;
5629 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5630 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5631 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5632 path = gtk_tree_row_reference_get_path (helper->reference);
5633 /* We need to unselect the previous one
5634 because we could be copying instead of
5636 gtk_tree_selection_unselect_all (sel);
5637 gtk_tree_selection_select_path (sel, path);
5638 gtk_tree_path_free (path);
5640 g_object_unref (object);
5643 /* Destroy the helper */
5644 move_to_helper_destroyer (helper);
5648 folder_move_to_cb (ModestMailOperation *mail_op,
5649 TnyFolder *new_folder,
5652 GtkWidget *folder_view;
5655 object = modest_mail_operation_get_source (mail_op);
5656 if (MODEST_IS_MAIN_WINDOW (object)) {
5657 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5658 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5659 g_object_ref (folder_view);
5660 g_object_unref (object);
5661 move_to_cb (mail_op, user_data);
5662 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5663 g_object_unref (folder_view);
5665 move_to_cb (mail_op, user_data);
5670 msgs_move_to_cb (ModestMailOperation *mail_op,
5673 move_to_cb (mail_op, user_data);
5677 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5680 GObject *win = NULL;
5681 const GError *error;
5682 TnyAccount *account = NULL;
5684 #ifndef MODEST_TOOLKIT_HILDON2
5685 ModestWindow *main_window = NULL;
5687 /* Disable next automatic folder selection */
5688 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5689 FALSE); /* don't create */
5691 /* Show notification dialog only if the main window exists */
5693 GtkWidget *folder_view = NULL;
5695 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5696 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5697 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5699 if (user_data && TNY_IS_FOLDER (user_data)) {
5700 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5701 TNY_FOLDER (user_data), FALSE);
5705 win = modest_mail_operation_get_source (mail_op);
5706 error = modest_mail_operation_get_error (mail_op);
5708 if (TNY_IS_FOLDER (user_data))
5709 account = modest_tny_folder_get_account (TNY_FOLDER (user_data));
5710 else if (TNY_IS_ACCOUNT (user_data))
5711 account = g_object_ref (user_data);
5713 /* If it's not a disk full error then show a generic error */
5714 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5715 (GtkWidget *) win, (GError *) error,
5717 modest_platform_run_information_dialog ((GtkWindow *) win,
5718 _("mail_in_ui_folder_move_target_error"),
5721 g_object_unref (account);
5723 g_object_unref (win);
5727 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5736 gint pending_purges = 0;
5737 gboolean some_purged = FALSE;
5738 ModestWindow *win = MODEST_WINDOW (user_data);
5739 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5741 /* If there was any error */
5742 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5743 modest_window_mgr_unregister_header (mgr, header);
5747 /* Once the message has been retrieved for purging, we check if
5748 * it's all ok for purging */
5750 parts = tny_simple_list_new ();
5751 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5752 iter = tny_list_create_iterator (parts);
5754 while (!tny_iterator_is_done (iter)) {
5756 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5757 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5758 if (tny_mime_part_is_purged (part))
5765 g_object_unref (part);
5767 tny_iterator_next (iter);
5769 g_object_unref (iter);
5772 if (pending_purges>0) {
5774 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5776 if (response == GTK_RESPONSE_OK) {
5779 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5780 iter = tny_list_create_iterator (parts);
5781 while (!tny_iterator_is_done (iter)) {
5784 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5785 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5786 tny_mime_part_set_purged (part);
5789 g_object_unref (part);
5791 tny_iterator_next (iter);
5793 g_object_unref (iter);
5795 tny_msg_rewrite_cache (msg);
5797 gtk_widget_destroy (info);
5801 modest_window_mgr_unregister_header (mgr, header);
5803 g_object_unref (parts);
5807 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5808 ModestMainWindow *win)
5810 GtkWidget *header_view;
5811 TnyList *header_list;
5813 TnyHeaderFlags flags;
5814 ModestWindow *msg_view_window = NULL;
5817 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5819 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5820 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5822 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5824 g_warning ("%s: no header selected", __FUNCTION__);
5828 if (tny_list_get_length (header_list) == 1) {
5829 TnyIterator *iter = tny_list_create_iterator (header_list);
5830 header = TNY_HEADER (tny_iterator_get_current (iter));
5831 g_object_unref (iter);
5835 if (!header || !TNY_IS_HEADER(header)) {
5836 g_warning ("%s: header is not valid", __FUNCTION__);
5840 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5841 header, &msg_view_window);
5842 flags = tny_header_get_flags (header);
5843 if (!(flags & TNY_HEADER_FLAG_CACHED))
5846 if (msg_view_window != NULL)
5847 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5849 /* do nothing; uid was registered before, so window is probably on it's way */
5850 g_debug ("header %p has already been registered", header);
5853 ModestMailOperation *mail_op = NULL;
5854 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5855 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5856 modest_ui_actions_disk_operations_error_handler,
5858 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5859 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5861 g_object_unref (mail_op);
5864 g_object_unref (header);
5866 g_object_unref (header_list);
5870 * Checks if we need a connection to do the transfer and if the user
5871 * wants to connect to complete it
5874 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5875 TnyFolderStore *src_folder,
5877 TnyFolder *dst_folder,
5878 gboolean delete_originals,
5879 gboolean *need_connection,
5882 TnyAccount *src_account;
5883 gint uncached_msgs = 0;
5885 /* We don't need any further check if
5887 * 1- the source folder is local OR
5888 * 2- the device is already online
5890 if (!modest_tny_folder_store_is_remote (src_folder) ||
5891 tny_device_is_online (modest_runtime_get_device())) {
5892 *need_connection = FALSE;
5897 /* We must ask for a connection when
5899 * - the message(s) is not already cached OR
5900 * - the message(s) is cached but the leave_on_server setting
5901 * is FALSE (because we need to sync the source folder to
5902 * delete the message from the server (for IMAP we could do it
5903 * offline, it'll take place the next time we get a
5906 uncached_msgs = header_list_count_uncached_msgs (headers);
5907 src_account = get_account_from_folder_store (src_folder);
5908 if (uncached_msgs > 0) {
5912 *need_connection = TRUE;
5913 num_headers = tny_list_get_length (headers);
5914 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5916 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5917 GTK_RESPONSE_CANCEL) {
5923 /* The transfer is possible and the user wants to */
5926 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5927 const gchar *account_name;
5928 gboolean leave_on_server;
5930 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5931 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5934 if (leave_on_server == TRUE) {
5935 *need_connection = FALSE;
5937 *need_connection = TRUE;
5940 *need_connection = FALSE;
5945 g_object_unref (src_account);
5949 xfer_messages_error_handler (ModestMailOperation *mail_op,
5953 const GError *error;
5954 TnyAccount *account;
5956 win = modest_mail_operation_get_source (mail_op);
5957 error = modest_mail_operation_get_error (mail_op);
5959 /* We cannot get the account from the mail op as that is the
5960 source account and for checking memory full conditions we
5961 need the destination one */
5962 account = TNY_ACCOUNT (user_data);
5965 !modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5966 (GtkWidget *) win, (GError*) error,
5967 account, _KR("cerm_memory_card_full"))) {
5968 modest_platform_run_information_dialog ((GtkWindow *) win,
5969 _("mail_in_ui_folder_move_target_error"),
5973 g_object_unref (win);
5977 TnyFolderStore *dst_folder;
5982 * Utility function that transfer messages from both the main window
5983 * and the msg view window when using the "Move to" dialog
5986 xfer_messages_performer (gboolean canceled,
5988 GtkWindow *parent_window,
5989 TnyAccount *account,
5992 ModestWindow *win = MODEST_WINDOW (parent_window);
5993 TnyAccount *dst_account = NULL;
5994 gboolean dst_forbids_message_add = FALSE;
5995 XferMsgsHelper *helper;
5996 MoveToHelper *movehelper;
5997 ModestMailOperation *mail_op;
5999 helper = (XferMsgsHelper *) user_data;
6001 if (canceled || err) {
6002 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6003 (GtkWidget *) parent_window, err,
6005 /* Show the proper error message */
6006 modest_ui_actions_on_account_connection_error (parent_window, account);
6011 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
6013 /* tinymail will return NULL for local folders it seems */
6014 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
6015 modest_tny_account_get_protocol_type (dst_account),
6016 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
6018 if (dst_forbids_message_add) {
6019 modest_platform_information_banner (GTK_WIDGET (win),
6021 ngettext("mail_in_ui_folder_move_target_error",
6022 "mail_in_ui_folder_move_targets_error",
6023 tny_list_get_length (helper->headers)));
6027 movehelper = g_new0 (MoveToHelper, 1);
6029 #ifndef MODEST_TOOLKIT_HILDON2
6030 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
6031 _CS("ckct_nw_pasting"));
6032 if (movehelper->banner != NULL) {
6033 g_object_ref (movehelper->banner);
6034 gtk_widget_show (GTK_WIDGET (movehelper->banner));
6038 if (MODEST_IS_MAIN_WINDOW (win)) {
6039 GtkWidget *header_view =
6040 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6041 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6042 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
6045 /* Perform the mail operation */
6046 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
6047 xfer_messages_error_handler,
6048 g_object_ref (dst_account),
6050 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
6053 modest_mail_operation_xfer_msgs (mail_op,
6055 TNY_FOLDER (helper->dst_folder),
6060 g_object_unref (G_OBJECT (mail_op));
6063 g_object_unref (dst_account);
6064 g_object_unref (helper->dst_folder);
6065 g_object_unref (helper->headers);
6066 g_slice_free (XferMsgsHelper, helper);
6070 TnyFolder *src_folder;
6071 TnyFolderStore *dst_folder;
6072 gboolean delete_original;
6073 GtkWidget *folder_view;
6077 on_move_folder_cb (gboolean canceled,
6079 GtkWindow *parent_window,
6080 TnyAccount *account,
6083 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
6084 GtkTreeSelection *sel;
6085 ModestMailOperation *mail_op = NULL;
6087 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
6088 /* Note that the connection process can fail due to
6089 memory low conditions as it can not successfully
6090 store the summary */
6091 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6092 (GtkWidget*) parent_window, err,
6094 g_debug ("Error connecting when trying to move a folder");
6096 g_object_unref (G_OBJECT (info->src_folder));
6097 g_object_unref (G_OBJECT (info->dst_folder));
6102 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
6103 #ifndef MODEST_TOOLKIT_HILDON2
6104 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
6105 _CS("ckct_nw_pasting"));
6106 if (helper->banner != NULL) {
6107 g_object_ref (helper->banner);
6108 gtk_widget_show (GTK_WIDGET(helper->banner));
6111 /* Clean folder on header view before moving it */
6112 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
6113 gtk_tree_selection_unselect_all (sel);
6115 /* Let gtk events run. We need that the folder
6116 view frees its reference to the source
6117 folder *before* issuing the mail operation
6118 so we need the signal handler of selection
6119 changed to happen before the mail
6121 while (gtk_events_pending ())
6122 gtk_main_iteration (); */
6125 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
6126 modest_ui_actions_move_folder_error_handler,
6127 g_object_ref (info->dst_folder), g_object_unref);
6128 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
6131 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
6132 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
6133 TNY_FOLDER (info->dst_folder), TRUE);
6135 modest_mail_operation_xfer_folder (mail_op,
6136 TNY_FOLDER (info->src_folder),
6138 info->delete_original,
6141 g_object_unref (G_OBJECT (info->src_folder));
6143 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
6146 /* Unref mail operation */
6147 g_object_unref (G_OBJECT (mail_op));
6148 g_object_unref (G_OBJECT (info->dst_folder));
6153 get_account_from_folder_store (TnyFolderStore *folder_store)
6155 if (TNY_IS_ACCOUNT (folder_store))
6156 return g_object_ref (folder_store);
6158 return tny_folder_get_account (TNY_FOLDER (folder_store));
6162 * UI handler for the "Move to" action when invoked from the
6166 modest_ui_actions_on_main_window_move_to (GtkAction *action,
6167 GtkWidget *folder_view,
6168 TnyFolderStore *dst_folder,
6169 ModestMainWindow *win)
6171 ModestHeaderView *header_view = NULL;
6172 TnyFolderStore *src_folder = NULL;
6174 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
6176 /* Get the source folder */
6177 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6179 /* Get header view */
6180 header_view = (ModestHeaderView *)
6181 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6183 /* Get folder or messages to transfer */
6184 if (gtk_widget_is_focus (folder_view)) {
6185 gboolean do_xfer = TRUE;
6187 /* Allow only to transfer folders to the local root folder */
6188 if (TNY_IS_ACCOUNT (dst_folder) &&
6189 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
6190 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
6192 } else if (!TNY_IS_FOLDER (src_folder)) {
6193 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
6198 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
6199 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6201 info->src_folder = g_object_ref (src_folder);
6202 info->dst_folder = g_object_ref (dst_folder);
6203 info->delete_original = TRUE;
6204 info->folder_view = folder_view;
6206 connect_info->callback = on_move_folder_cb;
6207 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6208 connect_info->data = info;
6210 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6211 TNY_FOLDER_STORE (src_folder),
6214 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
6217 headers = modest_header_view_get_selected_headers(header_view);
6219 /* Transfer the messages */
6220 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
6221 headers, TNY_FOLDER (dst_folder));
6223 g_object_unref (headers);
6227 g_object_unref (src_folder);
6230 #ifdef MODEST_TOOLKIT_HILDON2
6232 * UI handler for the "Move to" action when invoked from the
6233 * ModestFolderWindow
6236 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
6237 TnyFolderStore *dst_folder,
6241 TnyFolderStore *src_folder = NULL;
6242 TnyIterator *iterator;
6244 if (tny_list_get_length (selection) != 1)
6247 iterator = tny_list_create_iterator (selection);
6248 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
6249 g_object_unref (iterator);
6252 gboolean do_xfer = TRUE;
6254 /* Allow only to transfer folders to the local root folder */
6255 if (TNY_IS_ACCOUNT (dst_folder) &&
6256 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
6257 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
6260 modest_platform_run_information_dialog (win,
6261 _("mail_in_ui_folder_move_target_error"),
6263 } else if (!TNY_IS_FOLDER (src_folder)) {
6264 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
6269 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
6270 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6272 info->src_folder = g_object_ref (src_folder);
6273 info->dst_folder = g_object_ref (dst_folder);
6274 info->delete_original = TRUE;
6275 info->folder_view = folder_view;
6277 connect_info->callback = on_move_folder_cb;
6278 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6279 connect_info->data = info;
6281 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6282 TNY_FOLDER_STORE (src_folder),
6287 g_object_unref (src_folder);
6293 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
6294 TnyFolder *src_folder,
6296 TnyFolder *dst_folder)
6298 gboolean need_connection = TRUE;
6299 gboolean do_xfer = TRUE;
6300 XferMsgsHelper *helper;
6302 g_return_if_fail (TNY_IS_FOLDER (src_folder));
6303 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6304 g_return_if_fail (TNY_IS_LIST (headers));
6306 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
6307 headers, TNY_FOLDER (dst_folder),
6308 TRUE, &need_connection,
6311 /* If we don't want to transfer just return */
6315 /* Create the helper */
6316 helper = g_slice_new (XferMsgsHelper);
6317 helper->dst_folder = g_object_ref (dst_folder);
6318 helper->headers = g_object_ref (headers);
6320 if (need_connection) {
6321 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6322 connect_info->callback = xfer_messages_performer;
6323 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
6324 connect_info->data = helper;
6326 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6327 TNY_FOLDER_STORE (src_folder),
6330 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
6331 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
6332 src_account, helper);
6333 g_object_unref (src_account);
6338 * UI handler for the "Move to" action when invoked from the
6339 * ModestMsgViewWindow
6342 modest_ui_actions_on_window_move_to (GtkAction *action,
6344 TnyFolderStore *dst_folder,
6347 TnyFolder *src_folder = NULL;
6349 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6352 TnyHeader *header = NULL;
6355 iter = tny_list_create_iterator (headers);
6356 header = (TnyHeader *) tny_iterator_get_current (iter);
6357 src_folder = tny_header_get_folder (header);
6359 /* Transfer the messages */
6360 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
6362 TNY_FOLDER (dst_folder));
6365 g_object_unref (header);
6366 g_object_unref (iter);
6367 g_object_unref (src_folder);
6372 modest_ui_actions_on_move_to (GtkAction *action,
6375 modest_ui_actions_on_edit_mode_move_to (win);
6379 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
6381 GtkWidget *dialog = NULL;
6382 MoveToInfo *helper = NULL;
6383 TnyList *list_to_move;
6385 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
6387 #ifndef MODEST_TOOLKIT_HILDON2
6388 /* Get the main window if exists */
6389 ModestMainWindow *main_window;
6390 if (MODEST_IS_MAIN_WINDOW (win))
6391 main_window = MODEST_MAIN_WINDOW (win);
6394 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
6395 FALSE)); /* don't create */
6398 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
6403 if (tny_list_get_length (list_to_move) < 1) {
6404 g_object_unref (list_to_move);
6408 /* Create and run the dialog */
6409 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
6410 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
6411 GTK_WINDOW (dialog),
6415 helper = g_slice_new0 (MoveToInfo);
6416 helper->list = list_to_move;
6419 /* Listen to response signal */
6420 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
6422 /* Show the dialog */
6423 gtk_widget_show (dialog);
6429 * Calls #HeadersFunc for each header already selected in the main
6430 * window or the message currently being shown in the msg view window
6433 do_headers_action (ModestWindow *win,
6437 TnyList *headers_list = NULL;
6438 TnyIterator *iter = NULL;
6439 TnyHeader *header = NULL;
6440 TnyFolder *folder = NULL;
6443 headers_list = get_selected_headers (win);
6447 /* Get the folder */
6448 iter = tny_list_create_iterator (headers_list);
6449 header = TNY_HEADER (tny_iterator_get_current (iter));
6451 folder = tny_header_get_folder (header);
6452 g_object_unref (header);
6455 /* Call the function for each header */
6456 while (!tny_iterator_is_done (iter)) {
6457 header = TNY_HEADER (tny_iterator_get_current (iter));
6458 func (header, win, user_data);
6459 g_object_unref (header);
6460 tny_iterator_next (iter);
6463 /* Trick: do a poke status in order to speed up the signaling
6466 tny_folder_poke_status (folder);
6467 g_object_unref (folder);
6471 g_object_unref (iter);
6472 g_object_unref (headers_list);
6476 modest_ui_actions_view_attachment (GtkAction *action,
6477 ModestWindow *window)
6479 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6480 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
6482 /* not supported window for this action */
6483 g_return_if_reached ();
6488 modest_ui_actions_save_attachments (GtkAction *action,
6489 ModestWindow *window)
6491 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6493 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
6496 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
6498 /* not supported window for this action */
6499 g_return_if_reached ();
6504 modest_ui_actions_remove_attachments (GtkAction *action,
6505 ModestWindow *window)
6507 if (MODEST_IS_MAIN_WINDOW (window)) {
6508 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
6509 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6510 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
6512 /* not supported window for this action */
6513 g_return_if_reached ();
6518 modest_ui_actions_on_settings (GtkAction *action,
6523 dialog = modest_platform_get_global_settings_dialog ();
6524 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
6525 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
6526 gtk_widget_show_all (dialog);
6528 gtk_dialog_run (GTK_DIALOG (dialog));
6530 gtk_widget_destroy (dialog);
6534 modest_ui_actions_on_help (GtkAction *action,
6537 /* Help app is not available at all in fremantle */
6538 #ifndef MODEST_TOOLKIT_HILDON2
6539 const gchar *help_id;
6541 g_return_if_fail (win && GTK_IS_WINDOW(win));
6543 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
6546 modest_platform_show_help (GTK_WINDOW (win), help_id);
6551 modest_ui_actions_on_csm_help (GtkAction *action,
6554 /* Help app is not available at all in fremantle */
6555 #ifndef MODEST_TOOLKIT_HILDON2
6557 const gchar* help_id = NULL;
6558 GtkWidget *folder_view;
6559 TnyFolderStore *folder_store;
6561 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
6563 /* Get selected folder */
6564 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
6565 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6566 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6568 /* Switch help_id */
6569 if (folder_store && TNY_IS_FOLDER (folder_store))
6570 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
6573 g_object_unref (folder_store);
6576 modest_platform_show_help (GTK_WINDOW (win), help_id);
6578 modest_ui_actions_on_help (action, win);
6583 retrieve_contents_cb (ModestMailOperation *mail_op,
6590 /* We only need this callback to show an error in case of
6591 memory low condition */
6592 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
6593 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
6598 retrieve_msg_contents_performer (gboolean canceled,
6600 GtkWindow *parent_window,
6601 TnyAccount *account,
6604 ModestMailOperation *mail_op;
6605 TnyList *headers = TNY_LIST (user_data);
6607 if (err || canceled) {
6608 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6609 (GtkWidget *) parent_window, err,
6614 /* Create mail operation */
6615 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
6616 modest_ui_actions_disk_operations_error_handler,
6618 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
6619 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
6622 g_object_unref (mail_op);
6624 g_object_unref (headers);
6625 g_object_unref (account);
6629 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
6630 ModestWindow *window)
6632 TnyList *headers = NULL;
6633 TnyAccount *account = NULL;
6634 TnyIterator *iter = NULL;
6635 TnyHeader *header = NULL;
6636 TnyFolder *folder = NULL;
6639 headers = get_selected_headers (window);
6643 /* Pick the account */
6644 iter = tny_list_create_iterator (headers);
6645 header = TNY_HEADER (tny_iterator_get_current (iter));
6646 folder = tny_header_get_folder (header);
6647 account = tny_folder_get_account (folder);
6648 g_object_unref (folder);
6649 g_object_unref (header);
6650 g_object_unref (iter);
6652 /* Connect and perform the message retrieval */
6653 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6654 g_object_ref (account),
6655 retrieve_msg_contents_performer,
6656 g_object_ref (headers));
6659 g_object_unref (account);
6660 g_object_unref (headers);
6664 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6666 g_return_if_fail (MODEST_IS_WINDOW (window));
6669 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6673 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6675 g_return_if_fail (MODEST_IS_WINDOW (window));
6678 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6682 modest_ui_actions_on_email_menu_activated (GtkAction *action,
6683 ModestWindow *window)
6685 g_return_if_fail (MODEST_IS_WINDOW (window));
6688 modest_ui_actions_check_menu_dimming_rules (window);
6692 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
6693 ModestWindow *window)
6695 g_return_if_fail (MODEST_IS_WINDOW (window));
6698 modest_ui_actions_check_menu_dimming_rules (window);
6702 modest_ui_actions_on_view_menu_activated (GtkAction *action,
6703 ModestWindow *window)
6705 g_return_if_fail (MODEST_IS_WINDOW (window));
6708 modest_ui_actions_check_menu_dimming_rules (window);
6712 modest_ui_actions_on_format_menu_activated (GtkAction *action,
6713 ModestWindow *window)
6715 g_return_if_fail (MODEST_IS_WINDOW (window));
6718 modest_ui_actions_check_menu_dimming_rules (window);
6722 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
6723 ModestWindow *window)
6725 g_return_if_fail (MODEST_IS_WINDOW (window));
6728 modest_ui_actions_check_menu_dimming_rules (window);
6732 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
6733 ModestWindow *window)
6735 g_return_if_fail (MODEST_IS_WINDOW (window));
6738 modest_ui_actions_check_menu_dimming_rules (window);
6742 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
6743 ModestWindow *window)
6745 g_return_if_fail (MODEST_IS_WINDOW (window));
6748 modest_ui_actions_check_menu_dimming_rules (window);
6752 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
6753 ModestWindow *window)
6755 g_return_if_fail (MODEST_IS_WINDOW (window));
6758 modest_ui_actions_check_menu_dimming_rules (window);
6762 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
6763 ModestWindow *window)
6765 g_return_if_fail (MODEST_IS_WINDOW (window));
6768 modest_ui_actions_check_menu_dimming_rules (window);
6772 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6774 g_return_if_fail (MODEST_IS_WINDOW (window));
6776 /* we check for low-mem; in that case, show a warning, and don't allow
6779 if (modest_platform_check_memory_low (window, TRUE))
6782 modest_platform_show_search_messages (GTK_WINDOW (window));
6786 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6788 g_return_if_fail (MODEST_IS_WINDOW (win));
6791 /* we check for low-mem; in that case, show a warning, and don't allow
6792 * for the addressbook
6794 if (modest_platform_check_memory_low (win, TRUE))
6798 modest_platform_show_addressbook (GTK_WINDOW (win));
6803 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6804 ModestWindow *window)
6807 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6809 if (GTK_IS_TOGGLE_ACTION (action))
6810 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6814 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window),
6819 on_send_receive_finished (ModestMailOperation *mail_op,
6822 GtkWidget *header_view, *folder_view;
6823 TnyFolderStore *folder_store;
6824 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6826 /* Set send/receive operation finished */
6827 modest_main_window_notify_send_receive_completed (main_win);
6829 /* Don't refresh the current folder if there were any errors */
6830 if (modest_mail_operation_get_status (mail_op) !=
6831 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6834 /* Refresh the current folder if we're viewing a window. We do
6835 this because the user won't be able to see the new mails in
6836 the selected folder after a Send&Receive because it only
6837 performs a poke_status, i.e, only the number of read/unread
6838 messages is updated, but the new headers are not
6840 folder_view = modest_main_window_get_child_widget (main_win,
6841 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6845 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6847 /* Do not need to refresh INBOX again because the
6848 update_account does it always automatically */
6849 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6850 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6851 ModestMailOperation *refresh_op;
6853 header_view = modest_main_window_get_child_widget (main_win,
6854 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6856 /* We do not need to set the contents style
6857 because it hasn't changed. We also do not
6858 need to save the widget status. Just force
6860 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6861 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6862 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6863 folder_refreshed_cb, main_win);
6864 g_object_unref (refresh_op);
6868 g_object_unref (folder_store);
6873 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6879 const gchar* server_name = NULL;
6880 TnyTransportAccount *transport;
6881 gchar *message = NULL;
6882 ModestProtocol *protocol;
6884 /* Don't show anything if the user cancelled something or the
6885 * send receive request is not interactive. Authentication
6886 * errors are managed by the account store so no need to show
6887 * a dialog here again */
6888 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6889 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6890 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6894 /* Get the server name. Note that we could be using a
6895 connection specific transport account */
6896 transport = (TnyTransportAccount *)
6897 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
6899 ModestTnyAccountStore *acc_store;
6900 const gchar *acc_name;
6901 TnyTransportAccount *conn_specific;
6903 acc_store = modest_runtime_get_account_store();
6904 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
6905 conn_specific = (TnyTransportAccount *)
6906 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
6907 if (conn_specific) {
6908 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
6909 g_object_unref (conn_specific);
6911 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
6913 g_object_unref (transport);
6917 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
6918 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
6919 tny_account_get_proto (TNY_ACCOUNT (transport)));
6921 g_warning ("%s: Account with no proto", __FUNCTION__);
6925 /* Show the appropriate message text for the GError: */
6926 switch (err->code) {
6927 case TNY_SERVICE_ERROR_CONNECT:
6928 message = modest_protocol_get_translation (protocol,
6929 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
6932 case TNY_SERVICE_ERROR_SEND:
6933 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6935 case TNY_SERVICE_ERROR_UNAVAILABLE:
6936 message = modest_protocol_get_translation (protocol,
6937 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
6941 g_warning ("%s: unexpected ERROR %d",
6942 __FUNCTION__, err->code);
6943 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6947 modest_platform_run_information_dialog (NULL, message, FALSE);
6952 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6957 ModestWindow *top_window = NULL;
6958 ModestWindowMgr *mgr = NULL;
6959 GtkWidget *header_view = NULL;
6960 TnyFolder *selected_folder = NULL;
6961 TnyFolderType folder_type;
6963 mgr = modest_runtime_get_window_mgr ();
6964 top_window = modest_window_mgr_get_current_top (mgr);
6969 #ifndef MODEST_TOOLKIT_HILDON2
6970 if (MODEST_IS_MAIN_WINDOW (top_window)) {
6971 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (top_window),
6972 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6975 if (MODEST_IS_HEADER_WINDOW (top_window)) {
6976 header_view = (GtkWidget *)
6977 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
6981 /* Get selected folder */
6983 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
6984 if (!selected_folder)
6987 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6988 #if GTK_CHECK_VERSION(2, 8, 0)
6989 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
6990 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6991 GtkTreeViewColumn *tree_column;
6993 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6994 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6996 gtk_tree_view_column_queue_resize (tree_column);
6998 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
6999 gtk_widget_queue_draw (header_view);
7002 #ifndef MODEST_TOOLKIT_HILDON2
7003 /* Rerun dimming rules, because the message could become deletable for example */
7004 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
7005 MODEST_DIMMING_RULES_TOOLBAR);
7006 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
7007 MODEST_DIMMING_RULES_MENU);
7011 g_object_unref (selected_folder);
7015 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
7016 TnyAccount *account)
7018 ModestProtocolType protocol_type;
7019 ModestProtocol *protocol;
7020 gchar *error_note = NULL;
7022 protocol_type = modest_tny_account_get_protocol_type (account);
7023 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
7026 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
7027 if (error_note == NULL) {
7028 g_warning ("%s: This should not be reached", __FUNCTION__);
7030 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
7031 g_free (error_note);
7036 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
7040 TnyFolderStore *folder = NULL;
7041 TnyAccount *account = NULL;
7042 ModestProtocolType proto;
7043 ModestProtocol *protocol;
7044 TnyHeader *header = NULL;
7046 if (MODEST_IS_MAIN_WINDOW (win)) {
7047 GtkWidget *header_view;
7048 TnyList* headers = NULL;
7050 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
7051 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
7052 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
7053 if (!headers || tny_list_get_length (headers) == 0) {
7055 g_object_unref (headers);
7058 iter = tny_list_create_iterator (headers);
7059 header = TNY_HEADER (tny_iterator_get_current (iter));
7060 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
7061 g_object_unref (iter);
7062 g_object_unref (headers);
7063 #ifdef MODEST_TOOLKIT_HILDON2
7064 } else if (MODEST_IS_HEADER_WINDOW (win)) {
7065 GtkWidget *header_view;
7066 TnyList* headers = NULL;
7068 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
7069 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
7070 if (!headers || tny_list_get_length (headers) == 0) {
7072 g_object_unref (headers);
7075 iter = tny_list_create_iterator (headers);
7076 header = TNY_HEADER (tny_iterator_get_current (iter));
7078 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
7080 g_warning ("List should contain headers");
7082 g_object_unref (iter);
7083 g_object_unref (headers);
7085 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
7086 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
7088 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
7091 if (!header || !folder)
7094 /* Get the account type */
7095 account = tny_folder_get_account (TNY_FOLDER (folder));
7096 proto = modest_tny_account_get_protocol_type (account);
7097 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
7100 subject = tny_header_dup_subject (header);
7101 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
7105 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
7111 g_object_unref (account);
7113 g_object_unref (folder);
7115 g_object_unref (header);
7121 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
7122 const gchar *account_name,
7123 const gchar *account_title)
7125 ModestAccountMgr *account_mgr;
7128 ModestProtocol *protocol;
7129 gboolean removed = FALSE;
7131 g_return_val_if_fail (account_name, FALSE);
7132 g_return_val_if_fail (account_title, FALSE);
7134 account_mgr = modest_runtime_get_account_mgr();
7136 /* The warning text depends on the account type: */
7137 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
7138 modest_account_mgr_get_store_protocol (account_mgr,
7140 txt = modest_protocol_get_translation (protocol,
7141 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
7144 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
7146 response = modest_platform_run_confirmation_dialog (parent_window, txt);
7150 if (response == GTK_RESPONSE_OK) {
7151 /* Remove account. If it succeeds then it also removes
7152 the account from the ModestAccountView: */
7153 gboolean is_default = FALSE;
7154 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
7155 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
7157 g_free (default_account_name);
7159 removed = modest_account_mgr_remove_account (account_mgr, account_name);
7161 #ifdef MODEST_TOOLKIT_HILDON2
7162 hildon_gtk_window_take_screenshot (parent_window, FALSE);
7164 /* Close all email notifications, we cannot
7165 distinguish if the notification belongs to
7166 this account or not, so for safety reasons
7167 we remove them all */
7168 modest_platform_remove_new_mail_notifications (FALSE, account_name);
7170 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
7177 on_fetch_images_performer (gboolean canceled,
7179 GtkWindow *parent_window,
7180 TnyAccount *account,
7183 if (err || canceled) {
7184 /* Show an unable to retrieve images ??? */
7188 /* Note that the user could have closed the window while connecting */
7189 if (GTK_WIDGET_VISIBLE (parent_window))
7190 modest_msg_view_window_fetch_images ((ModestMsgViewWindow *) parent_window);
7191 g_object_unref ((GObject *) user_data);
7195 modest_ui_actions_on_fetch_images (GtkAction *action,
7196 ModestWindow *window)
7198 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
7200 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
7202 on_fetch_images_performer,
7203 g_object_ref (window));
7207 modest_ui_actions_on_reload_message (const gchar *msg_id)
7209 ModestWindow *window = NULL;
7211 g_return_if_fail (msg_id && msg_id[0] != '\0');
7212 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
7218 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
7221 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));
7224 /** Check whether any connections are active, and cancel them if
7226 * Returns TRUE is there was no problem,
7227 * or if an operation was cancelled so we can continue.
7228 * Returns FALSE if the user chose to cancel his request instead.
7232 modest_ui_actions_check_for_active_account (ModestWindow *self,
7233 const gchar* account_name)
7235 ModestTnySendQueue *send_queue;
7236 ModestTnyAccountStore *acc_store;
7237 ModestMailOperationQueue* queue;
7238 TnyConnectionStatus store_conn_status;
7239 TnyAccount *store_account = NULL, *transport_account = NULL;
7240 gboolean retval = TRUE, sending = FALSE;
7242 acc_store = modest_runtime_get_account_store ();
7243 queue = modest_runtime_get_mail_operation_queue ();
7246 modest_tny_account_store_get_server_account (acc_store,
7248 TNY_ACCOUNT_TYPE_STORE);
7250 /* This could happen if the account was deleted before the
7251 call to this function */
7256 modest_tny_account_store_get_server_account (acc_store,
7258 TNY_ACCOUNT_TYPE_TRANSPORT);
7260 /* This could happen if the account was deleted before the
7261 call to this function */
7262 if (!transport_account) {
7263 g_object_unref (store_account);
7267 /* If the transport account was not used yet, then the send
7268 queue could not exist (it's created on demand) */
7269 send_queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (transport_account), FALSE);
7270 if (TNY_IS_SEND_QUEUE (send_queue))
7271 sending = modest_tny_send_queue_sending_in_progress (send_queue);
7273 store_conn_status = tny_account_get_connection_status (store_account);
7274 if (store_conn_status == TNY_CONNECTION_STATUS_CONNECTED || sending) {
7277 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (self),
7278 _("emev_nc_disconnect_account"));
7279 if (response == GTK_RESPONSE_OK) {
7288 /* FIXME: We should only cancel those of this account */
7289 modest_mail_operation_queue_cancel_all (queue);
7291 /* Also disconnect the account */
7292 if ((tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED) &&
7293 (tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)) {
7294 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
7298 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (transport_account),
7304 g_object_unref (store_account);
7305 g_object_unref (transport_account);