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;
403 g_return_if_fail (TNY_IS_HEADER(header));
405 flags = tny_header_get_flags (header);
406 if (flags & TNY_HEADER_FLAG_SEEN) return;
407 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
408 uid = modest_tny_folder_get_header_unique_id (header);
409 modest_platform_emit_msg_read_changed_signal (uid, TRUE);
414 headers_action_mark_as_unread (TnyHeader *header,
418 TnyHeaderFlags flags;
420 g_return_if_fail (TNY_IS_HEADER(header));
422 flags = tny_header_get_flags (header);
423 if (flags & TNY_HEADER_FLAG_SEEN) {
425 uid = modest_tny_folder_get_header_unique_id (header);
426 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
427 modest_platform_emit_msg_read_changed_signal (uid, FALSE);
431 /** After deleing a message that is currently visible in a window,
432 * show the next message from the list, or close the window if there are no more messages.
435 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
437 /* Close msg view window or select next */
438 if (!modest_msg_view_window_select_next_message (win) &&
439 !modest_msg_view_window_select_previous_message (win)) {
441 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
447 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
449 modest_ui_actions_on_edit_mode_delete_message (win);
453 modest_ui_actions_on_edit_mode_delete_message (ModestWindow *win)
455 TnyList *header_list = NULL;
456 TnyIterator *iter = NULL;
457 TnyHeader *header = NULL;
458 gchar *message = NULL;
461 ModestWindowMgr *mgr;
462 GtkWidget *header_view = NULL;
463 gboolean retval = TRUE;
465 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
467 /* Check first if the header view has the focus */
468 if (MODEST_IS_MAIN_WINDOW (win)) {
470 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
471 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
472 if (!gtk_widget_is_focus (header_view))
476 /* Get the headers, either from the header view (if win is the main window),
477 * or from the message view window: */
478 header_list = get_selected_headers (win);
479 if (!header_list) return FALSE;
481 /* Check if any of the headers are already opened, or in the process of being opened */
482 if (MODEST_IS_MAIN_WINDOW (win)) {
483 gint opened_headers = 0;
485 iter = tny_list_create_iterator (header_list);
486 mgr = modest_runtime_get_window_mgr ();
487 while (!tny_iterator_is_done (iter)) {
488 header = TNY_HEADER (tny_iterator_get_current (iter));
490 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
492 g_object_unref (header);
494 tny_iterator_next (iter);
496 g_object_unref (iter);
498 if (opened_headers > 0) {
501 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
504 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg, FALSE);
507 g_object_unref (header_list);
513 if (tny_list_get_length(header_list) == 1) {
514 iter = tny_list_create_iterator (header_list);
515 header = TNY_HEADER (tny_iterator_get_current (iter));
518 subject = tny_header_dup_subject (header);
520 subject = g_strdup (_("mail_va_no_subject"));
521 desc = g_strdup_printf ("%s", subject);
523 g_object_unref (header);
526 g_object_unref (iter);
528 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
529 tny_list_get_length(header_list)), desc);
531 /* Confirmation dialog */
532 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
536 if (response == GTK_RESPONSE_OK) {
537 ModestWindowMgr *mgr = NULL;
538 GtkTreeModel *model = NULL;
539 GtkTreeSelection *sel = NULL;
540 GList *sel_list = NULL, *tmp = NULL;
541 GtkTreeRowReference *next_row_reference = NULL;
542 GtkTreeRowReference *prev_row_reference = NULL;
543 GtkTreePath *next_path = NULL;
544 GtkTreePath *prev_path = NULL;
545 ModestMailOperation *mail_op = NULL;
547 /* Find last selected row */
548 if (MODEST_IS_MAIN_WINDOW (win)) {
549 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
550 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
551 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
552 for (tmp=sel_list; tmp; tmp=tmp->next) {
553 if (tmp->next == NULL) {
554 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
555 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
557 gtk_tree_path_prev (prev_path);
558 gtk_tree_path_next (next_path);
560 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
561 next_row_reference = gtk_tree_row_reference_new (model, next_path);
566 /* Disable window dimming management */
567 modest_window_disable_dimming (win);
569 /* Remove each header. If it's a view window header_view == NULL */
570 mail_op = modest_mail_operation_new ((GObject *) win);
571 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
573 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
574 g_object_unref (mail_op);
576 /* Enable window dimming management */
578 gtk_tree_selection_unselect_all (sel);
580 modest_window_enable_dimming (win);
582 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
583 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
585 /* Get main window */
586 mgr = modest_runtime_get_window_mgr ();
587 } else if (MODEST_IS_MAIN_WINDOW (win)) {
588 /* Select next or previous row */
589 if (gtk_tree_row_reference_valid (next_row_reference)) {
590 gtk_tree_selection_select_path (sel, next_path);
592 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
593 gtk_tree_selection_select_path (sel, prev_path);
597 if (gtk_tree_row_reference_valid (next_row_reference))
598 gtk_tree_row_reference_free (next_row_reference);
599 if (next_path != NULL)
600 gtk_tree_path_free (next_path);
601 if (gtk_tree_row_reference_valid (prev_row_reference))
602 gtk_tree_row_reference_free (prev_row_reference);
603 if (prev_path != NULL)
604 gtk_tree_path_free (prev_path);
607 /* Update toolbar dimming state */
608 modest_ui_actions_check_menu_dimming_rules (win);
609 modest_ui_actions_check_toolbar_dimming_rules (win);
612 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
613 g_list_free (sel_list);
622 g_object_unref (header_list);
630 /* delete either message or folder, based on where we are */
632 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
634 g_return_if_fail (MODEST_IS_WINDOW(win));
636 /* Check first if the header view has the focus */
637 if (MODEST_IS_MAIN_WINDOW (win)) {
639 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
640 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
641 if (gtk_widget_is_focus (w)) {
642 modest_ui_actions_on_delete_folder (action, MODEST_WINDOW(win));
646 modest_ui_actions_on_delete_message (action, win);
650 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
652 ModestWindowMgr *mgr = NULL;
654 #ifdef MODEST_PLATFORM_MAEMO
655 modest_window_mgr_save_state_for_all_windows (modest_runtime_get_window_mgr ());
656 #endif /* MODEST_PLATFORM_MAEMO */
658 g_debug ("closing down, clearing %d item(s) from operation queue",
659 modest_mail_operation_queue_num_elements
660 (modest_runtime_get_mail_operation_queue()));
662 /* cancel all outstanding operations */
663 modest_mail_operation_queue_cancel_all
664 (modest_runtime_get_mail_operation_queue());
666 g_debug ("queue has been cleared");
669 /* Check if there are opened editing windows */
670 mgr = modest_runtime_get_window_mgr ();
671 modest_window_mgr_close_all_windows (mgr);
673 /* note: when modest-tny-account-store is finalized,
674 it will automatically set all network connections
677 /* gtk_main_quit (); */
681 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
685 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
687 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
688 /* gtk_widget_destroy (GTK_WIDGET (win)); */
689 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
690 /* gboolean ret_value; */
691 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
692 /* } else if (MODEST_IS_WINDOW (win)) { */
693 /* gtk_widget_destroy (GTK_WIDGET (win)); */
695 /* g_return_if_reached (); */
700 modest_ui_actions_add_to_contacts (GtkAction *action, ModestWindow *win)
702 if (MODEST_IS_MSG_VIEW_WINDOW (win))
703 modest_msg_view_window_add_to_contacts (MODEST_MSG_VIEW_WINDOW (win));
704 else if (MODEST_IS_MSG_EDIT_WINDOW (win))
705 modest_msg_edit_window_add_to_contacts (MODEST_MSG_EDIT_WINDOW (win));
709 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
711 GtkClipboard *clipboard = NULL;
712 gchar *selection = NULL;
714 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
715 selection = gtk_clipboard_wait_for_text (clipboard);
718 modest_address_book_add_address (selection, (GtkWindow *) win);
724 modest_ui_actions_on_new_account (GtkAction *action,
725 ModestWindow *window)
727 if (!modest_ui_actions_run_account_setup_wizard (window)) {
728 g_debug ("%s: wizard was already running", __FUNCTION__);
733 modest_ui_actions_on_accounts (GtkAction *action,
736 /* This is currently only implemented for Maemo */
737 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
738 if (!modest_ui_actions_run_account_setup_wizard (win))
739 g_debug ("%s: wizard was already running", __FUNCTION__);
743 /* Show the list of accounts */
744 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
746 /* The accounts dialog must be modal */
747 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
748 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
753 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
755 /* This is currently only implemented for Maemo,
756 * because it requires an API (libconic) to detect different connection
759 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
761 /* Create the window if necessary: */
762 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
763 modest_connection_specific_smtp_window_fill_with_connections (
764 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
765 modest_runtime_get_account_mgr());
767 /* Show the window: */
768 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
769 GTK_WINDOW (specific_window), (GtkWindow *) win);
770 gtk_widget_show (specific_window);
771 #endif /* !MODEST_TOOLKIT_GTK */
775 count_part_size (const gchar *part)
777 GnomeVFSURI *vfs_uri;
778 gchar *escaped_filename;
780 GnomeVFSFileInfo *info;
783 /* Estimation of attachment size if we cannot get it from file info */
786 vfs_uri = gnome_vfs_uri_new (part);
788 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
789 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
790 g_free (escaped_filename);
791 gnome_vfs_uri_unref (vfs_uri);
793 info = gnome_vfs_file_info_new ();
795 if (gnome_vfs_get_file_info (part,
797 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
799 if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) {
804 gnome_vfs_file_info_unref (info);
810 count_parts_size (GSList *parts)
815 for (node = parts; node != NULL; node = g_slist_next (node)) {
816 result += count_part_size ((const gchar *) node->data);
823 modest_ui_actions_compose_msg(ModestWindow *win,
826 const gchar *bcc_str,
827 const gchar *subject_str,
828 const gchar *body_str,
830 gboolean set_as_modified)
832 gchar *account_name = NULL;
833 const gchar *mailbox;
835 TnyAccount *account = NULL;
836 TnyFolder *folder = NULL;
837 gchar *from_str = NULL, *signature = NULL, *body = NULL, *recipient = NULL, *tmp = NULL;
838 gboolean use_signature = FALSE;
839 ModestWindow *msg_win = NULL;
840 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
841 ModestTnyAccountStore *store = modest_runtime_get_account_store();
842 GnomeVFSFileSize total_size, allowed_size;
843 guint64 available_disk, expected_size, parts_size;
846 /* we check for low-mem */
847 if (modest_platform_check_memory_low (win, TRUE))
850 available_disk = modest_utils_get_available_space (NULL);
851 parts_count = g_slist_length (attachments);
852 parts_size = count_parts_size (attachments);
853 expected_size = modest_tny_msg_estimate_size (body, NULL, parts_count, parts_size);
855 /* Double check: disk full condition or message too big */
856 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
857 expected_size > available_disk) {
858 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
859 modest_platform_system_banner (NULL, NULL, msg);
865 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
866 modest_platform_run_information_dialog (
868 _("mail_ib_error_attachment_size"),
874 #ifdef MODEST_TOOLKIT_HILDON2
876 account_name = g_strdup (modest_window_get_active_account(win));
879 account_name = modest_account_mgr_get_default_account(mgr);
882 g_printerr ("modest: no account found\n");
887 mailbox = modest_window_get_active_mailbox (win);
890 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
892 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
895 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
897 g_printerr ("modest: failed to find Drafts folder\n");
900 from_str = modest_account_mgr_get_from_string (mgr, account_name, mailbox);
902 g_printerr ("modest: failed get from string for '%s'\n", account_name);
907 recipient = modest_text_utils_get_email_address (from_str);
908 tmp = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr (),
911 signature = modest_text_utils_create_colored_signature (tmp);
915 body = use_signature ? g_strconcat ((body_str) ? body_str : "", signature, NULL) :
918 msg = modest_tny_msg_new_html_plain (to_str, from_str, cc_str, bcc_str, subject_str,
919 NULL, NULL, body, NULL, NULL, NULL, NULL, NULL);
921 g_printerr ("modest: failed to create new msg\n");
925 /* Create and register edit window */
926 /* This is destroyed by TODO. */
928 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
929 msg_win = modest_msg_edit_window_new (msg, account_name, mailbox, FALSE);
931 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, win)) {
932 gtk_widget_destroy (GTK_WIDGET (msg_win));
935 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
936 gtk_widget_show_all (GTK_WIDGET (msg_win));
938 while (attachments) {
939 GnomeVFSFileSize att_size;
941 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
942 attachments->data, allowed_size);
943 total_size += att_size;
945 if (att_size > allowed_size) {
946 g_debug ("%s: total size: %u",
947 __FUNCTION__, (unsigned int)total_size);
950 allowed_size -= att_size;
952 attachments = g_slist_next(attachments);
959 g_free (account_name);
961 g_object_unref (G_OBJECT(account));
963 g_object_unref (G_OBJECT(folder));
965 g_object_unref (G_OBJECT(msg));
969 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
971 /* if there are no accounts yet, just show the wizard */
972 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
973 if (!modest_ui_actions_run_account_setup_wizard (win))
976 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
981 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
985 ModestMailOperationStatus status;
987 /* If there is no message or the operation was not successful */
988 status = modest_mail_operation_get_status (mail_op);
989 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
992 /* If it's a memory low issue, then show a banner */
993 error = modest_mail_operation_get_error (mail_op);
994 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
995 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
996 GObject *source = modest_mail_operation_get_source (mail_op);
997 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
998 _KR("memr_ib_operation_disabled"),
1000 g_object_unref (source);
1003 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
1004 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
1005 gchar *subject, *msg, *format = NULL;
1006 TnyAccount *account;
1008 subject = (header) ? tny_header_dup_subject (header) : NULL;
1010 subject = g_strdup (_("mail_va_no_subject"));
1012 account = modest_mail_operation_get_account (mail_op);
1014 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
1015 ModestProtocol *protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), proto);
1018 if (tny_account_get_connection_status (account) ==
1019 TNY_CONNECTION_STATUS_CONNECTED) {
1021 format = modest_protocol_get_translation (protocol,
1022 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE,
1025 format = modest_protocol_get_translation (protocol,
1026 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE_LOST_HEADER);
1029 format = g_strdup_printf (_("mail_ib_backend_server_invalid"),
1030 tny_account_get_hostname (account));
1033 g_object_unref (account);
1038 format = g_strdup (_("emev_ni_ui_imap_message_not_available_in_server"));
1040 format = g_strdup (_("emev_ni_ui_pop3_msg_recv_error"));
1044 msg = g_strdup_printf (format, subject);
1045 modest_platform_run_information_dialog (NULL, msg, FALSE);
1051 /* Remove the header from the preregistered uids */
1052 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1065 } OpenMsgBannerInfo;
1068 GtkTreeModel *model;
1070 ModestWindow *caller_window;
1071 OpenMsgBannerInfo *banner_info;
1072 GtkTreeRowReference *rowref;
1076 open_msg_banner_idle (gpointer userdata)
1078 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
1080 gdk_threads_enter ();
1081 banner_info->idle_handler = 0;
1082 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
1083 if (banner_info->banner)
1084 g_object_ref (banner_info->banner);
1086 gdk_threads_leave ();
1092 get_header_view_from_window (ModestWindow *window)
1094 GtkWidget *header_view;
1096 if (MODEST_IS_MAIN_WINDOW (window)) {
1097 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
1098 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1099 #ifdef MODEST_TOOLKIT_HILDON2
1100 } else if (MODEST_IS_HEADER_WINDOW (window)){
1101 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
1111 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
1114 gchar *account = NULL;
1115 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
1120 folder = tny_header_get_folder (header);
1121 /* Gets folder type (OUTBOX headers will be opened in edit window */
1122 if (modest_tny_folder_is_local_folder (folder)) {
1123 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1124 if (folder_type == TNY_FOLDER_TYPE_INVALID)
1125 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1128 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
1129 TnyTransportAccount *traccount = NULL;
1130 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
1131 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
1133 ModestTnySendQueue *send_queue = NULL;
1134 ModestTnySendQueueStatus status;
1136 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
1137 TNY_ACCOUNT(traccount)));
1138 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
1139 if (TNY_IS_SEND_QUEUE (send_queue)) {
1140 msg_id = modest_tny_send_queue_get_msg_id (header);
1141 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
1143 /* Only open messages in outbox with the editor if they are in Failed state */
1144 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
1147 #ifdef MODEST_TOOLKIT_HILDON2
1149 /* In Fremantle we can not
1150 open any message from
1151 outbox which is not in
1157 g_object_unref(traccount);
1159 g_warning("Cannot get transport account for message in outbox!!");
1161 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
1162 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
1166 TnyAccount *acc = tny_folder_get_account (folder);
1169 g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (acc));
1170 g_object_unref (acc);
1174 g_object_unref (folder);
1180 open_msg_cb (ModestMailOperation *mail_op,
1187 ModestWindowMgr *mgr = NULL;
1188 ModestWindow *parent_win = NULL;
1189 ModestWindow *win = NULL;
1190 gchar *account = NULL;
1191 gboolean open_in_editor = FALSE;
1193 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1195 /* Do nothing if there was any problem with the mail
1196 operation. The error will be shown by the error_handler of
1197 the mail operation */
1198 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1201 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1203 /* Mark header as read */
1204 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1206 account = get_info_from_header (header, &open_in_editor, &can_open);
1210 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1212 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1214 if (open_in_editor) {
1215 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1216 gchar *from_header = NULL, *acc_name;
1217 gchar *mailbox = NULL;
1219 from_header = tny_header_dup_from (header);
1221 /* we cannot edit without a valid account... */
1222 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1223 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1224 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1226 g_free (from_header);
1231 acc_name = modest_utils_get_account_name_from_recipient (from_header, &mailbox);
1232 g_free (from_header);
1238 win = modest_msg_edit_window_new (msg, account, mailbox, TRUE);
1242 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1243 const gchar *mailbox = NULL;
1245 if (parent_win && MODEST_IS_WINDOW (parent_win))
1246 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_win));
1248 if (helper->rowref && helper->model) {
1249 win = modest_msg_view_window_new_with_header_model (msg, account, mailbox, (const gchar*) uid,
1250 helper->model, helper->rowref);
1252 win = modest_msg_view_window_new_for_attachment (msg, NULL, account, mailbox, (const gchar*) uid);
1257 /* Register and show new window */
1259 mgr = modest_runtime_get_window_mgr ();
1260 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1261 gtk_widget_destroy (GTK_WIDGET (win));
1264 gtk_widget_show_all (GTK_WIDGET(win));
1267 /* Update toolbar dimming state */
1268 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1269 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1275 g_object_unref (parent_win);
1279 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1282 const GError *error;
1283 GObject *win = NULL;
1284 ModestMailOperationStatus status;
1286 win = modest_mail_operation_get_source (mail_op);
1287 error = modest_mail_operation_get_error (mail_op);
1288 status = modest_mail_operation_get_status (mail_op);
1290 /* If the mail op has been cancelled then it's not an error:
1291 don't show any message */
1292 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1293 TnyAccount *account = modest_mail_operation_get_account (mail_op);
1294 if (modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
1295 (GError *) error, account)) {
1296 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
1297 modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
1299 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1300 modest_platform_information_banner ((GtkWidget *) win,
1301 NULL, _("emev_ui_imap_inbox_select_error"));
1302 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1303 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1304 modest_platform_information_banner ((GtkWidget *) win,
1305 NULL, _CS ("sfil_ni_unable_to_open_file_not_found"));
1306 } else if (user_data) {
1307 modest_platform_information_banner ((GtkWidget *) win,
1311 g_object_unref (account);
1315 g_object_unref (win);
1319 * Returns the account a list of headers belongs to. It returns a
1320 * *new* reference so don't forget to unref it
1323 get_account_from_header_list (TnyList *headers)
1325 TnyAccount *account = NULL;
1327 if (tny_list_get_length (headers) > 0) {
1328 TnyIterator *iter = tny_list_create_iterator (headers);
1329 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1330 TnyFolder *folder = tny_header_get_folder (header);
1333 g_object_unref (header);
1335 while (!tny_iterator_is_done (iter)) {
1336 header = TNY_HEADER (tny_iterator_get_current (iter));
1337 folder = tny_header_get_folder (header);
1340 g_object_unref (header);
1342 tny_iterator_next (iter);
1347 account = tny_folder_get_account (folder);
1348 g_object_unref (folder);
1352 g_object_unref (header);
1354 g_object_unref (iter);
1360 get_account_from_header (TnyHeader *header)
1362 TnyAccount *account = NULL;
1365 folder = tny_header_get_folder (header);
1368 account = tny_folder_get_account (folder);
1369 g_object_unref (folder);
1375 caller_win_destroyed (OpenMsgHelper *helper, GObject *object)
1377 if (helper->caller_window)
1378 helper->caller_window = NULL;
1382 open_msg_helper_destroyer (gpointer user_data)
1384 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1386 if (helper->caller_window) {
1387 g_object_weak_unref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1388 helper->caller_window = NULL;
1391 if (helper->banner_info) {
1392 g_free (helper->banner_info->message);
1393 if (helper->banner_info->idle_handler > 0) {
1394 g_source_remove (helper->banner_info->idle_handler);
1395 helper->banner_info->idle_handler = 0;
1397 if (helper->banner_info->banner != NULL) {
1398 gtk_widget_destroy (helper->banner_info->banner);
1399 g_object_unref (helper->banner_info->banner);
1400 helper->banner_info->banner = NULL;
1402 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1403 helper->banner_info = NULL;
1405 g_object_unref (helper->model);
1406 g_object_unref (helper->header);
1407 gtk_tree_row_reference_free (helper->rowref);
1408 g_slice_free (OpenMsgHelper, helper);
1412 open_msg_performer(gboolean canceled,
1414 GtkWindow *parent_window,
1415 TnyAccount *account,
1418 ModestMailOperation *mail_op = NULL;
1419 gchar *error_msg = NULL;
1420 ModestProtocolType proto;
1421 TnyConnectionStatus status;
1422 OpenMsgHelper *helper = NULL;
1423 ModestProtocol *protocol;
1424 ModestProtocolRegistry *protocol_registry;
1427 helper = (OpenMsgHelper *) user_data;
1429 status = tny_account_get_connection_status (account);
1430 if (err || canceled || helper->caller_window == NULL) {
1431 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1432 /* Free the helper */
1433 open_msg_helper_destroyer (helper);
1435 /* In disk full conditions we could get this error here */
1436 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
1437 (GtkWidget *) parent_window, err,
1443 /* Get the error message depending on the protocol */
1444 proto = modest_tny_account_get_protocol_type (account);
1445 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1446 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1449 protocol_registry = modest_runtime_get_protocol_registry ();
1450 subject = tny_header_dup_subject (helper->header);
1452 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1453 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1457 if (error_msg == NULL) {
1458 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1461 #ifndef MODEST_TOOLKIT_HILDON2
1462 gboolean show_open_draft = FALSE;
1463 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1465 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1467 TnyFolderType folder_type;
1469 folder = tny_header_get_folder (helper->header);
1470 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1471 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1472 g_object_unref (folder);
1476 #ifdef MODEST_TOOLKIT_HILDON2
1479 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1481 if (!g_strcmp0 (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) ||
1482 !g_strcmp0 (account_name, MODEST_MMC_ACCOUNT_ID)) {
1483 g_free (account_name);
1484 account_name = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_window)));
1488 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1489 g_free (account_name);
1490 open_msg_helper_destroyer (helper);
1495 ModestWindow *window;
1496 GtkWidget *header_view;
1499 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1500 uid = modest_tny_folder_get_header_unique_id (helper->header);
1502 const gchar *mailbox = NULL;
1503 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_window));
1504 window = modest_msg_view_window_new_from_header_view
1505 (MODEST_HEADER_VIEW (header_view), account_name, mailbox, uid, helper->rowref);
1506 if (window != NULL) {
1507 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1509 gtk_widget_destroy (GTK_WIDGET (window));
1511 gtk_widget_show_all (GTK_WIDGET(window));
1515 g_free (account_name);
1517 open_msg_helper_destroyer (helper);
1520 g_free (account_name);
1522 /* Create the mail operation */
1524 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1525 modest_ui_actions_disk_operations_error_handler,
1526 g_strdup (error_msg), g_free);
1527 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1531 #ifndef MODEST_TOOLKIT_HILDON2
1532 if (show_open_draft) {
1533 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1534 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1535 helper->banner_info->banner = NULL;
1536 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1537 helper->banner_info);
1543 headers = TNY_LIST (tny_simple_list_new ());
1544 tny_list_prepend (headers, G_OBJECT (helper->header));
1545 modest_mail_operation_get_msgs_full (mail_op,
1549 open_msg_helper_destroyer);
1550 g_object_unref (headers);
1557 g_object_unref (mail_op);
1558 g_object_unref (account);
1562 * This function is used by both modest_ui_actions_on_open and
1563 * modest_ui_actions_on_header_activated. This way we always do the
1564 * same when trying to open messages.
1567 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1569 ModestWindowMgr *mgr = NULL;
1570 TnyAccount *account;
1571 gboolean cached = FALSE;
1573 GtkWidget *header_view = NULL;
1574 OpenMsgHelper *helper;
1575 ModestWindow *window;
1577 g_return_if_fail (header != NULL && rowref != NULL && gtk_tree_row_reference_valid (rowref));
1579 mgr = modest_runtime_get_window_mgr ();
1582 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1583 if (header_view == NULL)
1586 /* Get the account */
1587 account = get_account_from_header (header);
1592 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1594 /* Do not open again the message and present the
1595 window to the user */
1598 #ifndef MODEST_TOOLKIT_HILDON2
1599 gtk_window_present (GTK_WINDOW (window));
1602 /* the header has been registered already, we don't do
1603 * anything but wait for the window to come up*/
1604 g_debug ("header %p already registered, waiting for window", header);
1609 /* Open each message */
1610 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1612 /* Allways download if we are online. */
1613 if (!tny_device_is_online (modest_runtime_get_device ())) {
1616 /* If ask for user permission to download the messages */
1617 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1618 _("mcen_nc_get_msg"));
1620 /* End if the user does not want to continue */
1621 if (response == GTK_RESPONSE_CANCEL) {
1627 /* We register the window for opening */
1628 modest_window_mgr_register_header (mgr, header, NULL);
1630 /* Create the helper. We need to get a reference to the model
1631 here because it could change while the message is readed
1632 (the user could switch between folders) */
1633 helper = g_slice_new (OpenMsgHelper);
1634 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1635 helper->caller_window = win;
1636 g_object_weak_ref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1637 helper->header = g_object_ref (header);
1638 helper->rowref = gtk_tree_row_reference_copy (rowref);
1639 helper->banner_info = NULL;
1641 /* Connect to the account and perform */
1643 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1644 open_msg_performer, helper);
1646 /* Call directly the performer, do not need to connect */
1647 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1648 g_object_ref (account), helper);
1653 g_object_unref (account);
1657 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1664 /* we check for low-mem; in that case, show a warning, and don't allow
1667 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1671 headers = get_selected_headers (win);
1675 headers_count = tny_list_get_length (headers);
1676 if (headers_count != 1) {
1677 if (headers_count > 1) {
1678 /* Don't allow activation if there are more than one message selected */
1679 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1682 g_object_unref (headers);
1686 iter = tny_list_create_iterator (headers);
1687 header = TNY_HEADER (tny_iterator_get_current (iter));
1688 g_object_unref (iter);
1692 open_msg_from_header (header, NULL, win);
1693 g_object_unref (header);
1696 g_object_unref(headers);
1700 rf_helper_window_closed (gpointer data,
1703 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1705 helper->parent_window = NULL;
1708 static ReplyForwardHelper*
1709 create_reply_forward_helper (ReplyForwardAction action,
1711 guint reply_forward_type,
1714 TnyHeader *top_header,
1717 ReplyForwardHelper *rf_helper = NULL;
1718 const gchar *active_acc = modest_window_get_active_account (win);
1719 const gchar *active_mailbox = modest_window_get_active_mailbox (win);
1721 rf_helper = g_slice_new0 (ReplyForwardHelper);
1722 rf_helper->reply_forward_type = reply_forward_type;
1723 rf_helper->action = action;
1724 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1725 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1726 rf_helper->top_header = (top_header) ? g_object_ref (top_header) : NULL;
1727 rf_helper->msg_part = (msg_part) ? g_object_ref (msg_part) : NULL;
1728 rf_helper->account_name = (active_acc) ?
1729 g_strdup (active_acc) :
1730 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1731 rf_helper->mailbox = g_strdup (active_mailbox);
1733 rf_helper->parts = g_object_ref (parts);
1735 rf_helper->parts = NULL;
1737 /* Note that window could be destroyed just AFTER calling
1738 register_window so we must ensure that this pointer does
1739 not hold invalid references */
1740 if (rf_helper->parent_window)
1741 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1742 rf_helper_window_closed, rf_helper);
1748 free_reply_forward_helper (gpointer data)
1750 ReplyForwardHelper *helper;
1752 helper = (ReplyForwardHelper *) data;
1753 g_free (helper->account_name);
1754 g_free (helper->mailbox);
1756 g_object_unref (helper->header);
1757 if (helper->top_header)
1758 g_object_unref (helper->top_header);
1759 if (helper->msg_part)
1760 g_object_unref (helper->msg_part);
1762 g_object_unref (helper->parts);
1763 if (helper->parent_window)
1764 g_object_weak_unref (G_OBJECT (helper->parent_window),
1765 rf_helper_window_closed, helper);
1766 g_slice_free (ReplyForwardHelper, helper);
1770 reply_forward_cb (ModestMailOperation *mail_op,
1777 TnyMsg *new_msg = NULL;
1778 ReplyForwardHelper *rf_helper;
1779 ModestWindow *msg_win = NULL;
1780 ModestEditType edit_type;
1782 TnyAccount *account = NULL;
1783 ModestWindowMgr *mgr = NULL;
1784 gchar *signature = NULL, *recipient = NULL;
1785 gboolean use_signature;
1787 /* If there was any error. The mail operation could be NULL,
1788 this means that we already have the message downloaded and
1789 that we didn't do a mail operation to retrieve it */
1790 rf_helper = (ReplyForwardHelper *) user_data;
1791 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1794 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1795 rf_helper->account_name, rf_helper->mailbox);
1797 recipient = modest_text_utils_get_email_address (from);
1798 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr (),
1803 /* Create reply mail */
1804 switch (rf_helper->action) {
1805 /* Use the msg_header to ensure that we have all the
1806 information. The summary can lack some data */
1807 TnyHeader *msg_header;
1809 msg_header = tny_msg_get_header (rf_helper->msg_part?rf_helper->msg_part:msg);
1811 modest_tny_msg_create_reply_msg (rf_helper->msg_part?rf_helper->msg_part:msg, msg_header, from,
1812 (use_signature) ? signature : NULL,
1813 rf_helper->reply_forward_type,
1814 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1815 g_object_unref (msg_header);
1817 case ACTION_REPLY_TO_ALL:
1818 msg_header = tny_msg_get_header (rf_helper->msg_part?rf_helper->msg_part:msg);
1820 modest_tny_msg_create_reply_msg (rf_helper->msg_part?rf_helper->msg_part:msg, msg_header, from,
1821 (use_signature) ? signature : NULL,
1822 rf_helper->reply_forward_type,
1823 MODEST_TNY_MSG_REPLY_MODE_ALL);
1824 edit_type = MODEST_EDIT_TYPE_REPLY;
1825 g_object_unref (msg_header);
1827 case ACTION_FORWARD:
1829 modest_tny_msg_create_forward_msg (rf_helper->msg_part?rf_helper->msg_part:msg, from,
1830 (use_signature) ? signature : NULL,
1831 rf_helper->reply_forward_type);
1832 edit_type = MODEST_EDIT_TYPE_FORWARD;
1835 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1837 g_return_if_reached ();
1845 g_warning ("%s: failed to create message\n", __FUNCTION__);
1849 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1850 rf_helper->account_name,
1851 TNY_ACCOUNT_TYPE_STORE);
1853 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1857 /* Create and register the windows */
1858 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, rf_helper->mailbox, FALSE);
1859 mgr = modest_runtime_get_window_mgr ();
1860 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1862 /* Note that register_window could have deleted the account */
1863 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1864 gdouble parent_zoom;
1866 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1867 modest_window_set_zoom (msg_win, parent_zoom);
1870 /* Show edit window */
1871 gtk_widget_show_all (GTK_WIDGET (msg_win));
1874 /* We always unregister the header because the message is
1875 forwarded or replied so the original one is no longer
1877 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1880 g_object_unref (G_OBJECT (new_msg));
1882 g_object_unref (G_OBJECT (account));
1883 free_reply_forward_helper (rf_helper);
1886 /* Checks a list of headers. If any of them are not currently
1887 * downloaded (CACHED) then returns TRUE else returns FALSE.
1890 header_list_count_uncached_msgs (TnyList *header_list)
1893 gint uncached_messages = 0;
1895 iter = tny_list_create_iterator (header_list);
1896 while (!tny_iterator_is_done (iter)) {
1899 header = TNY_HEADER (tny_iterator_get_current (iter));
1901 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1902 uncached_messages ++;
1903 g_object_unref (header);
1906 tny_iterator_next (iter);
1908 g_object_unref (iter);
1910 return uncached_messages;
1913 /* Returns FALSE if the user does not want to download the
1914 * messages. Returns TRUE if the user allowed the download.
1917 connect_to_get_msg (ModestWindow *win,
1918 gint num_of_uncached_msgs,
1919 TnyAccount *account)
1921 GtkResponseType response;
1923 /* Allways download if we are online. */
1924 if (tny_device_is_online (modest_runtime_get_device ()))
1927 /* If offline, then ask for user permission to download the messages */
1928 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1929 ngettext("mcen_nc_get_msg",
1931 num_of_uncached_msgs));
1933 if (response == GTK_RESPONSE_CANCEL)
1936 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1940 reply_forward_performer (gboolean canceled,
1942 GtkWindow *parent_window,
1943 TnyAccount *account,
1946 ReplyForwardHelper *rf_helper = NULL;
1947 ModestMailOperation *mail_op;
1949 rf_helper = (ReplyForwardHelper *) user_data;
1951 if (canceled || err) {
1952 free_reply_forward_helper (rf_helper);
1956 /* Retrieve the message */
1957 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1958 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1959 modest_ui_actions_disk_operations_error_handler,
1961 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1962 modest_mail_operation_get_msg_and_parts (mail_op, rf_helper->top_header, rf_helper->parts, TRUE, reply_forward_cb, rf_helper);
1965 g_object_unref(mail_op);
1969 all_parts_retrieved (TnyMimePart *part)
1971 if (!TNY_IS_CAMEL_BS_MIME_PART (part)) {
1974 TnyList *pending_parts;
1975 TnyIterator *iterator;
1976 gboolean all_retrieved = TRUE;
1978 pending_parts = TNY_LIST (tny_simple_list_new ());
1979 tny_mime_part_get_parts (part, pending_parts);
1980 iterator = tny_list_create_iterator (pending_parts);
1981 while (all_retrieved && !tny_iterator_is_done (iterator)) {
1984 child = TNY_MIME_PART (tny_iterator_get_current (iterator));
1986 if (tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (child))) {
1987 all_retrieved = all_parts_retrieved (TNY_MIME_PART (child));
1989 all_retrieved = FALSE;
1992 g_object_unref (child);
1993 tny_iterator_next (iterator);
1995 g_object_unref (iterator);
1996 g_object_unref (pending_parts);
1997 return all_retrieved;
2002 forward_pending_parts_helper (TnyMimePart *part, TnyList *list)
2005 TnyIterator *iterator;
2007 if (!tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (part))) {
2008 tny_list_append (list, G_OBJECT (part));
2010 parts = TNY_LIST (tny_simple_list_new ());
2011 tny_mime_part_get_parts (part, parts);
2012 for (iterator = tny_list_create_iterator (parts);
2013 !tny_iterator_is_done (iterator);
2014 tny_iterator_next (iterator)) {
2017 child = TNY_MIME_PART (tny_iterator_get_current (iterator));
2018 forward_pending_parts_helper (child, list);
2019 g_object_unref (child);
2021 g_object_unref (iterator);
2022 g_object_unref (parts);
2026 forward_pending_parts (TnyMsg *msg)
2028 TnyList *result = TNY_LIST (tny_simple_list_new ());
2029 if (TNY_IS_CAMEL_BS_MIME_PART (msg)) {
2030 forward_pending_parts_helper (TNY_MIME_PART (msg), result);
2037 * Common code for the reply and forward actions
2040 reply_forward (ReplyForwardAction action, ModestWindow *win)
2042 ReplyForwardHelper *rf_helper = NULL;
2043 guint reply_forward_type;
2045 g_return_if_fail (win && MODEST_IS_WINDOW(win));
2047 /* we check for low-mem; in that case, show a warning, and don't allow
2048 * reply/forward (because it could potentially require a lot of memory */
2049 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2053 /* we need an account when editing */
2054 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
2055 if (!modest_ui_actions_run_account_setup_wizard (win))
2059 reply_forward_type =
2060 modest_conf_get_int (modest_runtime_get_conf (),
2061 (action == ACTION_FORWARD) ?
2062 MODEST_CONF_FORWARD_TYPE :
2063 MODEST_CONF_REPLY_TYPE,
2066 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2068 TnyMsg *top_msg = NULL;
2069 TnyHeader *header = NULL;
2070 /* Get header and message. Do not free them here, the
2071 reply_forward_cb must do it */
2072 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
2073 top_msg = modest_msg_view_window_get_top_message (MODEST_MSG_VIEW_WINDOW(win));
2074 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
2076 if (msg && header && (action != ACTION_FORWARD || all_parts_retrieved (TNY_MIME_PART (msg)))) {
2078 rf_helper = create_reply_forward_helper (action, win,
2079 reply_forward_type, header, NULL, NULL, NULL);
2080 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
2082 gboolean do_download = TRUE;
2084 if (msg && header && action == ACTION_FORWARD) {
2085 if (top_msg == NULL)
2086 top_msg = g_object_ref (msg);
2087 /* Not all parts retrieved. Then we have to retrieve them all before
2088 * creating the forward message */
2089 if (!tny_device_is_online (modest_runtime_get_device ())) {
2092 /* If ask for user permission to download the messages */
2093 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2094 ngettext("mcen_nc_get_msg",
2098 /* End if the user does not want to continue */
2099 if (response == GTK_RESPONSE_CANCEL)
2100 do_download = FALSE;
2104 TnyList *pending_parts;
2106 TnyAccount *account;
2107 TnyHeader *top_header;
2110 top_header = tny_msg_get_header (top_msg);
2111 pending_parts = forward_pending_parts (top_msg);
2112 rf_helper = create_reply_forward_helper (action, win,
2113 reply_forward_type, header, msg, top_header, pending_parts);
2114 g_object_unref (pending_parts);
2116 folder = tny_header_get_folder (top_header);
2117 account = tny_folder_get_account (folder);
2118 modest_platform_connect_and_perform (GTK_WINDOW (win),
2120 reply_forward_performer,
2122 if (folder) g_object_unref (folder);
2123 g_object_unref (account);
2124 if (top_header) g_object_unref (top_header);
2128 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
2133 g_object_unref (msg);
2135 g_object_unref (top_msg);
2137 g_object_unref (header);
2139 TnyHeader *header = NULL;
2141 gboolean do_retrieve = TRUE;
2142 TnyList *header_list = NULL;
2144 header_list = get_selected_headers (win);
2147 /* Check that only one message is selected for replying */
2148 if (tny_list_get_length (header_list) != 1) {
2149 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
2150 NULL, _("mcen_ib_select_one_message"));
2151 g_object_unref (header_list);
2155 /* Only reply/forward to one message */
2156 iter = tny_list_create_iterator (header_list);
2157 header = TNY_HEADER (tny_iterator_get_current (iter));
2158 g_object_unref (iter);
2160 /* Retrieve messages */
2161 do_retrieve = (action == ACTION_FORWARD) ||
2162 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
2165 TnyAccount *account = NULL;
2166 TnyFolder *folder = NULL;
2167 gdouble download = TRUE;
2168 guint uncached_msgs = 0;
2170 folder = tny_header_get_folder (header);
2172 goto do_retrieve_frees;
2173 account = tny_folder_get_account (folder);
2175 goto do_retrieve_frees;
2177 uncached_msgs = header_list_count_uncached_msgs (header_list);
2179 if (uncached_msgs > 0) {
2180 /* Allways download if we are online. */
2181 if (!tny_device_is_online (modest_runtime_get_device ())) {
2184 /* If ask for user permission to download the messages */
2185 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2186 ngettext("mcen_nc_get_msg",
2190 /* End if the user does not want to continue */
2191 if (response == GTK_RESPONSE_CANCEL)
2198 rf_helper = create_reply_forward_helper (action, win,
2199 reply_forward_type, header, NULL, NULL, NULL);
2200 if (uncached_msgs > 0) {
2201 modest_platform_connect_and_perform (GTK_WINDOW (win),
2203 reply_forward_performer,
2206 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
2207 account, rf_helper);
2212 g_object_unref (account);
2214 g_object_unref (folder);
2216 reply_forward_cb (NULL, header, FALSE, NULL, NULL, NULL);
2219 g_object_unref (header_list);
2220 g_object_unref (header);
2225 modest_ui_actions_reply_calendar (ModestWindow *win, TnyMsg *msg, TnyList *header_pairs)
2230 gboolean use_signature;
2233 gdouble parent_zoom;
2234 const gchar *account_name;
2235 const gchar *mailbox;
2236 TnyHeader *msg_header;
2237 ModestWindowMgr *mgr;
2239 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW(win));
2241 /* we check for low-mem; in that case, show a warning, and don't allow
2242 * reply/forward (because it could potentially require a lot of memory */
2243 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2246 account_name = modest_window_get_active_account (MODEST_WINDOW (win));
2247 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (win));
2248 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
2249 account_name, mailbox);
2250 recipient = modest_text_utils_get_email_address (from);
2251 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr(),
2256 msg_header = tny_msg_get_header (msg);
2258 modest_tny_msg_create_reply_calendar_msg (msg, msg_header, from,
2259 (use_signature) ? signature : NULL,
2261 g_object_unref (msg_header);
2267 g_warning ("%s: failed to create message\n", __FUNCTION__);
2271 msg_win = (GtkWidget *) modest_msg_edit_window_new (new_msg, account_name, mailbox, FALSE);
2272 mgr = modest_runtime_get_window_mgr ();
2273 modest_window_mgr_register_window (mgr, MODEST_WINDOW (msg_win), (ModestWindow *) win);
2275 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (win));
2276 modest_window_set_zoom (MODEST_WINDOW (msg_win), parent_zoom);
2278 /* Show edit window */
2279 gtk_widget_show_all (GTK_WIDGET (msg_win));
2283 g_object_unref (G_OBJECT (new_msg));
2287 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
2289 g_return_if_fail (MODEST_IS_WINDOW(win));
2291 reply_forward (ACTION_REPLY, win);
2295 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
2297 g_return_if_fail (MODEST_IS_WINDOW(win));
2299 reply_forward (ACTION_FORWARD, win);
2303 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
2305 g_return_if_fail (MODEST_IS_WINDOW(win));
2307 reply_forward (ACTION_REPLY_TO_ALL, win);
2311 modest_ui_actions_on_next (GtkAction *action,
2312 ModestWindow *window)
2314 if (MODEST_IS_MAIN_WINDOW (window)) {
2315 GtkWidget *header_view;
2317 header_view = modest_main_window_get_child_widget (
2318 MODEST_MAIN_WINDOW(window),
2319 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2323 modest_header_view_select_next (
2324 MODEST_HEADER_VIEW(header_view));
2325 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2326 modest_msg_view_window_select_next_message (
2327 MODEST_MSG_VIEW_WINDOW (window));
2329 g_return_if_reached ();
2334 modest_ui_actions_on_prev (GtkAction *action,
2335 ModestWindow *window)
2337 g_return_if_fail (MODEST_IS_WINDOW(window));
2339 if (MODEST_IS_MAIN_WINDOW (window)) {
2340 GtkWidget *header_view;
2341 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2342 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2346 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
2347 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2348 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
2350 g_return_if_reached ();
2355 modest_ui_actions_on_sort (GtkAction *action,
2356 ModestWindow *window)
2358 GtkWidget *header_view = NULL;
2360 g_return_if_fail (MODEST_IS_WINDOW(window));
2362 if (MODEST_IS_MAIN_WINDOW (window)) {
2363 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2364 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2365 #ifdef MODEST_TOOLKIT_HILDON2
2366 } else if (MODEST_IS_HEADER_WINDOW (window)) {
2367 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2372 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
2377 /* Show sorting dialog */
2378 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
2382 sync_folder_cb (ModestMailOperation *mail_op,
2386 ModestHeaderView *header_view = (ModestHeaderView *) user_data;
2388 if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
2389 ModestWindow *parent = (ModestWindow *) modest_mail_operation_get_source (mail_op);
2391 /* We must clear first, because otherwise set_folder will ignore */
2392 /* the change as the folders are the same */
2393 modest_header_view_clear (header_view);
2394 modest_header_view_set_folder (header_view, folder, TRUE, parent, NULL, NULL);
2396 g_object_unref (parent);
2399 g_object_unref (header_view);
2403 idle_refresh_folder (gpointer source)
2405 ModestHeaderView *header_view = NULL;
2407 /* If the window still exists */
2408 if (!GTK_IS_WIDGET (source) ||
2409 !GTK_WIDGET_VISIBLE (source))
2412 /* Refresh the current view */
2413 #ifdef MODEST_TOOLKIT_HILDON2
2414 if (MODEST_IS_HEADER_WINDOW (source))
2415 header_view = modest_header_window_get_header_view ((ModestHeaderWindow *) source);
2417 if (MODEST_IS_MAIN_WINDOW (source))
2418 header_view = MODEST_HEADER_VIEW (modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source),
2419 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
2422 TnyFolder *folder = modest_header_view_get_folder (header_view);
2424 /* Sync the folder status */
2425 ModestMailOperation *mail_op = modest_mail_operation_new (source);
2426 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2427 modest_mail_operation_sync_folder (mail_op, folder, FALSE, sync_folder_cb, g_object_ref (header_view));
2428 g_object_unref (folder);
2429 g_object_unref (mail_op);
2437 update_account_cb (ModestMailOperation *self,
2438 TnyList *new_headers,
2442 gboolean show_visual_notifications;
2444 top = modest_window_mgr_get_current_top (modest_runtime_get_window_mgr ());
2445 show_visual_notifications = (top) ? FALSE : TRUE;
2447 /* Notify new messages have been downloaded. If the
2448 send&receive was invoked by the user then do not show any
2449 visual notification, only play a sound and activate the LED
2450 (for the Maemo version) */
2451 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0) {
2453 /* We only notify about really new messages (not seen) we get */
2454 TnyList *actually_new_list;
2455 TnyIterator *iterator;
2456 actually_new_list = TNY_LIST (tny_simple_list_new ());
2457 for (iterator = tny_list_create_iterator (new_headers);
2458 !tny_iterator_is_done (iterator);
2459 tny_iterator_next (iterator)) {
2461 TnyHeaderFlags flags;
2462 header = TNY_HEADER (tny_iterator_get_current (iterator));
2463 flags = tny_header_get_flags (header);
2465 if (!(flags & TNY_HEADER_FLAG_SEEN)) {
2466 /* Messages are ordered from most
2467 recent to oldest. But we want to
2468 show notifications starting from
2469 the oldest message. That's why we
2471 tny_list_prepend (actually_new_list, G_OBJECT (header));
2473 g_object_unref (header);
2475 g_object_unref (iterator);
2477 if (tny_list_get_length (actually_new_list) > 0) {
2478 GList *new_headers_list = NULL;
2480 new_headers_list = modest_utils_create_notification_list_from_header_list (actually_new_list);
2482 /* Send notifications */
2483 if (new_headers_list) {
2484 modest_platform_on_new_headers_received (new_headers_list,
2485 show_visual_notifications);
2487 modest_utils_free_notification_list (new_headers_list);
2490 g_object_unref (actually_new_list);
2494 /* Refresh the current folder in an idle. We do this
2495 in order to avoid refresh cancelations if the
2496 currently viewed folder is the inbox */
2497 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
2498 idle_refresh_folder,
2505 TnyAccount *account;
2507 gchar *account_name;
2508 gboolean poke_status;
2509 gboolean interactive;
2510 ModestMailOperation *mail_op;
2514 do_send_receive_performer (gboolean canceled,
2516 GtkWindow *parent_window,
2517 TnyAccount *account,
2520 SendReceiveInfo *info;
2522 info = (SendReceiveInfo *) user_data;
2524 if (err || canceled) {
2525 /* In disk full conditions we could get this error here */
2526 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
2527 (GtkWidget *) parent_window, err,
2530 if (info->mail_op) {
2531 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2537 /* Set send/receive operation in progress */
2538 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2539 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2542 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2543 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2544 G_CALLBACK (on_send_receive_finished),
2547 /* Send & receive. */
2548 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2549 update_account_cb, info->win);
2554 g_object_unref (G_OBJECT (info->mail_op));
2555 if (info->account_name)
2556 g_free (info->account_name);
2558 g_object_unref (info->win);
2560 g_object_unref (info->account);
2561 g_slice_free (SendReceiveInfo, info);
2565 * This function performs the send & receive required actions. The
2566 * window is used to create the mail operation. Typically it should
2567 * always be the main window, but we pass it as argument in order to
2571 modest_ui_actions_do_send_receive (const gchar *account_name,
2572 gboolean force_connection,
2573 gboolean poke_status,
2574 gboolean interactive,
2577 gchar *acc_name = NULL;
2578 SendReceiveInfo *info;
2579 ModestTnyAccountStore *acc_store;
2580 TnyAccount *account;
2582 /* If no account name was provided then get the current account, and if
2583 there is no current account then pick the default one: */
2584 if (!account_name) {
2586 acc_name = g_strdup (modest_window_get_active_account (win));
2588 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2590 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2594 acc_name = g_strdup (account_name);
2597 acc_store = modest_runtime_get_account_store ();
2598 account = modest_tny_account_store_get_server_account (acc_store, acc_name, TNY_ACCOUNT_TYPE_STORE);
2602 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2606 /* Do not automatically refresh accounts that are flagged as
2607 NO_AUTO_UPDATE. This could be useful for accounts that
2608 handle their own update times */
2610 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
2611 if (proto != MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
2612 const gchar *tag = MODEST_PROTOCOL_REGISTRY_NO_AUTO_UPDATE_PROTOCOLS;
2613 ModestProtocolRegistry *registry = modest_runtime_get_protocol_registry ();
2615 if (modest_protocol_registry_protocol_type_has_tag (registry, proto, tag)) {
2616 g_debug ("%s no auto update allowed for account %s", __FUNCTION__, account_name);
2617 g_object_unref (account);
2624 /* Create the info for the connect and perform */
2625 info = g_slice_new (SendReceiveInfo);
2626 info->account_name = acc_name;
2627 info->win = (win) ? g_object_ref (win) : NULL;
2628 info->poke_status = poke_status;
2629 info->interactive = interactive;
2630 info->account = account;
2631 /* We need to create the operation here, because otherwise it
2632 could happen that the queue emits the queue-empty signal
2633 while we're trying to connect the account */
2634 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2635 modest_ui_actions_disk_operations_error_handler,
2637 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2639 /* Invoke the connect and perform */
2640 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2641 force_connection, info->account,
2642 do_send_receive_performer, info);
2647 modest_ui_actions_do_cancel_send (const gchar *account_name,
2650 TnyTransportAccount *transport_account;
2651 TnySendQueue *send_queue = NULL;
2652 GError *error = NULL;
2654 /* Get transport account */
2656 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2657 (modest_runtime_get_account_store(),
2659 TNY_ACCOUNT_TYPE_TRANSPORT));
2660 if (!transport_account) {
2661 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2666 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2667 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2668 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2669 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2670 "modest: could not find send queue for account\n");
2672 /* Cancel the current send */
2673 tny_account_cancel (TNY_ACCOUNT (transport_account));
2675 /* Suspend all pending messages */
2676 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2680 if (transport_account != NULL)
2681 g_object_unref (G_OBJECT (transport_account));
2685 modest_ui_actions_cancel_send_all (ModestWindow *win)
2687 GSList *account_names, *iter;
2689 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2692 iter = account_names;
2694 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2695 iter = g_slist_next (iter);
2698 modest_account_mgr_free_account_names (account_names);
2699 account_names = NULL;
2703 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2706 /* Check if accounts exist */
2707 gboolean accounts_exist =
2708 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2710 /* If not, allow the user to create an account before trying to send/receive. */
2711 if (!accounts_exist)
2712 modest_ui_actions_on_accounts (NULL, win);
2714 /* Cancel all sending operaitons */
2715 modest_ui_actions_cancel_send_all (win);
2719 * Refreshes all accounts. This function will be used by automatic
2723 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2724 gboolean force_connection,
2725 gboolean poke_status,
2726 gboolean interactive)
2728 GSList *account_names, *iter;
2730 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2733 iter = account_names;
2735 modest_ui_actions_do_send_receive ((const char*) iter->data,
2737 poke_status, interactive, win);
2738 iter = g_slist_next (iter);
2741 modest_account_mgr_free_account_names (account_names);
2742 account_names = NULL;
2746 * Handler of the click on Send&Receive button in the main toolbar
2749 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2751 /* Check if accounts exist */
2752 gboolean accounts_exist;
2755 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2757 /* If not, allow the user to create an account before trying to send/receive. */
2758 if (!accounts_exist)
2759 modest_ui_actions_on_accounts (NULL, win);
2761 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2762 if (MODEST_IS_MAIN_WINDOW (win)) {
2763 GtkWidget *folder_view;
2764 TnyFolderStore *folder_store;
2767 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2768 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2772 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2775 g_object_unref (folder_store);
2776 /* Refresh the active account. Force the connection if needed
2777 and poke the status of all folders */
2778 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2779 #ifdef MODEST_TOOLKIT_HILDON2
2780 } else if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2781 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2784 const gchar *active_account;
2785 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2787 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2794 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2797 GtkWidget *header_view;
2799 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2801 header_view = modest_main_window_get_child_widget (main_window,
2802 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2806 conf = modest_runtime_get_conf ();
2808 /* what is saved/restored is depending on the style; thus; we save with
2809 * old style, then update the style, and restore for this new style
2811 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2813 if (modest_header_view_get_style
2814 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2815 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2816 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2818 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2819 MODEST_HEADER_VIEW_STYLE_DETAILS);
2821 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2822 MODEST_CONF_HEADER_VIEW_KEY);
2827 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2829 ModestMainWindow *main_window)
2831 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2832 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2834 /* in the case the folder is empty, show the empty folder message and focus
2836 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2837 if (modest_header_view_is_empty (header_view)) {
2838 TnyFolder *folder = modest_header_view_get_folder (header_view);
2839 GtkWidget *folder_view =
2840 modest_main_window_get_child_widget (main_window,
2841 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2842 if (folder != NULL) {
2843 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2844 g_object_unref (folder);
2846 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2850 /* If no header has been selected then exit */
2855 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2856 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2858 /* Update toolbar dimming state */
2859 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2860 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2864 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2867 ModestWindow *window)
2869 GtkWidget *open_widget;
2870 GtkTreeRowReference *rowref;
2872 g_return_if_fail (MODEST_IS_WINDOW(window));
2873 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2874 g_return_if_fail (TNY_IS_HEADER (header));
2876 if (modest_header_view_count_selected_headers (header_view) > 1) {
2877 /* Don't allow activation if there are more than one message selected */
2878 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2882 /* we check for low-mem; in that case, show a warning, and don't allow
2883 * activating headers
2885 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2888 if (MODEST_IS_MAIN_WINDOW (window)) {
2889 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2890 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2891 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2895 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2896 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2897 gtk_tree_row_reference_free (rowref);
2901 set_active_account_from_tny_account (TnyAccount *account,
2902 ModestWindow *window)
2904 const gchar *server_acc_name = tny_account_get_id (account);
2906 /* We need the TnyAccount provided by the
2907 account store because that is the one that
2908 knows the name of the Modest account */
2909 TnyAccount *modest_server_account =
2910 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2911 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2913 if (!modest_server_account) {
2914 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2918 /* Update active account, but only if it's not a pseudo-account */
2919 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2920 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2921 const gchar *modest_acc_name =
2922 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2923 if (modest_acc_name)
2924 modest_window_set_active_account (window, modest_acc_name);
2927 g_object_unref (modest_server_account);
2932 folder_refreshed_cb (ModestMailOperation *mail_op,
2936 ModestMainWindow *win = NULL;
2937 GtkWidget *folder_view, *header_view;
2938 const GError *error;
2940 g_return_if_fail (TNY_IS_FOLDER (folder));
2942 win = MODEST_MAIN_WINDOW (user_data);
2944 /* Check if the operation failed due to memory low conditions */
2945 error = modest_mail_operation_get_error (mail_op);
2946 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2947 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2948 modest_platform_run_information_dialog (GTK_WINDOW (win),
2949 _KR("memr_ib_operation_disabled"),
2955 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2957 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2960 TnyFolderStore *current_folder;
2962 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2963 if (current_folder) {
2964 gboolean different = ((TnyFolderStore *) folder != current_folder);
2965 g_object_unref (current_folder);
2971 /* Check if folder is empty and set headers view contents style */
2972 if ((tny_folder_get_all_count (folder) == 0) ||
2973 modest_header_view_is_empty (MODEST_HEADER_VIEW (header_view)))
2974 modest_main_window_set_contents_style (win,
2975 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2979 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2980 TnyFolderStore *folder_store,
2982 ModestMainWindow *main_window)
2984 GtkWidget *header_view;
2986 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2988 header_view = modest_main_window_get_child_widget(main_window,
2989 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2994 if (TNY_IS_ACCOUNT (folder_store)) {
2996 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2998 /* Show account details */
2999 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
3002 if (TNY_IS_FOLDER (folder_store) && selected) {
3003 TnyAccount *account;
3005 /* Update the active account */
3006 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
3008 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
3009 g_object_unref (account);
3013 /* Set the header style by default, it could
3014 be changed later by the refresh callback to
3016 modest_main_window_set_contents_style (main_window,
3017 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
3019 /* Set folder on header view. This function
3020 will call tny_folder_refresh_async so we
3021 pass a callback that will be called when
3022 finished. We use that callback to set the
3023 empty view if there are no messages */
3024 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
3025 TNY_FOLDER (folder_store),
3027 MODEST_WINDOW (main_window),
3028 folder_refreshed_cb,
3031 /* Restore configuration. We need to do this
3032 *after* the set_folder because the widget
3033 memory asks the header view about its
3035 modest_widget_memory_restore (modest_runtime_get_conf (),
3036 G_OBJECT(header_view),
3037 MODEST_CONF_HEADER_VIEW_KEY);
3039 /* No need to save the header view
3040 configuration for Maemo because it only
3041 saves the sorting stuff and that it's
3042 already being done by the sort
3043 dialog. Remove it when the GNOME version
3044 has the same behaviour */
3045 #ifdef MODEST_TOOLKIT_GTK
3046 if (modest_main_window_get_contents_style (main_window) ==
3047 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
3048 modest_widget_memory_save (modest_runtime_get_conf (),
3049 G_OBJECT (header_view),
3050 MODEST_CONF_HEADER_VIEW_KEY);
3052 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
3056 /* Update dimming state */
3057 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
3058 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
3062 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
3069 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
3071 online = tny_device_is_online (modest_runtime_get_device());
3074 /* already online -- the item is simply not there... */
3075 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
3077 GTK_MESSAGE_WARNING,
3079 _("The %s you selected cannot be found"),
3081 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
3082 gtk_dialog_run (GTK_DIALOG(dialog));
3084 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
3087 _("mcen_bd_dialog_cancel"),
3088 GTK_RESPONSE_REJECT,
3089 _("mcen_bd_dialog_ok"),
3090 GTK_RESPONSE_ACCEPT,
3092 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
3093 "Do you want to get online?"), item);
3094 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
3095 gtk_label_new (txt), FALSE, FALSE, 0);
3096 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3099 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
3100 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3101 /* TODO: Comment about why is this commented out: */
3102 /* modest_platform_connect_and_wait (); */
3105 gtk_widget_destroy (dialog);
3109 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
3112 /* g_debug ("%s %s", __FUNCTION__, link); */
3117 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
3120 modest_platform_activate_uri (link);
3124 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
3127 modest_platform_show_uri_popup (link);
3131 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
3134 /* we check for low-mem; in that case, show a warning, and don't allow
3135 * viewing attachments
3137 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
3140 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
3144 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
3145 const gchar *address,
3148 /* g_debug ("%s %s", __FUNCTION__, address); */
3152 on_save_to_drafts_cb (ModestMailOperation *mail_op,
3153 TnyMsg *saved_draft,
3156 ModestMsgEditWindow *edit_window;
3158 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
3159 #ifndef MODEST_TOOLKIT_HILDON2
3160 ModestMainWindow *win;
3162 /* FIXME. Make the header view sensitive again. This is a
3163 * temporary hack. See modest_ui_actions_on_save_to_drafts()
3165 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
3166 modest_runtime_get_window_mgr(), FALSE));
3168 GtkWidget *hdrview = modest_main_window_get_child_widget(
3169 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3170 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
3174 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
3176 /* Set draft is there was no error */
3177 if (!modest_mail_operation_get_error (mail_op))
3178 modest_msg_edit_window_set_draft (edit_window, saved_draft);
3180 g_object_unref(edit_window);
3184 enough_space_for_message (ModestMsgEditWindow *edit_window,
3187 guint64 available_disk, expected_size;
3192 available_disk = modest_utils_get_available_space (NULL);
3193 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
3194 expected_size = modest_tny_msg_estimate_size (data->plain_body,
3199 /* Double check: disk full condition or message too big */
3200 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
3201 expected_size > available_disk) {
3202 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3203 modest_platform_information_banner (NULL, NULL, msg);
3210 * djcb: if we're in low-memory state, we only allow for
3211 * saving messages smaller than
3212 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
3213 * should still allow for sending anything critical...
3215 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
3216 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
3220 * djcb: we also make sure that the attachments are smaller than the max size
3221 * this is for the case where we'd try to forward a message with attachments
3222 * bigger than our max allowed size, or sending an message from drafts which
3223 * somehow got past our checks when attaching.
3225 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
3226 modest_platform_run_information_dialog (
3227 GTK_WINDOW(edit_window),
3228 _("mail_ib_error_attachment_size"),
3237 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3239 TnyTransportAccount *transport_account;
3240 ModestMailOperation *mail_operation;
3242 gchar *account_name;
3243 ModestAccountMgr *account_mgr;
3244 gboolean had_error = FALSE;
3245 ModestMainWindow *win = NULL;
3247 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
3249 data = modest_msg_edit_window_get_msg_data (edit_window);
3252 if (!enough_space_for_message (edit_window, data)) {
3253 modest_msg_edit_window_free_msg_data (edit_window, data);
3257 account_name = g_strdup (data->account_name);
3258 account_mgr = modest_runtime_get_account_mgr();
3260 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3262 account_name = modest_account_mgr_get_default_account (account_mgr);
3263 if (!account_name) {
3264 g_printerr ("modest: no account found\n");
3265 modest_msg_edit_window_free_msg_data (edit_window, data);
3269 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
3270 account_name = g_strdup (data->account_name);
3274 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3275 (modest_runtime_get_account_store (),
3277 TNY_ACCOUNT_TYPE_TRANSPORT));
3278 if (!transport_account) {
3279 g_printerr ("modest: no transport account found for '%s'\n", account_name);
3280 g_free (account_name);
3281 modest_msg_edit_window_free_msg_data (edit_window, data);
3285 /* Create the mail operation */
3286 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
3288 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3290 modest_mail_operation_save_to_drafts (mail_operation,
3302 data->priority_flags,
3305 on_save_to_drafts_cb,
3306 g_object_ref(edit_window));
3308 #ifdef MODEST_TOOLKIT_HILDON2
3309 /* In hildon2 we always show the information banner on saving to drafts.
3310 * It will be a system information banner in this case.
3312 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3313 modest_platform_information_banner (NULL, NULL, text);
3316 /* Use the main window as the parent of the banner, if the
3317 main window does not exist it won't be shown, if the parent
3318 window exists then it's properly shown. We don't use the
3319 editor window because it could be closed (save to drafts
3320 could happen after closing the window */
3321 win = (ModestMainWindow *)
3322 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
3324 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3325 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
3329 modest_msg_edit_window_set_modified (edit_window, FALSE);
3332 g_free (account_name);
3333 g_object_unref (G_OBJECT (transport_account));
3334 g_object_unref (G_OBJECT (mail_operation));
3336 modest_msg_edit_window_free_msg_data (edit_window, data);
3339 * If the drafts folder is selected then make the header view
3340 * insensitive while the message is being saved to drafts
3341 * (it'll be sensitive again in on_save_to_drafts_cb()). This
3342 * is not very clean but it avoids letting the drafts folder
3343 * in an inconsistent state: the user could edit the message
3344 * being saved and undesirable things would happen.
3345 * In the average case the user won't notice anything at
3346 * all. In the worst case (the user is editing a really big
3347 * file from Drafts) the header view will be insensitive
3348 * during the saving process (10 or 20 seconds, depending on
3349 * the message). Anyway this is just a quick workaround: once
3350 * we find a better solution it should be removed
3351 * See NB#65125 (commend #18) for details.
3353 if (!had_error && win != NULL) {
3354 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
3355 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
3357 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
3359 if (modest_tny_folder_is_local_folder(folder)) {
3360 TnyFolderType folder_type;
3361 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
3362 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
3363 GtkWidget *hdrview = modest_main_window_get_child_widget(
3364 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3365 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
3369 if (folder != NULL) g_object_unref(folder);
3376 /* For instance, when clicking the Send toolbar button when editing a message: */
3378 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3380 TnyTransportAccount *transport_account = NULL;
3381 gboolean had_error = FALSE, add_to_contacts;
3383 ModestAccountMgr *account_mgr;
3384 gchar *account_name;
3385 ModestMailOperation *mail_operation;
3388 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
3390 /* Check whether to automatically add new contacts to addressbook or not */
3391 add_to_contacts = modest_conf_get_bool (modest_runtime_get_conf (),
3392 MODEST_CONF_AUTO_ADD_TO_CONTACTS, NULL);
3393 if (!modest_msg_edit_window_check_names (edit_window, add_to_contacts))
3396 data = modest_msg_edit_window_get_msg_data (edit_window);
3398 recipients = g_strconcat (data->to?data->to:"",
3399 data->cc?data->cc:"",
3400 data->bcc?data->bcc:"",
3402 if (recipients == NULL || recipients[0] == '\0') {
3403 /* Empty subject -> no send */
3404 g_free (recipients);
3405 modest_msg_edit_window_free_msg_data (edit_window, data);
3408 g_free (recipients);
3411 if (!enough_space_for_message (edit_window, data)) {
3412 modest_msg_edit_window_free_msg_data (edit_window, data);
3416 account_mgr = modest_runtime_get_account_mgr();
3417 account_name = g_strdup (data->account_name);
3419 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3422 account_name = modest_account_mgr_get_default_account (account_mgr);
3424 if (!account_name) {
3425 modest_msg_edit_window_free_msg_data (edit_window, data);
3426 /* Run account setup wizard */
3427 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
3432 /* Get the currently-active transport account for this modest account: */
3433 if (account_name && strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
3435 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3436 (modest_runtime_get_account_store (),
3437 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
3440 if (!transport_account) {
3441 modest_msg_edit_window_free_msg_data (edit_window, data);
3442 /* Run account setup wizard */
3443 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
3448 /* Create the mail operation */
3449 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
3450 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3452 modest_mail_operation_send_new_mail (mail_operation,
3466 data->priority_flags);
3468 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3469 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
3471 if (modest_mail_operation_get_error (mail_operation) != NULL) {
3472 const GError *error = modest_mail_operation_get_error (mail_operation);
3473 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3474 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3475 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3476 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3482 g_free (account_name);
3483 g_object_unref (G_OBJECT (transport_account));
3484 g_object_unref (G_OBJECT (mail_operation));
3486 modest_msg_edit_window_free_msg_data (edit_window, data);
3489 modest_msg_edit_window_set_sent (edit_window, TRUE);
3491 /* Save settings and close the window: */
3492 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3499 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3500 ModestMsgEditWindow *window)
3502 ModestMsgEditFormatState *format_state = NULL;
3504 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3505 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3507 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3510 format_state = modest_msg_edit_window_get_format_state (window);
3511 g_return_if_fail (format_state != NULL);
3513 format_state->bold = gtk_toggle_action_get_active (action);
3514 modest_msg_edit_window_set_format_state (window, format_state);
3515 g_free (format_state);
3520 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3521 ModestMsgEditWindow *window)
3523 ModestMsgEditFormatState *format_state = NULL;
3525 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3526 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3528 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3531 format_state = modest_msg_edit_window_get_format_state (window);
3532 g_return_if_fail (format_state != NULL);
3534 format_state->italics = gtk_toggle_action_get_active (action);
3535 modest_msg_edit_window_set_format_state (window, format_state);
3536 g_free (format_state);
3541 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3542 ModestMsgEditWindow *window)
3544 ModestMsgEditFormatState *format_state = NULL;
3546 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3547 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3549 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3552 format_state = modest_msg_edit_window_get_format_state (window);
3553 g_return_if_fail (format_state != NULL);
3555 format_state->bullet = gtk_toggle_action_get_active (action);
3556 modest_msg_edit_window_set_format_state (window, format_state);
3557 g_free (format_state);
3562 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3563 GtkRadioAction *selected,
3564 ModestMsgEditWindow *window)
3566 ModestMsgEditFormatState *format_state = NULL;
3567 GtkJustification value;
3569 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3571 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3574 value = gtk_radio_action_get_current_value (selected);
3576 format_state = modest_msg_edit_window_get_format_state (window);
3577 g_return_if_fail (format_state != NULL);
3579 format_state->justification = value;
3580 modest_msg_edit_window_set_format_state (window, format_state);
3581 g_free (format_state);
3585 modest_ui_actions_on_select_editor_color (GtkAction *action,
3586 ModestMsgEditWindow *window)
3588 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3589 g_return_if_fail (GTK_IS_ACTION (action));
3591 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3594 modest_msg_edit_window_select_color (window);
3598 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3599 ModestMsgEditWindow *window)
3601 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3602 g_return_if_fail (GTK_IS_ACTION (action));
3604 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3607 modest_msg_edit_window_select_background_color (window);
3611 modest_ui_actions_on_insert_image (GObject *object,
3612 ModestMsgEditWindow *window)
3614 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3617 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3620 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3623 modest_msg_edit_window_insert_image (window);
3627 modest_ui_actions_on_attach_file (GtkAction *action,
3628 ModestMsgEditWindow *window)
3630 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3631 g_return_if_fail (GTK_IS_ACTION (action));
3633 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3636 modest_msg_edit_window_offer_attach_file (window);
3640 modest_ui_actions_on_remove_attachments (GtkAction *action,
3641 ModestMsgEditWindow *window)
3643 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3645 modest_msg_edit_window_remove_attachments (window, NULL);
3649 do_create_folder_cb (ModestMailOperation *mail_op,
3650 TnyFolderStore *parent_folder,
3651 TnyFolder *new_folder,
3654 gchar *suggested_name = (gchar *) user_data;
3655 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3656 const GError *error;
3658 error = modest_mail_operation_get_error (mail_op);
3660 gboolean disk_full = FALSE;
3661 TnyAccount *account;
3662 /* Show an error. If there was some problem writing to
3663 disk, show it, otherwise show the generic folder
3664 create error. We do it here and not in an error
3665 handler because the call to do_create_folder will
3666 stop the main loop in a gtk_dialog_run and then,
3667 the message won't be shown until that dialog is
3669 account = modest_mail_operation_get_account (mail_op);
3672 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3673 (GtkWidget *) source_win,
3676 _("mail_in_ui_folder_create_error_memory"));
3677 g_object_unref (account);
3680 /* Show an error and try again if there is no
3681 full memory condition */
3682 modest_platform_information_banner ((GtkWidget *) source_win, NULL,
3683 _("mail_in_ui_folder_create_error"));
3684 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3688 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3689 * FIXME: any other? */
3690 GtkWidget *folder_view;
3692 if (MODEST_IS_MAIN_WINDOW(source_win))
3694 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3695 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3697 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3698 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3700 /* Select the newly created folder. It could happen
3701 that the widget is no longer there (i.e. the window
3702 has been destroyed, so we need to check this */
3704 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3706 g_object_unref (new_folder);
3708 /* Free. Note that the first time it'll be NULL so noop */
3709 g_free (suggested_name);
3710 g_object_unref (source_win);
3715 TnyFolderStore *parent;
3716 } CreateFolderConnect;
3719 do_create_folder_performer (gboolean canceled,
3721 GtkWindow *parent_window,
3722 TnyAccount *account,
3725 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3726 ModestMailOperation *mail_op;
3728 if (canceled || err) {
3729 /* In disk full conditions we could get this error here */
3730 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3731 (GtkWidget *) parent_window, err,
3732 NULL, _("mail_in_ui_folder_create_error_memory"));
3734 /* This happens if we have selected the outbox folder
3736 if (err && err->code == TNY_SERVICE_ERROR_UNKNOWN &&
3737 TNY_IS_MERGE_FOLDER (helper->parent)) {
3738 /* Show an error and retry */
3739 modest_platform_information_banner ((GtkWidget *) parent_window,
3741 _("mail_in_ui_folder_create_error"));
3743 do_create_folder (parent_window, helper->parent, helper->folder_name);
3749 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3750 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3752 modest_mail_operation_create_folder (mail_op,
3754 (const gchar *) helper->folder_name,
3755 do_create_folder_cb,
3756 g_strdup (helper->folder_name));
3757 g_object_unref (mail_op);
3761 g_object_unref (helper->parent);
3762 if (helper->folder_name)
3763 g_free (helper->folder_name);
3764 g_slice_free (CreateFolderConnect, helper);
3769 do_create_folder (GtkWindow *parent_window,
3770 TnyFolderStore *suggested_parent,
3771 const gchar *suggested_name)
3774 gchar *folder_name = NULL;
3775 TnyFolderStore *parent_folder = NULL;
3777 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3779 (gchar *) suggested_name,
3783 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3784 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3785 helper->folder_name = g_strdup (folder_name);
3786 helper->parent = g_object_ref (parent_folder);
3788 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3791 do_create_folder_performer,
3796 g_free (folder_name);
3798 g_object_unref (parent_folder);
3802 modest_ui_actions_create_folder(GtkWidget *parent_window,
3803 GtkWidget *folder_view,
3804 TnyFolderStore *parent_folder)
3806 if (!parent_folder) {
3807 #ifdef MODEST_TOOLKIT_HILDON2
3808 ModestTnyAccountStore *acc_store;
3810 acc_store = modest_runtime_get_account_store ();
3812 parent_folder = (TnyFolderStore *)
3813 modest_tny_account_store_get_local_folders_account (acc_store);
3815 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3819 if (parent_folder) {
3820 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3821 g_object_unref (parent_folder);
3826 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3829 g_return_if_fail (MODEST_IS_WINDOW(window));
3831 if (MODEST_IS_MAIN_WINDOW (window)) {
3832 GtkWidget *folder_view;
3834 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3835 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3839 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3840 #ifdef MODEST_TOOLKIT_HILDON2
3841 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3842 GtkWidget *folder_view;
3844 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3845 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3848 g_assert_not_reached ();
3853 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3856 const GError *error = NULL;
3857 gchar *message = NULL;
3859 TnyAccount *account = modest_mail_operation_get_account (mail_op);
3861 /* Get error message */
3862 error = modest_mail_operation_get_error (mail_op);
3864 g_return_if_reached ();
3866 mem_full = modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
3867 (GError *) error, account);
3869 message = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3870 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3871 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3872 message = _CS("ckdg_ib_folder_already_exists");
3873 } else if (error->domain == TNY_ERROR_DOMAIN &&
3874 error->code == TNY_SERVICE_ERROR_STATE) {
3875 /* This means that the folder is already in use (a
3876 message is opened for example */
3877 message = _("emev_ni_internal_error");
3879 message = _CS("ckdg_ib_unable_to_rename");
3882 /* We don't set a parent for the dialog because the dialog
3883 will be destroyed so the banner won't appear */
3884 modest_platform_information_banner (NULL, NULL, message);
3887 g_object_unref (account);
3893 TnyFolderStore *folder;
3898 on_rename_folder_cb (ModestMailOperation *mail_op,
3899 TnyFolder *new_folder,
3902 ModestFolderView *folder_view;
3904 /* If the window was closed when renaming a folder, or if
3905 * it's not a main window this will happen */
3906 if (!MODEST_IS_FOLDER_VIEW (user_data))
3909 folder_view = MODEST_FOLDER_VIEW (user_data);
3910 /* Note that if the rename fails new_folder will be NULL */
3912 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3914 modest_folder_view_select_first_inbox_or_local (folder_view);
3916 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3920 on_rename_folder_performer (gboolean canceled,
3922 GtkWindow *parent_window,
3923 TnyAccount *account,
3926 ModestMailOperation *mail_op = NULL;
3927 GtkTreeSelection *sel = NULL;
3928 GtkWidget *folder_view = NULL;
3929 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3931 if (canceled || err) {
3932 /* In disk full conditions we could get this error here */
3933 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3934 (GtkWidget *) parent_window, err,
3939 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3940 modest_ui_actions_rename_folder_error_handler,
3941 parent_window, NULL);
3943 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3946 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3948 folder_view = modest_main_window_get_child_widget (
3949 MODEST_MAIN_WINDOW (parent_window),
3950 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3952 #ifdef MODEST_TOOLKIT_HILDON2
3953 else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3954 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3955 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3959 /* Clear the folders view */
3960 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3961 gtk_tree_selection_unselect_all (sel);
3963 /* Actually rename the folder */
3964 modest_mail_operation_rename_folder (mail_op,
3965 TNY_FOLDER (data->folder),
3966 (const gchar *) (data->new_name),
3967 on_rename_folder_cb,
3969 g_object_unref (mail_op);
3972 g_object_unref (data->folder);
3973 g_free (data->new_name);
3978 modest_ui_actions_on_rename_folder (GtkAction *action,
3979 ModestWindow *window)
3981 modest_ui_actions_on_edit_mode_rename_folder (window);
3985 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3987 TnyFolderStore *folder;
3988 GtkWidget *folder_view;
3989 gboolean do_rename = TRUE;
3991 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3993 if (MODEST_IS_MAIN_WINDOW (window)) {
3994 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3995 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3999 #ifdef MODEST_TOOLKIT_HILDON2
4000 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
4001 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
4007 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
4012 if (TNY_IS_FOLDER (folder)) {
4013 gchar *folder_name = NULL;
4015 const gchar *current_name;
4016 TnyFolderStore *parent;
4018 current_name = tny_folder_get_name (TNY_FOLDER (folder));
4019 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
4020 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
4021 parent, current_name,
4023 g_object_unref (parent);
4025 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
4028 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
4029 rename_folder_data->folder = g_object_ref (folder);
4030 rename_folder_data->new_name = folder_name;
4031 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
4032 folder, on_rename_folder_performer, rename_folder_data);
4035 g_object_unref (folder);
4040 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
4043 GObject *win = modest_mail_operation_get_source (mail_op);
4045 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
4046 _("mail_in_ui_folder_delete_error"),
4048 g_object_unref (win);
4052 TnyFolderStore *folder;
4053 gboolean move_to_trash;
4057 on_delete_folder_cb (gboolean canceled,
4059 GtkWindow *parent_window,
4060 TnyAccount *account,
4063 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
4064 GtkWidget *folder_view;
4065 ModestMailOperation *mail_op;
4066 GtkTreeSelection *sel;
4068 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
4069 /* Note that the connection process can fail due to
4070 memory low conditions as it can not successfully
4071 store the summary */
4072 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4073 (GtkWidget*) parent_window, err,
4075 g_debug ("Error connecting when trying to delete a folder");
4076 g_object_unref (G_OBJECT (info->folder));
4081 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
4082 folder_view = modest_main_window_get_child_widget (
4083 MODEST_MAIN_WINDOW (parent_window),
4084 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4085 #ifdef MODEST_TOOLKIT_HILDON2
4086 } else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
4087 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
4090 g_object_unref (G_OBJECT (info->folder));
4095 /* Unselect the folder before deleting it to free the headers */
4096 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
4097 gtk_tree_selection_unselect_all (sel);
4099 /* Create the mail operation */
4101 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
4102 modest_ui_actions_delete_folder_error_handler,
4105 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4107 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
4109 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
4111 g_object_unref (mail_op);
4112 g_object_unref (info->folder);
4117 delete_folder (ModestWindow *window, gboolean move_to_trash)
4119 TnyFolderStore *folder;
4120 GtkWidget *folder_view;
4124 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
4126 if (MODEST_IS_MAIN_WINDOW (window)) {
4128 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4129 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4130 #ifdef MODEST_TOOLKIT_HILDON2
4131 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
4132 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
4140 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4145 /* Show an error if it's an account */
4146 if (!TNY_IS_FOLDER (folder)) {
4147 modest_platform_run_information_dialog (GTK_WINDOW (window),
4148 _("mail_in_ui_folder_delete_error"),
4150 g_object_unref (G_OBJECT (folder));
4155 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
4156 tny_folder_get_name (TNY_FOLDER (folder)));
4157 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
4158 (const gchar *) message);
4161 if (response == GTK_RESPONSE_OK) {
4162 TnyAccount *account = NULL;
4163 DeleteFolderInfo *info = NULL;
4164 info = g_new0(DeleteFolderInfo, 1);
4165 info->folder = g_object_ref (folder);
4166 info->move_to_trash = move_to_trash;
4168 account = tny_folder_get_account (TNY_FOLDER (folder));
4169 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
4171 TNY_FOLDER_STORE (account),
4172 on_delete_folder_cb, info);
4173 g_object_unref (account);
4174 g_object_unref (folder);
4182 modest_ui_actions_on_delete_folder (GtkAction *action,
4183 ModestWindow *window)
4185 modest_ui_actions_on_edit_mode_delete_folder (window);
4189 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
4191 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
4193 return delete_folder (window, FALSE);
4197 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
4199 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4201 delete_folder (MODEST_WINDOW (main_window), TRUE);
4205 typedef struct _PasswordDialogFields {
4206 GtkWidget *username;
4207 GtkWidget *password;
4209 } PasswordDialogFields;
4212 password_dialog_check_field (GtkEditable *editable,
4213 PasswordDialogFields *fields)
4216 gboolean any_value_empty = FALSE;
4218 #ifdef MODEST_TOOLKIT_HILDON2
4219 value = hildon_entry_get_text (HILDON_ENTRY (fields->username));
4221 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
4223 if ((value == NULL) || value[0] == '\0') {
4224 any_value_empty = TRUE;
4226 #ifdef MODEST_TOOLKIT_HILDON2
4227 value = hildon_entry_get_text (HILDON_ENTRY (fields->password));
4229 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
4231 if ((value == NULL) || value[0] == '\0') {
4232 any_value_empty = TRUE;
4234 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
4238 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
4239 const gchar* server_account_name,
4244 ModestMainWindow *main_window)
4246 g_return_if_fail(server_account_name);
4247 gboolean completed = FALSE;
4248 PasswordDialogFields *fields = NULL;
4250 /* Initalize output parameters: */
4257 #ifndef MODEST_TOOLKIT_GTK
4258 /* Maemo uses a different (awkward) button order,
4259 * It should probably just use gtk_alternative_dialog_button_order ().
4261 #ifdef MODEST_TOOLKIT_HILDON2
4263 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4266 _HL("wdgt_bd_done"),
4267 GTK_RESPONSE_ACCEPT,
4269 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
4270 HILDON_MARGIN_DOUBLE);
4273 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4276 _("mcen_bd_dialog_ok"),
4277 GTK_RESPONSE_ACCEPT,
4278 _("mcen_bd_dialog_cancel"),
4279 GTK_RESPONSE_REJECT,
4281 #endif /* MODEST_TOOLKIT_HILDON2 */
4284 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4288 GTK_RESPONSE_REJECT,
4290 GTK_RESPONSE_ACCEPT,
4292 #endif /* MODEST_TOOLKIT_GTK */
4294 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
4296 gchar *server_name = modest_account_mgr_get_server_account_hostname (
4297 modest_runtime_get_account_mgr(), server_account_name);
4298 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
4299 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
4302 gtk_widget_destroy (dialog);
4306 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
4307 GtkWidget *label = gtk_label_new (txt);
4308 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
4310 g_free (server_name);
4311 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
4316 gchar *initial_username = modest_account_mgr_get_server_account_username (
4317 modest_runtime_get_account_mgr(), server_account_name);
4319 #ifdef MODEST_TOOLKIT_HILDON2
4320 GtkWidget *entry_username = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4321 if (initial_username)
4322 hildon_entry_set_text (HILDON_ENTRY (entry_username), initial_username);
4324 GtkWidget *entry_username = gtk_entry_new ();
4325 if (initial_username)
4326 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
4328 /* Dim this if a connection has ever succeeded with this username,
4329 * as per the UI spec: */
4330 /* const gboolean username_known = */
4331 /* modest_account_mgr_get_server_account_username_has_succeeded( */
4332 /* modest_runtime_get_account_mgr(), server_account_name); */
4333 /* gtk_widget_set_sensitive (entry_username, !username_known); */
4335 /* We drop the username sensitive code and disallow changing it here
4336 * as tinymail does not support really changing the username in the callback
4338 gtk_widget_set_sensitive (entry_username, FALSE);
4340 #ifndef MODEST_TOOLKIT_GTK
4341 /* Auto-capitalization is the default, so let's turn it off: */
4342 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
4344 /* Create a size group to be used by all captions.
4345 * Note that HildonCaption does not create a default size group if we do not specify one.
4346 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
4347 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
4349 #ifdef MODEST_TOOLKIT_HILDON2
4350 GtkWidget *caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4351 _("mail_fi_username"), FALSE,
4354 GtkWidget *caption = hildon_caption_new (sizegroup,
4355 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
4357 gtk_widget_show (entry_username);
4358 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4359 FALSE, FALSE, MODEST_MARGIN_HALF);
4360 gtk_widget_show (caption);
4362 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
4364 #endif /* !MODEST_TOOLKIT_GTK */
4367 #ifdef MODEST_TOOLKIT_HILDON2
4368 GtkWidget *entry_password = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4370 GtkWidget *entry_password = gtk_entry_new ();
4372 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
4373 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
4375 #ifndef MODEST_TOOLKIT_GTK
4376 /* Auto-capitalization is the default, so let's turn it off: */
4377 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
4378 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
4380 #ifdef MODEST_TOOLKIT_HILDON2
4381 caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4382 _("mail_fi_password"), FALSE,
4385 caption = hildon_caption_new (sizegroup,
4386 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
4388 gtk_widget_show (entry_password);
4389 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4390 FALSE, FALSE, MODEST_MARGIN_HALF);
4391 gtk_widget_show (caption);
4392 g_object_unref (sizegroup);
4394 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
4396 #endif /* !MODEST_TOOLKIT_GTK */
4398 if (initial_username != NULL)
4399 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
4401 /* This is not in the Maemo UI spec:
4402 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
4403 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
4407 fields = g_slice_new0 (PasswordDialogFields);
4408 fields->username = entry_username;
4409 fields->password = entry_password;
4410 fields->dialog = dialog;
4412 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
4413 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
4414 password_dialog_check_field (NULL, fields);
4416 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4418 while (!completed) {
4420 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
4422 #ifdef MODEST_TOOLKIT_HILDON2
4423 *username = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_username)));
4425 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
4428 /* Note that an empty field becomes the "" string */
4429 if (*username && strlen (*username) > 0) {
4430 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
4431 server_account_name,
4435 const gboolean username_was_changed =
4436 (strcmp (*username, initial_username) != 0);
4437 if (username_was_changed) {
4438 g_warning ("%s: tinymail does not yet support changing the "
4439 "username in the get_password() callback.\n", __FUNCTION__);
4445 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
4446 _("mcen_ib_username_pw_incorrect"));
4452 #ifdef MODEST_TOOLKIT_HILDON2
4453 *password = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_password)));
4455 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
4458 /* We do not save the password in the configuration,
4459 * because this function is only called for passwords that should
4460 * not be remembered:
4461 modest_server_account_set_password (
4462 modest_runtime_get_account_mgr(), server_account_name,
4469 #ifndef MODEST_TOOLKIT_HILDON2
4470 /* Set parent to NULL or the banner will disappear with its parent dialog */
4471 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
4483 /* This is not in the Maemo UI spec:
4484 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
4490 g_free (initial_username);
4491 gtk_widget_destroy (dialog);
4492 g_slice_free (PasswordDialogFields, fields);
4494 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
4498 modest_ui_actions_on_cut (GtkAction *action,
4499 ModestWindow *window)
4501 GtkWidget *focused_widget;
4502 GtkClipboard *clipboard;
4504 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4505 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4506 if (GTK_IS_EDITABLE (focused_widget)) {
4507 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
4508 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4509 gtk_clipboard_store (clipboard);
4510 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4511 GtkTextBuffer *buffer;
4513 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4514 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4515 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
4516 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4517 gtk_clipboard_store (clipboard);
4519 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4520 TnyList *header_list = modest_header_view_get_selected_headers (
4521 MODEST_HEADER_VIEW (focused_widget));
4522 gboolean continue_download = FALSE;
4523 gint num_of_unc_msgs;
4525 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4527 if (num_of_unc_msgs) {
4528 TnyAccount *account = get_account_from_header_list (header_list);
4530 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4531 g_object_unref (account);
4535 if (num_of_unc_msgs == 0 || continue_download) {
4536 /* modest_platform_information_banner (
4537 NULL, NULL, _CS("mcen_ib_getting_items"));*/
4538 modest_header_view_cut_selection (
4539 MODEST_HEADER_VIEW (focused_widget));
4542 g_object_unref (header_list);
4543 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4544 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4549 modest_ui_actions_on_copy (GtkAction *action,
4550 ModestWindow *window)
4552 GtkClipboard *clipboard;
4553 GtkWidget *focused_widget;
4554 gboolean copied = TRUE;
4556 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4557 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4559 if (GTK_IS_LABEL (focused_widget)) {
4561 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4562 gtk_clipboard_set_text (clipboard, selection, -1);
4564 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4565 gtk_clipboard_store (clipboard);
4566 } else if (GTK_IS_EDITABLE (focused_widget)) {
4567 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4568 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4569 gtk_clipboard_store (clipboard);
4570 } else if (GTK_IS_HTML (focused_widget)) {
4573 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4574 if ((sel == NULL) || (sel[0] == '\0')) {
4577 gtk_html_copy (GTK_HTML (focused_widget));
4578 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4579 gtk_clipboard_store (clipboard);
4581 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4582 GtkTextBuffer *buffer;
4583 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4584 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4585 gtk_text_buffer_copy_clipboard (buffer, clipboard);
4586 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4587 gtk_clipboard_store (clipboard);
4589 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4590 TnyList *header_list = modest_header_view_get_selected_headers (
4591 MODEST_HEADER_VIEW (focused_widget));
4592 gboolean continue_download = FALSE;
4593 gint num_of_unc_msgs;
4595 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4597 if (num_of_unc_msgs) {
4598 TnyAccount *account = get_account_from_header_list (header_list);
4600 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4601 g_object_unref (account);
4605 if (num_of_unc_msgs == 0 || continue_download) {
4606 modest_platform_information_banner (
4607 NULL, NULL, _CS("mcen_ib_getting_items"));
4608 modest_header_view_copy_selection (
4609 MODEST_HEADER_VIEW (focused_widget));
4613 g_object_unref (header_list);
4615 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4616 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4619 /* Show information banner if there was a copy to clipboard */
4621 modest_platform_information_banner (
4622 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4626 modest_ui_actions_on_undo (GtkAction *action,
4627 ModestWindow *window)
4629 ModestEmailClipboard *clipboard = NULL;
4631 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4632 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4633 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4634 /* Clear clipboard source */
4635 clipboard = modest_runtime_get_email_clipboard ();
4636 modest_email_clipboard_clear (clipboard);
4639 g_return_if_reached ();
4644 modest_ui_actions_on_redo (GtkAction *action,
4645 ModestWindow *window)
4647 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4648 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4651 g_return_if_reached ();
4657 destroy_information_note (ModestMailOperation *mail_op,
4660 /* destroy information note */
4661 gtk_widget_destroy (GTK_WIDGET(user_data));
4665 destroy_folder_information_note (ModestMailOperation *mail_op,
4666 TnyFolder *new_folder,
4669 /* destroy information note */
4670 gtk_widget_destroy (GTK_WIDGET(user_data));
4675 paste_as_attachment_free (gpointer data)
4677 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4679 if (helper->banner) {
4680 gtk_widget_destroy (helper->banner);
4681 g_object_unref (helper->banner);
4687 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4692 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4693 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4698 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4703 modest_ui_actions_on_paste (GtkAction *action,
4704 ModestWindow *window)
4706 GtkWidget *focused_widget = NULL;
4707 GtkWidget *inf_note = NULL;
4708 ModestMailOperation *mail_op = NULL;
4710 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4711 if (GTK_IS_EDITABLE (focused_widget)) {
4712 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4713 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4714 ModestEmailClipboard *e_clipboard = NULL;
4715 e_clipboard = modest_runtime_get_email_clipboard ();
4716 if (modest_email_clipboard_cleared (e_clipboard)) {
4717 GtkTextBuffer *buffer;
4718 GtkClipboard *clipboard;
4720 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4721 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4722 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4723 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4724 ModestMailOperation *mail_op;
4725 TnyFolder *src_folder = NULL;
4726 TnyList *data = NULL;
4728 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4729 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4730 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4731 _CS("ckct_nw_pasting"));
4732 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4733 mail_op = modest_mail_operation_new (G_OBJECT (window));
4734 if (helper->banner != NULL) {
4735 g_object_ref (G_OBJECT (helper->banner));
4736 gtk_widget_show (GTK_WIDGET (helper->banner));
4740 modest_mail_operation_get_msgs_full (mail_op,
4742 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4744 paste_as_attachment_free);
4748 g_object_unref (data);
4750 g_object_unref (src_folder);
4753 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4754 ModestEmailClipboard *clipboard = NULL;
4755 TnyFolder *src_folder = NULL;
4756 TnyFolderStore *folder_store = NULL;
4757 TnyList *data = NULL;
4758 gboolean delete = FALSE;
4760 /* Check clipboard source */
4761 clipboard = modest_runtime_get_email_clipboard ();
4762 if (modest_email_clipboard_cleared (clipboard))
4765 /* Get elements to paste */
4766 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4768 /* Create a new mail operation */
4769 mail_op = modest_mail_operation_new (G_OBJECT(window));
4771 /* Get destination folder */
4772 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4774 /* transfer messages */
4778 /* Ask for user confirmation */
4780 modest_ui_actions_msgs_move_to_confirmation (window,
4781 TNY_FOLDER (folder_store),
4785 if (response == GTK_RESPONSE_OK) {
4786 /* Launch notification */
4787 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4788 _CS("ckct_nw_pasting"));
4789 if (inf_note != NULL) {
4790 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4791 gtk_widget_show (GTK_WIDGET(inf_note));
4794 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4795 modest_mail_operation_xfer_msgs (mail_op,
4797 TNY_FOLDER (folder_store),
4799 destroy_information_note,
4802 g_object_unref (mail_op);
4805 } else if (src_folder != NULL) {
4806 /* Launch notification */
4807 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4808 _CS("ckct_nw_pasting"));
4809 if (inf_note != NULL) {
4810 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4811 gtk_widget_show (GTK_WIDGET(inf_note));
4814 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4815 modest_mail_operation_xfer_folder (mail_op,
4819 destroy_folder_information_note,
4825 g_object_unref (data);
4826 if (src_folder != NULL)
4827 g_object_unref (src_folder);
4828 if (folder_store != NULL)
4829 g_object_unref (folder_store);
4835 modest_ui_actions_on_select_all (GtkAction *action,
4836 ModestWindow *window)
4838 GtkWidget *focused_widget;
4840 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4841 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4842 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4843 } else if (GTK_IS_LABEL (focused_widget)) {
4844 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4845 } else if (GTK_IS_EDITABLE (focused_widget)) {
4846 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4847 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4848 GtkTextBuffer *buffer;
4849 GtkTextIter start, end;
4851 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4852 gtk_text_buffer_get_start_iter (buffer, &start);
4853 gtk_text_buffer_get_end_iter (buffer, &end);
4854 gtk_text_buffer_select_range (buffer, &start, &end);
4855 } else if (GTK_IS_HTML (focused_widget)) {
4856 gtk_html_select_all (GTK_HTML (focused_widget));
4857 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4858 GtkWidget *header_view = focused_widget;
4859 GtkTreeSelection *selection = NULL;
4861 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4862 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4863 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4866 /* Disable window dimming management */
4867 modest_window_disable_dimming (MODEST_WINDOW(window));
4869 /* Select all messages */
4870 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4871 gtk_tree_selection_select_all (selection);
4873 /* Set focuse on header view */
4874 gtk_widget_grab_focus (header_view);
4876 /* Enable window dimming management */
4877 modest_window_enable_dimming (MODEST_WINDOW(window));
4878 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4879 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4885 modest_ui_actions_on_mark_as_read (GtkAction *action,
4886 ModestWindow *window)
4888 g_return_if_fail (MODEST_IS_WINDOW(window));
4890 /* Mark each header as read */
4891 do_headers_action (window, headers_action_mark_as_read, NULL);
4895 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4896 ModestWindow *window)
4898 g_return_if_fail (MODEST_IS_WINDOW(window));
4900 /* Mark each header as read */
4901 do_headers_action (window, headers_action_mark_as_unread, NULL);
4905 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4906 GtkRadioAction *selected,
4907 ModestWindow *window)
4911 value = gtk_radio_action_get_current_value (selected);
4912 if (MODEST_IS_WINDOW (window)) {
4913 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4918 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4919 GtkRadioAction *selected,
4920 ModestWindow *window)
4922 TnyHeaderFlags flags;
4923 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4925 flags = gtk_radio_action_get_current_value (selected);
4926 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4930 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4931 GtkRadioAction *selected,
4932 ModestWindow *window)
4936 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4938 file_format = gtk_radio_action_get_current_value (selected);
4939 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4944 modest_ui_actions_on_zoom_plus (GtkAction *action,
4945 ModestWindow *window)
4947 g_return_if_fail (MODEST_IS_WINDOW (window));
4949 modest_window_zoom_plus (MODEST_WINDOW (window));
4953 modest_ui_actions_on_zoom_minus (GtkAction *action,
4954 ModestWindow *window)
4956 g_return_if_fail (MODEST_IS_WINDOW (window));
4958 modest_window_zoom_minus (MODEST_WINDOW (window));
4962 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4963 ModestWindow *window)
4965 ModestWindowMgr *mgr;
4966 gboolean fullscreen, active;
4967 g_return_if_fail (MODEST_IS_WINDOW (window));
4969 mgr = modest_runtime_get_window_mgr ();
4971 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4972 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4974 if (active != fullscreen) {
4975 modest_window_mgr_set_fullscreen_mode (mgr, active);
4976 #ifndef MODEST_TOOLKIT_HILDON2
4977 gtk_window_present (GTK_WINDOW (window));
4983 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4984 ModestWindow *window)
4986 ModestWindowMgr *mgr;
4987 gboolean fullscreen;
4989 g_return_if_fail (MODEST_IS_WINDOW (window));
4991 mgr = modest_runtime_get_window_mgr ();
4992 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4993 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4995 #ifndef MODEST_TOOLKIT_HILDON2
4996 gtk_window_present (GTK_WINDOW (window));
5001 * Used by modest_ui_actions_on_details to call do_headers_action
5004 headers_action_show_details (TnyHeader *header,
5005 ModestWindow *window,
5009 gboolean async_retrieval;
5012 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5013 async_retrieval = TRUE;
5014 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
5015 async_retrieval = !TNY_IS_CAMEL_BS_MSG (msg);
5017 async_retrieval = FALSE;
5019 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header, async_retrieval, msg);
5021 g_object_unref (msg);
5025 * Show the header details in a ModestDetailsDialog widget
5028 modest_ui_actions_on_details (GtkAction *action,
5031 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
5035 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
5039 header = tny_msg_get_header (msg);
5041 headers_action_show_details (header, win, NULL);
5042 g_object_unref (header);
5044 g_object_unref (msg);
5046 } else if (MODEST_IS_MAIN_WINDOW (win)) {
5047 GtkWidget *folder_view, *header_view;
5049 /* Check which widget has the focus */
5050 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5051 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5052 if (gtk_widget_is_focus (folder_view)) {
5053 TnyFolderStore *folder_store
5054 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5055 if (!folder_store) {
5056 g_warning ("%s: No item was selected.\n", __FUNCTION__);
5059 /* Show only when it's a folder */
5060 /* This function should not be called for account items,
5061 * because we dim the menu item for them. */
5062 if (TNY_IS_FOLDER (folder_store)) {
5063 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
5064 TNY_FOLDER (folder_store));
5067 g_object_unref (folder_store);
5070 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5071 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5072 /* Show details of each header */
5073 do_headers_action (win, headers_action_show_details, header_view);
5075 #ifdef MODEST_TOOLKIT_HILDON2
5076 } else if (MODEST_IS_HEADER_WINDOW (win)) {
5078 GtkWidget *header_view;
5080 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
5081 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
5083 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
5085 g_object_unref (folder);
5092 modest_ui_actions_on_limit_error (GtkAction *action,
5095 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
5097 modest_platform_information_banner ((GtkWidget *) win, NULL, _CS("ckdg_ib_maximum_characters_reached"));
5102 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
5103 ModestMsgEditWindow *window)
5105 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5107 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
5111 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
5112 ModestMsgEditWindow *window)
5114 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5116 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
5120 modest_ui_actions_toggle_folders_view (GtkAction *action,
5121 ModestMainWindow *main_window)
5123 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
5125 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
5126 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
5128 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
5132 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
5133 ModestWindow *window)
5135 gboolean active, fullscreen = FALSE;
5136 ModestWindowMgr *mgr;
5138 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
5140 /* Check if we want to toggle the toolbar view in fullscreen
5142 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
5143 "ViewShowToolbarFullScreen")) {
5147 /* Toggle toolbar */
5148 mgr = modest_runtime_get_window_mgr ();
5149 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
5153 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
5154 ModestMsgEditWindow *window)
5156 modest_msg_edit_window_select_font (window);
5161 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
5162 const gchar *display_name,
5165 /* don't update the display name if it was already set;
5166 * updating the display name apparently is expensive */
5167 const gchar* old_name = gtk_window_get_title (window);
5169 if (display_name == NULL)
5172 if (old_name && display_name && strcmp (old_name, display_name) == 0)
5173 return; /* don't do anything */
5175 /* This is usually used to change the title of the main window, which
5176 * is the one that holds the folder view. Note that this change can
5177 * happen even when the widget doesn't have the focus. */
5178 gtk_window_set_title (window, display_name);
5183 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
5185 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5186 modest_msg_edit_window_select_contacts (window);
5190 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
5192 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5193 modest_msg_edit_window_check_names (window, FALSE);
5196 #ifndef MODEST_TOOLKIT_HILDON2
5198 * This function is used to track changes in the selection of the
5199 * folder view that is inside the "move to" dialog to enable/disable
5200 * the OK button because we do not want the user to select a disallowed
5201 * destination for a folder.
5202 * The user also not desired to be able to use NEW button on items where
5203 * folder creation is not possibel.
5206 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
5207 TnyFolderStore *folder_store,
5211 GtkWidget *dialog = NULL;
5212 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
5213 gboolean moving_folder = FALSE;
5214 gboolean is_local_account = TRUE;
5215 GtkWidget *folder_view = NULL;
5216 ModestTnyFolderRules rules;
5218 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
5223 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
5227 /* check if folder_store is an remote account */
5228 if (TNY_IS_ACCOUNT (folder_store)) {
5229 TnyAccount *local_account = NULL;
5230 TnyAccount *mmc_account = NULL;
5231 ModestTnyAccountStore *account_store = NULL;
5233 account_store = modest_runtime_get_account_store ();
5234 local_account = modest_tny_account_store_get_local_folders_account (account_store);
5235 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
5237 if ((gpointer) local_account != (gpointer) folder_store &&
5238 (gpointer) mmc_account != (gpointer) folder_store) {
5239 ModestProtocolType proto;
5240 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
5241 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
5242 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
5244 is_local_account = FALSE;
5245 /* New button should be dimmed on remote
5247 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5249 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
5251 g_object_unref (local_account);
5253 /* It could not exist */
5255 g_object_unref (mmc_account);
5258 /* Check the target folder rules */
5259 if (TNY_IS_FOLDER (folder_store)) {
5260 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
5261 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
5262 ok_sensitive = FALSE;
5263 new_sensitive = FALSE;
5268 /* Check if we're moving a folder */
5269 if (MODEST_IS_MAIN_WINDOW (user_data)) {
5270 /* Get the widgets */
5271 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
5272 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5273 if (gtk_widget_is_focus (folder_view))
5274 moving_folder = TRUE;
5277 if (moving_folder) {
5278 TnyFolderStore *moved_folder = NULL, *parent = NULL;
5280 /* Get the folder to move */
5281 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5283 /* Check that we're not moving to the same folder */
5284 if (TNY_IS_FOLDER (moved_folder)) {
5285 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
5286 if (parent == folder_store)
5287 ok_sensitive = FALSE;
5288 g_object_unref (parent);
5291 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
5292 /* Do not allow to move to an account unless it's the
5293 local folders account */
5294 if (!is_local_account)
5295 ok_sensitive = FALSE;
5298 if (ok_sensitive && (moved_folder == folder_store)) {
5299 /* Do not allow to move to itself */
5300 ok_sensitive = FALSE;
5302 g_object_unref (moved_folder);
5304 TnyFolder *src_folder = NULL;
5306 /* Moving a message */
5307 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
5309 TnyHeader *header = NULL;
5310 header = modest_msg_view_window_get_header
5311 (MODEST_MSG_VIEW_WINDOW (user_data));
5312 if (!TNY_IS_HEADER(header))
5313 g_warning ("%s: could not get source header", __FUNCTION__);
5315 src_folder = tny_header_get_folder (header);
5318 g_object_unref (header);
5321 TNY_FOLDER (modest_folder_view_get_selected
5322 (MODEST_FOLDER_VIEW (folder_view)));
5325 if (TNY_IS_FOLDER(src_folder)) {
5326 /* Do not allow to move the msg to the same folder */
5327 /* Do not allow to move the msg to an account */
5328 if ((gpointer) src_folder == (gpointer) folder_store ||
5329 TNY_IS_ACCOUNT (folder_store))
5330 ok_sensitive = FALSE;
5331 g_object_unref (src_folder);
5333 g_warning ("%s: could not get source folder", __FUNCTION__);
5337 /* Set sensitivity of the OK and NEW button */
5338 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
5339 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
5344 on_move_to_dialog_response (GtkDialog *dialog,
5348 GtkWidget *parent_win;
5349 MoveToInfo *helper = NULL;
5350 ModestFolderView *folder_view;
5351 gboolean unset_edit_mode = FALSE;
5353 helper = (MoveToInfo *) user_data;
5355 parent_win = (GtkWidget *) helper->win;
5356 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
5357 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
5359 TnyFolderStore *dst_folder;
5360 TnyFolderStore *selected;
5362 case MODEST_GTK_RESPONSE_NEW_FOLDER:
5363 selected = modest_folder_view_get_selected (folder_view);
5364 modest_ui_actions_create_folder (GTK_WIDGET (dialog), GTK_WIDGET (folder_view), selected);
5365 g_object_unref (selected);
5367 case GTK_RESPONSE_NONE:
5368 case GTK_RESPONSE_CANCEL:
5369 case GTK_RESPONSE_DELETE_EVENT:
5371 case GTK_RESPONSE_OK:
5372 dst_folder = modest_folder_view_get_selected (folder_view);
5374 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
5375 /* Clean list to move used for filtering */
5376 modest_folder_view_set_list_to_move (folder_view, NULL);
5378 modest_ui_actions_on_main_window_move_to (NULL,
5379 GTK_WIDGET (folder_view),
5381 MODEST_MAIN_WINDOW (parent_win));
5382 #ifdef MODEST_TOOLKIT_HILDON2
5383 } else if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
5384 /* Clean list to move used for filtering */
5385 modest_folder_view_set_list_to_move (folder_view, NULL);
5387 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
5390 GTK_WINDOW (parent_win));
5393 /* if the user selected a root folder
5394 (account) then do not perform any action */
5395 if (TNY_IS_ACCOUNT (dst_folder)) {
5396 g_signal_stop_emission_by_name (dialog, "response");
5400 /* Clean list to move used for filtering */
5401 modest_folder_view_set_list_to_move (folder_view, NULL);
5403 /* Moving from headers window in edit mode */
5404 modest_ui_actions_on_window_move_to (NULL, helper->list,
5406 MODEST_WINDOW (parent_win));
5410 g_object_unref (dst_folder);
5412 unset_edit_mode = TRUE;
5415 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
5418 /* Free the helper and exit */
5420 g_object_unref (helper->list);
5421 if (unset_edit_mode) {
5422 #ifdef MODEST_TOOLKIT_HILDON2
5423 modest_hildon2_window_unset_edit_mode (MODEST_HILDON2_WINDOW (helper->win));
5426 g_slice_free (MoveToInfo, helper);
5427 gtk_widget_destroy (GTK_WIDGET (dialog));
5431 create_move_to_dialog (GtkWindow *win,
5432 GtkWidget *folder_view,
5433 TnyList *list_to_move)
5435 GtkWidget *dialog, *tree_view = NULL;
5437 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
5439 #ifndef MODEST_TOOLKIT_HILDON2
5440 /* Track changes in the selection to
5441 * disable the OK button whenever "Move to" is not possible
5442 * disbale NEW button whenever New is not possible */
5443 g_signal_connect (tree_view,
5444 "folder_selection_changed",
5445 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
5449 /* It could happen that we're trying to move a message from a
5450 window (msg window for example) after the main window was
5451 closed, so we can not just get the model of the folder
5453 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
5454 const gchar *visible_id = NULL;
5456 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5457 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5458 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
5459 MODEST_FOLDER_VIEW(tree_view));
5462 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
5464 /* Show the same account than the one that is shown in the main window */
5465 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
5468 const gchar *active_account_name = NULL;
5469 ModestAccountMgr *mgr = NULL;
5470 ModestAccountSettings *settings = NULL;
5471 ModestServerAccountSettings *store_settings = NULL;
5473 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5474 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5476 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
5477 mgr = modest_runtime_get_account_mgr ();
5478 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
5481 const gchar *store_account_name;
5482 store_settings = modest_account_settings_get_store_settings (settings);
5483 store_account_name = modest_server_account_settings_get_account_name (store_settings);
5485 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
5486 store_account_name);
5487 g_object_unref (store_settings);
5488 g_object_unref (settings);
5492 /* we keep a pointer to the embedded folder view, so we can
5493 * retrieve it with get_folder_view_from_move_to_dialog (see
5494 * above) later (needed for focus handling)
5496 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
5498 /* Hide special folders */
5499 #ifndef MODEST_TOOLKIT_HILDON2
5500 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
5503 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
5504 #ifndef MODEST_TOOLKIT_HILDON2
5505 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5508 gtk_widget_show (GTK_WIDGET (tree_view));
5514 * Shows a confirmation dialog to the user when we're moving messages
5515 * from a remote server to the local storage. Returns the dialog
5516 * response. If it's other kind of movement then it always returns
5519 * This one is used by the next functions:
5520 * modest_ui_actions_on_paste - commented out
5521 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
5524 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
5525 TnyFolder *dest_folder,
5529 gint response = GTK_RESPONSE_OK;
5530 TnyAccount *account = NULL;
5531 TnyFolder *src_folder = NULL;
5532 TnyIterator *iter = NULL;
5533 TnyHeader *header = NULL;
5535 /* return with OK if the destination is a remote folder */
5536 if (modest_tny_folder_is_remote_folder (dest_folder))
5537 return GTK_RESPONSE_OK;
5539 /* Get source folder */
5540 iter = tny_list_create_iterator (headers);
5541 header = TNY_HEADER (tny_iterator_get_current (iter));
5543 src_folder = tny_header_get_folder (header);
5544 g_object_unref (header);
5546 g_object_unref (iter);
5548 /* if no src_folder, message may be an attahcment */
5549 if (src_folder == NULL)
5550 return GTK_RESPONSE_CANCEL;
5552 /* If the source is a local or MMC folder */
5553 if (!modest_tny_folder_is_remote_folder (src_folder)) {
5554 g_object_unref (src_folder);
5555 return GTK_RESPONSE_OK;
5558 /* Get the account */
5559 account = tny_folder_get_account (src_folder);
5561 /* now if offline we ask the user */
5562 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
5563 response = GTK_RESPONSE_OK;
5565 response = GTK_RESPONSE_CANCEL;
5568 g_object_unref (src_folder);
5569 g_object_unref (account);
5575 move_to_helper_destroyer (gpointer user_data)
5577 MoveToHelper *helper = (MoveToHelper *) user_data;
5579 /* Close the "Pasting" information banner */
5580 if (helper->banner) {
5581 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5582 g_object_unref (helper->banner);
5584 if (gtk_tree_row_reference_valid (helper->reference)) {
5585 gtk_tree_row_reference_free (helper->reference);
5586 helper->reference = NULL;
5592 move_to_cb (ModestMailOperation *mail_op,
5595 MoveToHelper *helper = (MoveToHelper *) user_data;
5596 GObject *object = modest_mail_operation_get_source (mail_op);
5598 /* Note that the operation could have failed, in that case do
5600 if (modest_mail_operation_get_status (mail_op) !=
5601 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5604 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5605 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5607 if (!modest_msg_view_window_select_next_message (self) &&
5608 !modest_msg_view_window_select_previous_message (self)) {
5609 /* No more messages to view, so close this window */
5610 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5612 } else if (MODEST_IS_MAIN_WINDOW (object) &&
5613 gtk_tree_row_reference_valid (helper->reference)) {
5614 GtkWidget *header_view;
5616 GtkTreeSelection *sel;
5618 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5619 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5620 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5621 path = gtk_tree_row_reference_get_path (helper->reference);
5622 /* We need to unselect the previous one
5623 because we could be copying instead of
5625 gtk_tree_selection_unselect_all (sel);
5626 gtk_tree_selection_select_path (sel, path);
5627 gtk_tree_path_free (path);
5629 g_object_unref (object);
5632 /* Destroy the helper */
5633 move_to_helper_destroyer (helper);
5637 folder_move_to_cb (ModestMailOperation *mail_op,
5638 TnyFolder *new_folder,
5641 GtkWidget *folder_view;
5644 object = modest_mail_operation_get_source (mail_op);
5645 if (MODEST_IS_MAIN_WINDOW (object)) {
5646 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5647 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5648 g_object_ref (folder_view);
5649 g_object_unref (object);
5650 move_to_cb (mail_op, user_data);
5651 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5652 g_object_unref (folder_view);
5654 move_to_cb (mail_op, user_data);
5659 msgs_move_to_cb (ModestMailOperation *mail_op,
5662 move_to_cb (mail_op, user_data);
5666 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5669 GObject *win = NULL;
5670 const GError *error;
5671 TnyAccount *account = NULL;
5673 #ifndef MODEST_TOOLKIT_HILDON2
5674 ModestWindow *main_window = NULL;
5676 /* Disable next automatic folder selection */
5677 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5678 FALSE); /* don't create */
5680 /* Show notification dialog only if the main window exists */
5682 GtkWidget *folder_view = NULL;
5684 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5685 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5686 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5688 if (user_data && TNY_IS_FOLDER (user_data)) {
5689 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5690 TNY_FOLDER (user_data), FALSE);
5694 win = modest_mail_operation_get_source (mail_op);
5695 error = modest_mail_operation_get_error (mail_op);
5697 if (TNY_IS_FOLDER (user_data))
5698 account = modest_tny_folder_get_account (TNY_FOLDER (user_data));
5699 else if (TNY_IS_ACCOUNT (user_data))
5700 account = g_object_ref (user_data);
5702 /* If it's not a disk full error then show a generic error */
5703 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5704 (GtkWidget *) win, (GError *) error,
5706 modest_platform_run_information_dialog ((GtkWindow *) win,
5707 _("mail_in_ui_folder_move_target_error"),
5710 g_object_unref (account);
5712 g_object_unref (win);
5716 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5725 gint pending_purges = 0;
5726 gboolean some_purged = FALSE;
5727 ModestWindow *win = MODEST_WINDOW (user_data);
5728 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5730 /* If there was any error */
5731 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5732 modest_window_mgr_unregister_header (mgr, header);
5736 /* Once the message has been retrieved for purging, we check if
5737 * it's all ok for purging */
5739 parts = tny_simple_list_new ();
5740 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5741 iter = tny_list_create_iterator (parts);
5743 while (!tny_iterator_is_done (iter)) {
5745 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5746 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5747 if (tny_mime_part_is_purged (part))
5754 g_object_unref (part);
5756 tny_iterator_next (iter);
5758 g_object_unref (iter);
5761 if (pending_purges>0) {
5763 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5765 if (response == GTK_RESPONSE_OK) {
5768 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5769 iter = tny_list_create_iterator (parts);
5770 while (!tny_iterator_is_done (iter)) {
5773 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5774 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5775 tny_mime_part_set_purged (part);
5778 g_object_unref (part);
5780 tny_iterator_next (iter);
5782 g_object_unref (iter);
5784 tny_msg_rewrite_cache (msg);
5786 gtk_widget_destroy (info);
5790 modest_window_mgr_unregister_header (mgr, header);
5792 g_object_unref (parts);
5796 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5797 ModestMainWindow *win)
5799 GtkWidget *header_view;
5800 TnyList *header_list;
5802 TnyHeaderFlags flags;
5803 ModestWindow *msg_view_window = NULL;
5806 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5808 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5809 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5811 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5813 g_warning ("%s: no header selected", __FUNCTION__);
5817 if (tny_list_get_length (header_list) == 1) {
5818 TnyIterator *iter = tny_list_create_iterator (header_list);
5819 header = TNY_HEADER (tny_iterator_get_current (iter));
5820 g_object_unref (iter);
5824 if (!header || !TNY_IS_HEADER(header)) {
5825 g_warning ("%s: header is not valid", __FUNCTION__);
5829 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5830 header, &msg_view_window);
5831 flags = tny_header_get_flags (header);
5832 if (!(flags & TNY_HEADER_FLAG_CACHED))
5835 if (msg_view_window != NULL)
5836 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5838 /* do nothing; uid was registered before, so window is probably on it's way */
5839 g_debug ("header %p has already been registered", header);
5842 ModestMailOperation *mail_op = NULL;
5843 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5844 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5845 modest_ui_actions_disk_operations_error_handler,
5847 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5848 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5850 g_object_unref (mail_op);
5853 g_object_unref (header);
5855 g_object_unref (header_list);
5859 * Checks if we need a connection to do the transfer and if the user
5860 * wants to connect to complete it
5863 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5864 TnyFolderStore *src_folder,
5866 TnyFolder *dst_folder,
5867 gboolean delete_originals,
5868 gboolean *need_connection,
5871 TnyAccount *src_account;
5872 gint uncached_msgs = 0;
5874 /* We don't need any further check if
5876 * 1- the source folder is local OR
5877 * 2- the device is already online
5879 if (!modest_tny_folder_store_is_remote (src_folder) ||
5880 tny_device_is_online (modest_runtime_get_device())) {
5881 *need_connection = FALSE;
5886 /* We must ask for a connection when
5888 * - the message(s) is not already cached OR
5889 * - the message(s) is cached but the leave_on_server setting
5890 * is FALSE (because we need to sync the source folder to
5891 * delete the message from the server (for IMAP we could do it
5892 * offline, it'll take place the next time we get a
5895 uncached_msgs = header_list_count_uncached_msgs (headers);
5896 src_account = get_account_from_folder_store (src_folder);
5897 if (uncached_msgs > 0) {
5901 *need_connection = TRUE;
5902 num_headers = tny_list_get_length (headers);
5903 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5905 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5906 GTK_RESPONSE_CANCEL) {
5912 /* The transfer is possible and the user wants to */
5915 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5916 const gchar *account_name;
5917 gboolean leave_on_server;
5919 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5920 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5923 if (leave_on_server == TRUE) {
5924 *need_connection = FALSE;
5926 *need_connection = TRUE;
5929 *need_connection = FALSE;
5934 g_object_unref (src_account);
5938 xfer_messages_error_handler (ModestMailOperation *mail_op,
5942 const GError *error;
5943 TnyAccount *account;
5945 win = modest_mail_operation_get_source (mail_op);
5946 error = modest_mail_operation_get_error (mail_op);
5948 /* We cannot get the account from the mail op as that is the
5949 source account and for checking memory full conditions we
5950 need the destination one */
5951 account = TNY_ACCOUNT (user_data);
5954 !modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5955 (GtkWidget *) win, (GError*) error,
5956 account, _KR("cerm_memory_card_full"))) {
5957 modest_platform_run_information_dialog ((GtkWindow *) win,
5958 _("mail_in_ui_folder_move_target_error"),
5962 g_object_unref (win);
5966 TnyFolderStore *dst_folder;
5971 * Utility function that transfer messages from both the main window
5972 * and the msg view window when using the "Move to" dialog
5975 xfer_messages_performer (gboolean canceled,
5977 GtkWindow *parent_window,
5978 TnyAccount *account,
5981 ModestWindow *win = MODEST_WINDOW (parent_window);
5982 TnyAccount *dst_account = NULL;
5983 gboolean dst_forbids_message_add = FALSE;
5984 XferMsgsHelper *helper;
5985 MoveToHelper *movehelper;
5986 ModestMailOperation *mail_op;
5988 helper = (XferMsgsHelper *) user_data;
5990 if (canceled || err) {
5991 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5992 (GtkWidget *) parent_window, err,
5994 /* Show the proper error message */
5995 modest_ui_actions_on_account_connection_error (parent_window, account);
6000 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
6002 /* tinymail will return NULL for local folders it seems */
6003 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
6004 modest_tny_account_get_protocol_type (dst_account),
6005 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
6007 if (dst_forbids_message_add) {
6008 modest_platform_information_banner (GTK_WIDGET (win),
6010 ngettext("mail_in_ui_folder_move_target_error",
6011 "mail_in_ui_folder_move_targets_error",
6012 tny_list_get_length (helper->headers)));
6016 movehelper = g_new0 (MoveToHelper, 1);
6018 #ifndef MODEST_TOOLKIT_HILDON2
6019 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
6020 _CS("ckct_nw_pasting"));
6021 if (movehelper->banner != NULL) {
6022 g_object_ref (movehelper->banner);
6023 gtk_widget_show (GTK_WIDGET (movehelper->banner));
6027 if (MODEST_IS_MAIN_WINDOW (win)) {
6028 GtkWidget *header_view =
6029 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6030 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6031 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
6034 /* Perform the mail operation */
6035 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
6036 xfer_messages_error_handler,
6037 g_object_ref (dst_account),
6039 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
6042 modest_mail_operation_xfer_msgs (mail_op,
6044 TNY_FOLDER (helper->dst_folder),
6049 g_object_unref (G_OBJECT (mail_op));
6052 g_object_unref (dst_account);
6053 g_object_unref (helper->dst_folder);
6054 g_object_unref (helper->headers);
6055 g_slice_free (XferMsgsHelper, helper);
6059 TnyFolder *src_folder;
6060 TnyFolderStore *dst_folder;
6061 gboolean delete_original;
6062 GtkWidget *folder_view;
6066 on_move_folder_cb (gboolean canceled,
6068 GtkWindow *parent_window,
6069 TnyAccount *account,
6072 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
6073 GtkTreeSelection *sel;
6074 ModestMailOperation *mail_op = NULL;
6076 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
6077 /* Note that the connection process can fail due to
6078 memory low conditions as it can not successfully
6079 store the summary */
6080 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6081 (GtkWidget*) parent_window, err,
6083 g_debug ("Error connecting when trying to move a folder");
6085 g_object_unref (G_OBJECT (info->src_folder));
6086 g_object_unref (G_OBJECT (info->dst_folder));
6091 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
6092 #ifndef MODEST_TOOLKIT_HILDON2
6093 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
6094 _CS("ckct_nw_pasting"));
6095 if (helper->banner != NULL) {
6096 g_object_ref (helper->banner);
6097 gtk_widget_show (GTK_WIDGET(helper->banner));
6100 /* Clean folder on header view before moving it */
6101 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
6102 gtk_tree_selection_unselect_all (sel);
6104 /* Let gtk events run. We need that the folder
6105 view frees its reference to the source
6106 folder *before* issuing the mail operation
6107 so we need the signal handler of selection
6108 changed to happen before the mail
6110 while (gtk_events_pending ())
6111 gtk_main_iteration (); */
6114 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
6115 modest_ui_actions_move_folder_error_handler,
6116 g_object_ref (info->dst_folder), g_object_unref);
6117 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
6120 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
6121 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
6122 TNY_FOLDER (info->dst_folder), TRUE);
6124 modest_mail_operation_xfer_folder (mail_op,
6125 TNY_FOLDER (info->src_folder),
6127 info->delete_original,
6130 g_object_unref (G_OBJECT (info->src_folder));
6132 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
6135 /* Unref mail operation */
6136 g_object_unref (G_OBJECT (mail_op));
6137 g_object_unref (G_OBJECT (info->dst_folder));
6142 get_account_from_folder_store (TnyFolderStore *folder_store)
6144 if (TNY_IS_ACCOUNT (folder_store))
6145 return g_object_ref (folder_store);
6147 return tny_folder_get_account (TNY_FOLDER (folder_store));
6151 * UI handler for the "Move to" action when invoked from the
6155 modest_ui_actions_on_main_window_move_to (GtkAction *action,
6156 GtkWidget *folder_view,
6157 TnyFolderStore *dst_folder,
6158 ModestMainWindow *win)
6160 ModestHeaderView *header_view = NULL;
6161 TnyFolderStore *src_folder = NULL;
6163 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
6165 /* Get the source folder */
6166 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6168 /* Get header view */
6169 header_view = (ModestHeaderView *)
6170 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6172 /* Get folder or messages to transfer */
6173 if (gtk_widget_is_focus (folder_view)) {
6174 gboolean do_xfer = TRUE;
6176 /* Allow only to transfer folders to the local root folder */
6177 if (TNY_IS_ACCOUNT (dst_folder) &&
6178 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
6179 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
6181 } else if (!TNY_IS_FOLDER (src_folder)) {
6182 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
6187 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
6188 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6190 info->src_folder = g_object_ref (src_folder);
6191 info->dst_folder = g_object_ref (dst_folder);
6192 info->delete_original = TRUE;
6193 info->folder_view = folder_view;
6195 connect_info->callback = on_move_folder_cb;
6196 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6197 connect_info->data = info;
6199 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6200 TNY_FOLDER_STORE (src_folder),
6203 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
6206 headers = modest_header_view_get_selected_headers(header_view);
6208 /* Transfer the messages */
6209 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
6210 headers, TNY_FOLDER (dst_folder));
6212 g_object_unref (headers);
6216 g_object_unref (src_folder);
6219 #ifdef MODEST_TOOLKIT_HILDON2
6221 * UI handler for the "Move to" action when invoked from the
6222 * ModestFolderWindow
6225 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
6226 TnyFolderStore *dst_folder,
6230 TnyFolderStore *src_folder = NULL;
6231 TnyIterator *iterator;
6233 if (tny_list_get_length (selection) != 1)
6236 iterator = tny_list_create_iterator (selection);
6237 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
6238 g_object_unref (iterator);
6241 gboolean do_xfer = TRUE;
6243 /* Allow only to transfer folders to the local root folder */
6244 if (TNY_IS_ACCOUNT (dst_folder) &&
6245 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
6246 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
6249 modest_platform_run_information_dialog (win,
6250 _("mail_in_ui_folder_move_target_error"),
6252 } else if (!TNY_IS_FOLDER (src_folder)) {
6253 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
6258 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
6259 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6261 info->src_folder = g_object_ref (src_folder);
6262 info->dst_folder = g_object_ref (dst_folder);
6263 info->delete_original = TRUE;
6264 info->folder_view = folder_view;
6266 connect_info->callback = on_move_folder_cb;
6267 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6268 connect_info->data = info;
6270 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6271 TNY_FOLDER_STORE (src_folder),
6276 g_object_unref (src_folder);
6282 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
6283 TnyFolder *src_folder,
6285 TnyFolder *dst_folder)
6287 gboolean need_connection = TRUE;
6288 gboolean do_xfer = TRUE;
6289 XferMsgsHelper *helper;
6291 g_return_if_fail (TNY_IS_FOLDER (src_folder));
6292 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6293 g_return_if_fail (TNY_IS_LIST (headers));
6295 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
6296 headers, TNY_FOLDER (dst_folder),
6297 TRUE, &need_connection,
6300 /* If we don't want to transfer just return */
6304 /* Create the helper */
6305 helper = g_slice_new (XferMsgsHelper);
6306 helper->dst_folder = g_object_ref (dst_folder);
6307 helper->headers = g_object_ref (headers);
6309 if (need_connection) {
6310 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6311 connect_info->callback = xfer_messages_performer;
6312 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
6313 connect_info->data = helper;
6315 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6316 TNY_FOLDER_STORE (src_folder),
6319 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
6320 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
6321 src_account, helper);
6322 g_object_unref (src_account);
6327 * UI handler for the "Move to" action when invoked from the
6328 * ModestMsgViewWindow
6331 modest_ui_actions_on_window_move_to (GtkAction *action,
6333 TnyFolderStore *dst_folder,
6336 TnyFolder *src_folder = NULL;
6338 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6341 TnyHeader *header = NULL;
6344 iter = tny_list_create_iterator (headers);
6345 header = (TnyHeader *) tny_iterator_get_current (iter);
6346 src_folder = tny_header_get_folder (header);
6348 /* Transfer the messages */
6349 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
6351 TNY_FOLDER (dst_folder));
6354 g_object_unref (header);
6355 g_object_unref (iter);
6356 g_object_unref (src_folder);
6361 modest_ui_actions_on_move_to (GtkAction *action,
6364 modest_ui_actions_on_edit_mode_move_to (win);
6368 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
6370 GtkWidget *dialog = NULL;
6371 MoveToInfo *helper = NULL;
6372 TnyList *list_to_move;
6374 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
6376 #ifndef MODEST_TOOLKIT_HILDON2
6377 /* Get the main window if exists */
6378 ModestMainWindow *main_window;
6379 if (MODEST_IS_MAIN_WINDOW (win))
6380 main_window = MODEST_MAIN_WINDOW (win);
6383 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
6384 FALSE)); /* don't create */
6387 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
6392 if (tny_list_get_length (list_to_move) < 1) {
6393 g_object_unref (list_to_move);
6397 /* Create and run the dialog */
6398 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
6399 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
6400 GTK_WINDOW (dialog),
6404 helper = g_slice_new0 (MoveToInfo);
6405 helper->list = list_to_move;
6408 /* Listen to response signal */
6409 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
6411 /* Show the dialog */
6412 gtk_widget_show (dialog);
6418 * Calls #HeadersFunc for each header already selected in the main
6419 * window or the message currently being shown in the msg view window
6422 do_headers_action (ModestWindow *win,
6426 TnyList *headers_list = NULL;
6427 TnyIterator *iter = NULL;
6428 TnyHeader *header = NULL;
6429 TnyFolder *folder = NULL;
6432 headers_list = get_selected_headers (win);
6436 /* Get the folder */
6437 iter = tny_list_create_iterator (headers_list);
6438 header = TNY_HEADER (tny_iterator_get_current (iter));
6440 folder = tny_header_get_folder (header);
6441 g_object_unref (header);
6444 /* Call the function for each header */
6445 while (!tny_iterator_is_done (iter)) {
6446 header = TNY_HEADER (tny_iterator_get_current (iter));
6447 func (header, win, user_data);
6448 g_object_unref (header);
6449 tny_iterator_next (iter);
6452 /* Trick: do a poke status in order to speed up the signaling
6455 tny_folder_poke_status (folder);
6456 g_object_unref (folder);
6460 g_object_unref (iter);
6461 g_object_unref (headers_list);
6465 modest_ui_actions_view_attachment (GtkAction *action,
6466 ModestWindow *window)
6468 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6469 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
6471 /* not supported window for this action */
6472 g_return_if_reached ();
6477 modest_ui_actions_save_attachments (GtkAction *action,
6478 ModestWindow *window)
6480 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6482 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
6485 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
6487 /* not supported window for this action */
6488 g_return_if_reached ();
6493 modest_ui_actions_remove_attachments (GtkAction *action,
6494 ModestWindow *window)
6496 if (MODEST_IS_MAIN_WINDOW (window)) {
6497 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
6498 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6499 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
6501 /* not supported window for this action */
6502 g_return_if_reached ();
6507 modest_ui_actions_on_settings (GtkAction *action,
6512 dialog = modest_platform_get_global_settings_dialog ();
6513 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
6514 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
6515 gtk_widget_show_all (dialog);
6517 gtk_dialog_run (GTK_DIALOG (dialog));
6519 gtk_widget_destroy (dialog);
6523 modest_ui_actions_on_help (GtkAction *action,
6526 /* Help app is not available at all in fremantle */
6527 #ifndef MODEST_TOOLKIT_HILDON2
6528 const gchar *help_id;
6530 g_return_if_fail (win && GTK_IS_WINDOW(win));
6532 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
6535 modest_platform_show_help (GTK_WINDOW (win), help_id);
6540 modest_ui_actions_on_csm_help (GtkAction *action,
6543 /* Help app is not available at all in fremantle */
6544 #ifndef MODEST_TOOLKIT_HILDON2
6546 const gchar* help_id = NULL;
6547 GtkWidget *folder_view;
6548 TnyFolderStore *folder_store;
6550 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
6552 /* Get selected folder */
6553 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
6554 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6555 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6557 /* Switch help_id */
6558 if (folder_store && TNY_IS_FOLDER (folder_store))
6559 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
6562 g_object_unref (folder_store);
6565 modest_platform_show_help (GTK_WINDOW (win), help_id);
6567 modest_ui_actions_on_help (action, win);
6572 retrieve_contents_cb (ModestMailOperation *mail_op,
6579 /* We only need this callback to show an error in case of
6580 memory low condition */
6581 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
6582 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
6587 retrieve_msg_contents_performer (gboolean canceled,
6589 GtkWindow *parent_window,
6590 TnyAccount *account,
6593 ModestMailOperation *mail_op;
6594 TnyList *headers = TNY_LIST (user_data);
6596 if (err || canceled) {
6597 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6598 (GtkWidget *) parent_window, err,
6603 /* Create mail operation */
6604 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
6605 modest_ui_actions_disk_operations_error_handler,
6607 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
6608 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
6611 g_object_unref (mail_op);
6613 g_object_unref (headers);
6614 g_object_unref (account);
6618 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
6619 ModestWindow *window)
6621 TnyList *headers = NULL;
6622 TnyAccount *account = NULL;
6623 TnyIterator *iter = NULL;
6624 TnyHeader *header = NULL;
6625 TnyFolder *folder = NULL;
6628 headers = get_selected_headers (window);
6632 /* Pick the account */
6633 iter = tny_list_create_iterator (headers);
6634 header = TNY_HEADER (tny_iterator_get_current (iter));
6635 folder = tny_header_get_folder (header);
6636 account = tny_folder_get_account (folder);
6637 g_object_unref (folder);
6638 g_object_unref (header);
6639 g_object_unref (iter);
6641 /* Connect and perform the message retrieval */
6642 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6643 g_object_ref (account),
6644 retrieve_msg_contents_performer,
6645 g_object_ref (headers));
6648 g_object_unref (account);
6649 g_object_unref (headers);
6653 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6655 g_return_if_fail (MODEST_IS_WINDOW (window));
6658 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6662 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6664 g_return_if_fail (MODEST_IS_WINDOW (window));
6667 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6671 modest_ui_actions_on_email_menu_activated (GtkAction *action,
6672 ModestWindow *window)
6674 g_return_if_fail (MODEST_IS_WINDOW (window));
6677 modest_ui_actions_check_menu_dimming_rules (window);
6681 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
6682 ModestWindow *window)
6684 g_return_if_fail (MODEST_IS_WINDOW (window));
6687 modest_ui_actions_check_menu_dimming_rules (window);
6691 modest_ui_actions_on_view_menu_activated (GtkAction *action,
6692 ModestWindow *window)
6694 g_return_if_fail (MODEST_IS_WINDOW (window));
6697 modest_ui_actions_check_menu_dimming_rules (window);
6701 modest_ui_actions_on_format_menu_activated (GtkAction *action,
6702 ModestWindow *window)
6704 g_return_if_fail (MODEST_IS_WINDOW (window));
6707 modest_ui_actions_check_menu_dimming_rules (window);
6711 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
6712 ModestWindow *window)
6714 g_return_if_fail (MODEST_IS_WINDOW (window));
6717 modest_ui_actions_check_menu_dimming_rules (window);
6721 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
6722 ModestWindow *window)
6724 g_return_if_fail (MODEST_IS_WINDOW (window));
6727 modest_ui_actions_check_menu_dimming_rules (window);
6731 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
6732 ModestWindow *window)
6734 g_return_if_fail (MODEST_IS_WINDOW (window));
6737 modest_ui_actions_check_menu_dimming_rules (window);
6741 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
6742 ModestWindow *window)
6744 g_return_if_fail (MODEST_IS_WINDOW (window));
6747 modest_ui_actions_check_menu_dimming_rules (window);
6751 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
6752 ModestWindow *window)
6754 g_return_if_fail (MODEST_IS_WINDOW (window));
6757 modest_ui_actions_check_menu_dimming_rules (window);
6761 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6763 g_return_if_fail (MODEST_IS_WINDOW (window));
6765 /* we check for low-mem; in that case, show a warning, and don't allow
6768 if (modest_platform_check_memory_low (window, TRUE))
6771 modest_platform_show_search_messages (GTK_WINDOW (window));
6775 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6777 g_return_if_fail (MODEST_IS_WINDOW (win));
6780 /* we check for low-mem; in that case, show a warning, and don't allow
6781 * for the addressbook
6783 if (modest_platform_check_memory_low (win, TRUE))
6787 modest_platform_show_addressbook (GTK_WINDOW (win));
6792 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6793 ModestWindow *window)
6796 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6798 if (GTK_IS_TOGGLE_ACTION (action))
6799 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6803 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window),
6808 on_send_receive_finished (ModestMailOperation *mail_op,
6811 GtkWidget *header_view, *folder_view;
6812 TnyFolderStore *folder_store;
6813 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6815 /* Set send/receive operation finished */
6816 modest_main_window_notify_send_receive_completed (main_win);
6818 /* Don't refresh the current folder if there were any errors */
6819 if (modest_mail_operation_get_status (mail_op) !=
6820 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6823 /* Refresh the current folder if we're viewing a window. We do
6824 this because the user won't be able to see the new mails in
6825 the selected folder after a Send&Receive because it only
6826 performs a poke_status, i.e, only the number of read/unread
6827 messages is updated, but the new headers are not
6829 folder_view = modest_main_window_get_child_widget (main_win,
6830 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6834 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6836 /* Do not need to refresh INBOX again because the
6837 update_account does it always automatically */
6838 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6839 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6840 ModestMailOperation *refresh_op;
6842 header_view = modest_main_window_get_child_widget (main_win,
6843 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6845 /* We do not need to set the contents style
6846 because it hasn't changed. We also do not
6847 need to save the widget status. Just force
6849 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6850 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6851 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6852 folder_refreshed_cb, main_win);
6853 g_object_unref (refresh_op);
6857 g_object_unref (folder_store);
6862 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6868 const gchar* server_name = NULL;
6869 TnyTransportAccount *transport;
6870 gchar *message = NULL;
6871 ModestProtocol *protocol;
6873 /* Don't show anything if the user cancelled something or the
6874 * send receive request is not interactive. Authentication
6875 * errors are managed by the account store so no need to show
6876 * a dialog here again */
6877 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6878 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6879 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6883 /* Get the server name. Note that we could be using a
6884 connection specific transport account */
6885 transport = (TnyTransportAccount *)
6886 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
6888 ModestTnyAccountStore *acc_store;
6889 const gchar *acc_name;
6890 TnyTransportAccount *conn_specific;
6892 acc_store = modest_runtime_get_account_store();
6893 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
6894 conn_specific = (TnyTransportAccount *)
6895 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
6896 if (conn_specific) {
6897 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
6898 g_object_unref (conn_specific);
6900 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
6902 g_object_unref (transport);
6906 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
6907 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
6908 tny_account_get_proto (TNY_ACCOUNT (transport)));
6910 g_warning ("%s: Account with no proto", __FUNCTION__);
6914 /* Show the appropriate message text for the GError: */
6915 switch (err->code) {
6916 case TNY_SERVICE_ERROR_CONNECT:
6917 message = modest_protocol_get_translation (protocol,
6918 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
6921 case TNY_SERVICE_ERROR_SEND:
6922 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6924 case TNY_SERVICE_ERROR_UNAVAILABLE:
6925 message = modest_protocol_get_translation (protocol,
6926 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
6930 g_warning ("%s: unexpected ERROR %d",
6931 __FUNCTION__, err->code);
6932 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6936 modest_platform_run_information_dialog (NULL, message, FALSE);
6941 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6946 ModestWindow *top_window = NULL;
6947 ModestWindowMgr *mgr = NULL;
6948 GtkWidget *header_view = NULL;
6949 TnyFolder *selected_folder = NULL;
6950 TnyFolderType folder_type;
6952 mgr = modest_runtime_get_window_mgr ();
6953 top_window = modest_window_mgr_get_current_top (mgr);
6958 #ifndef MODEST_TOOLKIT_HILDON2
6959 if (MODEST_IS_MAIN_WINDOW (top_window)) {
6960 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (top_window),
6961 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6964 if (MODEST_IS_HEADER_WINDOW (top_window)) {
6965 header_view = (GtkWidget *)
6966 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
6970 /* Get selected folder */
6972 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
6973 if (!selected_folder)
6976 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6977 #if GTK_CHECK_VERSION(2, 8, 0)
6978 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
6979 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6980 GtkTreeViewColumn *tree_column;
6982 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6983 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6985 gtk_tree_view_column_queue_resize (tree_column);
6987 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
6988 gtk_widget_queue_draw (header_view);
6991 #ifndef MODEST_TOOLKIT_HILDON2
6992 /* Rerun dimming rules, because the message could become deletable for example */
6993 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6994 MODEST_DIMMING_RULES_TOOLBAR);
6995 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6996 MODEST_DIMMING_RULES_MENU);
7000 g_object_unref (selected_folder);
7004 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
7005 TnyAccount *account)
7007 ModestProtocolType protocol_type;
7008 ModestProtocol *protocol;
7009 gchar *error_note = NULL;
7011 protocol_type = modest_tny_account_get_protocol_type (account);
7012 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
7015 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
7016 if (error_note == NULL) {
7017 g_warning ("%s: This should not be reached", __FUNCTION__);
7019 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
7020 g_free (error_note);
7025 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
7029 TnyFolderStore *folder = NULL;
7030 TnyAccount *account = NULL;
7031 ModestProtocolType proto;
7032 ModestProtocol *protocol;
7033 TnyHeader *header = NULL;
7035 if (MODEST_IS_MAIN_WINDOW (win)) {
7036 GtkWidget *header_view;
7037 TnyList* headers = NULL;
7039 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
7040 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
7041 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
7042 if (!headers || tny_list_get_length (headers) == 0) {
7044 g_object_unref (headers);
7047 iter = tny_list_create_iterator (headers);
7048 header = TNY_HEADER (tny_iterator_get_current (iter));
7049 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
7050 g_object_unref (iter);
7051 g_object_unref (headers);
7052 #ifdef MODEST_TOOLKIT_HILDON2
7053 } else if (MODEST_IS_HEADER_WINDOW (win)) {
7054 GtkWidget *header_view;
7055 TnyList* headers = NULL;
7057 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
7058 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
7059 if (!headers || tny_list_get_length (headers) == 0) {
7061 g_object_unref (headers);
7064 iter = tny_list_create_iterator (headers);
7065 header = TNY_HEADER (tny_iterator_get_current (iter));
7067 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
7069 g_warning ("List should contain headers");
7071 g_object_unref (iter);
7072 g_object_unref (headers);
7074 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
7075 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
7077 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
7080 if (!header || !folder)
7083 /* Get the account type */
7084 account = tny_folder_get_account (TNY_FOLDER (folder));
7085 proto = modest_tny_account_get_protocol_type (account);
7086 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
7089 subject = tny_header_dup_subject (header);
7090 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
7094 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
7100 g_object_unref (account);
7102 g_object_unref (folder);
7104 g_object_unref (header);
7110 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
7111 const gchar *account_name,
7112 const gchar *account_title)
7114 ModestAccountMgr *account_mgr;
7117 ModestProtocol *protocol;
7118 gboolean removed = FALSE;
7120 g_return_val_if_fail (account_name, FALSE);
7121 g_return_val_if_fail (account_title, FALSE);
7123 account_mgr = modest_runtime_get_account_mgr();
7125 /* The warning text depends on the account type: */
7126 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
7127 modest_account_mgr_get_store_protocol (account_mgr,
7129 txt = modest_protocol_get_translation (protocol,
7130 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
7133 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
7135 response = modest_platform_run_confirmation_dialog (parent_window, txt);
7139 if (response == GTK_RESPONSE_OK) {
7140 /* Remove account. If it succeeds then it also removes
7141 the account from the ModestAccountView: */
7142 gboolean is_default = FALSE;
7143 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
7144 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
7146 g_free (default_account_name);
7148 removed = modest_account_mgr_remove_account (account_mgr, account_name);
7150 #ifdef MODEST_TOOLKIT_HILDON2
7151 hildon_gtk_window_take_screenshot (parent_window, FALSE);
7153 /* Close all email notifications, we cannot
7154 distinguish if the notification belongs to
7155 this account or not, so for safety reasons
7156 we remove them all */
7157 modest_platform_remove_new_mail_notifications (FALSE, account_name);
7159 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
7166 on_fetch_images_performer (gboolean canceled,
7168 GtkWindow *parent_window,
7169 TnyAccount *account,
7172 if (err || canceled) {
7173 /* Show an unable to retrieve images ??? */
7177 /* Note that the user could have closed the window while connecting */
7178 if (GTK_WIDGET_VISIBLE (parent_window))
7179 modest_msg_view_window_fetch_images ((ModestMsgViewWindow *) parent_window);
7180 g_object_unref ((GObject *) user_data);
7184 modest_ui_actions_on_fetch_images (GtkAction *action,
7185 ModestWindow *window)
7187 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
7189 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
7191 on_fetch_images_performer,
7192 g_object_ref (window));
7196 modest_ui_actions_on_reload_message (const gchar *msg_id)
7198 ModestWindow *window = NULL;
7200 g_return_if_fail (msg_id && msg_id[0] != '\0');
7201 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
7207 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
7210 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));
7213 /** Check whether any connections are active, and cancel them if
7215 * Returns TRUE is there was no problem,
7216 * or if an operation was cancelled so we can continue.
7217 * Returns FALSE if the user chose to cancel his request instead.
7221 modest_ui_actions_check_for_active_account (ModestWindow *self,
7222 const gchar* account_name)
7224 ModestTnySendQueue *send_queue;
7225 ModestTnyAccountStore *acc_store;
7226 ModestMailOperationQueue* queue;
7227 TnyConnectionStatus store_conn_status;
7228 TnyAccount *store_account = NULL, *transport_account = NULL;
7229 gboolean retval = TRUE, sending = FALSE;
7231 acc_store = modest_runtime_get_account_store ();
7232 queue = modest_runtime_get_mail_operation_queue ();
7235 modest_tny_account_store_get_server_account (acc_store,
7237 TNY_ACCOUNT_TYPE_STORE);
7239 /* This could happen if the account was deleted before the
7240 call to this function */
7245 modest_tny_account_store_get_server_account (acc_store,
7247 TNY_ACCOUNT_TYPE_TRANSPORT);
7249 /* This could happen if the account was deleted before the
7250 call to this function */
7251 if (!transport_account) {
7252 g_object_unref (store_account);
7256 /* If the transport account was not used yet, then the send
7257 queue could not exist (it's created on demand) */
7258 send_queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (transport_account), FALSE);
7259 if (TNY_IS_SEND_QUEUE (send_queue))
7260 sending = modest_tny_send_queue_sending_in_progress (send_queue);
7262 store_conn_status = tny_account_get_connection_status (store_account);
7263 if (store_conn_status == TNY_CONNECTION_STATUS_CONNECTED || sending) {
7266 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (self),
7267 _("emev_nc_disconnect_account"));
7268 if (response == GTK_RESPONSE_OK) {
7277 /* FIXME: We should only cancel those of this account */
7278 modest_mail_operation_queue_cancel_all (queue);
7280 /* Also disconnect the account */
7281 if ((tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED) &&
7282 (tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)) {
7283 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
7287 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (transport_account),
7293 g_object_unref (store_account);
7294 g_object_unref (transport_account);