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, 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;
2240 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW(win));
2242 /* we check for low-mem; in that case, show a warning, and don't allow
2243 * reply/forward (because it could potentially require a lot of memory */
2244 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2247 account_name = modest_window_get_active_account (MODEST_WINDOW (win));
2248 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (win));
2249 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
2250 account_name, mailbox);
2251 recipient = modest_text_utils_get_email_address (from);
2252 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr(),
2257 msg = modest_msg_view_window_get_message(MODEST_MSG_VIEW_WINDOW(win));
2258 g_return_if_fail(msg);
2260 msg_header = tny_msg_get_header (msg);
2262 modest_tny_msg_create_reply_calendar_msg (msg, msg_header, from,
2263 (use_signature) ? signature : NULL,
2265 g_object_unref (msg_header);
2271 g_warning ("%s: failed to create message\n", __FUNCTION__);
2275 msg_win = (GtkWidget *) modest_msg_edit_window_new (new_msg, account_name, mailbox, FALSE);
2276 mgr = modest_runtime_get_window_mgr ();
2277 modest_window_mgr_register_window (mgr, MODEST_WINDOW (msg_win), (ModestWindow *) win);
2279 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (win));
2280 modest_window_set_zoom (MODEST_WINDOW (msg_win), parent_zoom);
2282 /* Show edit window */
2283 gtk_widget_show_all (GTK_WIDGET (msg_win));
2287 g_object_unref (G_OBJECT (new_msg));
2291 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
2293 g_return_if_fail (MODEST_IS_WINDOW(win));
2295 reply_forward (ACTION_REPLY, win);
2299 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
2301 g_return_if_fail (MODEST_IS_WINDOW(win));
2303 reply_forward (ACTION_FORWARD, win);
2307 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
2309 g_return_if_fail (MODEST_IS_WINDOW(win));
2311 reply_forward (ACTION_REPLY_TO_ALL, win);
2315 modest_ui_actions_on_next (GtkAction *action,
2316 ModestWindow *window)
2318 if (MODEST_IS_MAIN_WINDOW (window)) {
2319 GtkWidget *header_view;
2321 header_view = modest_main_window_get_child_widget (
2322 MODEST_MAIN_WINDOW(window),
2323 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2327 modest_header_view_select_next (
2328 MODEST_HEADER_VIEW(header_view));
2329 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2330 modest_msg_view_window_select_next_message (
2331 MODEST_MSG_VIEW_WINDOW (window));
2333 g_return_if_reached ();
2338 modest_ui_actions_on_prev (GtkAction *action,
2339 ModestWindow *window)
2341 g_return_if_fail (MODEST_IS_WINDOW(window));
2343 if (MODEST_IS_MAIN_WINDOW (window)) {
2344 GtkWidget *header_view;
2345 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2346 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2350 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
2351 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2352 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
2354 g_return_if_reached ();
2359 modest_ui_actions_on_sort (GtkAction *action,
2360 ModestWindow *window)
2362 GtkWidget *header_view = NULL;
2364 g_return_if_fail (MODEST_IS_WINDOW(window));
2366 if (MODEST_IS_MAIN_WINDOW (window)) {
2367 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2368 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2369 #ifdef MODEST_TOOLKIT_HILDON2
2370 } else if (MODEST_IS_HEADER_WINDOW (window)) {
2371 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2376 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
2381 /* Show sorting dialog */
2382 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
2386 sync_folder_cb (ModestMailOperation *mail_op,
2390 ModestHeaderView *header_view = (ModestHeaderView *) user_data;
2392 if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
2393 ModestWindow *parent = (ModestWindow *) modest_mail_operation_get_source (mail_op);
2395 /* We must clear first, because otherwise set_folder will ignore */
2396 /* the change as the folders are the same */
2397 modest_header_view_clear (header_view);
2398 modest_header_view_set_folder (header_view, folder, TRUE, parent, NULL, NULL);
2400 g_object_unref (parent);
2403 g_object_unref (header_view);
2407 idle_refresh_folder (gpointer source)
2409 ModestHeaderView *header_view = NULL;
2411 /* If the window still exists */
2412 if (!GTK_IS_WIDGET (source) ||
2413 !GTK_WIDGET_VISIBLE (source))
2416 /* Refresh the current view */
2417 #ifdef MODEST_TOOLKIT_HILDON2
2418 if (MODEST_IS_HEADER_WINDOW (source))
2419 header_view = modest_header_window_get_header_view ((ModestHeaderWindow *) source);
2421 if (MODEST_IS_MAIN_WINDOW (source))
2422 header_view = MODEST_HEADER_VIEW (modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source),
2423 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
2426 TnyFolder *folder = modest_header_view_get_folder (header_view);
2428 /* Sync the folder status */
2429 ModestMailOperation *mail_op = modest_mail_operation_new (source);
2430 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2431 modest_mail_operation_sync_folder (mail_op, folder, FALSE, sync_folder_cb, g_object_ref (header_view));
2432 g_object_unref (folder);
2433 g_object_unref (mail_op);
2441 update_account_cb (ModestMailOperation *self,
2442 TnyList *new_headers,
2446 gboolean show_visual_notifications;
2448 top = modest_window_mgr_get_current_top (modest_runtime_get_window_mgr ());
2449 show_visual_notifications = (top) ? FALSE : TRUE;
2451 /* Notify new messages have been downloaded. If the
2452 send&receive was invoked by the user then do not show any
2453 visual notification, only play a sound and activate the LED
2454 (for the Maemo version) */
2455 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0) {
2457 /* We only notify about really new messages (not seen) we get */
2458 TnyList *actually_new_list;
2459 TnyIterator *iterator;
2460 actually_new_list = TNY_LIST (tny_simple_list_new ());
2461 for (iterator = tny_list_create_iterator (new_headers);
2462 !tny_iterator_is_done (iterator);
2463 tny_iterator_next (iterator)) {
2465 TnyHeaderFlags flags;
2466 header = TNY_HEADER (tny_iterator_get_current (iterator));
2467 flags = tny_header_get_flags (header);
2469 if (!(flags & TNY_HEADER_FLAG_SEEN)) {
2470 /* Messages are ordered from most
2471 recent to oldest. But we want to
2472 show notifications starting from
2473 the oldest message. That's why we
2475 tny_list_prepend (actually_new_list, G_OBJECT (header));
2477 g_object_unref (header);
2479 g_object_unref (iterator);
2481 if (tny_list_get_length (actually_new_list) > 0) {
2482 GList *new_headers_list = NULL;
2484 new_headers_list = modest_utils_create_notification_list_from_header_list (actually_new_list);
2486 /* Send notifications */
2487 if (new_headers_list) {
2488 modest_platform_on_new_headers_received (new_headers_list,
2489 show_visual_notifications);
2491 modest_utils_free_notification_list (new_headers_list);
2494 g_object_unref (actually_new_list);
2498 /* Refresh the current folder in an idle. We do this
2499 in order to avoid refresh cancelations if the
2500 currently viewed folder is the inbox */
2501 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
2502 idle_refresh_folder,
2509 TnyAccount *account;
2511 gchar *account_name;
2512 gboolean poke_status;
2513 gboolean interactive;
2514 ModestMailOperation *mail_op;
2518 do_send_receive_performer (gboolean canceled,
2520 GtkWindow *parent_window,
2521 TnyAccount *account,
2524 SendReceiveInfo *info;
2526 info = (SendReceiveInfo *) user_data;
2528 if (err || canceled) {
2529 /* In disk full conditions we could get this error here */
2530 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
2531 (GtkWidget *) parent_window, err,
2534 if (info->mail_op) {
2535 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2541 /* Set send/receive operation in progress */
2542 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2543 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2546 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2547 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2548 G_CALLBACK (on_send_receive_finished),
2551 /* Send & receive. */
2552 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2553 update_account_cb, info->win);
2558 g_object_unref (G_OBJECT (info->mail_op));
2559 if (info->account_name)
2560 g_free (info->account_name);
2562 g_object_unref (info->win);
2564 g_object_unref (info->account);
2565 g_slice_free (SendReceiveInfo, info);
2569 * This function performs the send & receive required actions. The
2570 * window is used to create the mail operation. Typically it should
2571 * always be the main window, but we pass it as argument in order to
2575 modest_ui_actions_do_send_receive (const gchar *account_name,
2576 gboolean force_connection,
2577 gboolean poke_status,
2578 gboolean interactive,
2581 gchar *acc_name = NULL;
2582 SendReceiveInfo *info;
2583 ModestTnyAccountStore *acc_store;
2584 TnyAccount *account;
2586 /* If no account name was provided then get the current account, and if
2587 there is no current account then pick the default one: */
2588 if (!account_name) {
2590 acc_name = g_strdup (modest_window_get_active_account (win));
2592 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2594 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2598 acc_name = g_strdup (account_name);
2601 acc_store = modest_runtime_get_account_store ();
2602 account = modest_tny_account_store_get_server_account (acc_store, acc_name, TNY_ACCOUNT_TYPE_STORE);
2606 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2610 /* Do not automatically refresh accounts that are flagged as
2611 NO_AUTO_UPDATE. This could be useful for accounts that
2612 handle their own update times */
2614 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
2615 if (proto != MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
2616 const gchar *tag = MODEST_PROTOCOL_REGISTRY_NO_AUTO_UPDATE_PROTOCOLS;
2617 ModestProtocolRegistry *registry = modest_runtime_get_protocol_registry ();
2619 if (modest_protocol_registry_protocol_type_has_tag (registry, proto, tag)) {
2620 g_debug ("%s no auto update allowed for account %s", __FUNCTION__, account_name);
2621 g_object_unref (account);
2628 /* Create the info for the connect and perform */
2629 info = g_slice_new (SendReceiveInfo);
2630 info->account_name = acc_name;
2631 info->win = (win) ? g_object_ref (win) : NULL;
2632 info->poke_status = poke_status;
2633 info->interactive = interactive;
2634 info->account = account;
2635 /* We need to create the operation here, because otherwise it
2636 could happen that the queue emits the queue-empty signal
2637 while we're trying to connect the account */
2638 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2639 modest_ui_actions_disk_operations_error_handler,
2641 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2643 /* Invoke the connect and perform */
2644 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2645 force_connection, info->account,
2646 do_send_receive_performer, info);
2651 modest_ui_actions_do_cancel_send (const gchar *account_name,
2654 TnyTransportAccount *transport_account;
2655 TnySendQueue *send_queue = NULL;
2656 GError *error = NULL;
2658 /* Get transport account */
2660 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2661 (modest_runtime_get_account_store(),
2663 TNY_ACCOUNT_TYPE_TRANSPORT));
2664 if (!transport_account) {
2665 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2670 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2671 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2672 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2673 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2674 "modest: could not find send queue for account\n");
2676 /* Cancel the current send */
2677 tny_account_cancel (TNY_ACCOUNT (transport_account));
2679 /* Suspend all pending messages */
2680 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2684 if (transport_account != NULL)
2685 g_object_unref (G_OBJECT (transport_account));
2689 modest_ui_actions_cancel_send_all (ModestWindow *win)
2691 GSList *account_names, *iter;
2693 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2696 iter = account_names;
2698 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2699 iter = g_slist_next (iter);
2702 modest_account_mgr_free_account_names (account_names);
2703 account_names = NULL;
2707 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2710 /* Check if accounts exist */
2711 gboolean accounts_exist =
2712 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2714 /* If not, allow the user to create an account before trying to send/receive. */
2715 if (!accounts_exist)
2716 modest_ui_actions_on_accounts (NULL, win);
2718 /* Cancel all sending operaitons */
2719 modest_ui_actions_cancel_send_all (win);
2723 * Refreshes all accounts. This function will be used by automatic
2727 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2728 gboolean force_connection,
2729 gboolean poke_status,
2730 gboolean interactive)
2732 GSList *account_names, *iter;
2734 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2737 iter = account_names;
2739 modest_ui_actions_do_send_receive ((const char*) iter->data,
2741 poke_status, interactive, win);
2742 iter = g_slist_next (iter);
2745 modest_account_mgr_free_account_names (account_names);
2746 account_names = NULL;
2750 * Handler of the click on Send&Receive button in the main toolbar
2753 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2755 /* Check if accounts exist */
2756 gboolean accounts_exist;
2759 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2761 /* If not, allow the user to create an account before trying to send/receive. */
2762 if (!accounts_exist)
2763 modest_ui_actions_on_accounts (NULL, win);
2765 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2766 if (MODEST_IS_MAIN_WINDOW (win)) {
2767 GtkWidget *folder_view;
2768 TnyFolderStore *folder_store;
2771 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2772 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2776 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2779 g_object_unref (folder_store);
2780 /* Refresh the active account. Force the connection if needed
2781 and poke the status of all folders */
2782 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2783 #ifdef MODEST_TOOLKIT_HILDON2
2784 } else if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2785 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2788 const gchar *active_account;
2789 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2791 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2798 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2801 GtkWidget *header_view;
2803 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2805 header_view = modest_main_window_get_child_widget (main_window,
2806 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2810 conf = modest_runtime_get_conf ();
2812 /* what is saved/restored is depending on the style; thus; we save with
2813 * old style, then update the style, and restore for this new style
2815 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2817 if (modest_header_view_get_style
2818 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2819 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2820 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2822 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2823 MODEST_HEADER_VIEW_STYLE_DETAILS);
2825 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2826 MODEST_CONF_HEADER_VIEW_KEY);
2831 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2833 ModestMainWindow *main_window)
2835 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2836 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2838 /* in the case the folder is empty, show the empty folder message and focus
2840 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2841 if (modest_header_view_is_empty (header_view)) {
2842 TnyFolder *folder = modest_header_view_get_folder (header_view);
2843 GtkWidget *folder_view =
2844 modest_main_window_get_child_widget (main_window,
2845 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2846 if (folder != NULL) {
2847 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2848 g_object_unref (folder);
2850 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2854 /* If no header has been selected then exit */
2859 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2860 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2862 /* Update toolbar dimming state */
2863 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2864 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2868 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2871 ModestWindow *window)
2873 GtkWidget *open_widget;
2874 GtkTreeRowReference *rowref;
2876 g_return_if_fail (MODEST_IS_WINDOW(window));
2877 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2878 g_return_if_fail (TNY_IS_HEADER (header));
2880 if (modest_header_view_count_selected_headers (header_view) > 1) {
2881 /* Don't allow activation if there are more than one message selected */
2882 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2886 /* we check for low-mem; in that case, show a warning, and don't allow
2887 * activating headers
2889 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2892 if (MODEST_IS_MAIN_WINDOW (window)) {
2893 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2894 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2895 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2899 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2900 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2901 gtk_tree_row_reference_free (rowref);
2905 set_active_account_from_tny_account (TnyAccount *account,
2906 ModestWindow *window)
2908 const gchar *server_acc_name = tny_account_get_id (account);
2910 /* We need the TnyAccount provided by the
2911 account store because that is the one that
2912 knows the name of the Modest account */
2913 TnyAccount *modest_server_account =
2914 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2915 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2917 if (!modest_server_account) {
2918 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2922 /* Update active account, but only if it's not a pseudo-account */
2923 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2924 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2925 const gchar *modest_acc_name =
2926 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2927 if (modest_acc_name)
2928 modest_window_set_active_account (window, modest_acc_name);
2931 g_object_unref (modest_server_account);
2936 folder_refreshed_cb (ModestMailOperation *mail_op,
2940 ModestMainWindow *win = NULL;
2941 GtkWidget *folder_view, *header_view;
2942 const GError *error;
2944 g_return_if_fail (TNY_IS_FOLDER (folder));
2946 win = MODEST_MAIN_WINDOW (user_data);
2948 /* Check if the operation failed due to memory low conditions */
2949 error = modest_mail_operation_get_error (mail_op);
2950 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2951 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2952 modest_platform_run_information_dialog (GTK_WINDOW (win),
2953 _KR("memr_ib_operation_disabled"),
2959 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2961 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2964 TnyFolderStore *current_folder;
2966 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2967 if (current_folder) {
2968 gboolean different = ((TnyFolderStore *) folder != current_folder);
2969 g_object_unref (current_folder);
2975 /* Check if folder is empty and set headers view contents style */
2976 if ((tny_folder_get_all_count (folder) == 0) ||
2977 modest_header_view_is_empty (MODEST_HEADER_VIEW (header_view)))
2978 modest_main_window_set_contents_style (win,
2979 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2983 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2984 TnyFolderStore *folder_store,
2986 ModestMainWindow *main_window)
2988 GtkWidget *header_view;
2990 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2992 header_view = modest_main_window_get_child_widget(main_window,
2993 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2998 if (TNY_IS_ACCOUNT (folder_store)) {
3000 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
3002 /* Show account details */
3003 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
3006 if (TNY_IS_FOLDER (folder_store) && selected) {
3007 TnyAccount *account;
3009 /* Update the active account */
3010 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
3012 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
3013 g_object_unref (account);
3017 /* Set the header style by default, it could
3018 be changed later by the refresh callback to
3020 modest_main_window_set_contents_style (main_window,
3021 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
3023 /* Set folder on header view. This function
3024 will call tny_folder_refresh_async so we
3025 pass a callback that will be called when
3026 finished. We use that callback to set the
3027 empty view if there are no messages */
3028 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
3029 TNY_FOLDER (folder_store),
3031 MODEST_WINDOW (main_window),
3032 folder_refreshed_cb,
3035 /* Restore configuration. We need to do this
3036 *after* the set_folder because the widget
3037 memory asks the header view about its
3039 modest_widget_memory_restore (modest_runtime_get_conf (),
3040 G_OBJECT(header_view),
3041 MODEST_CONF_HEADER_VIEW_KEY);
3043 /* No need to save the header view
3044 configuration for Maemo because it only
3045 saves the sorting stuff and that it's
3046 already being done by the sort
3047 dialog. Remove it when the GNOME version
3048 has the same behaviour */
3049 #ifdef MODEST_TOOLKIT_GTK
3050 if (modest_main_window_get_contents_style (main_window) ==
3051 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
3052 modest_widget_memory_save (modest_runtime_get_conf (),
3053 G_OBJECT (header_view),
3054 MODEST_CONF_HEADER_VIEW_KEY);
3056 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
3060 /* Update dimming state */
3061 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
3062 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
3066 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
3073 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
3075 online = tny_device_is_online (modest_runtime_get_device());
3078 /* already online -- the item is simply not there... */
3079 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
3081 GTK_MESSAGE_WARNING,
3083 _("The %s you selected cannot be found"),
3085 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
3086 gtk_dialog_run (GTK_DIALOG(dialog));
3088 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
3091 _("mcen_bd_dialog_cancel"),
3092 GTK_RESPONSE_REJECT,
3093 _("mcen_bd_dialog_ok"),
3094 GTK_RESPONSE_ACCEPT,
3096 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
3097 "Do you want to get online?"), item);
3098 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
3099 gtk_label_new (txt), FALSE, FALSE, 0);
3100 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3103 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
3104 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3105 /* TODO: Comment about why is this commented out: */
3106 /* modest_platform_connect_and_wait (); */
3109 gtk_widget_destroy (dialog);
3113 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
3116 /* g_debug ("%s %s", __FUNCTION__, link); */
3121 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
3124 modest_platform_activate_uri (link);
3128 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
3131 modest_platform_show_uri_popup (link);
3135 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
3138 /* we check for low-mem; in that case, show a warning, and don't allow
3139 * viewing attachments
3141 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
3144 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
3148 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
3149 const gchar *address,
3152 /* g_debug ("%s %s", __FUNCTION__, address); */
3156 on_save_to_drafts_cb (ModestMailOperation *mail_op,
3157 TnyMsg *saved_draft,
3160 ModestMsgEditWindow *edit_window;
3162 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
3163 #ifndef MODEST_TOOLKIT_HILDON2
3164 ModestMainWindow *win;
3166 /* FIXME. Make the header view sensitive again. This is a
3167 * temporary hack. See modest_ui_actions_on_save_to_drafts()
3169 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
3170 modest_runtime_get_window_mgr(), FALSE));
3172 GtkWidget *hdrview = modest_main_window_get_child_widget(
3173 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3174 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
3178 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
3180 /* Set draft is there was no error */
3181 if (!modest_mail_operation_get_error (mail_op))
3182 modest_msg_edit_window_set_draft (edit_window, saved_draft);
3184 g_object_unref(edit_window);
3188 enough_space_for_message (ModestMsgEditWindow *edit_window,
3191 guint64 available_disk, expected_size;
3196 available_disk = modest_utils_get_available_space (NULL);
3197 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
3198 expected_size = modest_tny_msg_estimate_size (data->plain_body,
3203 /* Double check: disk full condition or message too big */
3204 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
3205 expected_size > available_disk) {
3206 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3207 modest_platform_information_banner (NULL, NULL, msg);
3214 * djcb: if we're in low-memory state, we only allow for
3215 * saving messages smaller than
3216 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
3217 * should still allow for sending anything critical...
3219 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
3220 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
3224 * djcb: we also make sure that the attachments are smaller than the max size
3225 * this is for the case where we'd try to forward a message with attachments
3226 * bigger than our max allowed size, or sending an message from drafts which
3227 * somehow got past our checks when attaching.
3229 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
3230 modest_platform_run_information_dialog (
3231 GTK_WINDOW(edit_window),
3232 _("mail_ib_error_attachment_size"),
3241 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3243 TnyTransportAccount *transport_account;
3244 ModestMailOperation *mail_operation;
3246 gchar *account_name;
3247 ModestAccountMgr *account_mgr;
3248 gboolean had_error = FALSE;
3249 ModestMainWindow *win = NULL;
3251 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
3253 data = modest_msg_edit_window_get_msg_data (edit_window);
3256 if (!enough_space_for_message (edit_window, data)) {
3257 modest_msg_edit_window_free_msg_data (edit_window, data);
3261 account_name = g_strdup (data->account_name);
3262 account_mgr = modest_runtime_get_account_mgr();
3264 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3266 account_name = modest_account_mgr_get_default_account (account_mgr);
3267 if (!account_name) {
3268 g_printerr ("modest: no account found\n");
3269 modest_msg_edit_window_free_msg_data (edit_window, data);
3273 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
3274 account_name = g_strdup (data->account_name);
3278 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3279 (modest_runtime_get_account_store (),
3281 TNY_ACCOUNT_TYPE_TRANSPORT));
3282 if (!transport_account) {
3283 g_printerr ("modest: no transport account found for '%s'\n", account_name);
3284 g_free (account_name);
3285 modest_msg_edit_window_free_msg_data (edit_window, data);
3289 /* Create the mail operation */
3290 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
3292 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3294 modest_mail_operation_save_to_drafts (mail_operation,
3306 data->priority_flags,
3309 on_save_to_drafts_cb,
3310 g_object_ref(edit_window));
3312 #ifdef MODEST_TOOLKIT_HILDON2
3313 /* In hildon2 we always show the information banner on saving to drafts.
3314 * It will be a system information banner in this case.
3316 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3317 modest_platform_information_banner (NULL, NULL, text);
3320 /* Use the main window as the parent of the banner, if the
3321 main window does not exist it won't be shown, if the parent
3322 window exists then it's properly shown. We don't use the
3323 editor window because it could be closed (save to drafts
3324 could happen after closing the window */
3325 win = (ModestMainWindow *)
3326 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
3328 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3329 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
3333 modest_msg_edit_window_set_modified (edit_window, FALSE);
3336 g_free (account_name);
3337 g_object_unref (G_OBJECT (transport_account));
3338 g_object_unref (G_OBJECT (mail_operation));
3340 modest_msg_edit_window_free_msg_data (edit_window, data);
3343 * If the drafts folder is selected then make the header view
3344 * insensitive while the message is being saved to drafts
3345 * (it'll be sensitive again in on_save_to_drafts_cb()). This
3346 * is not very clean but it avoids letting the drafts folder
3347 * in an inconsistent state: the user could edit the message
3348 * being saved and undesirable things would happen.
3349 * In the average case the user won't notice anything at
3350 * all. In the worst case (the user is editing a really big
3351 * file from Drafts) the header view will be insensitive
3352 * during the saving process (10 or 20 seconds, depending on
3353 * the message). Anyway this is just a quick workaround: once
3354 * we find a better solution it should be removed
3355 * See NB#65125 (commend #18) for details.
3357 if (!had_error && win != NULL) {
3358 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
3359 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
3361 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
3363 if (modest_tny_folder_is_local_folder(folder)) {
3364 TnyFolderType folder_type;
3365 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
3366 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
3367 GtkWidget *hdrview = modest_main_window_get_child_widget(
3368 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3369 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
3373 if (folder != NULL) g_object_unref(folder);
3380 /* For instance, when clicking the Send toolbar button when editing a message: */
3382 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3384 TnyTransportAccount *transport_account = NULL;
3385 gboolean had_error = FALSE, add_to_contacts;
3387 ModestAccountMgr *account_mgr;
3388 gchar *account_name;
3389 ModestMailOperation *mail_operation;
3392 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
3394 /* Check whether to automatically add new contacts to addressbook or not */
3395 add_to_contacts = modest_conf_get_bool (modest_runtime_get_conf (),
3396 MODEST_CONF_AUTO_ADD_TO_CONTACTS, NULL);
3397 if (!modest_msg_edit_window_check_names (edit_window, add_to_contacts))
3400 data = modest_msg_edit_window_get_msg_data (edit_window);
3402 recipients = g_strconcat (data->to?data->to:"",
3403 data->cc?data->cc:"",
3404 data->bcc?data->bcc:"",
3406 if (recipients == NULL || recipients[0] == '\0') {
3407 /* Empty subject -> no send */
3408 g_free (recipients);
3409 modest_msg_edit_window_free_msg_data (edit_window, data);
3412 g_free (recipients);
3415 if (!enough_space_for_message (edit_window, data)) {
3416 modest_msg_edit_window_free_msg_data (edit_window, data);
3420 account_mgr = modest_runtime_get_account_mgr();
3421 account_name = g_strdup (data->account_name);
3423 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3426 account_name = modest_account_mgr_get_default_account (account_mgr);
3428 if (!account_name) {
3429 modest_msg_edit_window_free_msg_data (edit_window, data);
3430 /* Run account setup wizard */
3431 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
3436 /* Get the currently-active transport account for this modest account: */
3437 if (account_name && strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
3439 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3440 (modest_runtime_get_account_store (),
3441 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
3444 if (!transport_account) {
3445 modest_msg_edit_window_free_msg_data (edit_window, data);
3446 /* Run account setup wizard */
3447 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
3452 /* Create the mail operation */
3453 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
3454 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3456 modest_mail_operation_send_new_mail (mail_operation,
3470 data->priority_flags);
3472 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3473 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
3475 if (modest_mail_operation_get_error (mail_operation) != NULL) {
3476 const GError *error = modest_mail_operation_get_error (mail_operation);
3477 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3478 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3479 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3480 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3486 g_free (account_name);
3487 g_object_unref (G_OBJECT (transport_account));
3488 g_object_unref (G_OBJECT (mail_operation));
3490 modest_msg_edit_window_free_msg_data (edit_window, data);
3493 modest_msg_edit_window_set_sent (edit_window, TRUE);
3495 /* Save settings and close the window: */
3496 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3503 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3504 ModestMsgEditWindow *window)
3506 ModestMsgEditFormatState *format_state = NULL;
3508 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3509 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3511 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3514 format_state = modest_msg_edit_window_get_format_state (window);
3515 g_return_if_fail (format_state != NULL);
3517 format_state->bold = gtk_toggle_action_get_active (action);
3518 modest_msg_edit_window_set_format_state (window, format_state);
3519 g_free (format_state);
3524 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3525 ModestMsgEditWindow *window)
3527 ModestMsgEditFormatState *format_state = NULL;
3529 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3530 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3532 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3535 format_state = modest_msg_edit_window_get_format_state (window);
3536 g_return_if_fail (format_state != NULL);
3538 format_state->italics = gtk_toggle_action_get_active (action);
3539 modest_msg_edit_window_set_format_state (window, format_state);
3540 g_free (format_state);
3545 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3546 ModestMsgEditWindow *window)
3548 ModestMsgEditFormatState *format_state = NULL;
3550 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3551 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3553 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3556 format_state = modest_msg_edit_window_get_format_state (window);
3557 g_return_if_fail (format_state != NULL);
3559 format_state->bullet = gtk_toggle_action_get_active (action);
3560 modest_msg_edit_window_set_format_state (window, format_state);
3561 g_free (format_state);
3566 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3567 GtkRadioAction *selected,
3568 ModestMsgEditWindow *window)
3570 ModestMsgEditFormatState *format_state = NULL;
3571 GtkJustification value;
3573 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3575 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3578 value = gtk_radio_action_get_current_value (selected);
3580 format_state = modest_msg_edit_window_get_format_state (window);
3581 g_return_if_fail (format_state != NULL);
3583 format_state->justification = value;
3584 modest_msg_edit_window_set_format_state (window, format_state);
3585 g_free (format_state);
3589 modest_ui_actions_on_select_editor_color (GtkAction *action,
3590 ModestMsgEditWindow *window)
3592 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3593 g_return_if_fail (GTK_IS_ACTION (action));
3595 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3598 modest_msg_edit_window_select_color (window);
3602 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3603 ModestMsgEditWindow *window)
3605 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3606 g_return_if_fail (GTK_IS_ACTION (action));
3608 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3611 modest_msg_edit_window_select_background_color (window);
3615 modest_ui_actions_on_insert_image (GObject *object,
3616 ModestMsgEditWindow *window)
3618 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3621 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3624 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3627 modest_msg_edit_window_insert_image (window);
3631 modest_ui_actions_on_attach_file (GtkAction *action,
3632 ModestMsgEditWindow *window)
3634 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3635 g_return_if_fail (GTK_IS_ACTION (action));
3637 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3640 modest_msg_edit_window_offer_attach_file (window);
3644 modest_ui_actions_on_remove_attachments (GtkAction *action,
3645 ModestMsgEditWindow *window)
3647 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3649 modest_msg_edit_window_remove_attachments (window, NULL);
3653 do_create_folder_cb (ModestMailOperation *mail_op,
3654 TnyFolderStore *parent_folder,
3655 TnyFolder *new_folder,
3658 gchar *suggested_name = (gchar *) user_data;
3659 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3660 const GError *error;
3662 error = modest_mail_operation_get_error (mail_op);
3664 gboolean disk_full = FALSE;
3665 TnyAccount *account;
3666 /* Show an error. If there was some problem writing to
3667 disk, show it, otherwise show the generic folder
3668 create error. We do it here and not in an error
3669 handler because the call to do_create_folder will
3670 stop the main loop in a gtk_dialog_run and then,
3671 the message won't be shown until that dialog is
3673 account = modest_mail_operation_get_account (mail_op);
3676 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3677 (GtkWidget *) source_win,
3680 _("mail_in_ui_folder_create_error_memory"));
3681 g_object_unref (account);
3684 /* Show an error and try again if there is no
3685 full memory condition */
3686 modest_platform_information_banner ((GtkWidget *) source_win, NULL,
3687 _("mail_in_ui_folder_create_error"));
3688 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3692 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3693 * FIXME: any other? */
3694 GtkWidget *folder_view;
3696 if (MODEST_IS_MAIN_WINDOW(source_win))
3698 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3699 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3701 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3702 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3704 /* Select the newly created folder. It could happen
3705 that the widget is no longer there (i.e. the window
3706 has been destroyed, so we need to check this */
3708 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3710 g_object_unref (new_folder);
3712 /* Free. Note that the first time it'll be NULL so noop */
3713 g_free (suggested_name);
3714 g_object_unref (source_win);
3719 TnyFolderStore *parent;
3720 } CreateFolderConnect;
3723 do_create_folder_performer (gboolean canceled,
3725 GtkWindow *parent_window,
3726 TnyAccount *account,
3729 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3730 ModestMailOperation *mail_op;
3732 if (canceled || err) {
3733 /* In disk full conditions we could get this error here */
3734 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3735 (GtkWidget *) parent_window, err,
3736 NULL, _("mail_in_ui_folder_create_error_memory"));
3738 /* This happens if we have selected the outbox folder
3740 if (err && err->code == TNY_SERVICE_ERROR_UNKNOWN &&
3741 TNY_IS_MERGE_FOLDER (helper->parent)) {
3742 /* Show an error and retry */
3743 modest_platform_information_banner ((GtkWidget *) parent_window,
3745 _("mail_in_ui_folder_create_error"));
3747 do_create_folder (parent_window, helper->parent, helper->folder_name);
3753 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3754 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3756 modest_mail_operation_create_folder (mail_op,
3758 (const gchar *) helper->folder_name,
3759 do_create_folder_cb,
3760 g_strdup (helper->folder_name));
3761 g_object_unref (mail_op);
3765 g_object_unref (helper->parent);
3766 if (helper->folder_name)
3767 g_free (helper->folder_name);
3768 g_slice_free (CreateFolderConnect, helper);
3773 do_create_folder (GtkWindow *parent_window,
3774 TnyFolderStore *suggested_parent,
3775 const gchar *suggested_name)
3778 gchar *folder_name = NULL;
3779 TnyFolderStore *parent_folder = NULL;
3781 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3783 (gchar *) suggested_name,
3787 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3788 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3789 helper->folder_name = g_strdup (folder_name);
3790 helper->parent = g_object_ref (parent_folder);
3792 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3795 do_create_folder_performer,
3800 g_free (folder_name);
3802 g_object_unref (parent_folder);
3806 modest_ui_actions_create_folder(GtkWidget *parent_window,
3807 GtkWidget *folder_view,
3808 TnyFolderStore *parent_folder)
3810 if (!parent_folder) {
3811 #ifdef MODEST_TOOLKIT_HILDON2
3812 ModestTnyAccountStore *acc_store;
3814 acc_store = modest_runtime_get_account_store ();
3816 parent_folder = (TnyFolderStore *)
3817 modest_tny_account_store_get_local_folders_account (acc_store);
3819 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3823 if (parent_folder) {
3824 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3825 g_object_unref (parent_folder);
3830 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3833 g_return_if_fail (MODEST_IS_WINDOW(window));
3835 if (MODEST_IS_MAIN_WINDOW (window)) {
3836 GtkWidget *folder_view;
3838 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3839 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3843 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3844 #ifdef MODEST_TOOLKIT_HILDON2
3845 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3846 GtkWidget *folder_view;
3848 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3849 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3852 g_assert_not_reached ();
3857 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3860 const GError *error = NULL;
3861 gchar *message = NULL;
3863 TnyAccount *account = modest_mail_operation_get_account (mail_op);
3865 /* Get error message */
3866 error = modest_mail_operation_get_error (mail_op);
3868 g_return_if_reached ();
3870 mem_full = modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
3871 (GError *) error, account);
3873 message = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3874 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3875 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3876 message = _CS("ckdg_ib_folder_already_exists");
3877 } else if (error->domain == TNY_ERROR_DOMAIN &&
3878 error->code == TNY_SERVICE_ERROR_STATE) {
3879 /* This means that the folder is already in use (a
3880 message is opened for example */
3881 message = _("emev_ni_internal_error");
3883 message = _CS("ckdg_ib_unable_to_rename");
3886 /* We don't set a parent for the dialog because the dialog
3887 will be destroyed so the banner won't appear */
3888 modest_platform_information_banner (NULL, NULL, message);
3891 g_object_unref (account);
3897 TnyFolderStore *folder;
3902 on_rename_folder_cb (ModestMailOperation *mail_op,
3903 TnyFolder *new_folder,
3906 ModestFolderView *folder_view;
3908 /* If the window was closed when renaming a folder, or if
3909 * it's not a main window this will happen */
3910 if (!MODEST_IS_FOLDER_VIEW (user_data))
3913 folder_view = MODEST_FOLDER_VIEW (user_data);
3914 /* Note that if the rename fails new_folder will be NULL */
3916 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3918 modest_folder_view_select_first_inbox_or_local (folder_view);
3920 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3924 on_rename_folder_performer (gboolean canceled,
3926 GtkWindow *parent_window,
3927 TnyAccount *account,
3930 ModestMailOperation *mail_op = NULL;
3931 GtkTreeSelection *sel = NULL;
3932 GtkWidget *folder_view = NULL;
3933 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3935 if (canceled || err) {
3936 /* In disk full conditions we could get this error here */
3937 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3938 (GtkWidget *) parent_window, err,
3943 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3944 modest_ui_actions_rename_folder_error_handler,
3945 parent_window, NULL);
3947 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3950 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3952 folder_view = modest_main_window_get_child_widget (
3953 MODEST_MAIN_WINDOW (parent_window),
3954 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3956 #ifdef MODEST_TOOLKIT_HILDON2
3957 else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3958 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3959 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3963 /* Clear the folders view */
3964 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3965 gtk_tree_selection_unselect_all (sel);
3967 /* Actually rename the folder */
3968 modest_mail_operation_rename_folder (mail_op,
3969 TNY_FOLDER (data->folder),
3970 (const gchar *) (data->new_name),
3971 on_rename_folder_cb,
3973 g_object_unref (mail_op);
3976 g_object_unref (data->folder);
3977 g_free (data->new_name);
3982 modest_ui_actions_on_rename_folder (GtkAction *action,
3983 ModestWindow *window)
3985 modest_ui_actions_on_edit_mode_rename_folder (window);
3989 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3991 TnyFolderStore *folder;
3992 GtkWidget *folder_view;
3993 gboolean do_rename = TRUE;
3995 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3997 if (MODEST_IS_MAIN_WINDOW (window)) {
3998 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3999 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4003 #ifdef MODEST_TOOLKIT_HILDON2
4004 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
4005 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
4011 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
4016 if (TNY_IS_FOLDER (folder)) {
4017 gchar *folder_name = NULL;
4019 const gchar *current_name;
4020 TnyFolderStore *parent;
4022 current_name = tny_folder_get_name (TNY_FOLDER (folder));
4023 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
4024 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
4025 parent, current_name,
4027 g_object_unref (parent);
4029 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
4032 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
4033 rename_folder_data->folder = g_object_ref (folder);
4034 rename_folder_data->new_name = folder_name;
4035 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
4036 folder, on_rename_folder_performer, rename_folder_data);
4039 g_object_unref (folder);
4044 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
4047 GObject *win = modest_mail_operation_get_source (mail_op);
4049 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
4050 _("mail_in_ui_folder_delete_error"),
4052 g_object_unref (win);
4056 TnyFolderStore *folder;
4057 gboolean move_to_trash;
4061 on_delete_folder_cb (gboolean canceled,
4063 GtkWindow *parent_window,
4064 TnyAccount *account,
4067 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
4068 GtkWidget *folder_view;
4069 ModestMailOperation *mail_op;
4070 GtkTreeSelection *sel;
4072 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
4073 /* Note that the connection process can fail due to
4074 memory low conditions as it can not successfully
4075 store the summary */
4076 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4077 (GtkWidget*) parent_window, err,
4079 g_debug ("Error connecting when trying to delete a folder");
4080 g_object_unref (G_OBJECT (info->folder));
4085 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
4086 folder_view = modest_main_window_get_child_widget (
4087 MODEST_MAIN_WINDOW (parent_window),
4088 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4089 #ifdef MODEST_TOOLKIT_HILDON2
4090 } else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
4091 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
4094 g_object_unref (G_OBJECT (info->folder));
4099 /* Unselect the folder before deleting it to free the headers */
4100 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
4101 gtk_tree_selection_unselect_all (sel);
4103 /* Create the mail operation */
4105 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
4106 modest_ui_actions_delete_folder_error_handler,
4109 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4111 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
4113 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
4115 g_object_unref (mail_op);
4116 g_object_unref (info->folder);
4121 delete_folder (ModestWindow *window, gboolean move_to_trash)
4123 TnyFolderStore *folder;
4124 GtkWidget *folder_view;
4128 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
4130 if (MODEST_IS_MAIN_WINDOW (window)) {
4132 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4133 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4134 #ifdef MODEST_TOOLKIT_HILDON2
4135 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
4136 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
4144 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4149 /* Show an error if it's an account */
4150 if (!TNY_IS_FOLDER (folder)) {
4151 modest_platform_run_information_dialog (GTK_WINDOW (window),
4152 _("mail_in_ui_folder_delete_error"),
4154 g_object_unref (G_OBJECT (folder));
4159 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
4160 tny_folder_get_name (TNY_FOLDER (folder)));
4161 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
4162 (const gchar *) message);
4165 if (response == GTK_RESPONSE_OK) {
4166 TnyAccount *account = NULL;
4167 DeleteFolderInfo *info = NULL;
4168 info = g_new0(DeleteFolderInfo, 1);
4169 info->folder = g_object_ref (folder);
4170 info->move_to_trash = move_to_trash;
4172 account = tny_folder_get_account (TNY_FOLDER (folder));
4173 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
4175 TNY_FOLDER_STORE (account),
4176 on_delete_folder_cb, info);
4177 g_object_unref (account);
4178 g_object_unref (folder);
4186 modest_ui_actions_on_delete_folder (GtkAction *action,
4187 ModestWindow *window)
4189 modest_ui_actions_on_edit_mode_delete_folder (window);
4193 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
4195 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
4197 return delete_folder (window, FALSE);
4201 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
4203 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4205 delete_folder (MODEST_WINDOW (main_window), TRUE);
4209 typedef struct _PasswordDialogFields {
4210 GtkWidget *username;
4211 GtkWidget *password;
4213 } PasswordDialogFields;
4216 password_dialog_check_field (GtkEditable *editable,
4217 PasswordDialogFields *fields)
4220 gboolean any_value_empty = FALSE;
4222 #ifdef MODEST_TOOLKIT_HILDON2
4223 value = hildon_entry_get_text (HILDON_ENTRY (fields->username));
4225 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
4227 if ((value == NULL) || value[0] == '\0') {
4228 any_value_empty = TRUE;
4230 #ifdef MODEST_TOOLKIT_HILDON2
4231 value = hildon_entry_get_text (HILDON_ENTRY (fields->password));
4233 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
4235 if ((value == NULL) || value[0] == '\0') {
4236 any_value_empty = TRUE;
4238 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
4242 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
4243 const gchar* server_account_name,
4248 ModestMainWindow *main_window)
4250 g_return_if_fail(server_account_name);
4251 gboolean completed = FALSE;
4252 PasswordDialogFields *fields = NULL;
4254 /* Initalize output parameters: */
4261 #ifndef MODEST_TOOLKIT_GTK
4262 /* Maemo uses a different (awkward) button order,
4263 * It should probably just use gtk_alternative_dialog_button_order ().
4265 #ifdef MODEST_TOOLKIT_HILDON2
4267 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4270 _HL("wdgt_bd_done"),
4271 GTK_RESPONSE_ACCEPT,
4273 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
4274 HILDON_MARGIN_DOUBLE);
4277 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4280 _("mcen_bd_dialog_ok"),
4281 GTK_RESPONSE_ACCEPT,
4282 _("mcen_bd_dialog_cancel"),
4283 GTK_RESPONSE_REJECT,
4285 #endif /* MODEST_TOOLKIT_HILDON2 */
4288 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4292 GTK_RESPONSE_REJECT,
4294 GTK_RESPONSE_ACCEPT,
4296 #endif /* MODEST_TOOLKIT_GTK */
4298 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
4300 gchar *server_name = modest_account_mgr_get_server_account_hostname (
4301 modest_runtime_get_account_mgr(), server_account_name);
4302 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
4303 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
4306 gtk_widget_destroy (dialog);
4310 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
4311 GtkWidget *label = gtk_label_new (txt);
4312 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
4314 g_free (server_name);
4315 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
4320 gchar *initial_username = modest_account_mgr_get_server_account_username (
4321 modest_runtime_get_account_mgr(), server_account_name);
4323 #ifdef MODEST_TOOLKIT_HILDON2
4324 GtkWidget *entry_username = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4325 if (initial_username)
4326 hildon_entry_set_text (HILDON_ENTRY (entry_username), initial_username);
4328 GtkWidget *entry_username = gtk_entry_new ();
4329 if (initial_username)
4330 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
4332 /* Dim this if a connection has ever succeeded with this username,
4333 * as per the UI spec: */
4334 /* const gboolean username_known = */
4335 /* modest_account_mgr_get_server_account_username_has_succeeded( */
4336 /* modest_runtime_get_account_mgr(), server_account_name); */
4337 /* gtk_widget_set_sensitive (entry_username, !username_known); */
4339 /* We drop the username sensitive code and disallow changing it here
4340 * as tinymail does not support really changing the username in the callback
4342 gtk_widget_set_sensitive (entry_username, FALSE);
4344 #ifndef MODEST_TOOLKIT_GTK
4345 /* Auto-capitalization is the default, so let's turn it off: */
4346 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
4348 /* Create a size group to be used by all captions.
4349 * Note that HildonCaption does not create a default size group if we do not specify one.
4350 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
4351 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
4353 #ifdef MODEST_TOOLKIT_HILDON2
4354 GtkWidget *caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4355 _("mail_fi_username"), FALSE,
4358 GtkWidget *caption = hildon_caption_new (sizegroup,
4359 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
4361 gtk_widget_show (entry_username);
4362 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4363 FALSE, FALSE, MODEST_MARGIN_HALF);
4364 gtk_widget_show (caption);
4366 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
4368 #endif /* !MODEST_TOOLKIT_GTK */
4371 #ifdef MODEST_TOOLKIT_HILDON2
4372 GtkWidget *entry_password = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4374 GtkWidget *entry_password = gtk_entry_new ();
4376 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
4377 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
4379 #ifndef MODEST_TOOLKIT_GTK
4380 /* Auto-capitalization is the default, so let's turn it off: */
4381 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
4382 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
4384 #ifdef MODEST_TOOLKIT_HILDON2
4385 caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4386 _("mail_fi_password"), FALSE,
4389 caption = hildon_caption_new (sizegroup,
4390 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
4392 gtk_widget_show (entry_password);
4393 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4394 FALSE, FALSE, MODEST_MARGIN_HALF);
4395 gtk_widget_show (caption);
4396 g_object_unref (sizegroup);
4398 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
4400 #endif /* !MODEST_TOOLKIT_GTK */
4402 if (initial_username != NULL)
4403 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
4405 /* This is not in the Maemo UI spec:
4406 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
4407 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
4411 fields = g_slice_new0 (PasswordDialogFields);
4412 fields->username = entry_username;
4413 fields->password = entry_password;
4414 fields->dialog = dialog;
4416 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
4417 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
4418 password_dialog_check_field (NULL, fields);
4420 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4422 while (!completed) {
4424 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
4426 #ifdef MODEST_TOOLKIT_HILDON2
4427 *username = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_username)));
4429 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
4432 /* Note that an empty field becomes the "" string */
4433 if (*username && strlen (*username) > 0) {
4434 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
4435 server_account_name,
4439 const gboolean username_was_changed =
4440 (strcmp (*username, initial_username) != 0);
4441 if (username_was_changed) {
4442 g_warning ("%s: tinymail does not yet support changing the "
4443 "username in the get_password() callback.\n", __FUNCTION__);
4449 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
4450 _("mcen_ib_username_pw_incorrect"));
4456 #ifdef MODEST_TOOLKIT_HILDON2
4457 *password = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_password)));
4459 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
4462 /* We do not save the password in the configuration,
4463 * because this function is only called for passwords that should
4464 * not be remembered:
4465 modest_server_account_set_password (
4466 modest_runtime_get_account_mgr(), server_account_name,
4473 #ifndef MODEST_TOOLKIT_HILDON2
4474 /* Set parent to NULL or the banner will disappear with its parent dialog */
4475 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
4487 /* This is not in the Maemo UI spec:
4488 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
4494 g_free (initial_username);
4495 gtk_widget_destroy (dialog);
4496 g_slice_free (PasswordDialogFields, fields);
4498 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
4502 modest_ui_actions_on_cut (GtkAction *action,
4503 ModestWindow *window)
4505 GtkWidget *focused_widget;
4506 GtkClipboard *clipboard;
4508 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4509 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4510 if (GTK_IS_EDITABLE (focused_widget)) {
4511 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
4512 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4513 gtk_clipboard_store (clipboard);
4514 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4515 GtkTextBuffer *buffer;
4517 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4518 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4519 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
4520 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4521 gtk_clipboard_store (clipboard);
4523 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4524 TnyList *header_list = modest_header_view_get_selected_headers (
4525 MODEST_HEADER_VIEW (focused_widget));
4526 gboolean continue_download = FALSE;
4527 gint num_of_unc_msgs;
4529 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4531 if (num_of_unc_msgs) {
4532 TnyAccount *account = get_account_from_header_list (header_list);
4534 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4535 g_object_unref (account);
4539 if (num_of_unc_msgs == 0 || continue_download) {
4540 /* modest_platform_information_banner (
4541 NULL, NULL, _CS("mcen_ib_getting_items"));*/
4542 modest_header_view_cut_selection (
4543 MODEST_HEADER_VIEW (focused_widget));
4546 g_object_unref (header_list);
4547 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4548 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4553 modest_ui_actions_on_copy (GtkAction *action,
4554 ModestWindow *window)
4556 GtkClipboard *clipboard;
4557 GtkWidget *focused_widget;
4558 gboolean copied = TRUE;
4560 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4561 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4563 if (GTK_IS_LABEL (focused_widget)) {
4565 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4566 gtk_clipboard_set_text (clipboard, selection, -1);
4568 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4569 gtk_clipboard_store (clipboard);
4570 } else if (GTK_IS_EDITABLE (focused_widget)) {
4571 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4572 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4573 gtk_clipboard_store (clipboard);
4574 } else if (GTK_IS_HTML (focused_widget)) {
4577 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4578 if ((sel == NULL) || (sel[0] == '\0')) {
4581 gtk_html_copy (GTK_HTML (focused_widget));
4582 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4583 gtk_clipboard_store (clipboard);
4585 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4586 GtkTextBuffer *buffer;
4587 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4588 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4589 gtk_text_buffer_copy_clipboard (buffer, clipboard);
4590 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4591 gtk_clipboard_store (clipboard);
4593 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4594 TnyList *header_list = modest_header_view_get_selected_headers (
4595 MODEST_HEADER_VIEW (focused_widget));
4596 gboolean continue_download = FALSE;
4597 gint num_of_unc_msgs;
4599 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4601 if (num_of_unc_msgs) {
4602 TnyAccount *account = get_account_from_header_list (header_list);
4604 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4605 g_object_unref (account);
4609 if (num_of_unc_msgs == 0 || continue_download) {
4610 modest_platform_information_banner (
4611 NULL, NULL, _CS("mcen_ib_getting_items"));
4612 modest_header_view_copy_selection (
4613 MODEST_HEADER_VIEW (focused_widget));
4617 g_object_unref (header_list);
4619 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4620 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4623 /* Show information banner if there was a copy to clipboard */
4625 modest_platform_information_banner (
4626 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4630 modest_ui_actions_on_undo (GtkAction *action,
4631 ModestWindow *window)
4633 ModestEmailClipboard *clipboard = NULL;
4635 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4636 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4637 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4638 /* Clear clipboard source */
4639 clipboard = modest_runtime_get_email_clipboard ();
4640 modest_email_clipboard_clear (clipboard);
4643 g_return_if_reached ();
4648 modest_ui_actions_on_redo (GtkAction *action,
4649 ModestWindow *window)
4651 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4652 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4655 g_return_if_reached ();
4661 destroy_information_note (ModestMailOperation *mail_op,
4664 /* destroy information note */
4665 gtk_widget_destroy (GTK_WIDGET(user_data));
4669 destroy_folder_information_note (ModestMailOperation *mail_op,
4670 TnyFolder *new_folder,
4673 /* destroy information note */
4674 gtk_widget_destroy (GTK_WIDGET(user_data));
4679 paste_as_attachment_free (gpointer data)
4681 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4683 if (helper->banner) {
4684 gtk_widget_destroy (helper->banner);
4685 g_object_unref (helper->banner);
4691 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4696 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4697 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4702 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4707 modest_ui_actions_on_paste (GtkAction *action,
4708 ModestWindow *window)
4710 GtkWidget *focused_widget = NULL;
4711 GtkWidget *inf_note = NULL;
4712 ModestMailOperation *mail_op = NULL;
4714 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4715 if (GTK_IS_EDITABLE (focused_widget)) {
4716 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4717 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4718 ModestEmailClipboard *e_clipboard = NULL;
4719 e_clipboard = modest_runtime_get_email_clipboard ();
4720 if (modest_email_clipboard_cleared (e_clipboard)) {
4721 GtkTextBuffer *buffer;
4722 GtkClipboard *clipboard;
4724 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4725 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4726 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4727 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4728 ModestMailOperation *mail_op;
4729 TnyFolder *src_folder = NULL;
4730 TnyList *data = NULL;
4732 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4733 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4734 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4735 _CS("ckct_nw_pasting"));
4736 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4737 mail_op = modest_mail_operation_new (G_OBJECT (window));
4738 if (helper->banner != NULL) {
4739 g_object_ref (G_OBJECT (helper->banner));
4740 gtk_widget_show (GTK_WIDGET (helper->banner));
4744 modest_mail_operation_get_msgs_full (mail_op,
4746 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4748 paste_as_attachment_free);
4752 g_object_unref (data);
4754 g_object_unref (src_folder);
4757 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4758 ModestEmailClipboard *clipboard = NULL;
4759 TnyFolder *src_folder = NULL;
4760 TnyFolderStore *folder_store = NULL;
4761 TnyList *data = NULL;
4762 gboolean delete = FALSE;
4764 /* Check clipboard source */
4765 clipboard = modest_runtime_get_email_clipboard ();
4766 if (modest_email_clipboard_cleared (clipboard))
4769 /* Get elements to paste */
4770 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4772 /* Create a new mail operation */
4773 mail_op = modest_mail_operation_new (G_OBJECT(window));
4775 /* Get destination folder */
4776 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4778 /* transfer messages */
4782 /* Ask for user confirmation */
4784 modest_ui_actions_msgs_move_to_confirmation (window,
4785 TNY_FOLDER (folder_store),
4789 if (response == GTK_RESPONSE_OK) {
4790 /* Launch notification */
4791 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4792 _CS("ckct_nw_pasting"));
4793 if (inf_note != NULL) {
4794 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4795 gtk_widget_show (GTK_WIDGET(inf_note));
4798 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4799 modest_mail_operation_xfer_msgs (mail_op,
4801 TNY_FOLDER (folder_store),
4803 destroy_information_note,
4806 g_object_unref (mail_op);
4809 } else if (src_folder != NULL) {
4810 /* Launch notification */
4811 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4812 _CS("ckct_nw_pasting"));
4813 if (inf_note != NULL) {
4814 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4815 gtk_widget_show (GTK_WIDGET(inf_note));
4818 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4819 modest_mail_operation_xfer_folder (mail_op,
4823 destroy_folder_information_note,
4829 g_object_unref (data);
4830 if (src_folder != NULL)
4831 g_object_unref (src_folder);
4832 if (folder_store != NULL)
4833 g_object_unref (folder_store);
4839 modest_ui_actions_on_select_all (GtkAction *action,
4840 ModestWindow *window)
4842 GtkWidget *focused_widget;
4844 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4845 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4846 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4847 } else if (GTK_IS_LABEL (focused_widget)) {
4848 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4849 } else if (GTK_IS_EDITABLE (focused_widget)) {
4850 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4851 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4852 GtkTextBuffer *buffer;
4853 GtkTextIter start, end;
4855 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4856 gtk_text_buffer_get_start_iter (buffer, &start);
4857 gtk_text_buffer_get_end_iter (buffer, &end);
4858 gtk_text_buffer_select_range (buffer, &start, &end);
4859 } else if (GTK_IS_HTML (focused_widget)) {
4860 gtk_html_select_all (GTK_HTML (focused_widget));
4861 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4862 GtkWidget *header_view = focused_widget;
4863 GtkTreeSelection *selection = NULL;
4865 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4866 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4867 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4870 /* Disable window dimming management */
4871 modest_window_disable_dimming (MODEST_WINDOW(window));
4873 /* Select all messages */
4874 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4875 gtk_tree_selection_select_all (selection);
4877 /* Set focuse on header view */
4878 gtk_widget_grab_focus (header_view);
4880 /* Enable window dimming management */
4881 modest_window_enable_dimming (MODEST_WINDOW(window));
4882 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4883 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4889 modest_ui_actions_on_mark_as_read (GtkAction *action,
4890 ModestWindow *window)
4892 g_return_if_fail (MODEST_IS_WINDOW(window));
4894 /* Mark each header as read */
4895 do_headers_action (window, headers_action_mark_as_read, NULL);
4899 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4900 ModestWindow *window)
4902 g_return_if_fail (MODEST_IS_WINDOW(window));
4904 /* Mark each header as read */
4905 do_headers_action (window, headers_action_mark_as_unread, NULL);
4909 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4910 GtkRadioAction *selected,
4911 ModestWindow *window)
4915 value = gtk_radio_action_get_current_value (selected);
4916 if (MODEST_IS_WINDOW (window)) {
4917 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4922 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4923 GtkRadioAction *selected,
4924 ModestWindow *window)
4926 TnyHeaderFlags flags;
4927 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4929 flags = gtk_radio_action_get_current_value (selected);
4930 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4934 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4935 GtkRadioAction *selected,
4936 ModestWindow *window)
4940 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4942 file_format = gtk_radio_action_get_current_value (selected);
4943 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4948 modest_ui_actions_on_zoom_plus (GtkAction *action,
4949 ModestWindow *window)
4951 g_return_if_fail (MODEST_IS_WINDOW (window));
4953 modest_window_zoom_plus (MODEST_WINDOW (window));
4957 modest_ui_actions_on_zoom_minus (GtkAction *action,
4958 ModestWindow *window)
4960 g_return_if_fail (MODEST_IS_WINDOW (window));
4962 modest_window_zoom_minus (MODEST_WINDOW (window));
4966 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4967 ModestWindow *window)
4969 ModestWindowMgr *mgr;
4970 gboolean fullscreen, active;
4971 g_return_if_fail (MODEST_IS_WINDOW (window));
4973 mgr = modest_runtime_get_window_mgr ();
4975 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4976 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4978 if (active != fullscreen) {
4979 modest_window_mgr_set_fullscreen_mode (mgr, active);
4980 #ifndef MODEST_TOOLKIT_HILDON2
4981 gtk_window_present (GTK_WINDOW (window));
4987 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4988 ModestWindow *window)
4990 ModestWindowMgr *mgr;
4991 gboolean fullscreen;
4993 g_return_if_fail (MODEST_IS_WINDOW (window));
4995 mgr = modest_runtime_get_window_mgr ();
4996 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4997 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4999 #ifndef MODEST_TOOLKIT_HILDON2
5000 gtk_window_present (GTK_WINDOW (window));
5005 * Used by modest_ui_actions_on_details to call do_headers_action
5008 headers_action_show_details (TnyHeader *header,
5009 ModestWindow *window,
5013 gboolean async_retrieval;
5016 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5017 async_retrieval = TRUE;
5018 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
5019 async_retrieval = !TNY_IS_CAMEL_BS_MSG (msg);
5021 async_retrieval = FALSE;
5023 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header, async_retrieval, msg);
5025 g_object_unref (msg);
5029 * Show the header details in a ModestDetailsDialog widget
5032 modest_ui_actions_on_details (GtkAction *action,
5035 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
5039 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
5043 header = tny_msg_get_header (msg);
5045 headers_action_show_details (header, win, NULL);
5046 g_object_unref (header);
5048 g_object_unref (msg);
5050 } else if (MODEST_IS_MAIN_WINDOW (win)) {
5051 GtkWidget *folder_view, *header_view;
5053 /* Check which widget has the focus */
5054 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5055 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5056 if (gtk_widget_is_focus (folder_view)) {
5057 TnyFolderStore *folder_store
5058 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5059 if (!folder_store) {
5060 g_warning ("%s: No item was selected.\n", __FUNCTION__);
5063 /* Show only when it's a folder */
5064 /* This function should not be called for account items,
5065 * because we dim the menu item for them. */
5066 if (TNY_IS_FOLDER (folder_store)) {
5067 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
5068 TNY_FOLDER (folder_store));
5071 g_object_unref (folder_store);
5074 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5075 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5076 /* Show details of each header */
5077 do_headers_action (win, headers_action_show_details, header_view);
5079 #ifdef MODEST_TOOLKIT_HILDON2
5080 } else if (MODEST_IS_HEADER_WINDOW (win)) {
5082 GtkWidget *header_view;
5084 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
5085 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
5087 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
5089 g_object_unref (folder);
5096 modest_ui_actions_on_limit_error (GtkAction *action,
5099 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
5101 modest_platform_information_banner ((GtkWidget *) win, NULL, _CS("ckdg_ib_maximum_characters_reached"));
5106 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
5107 ModestMsgEditWindow *window)
5109 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5111 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
5115 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
5116 ModestMsgEditWindow *window)
5118 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5120 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
5124 modest_ui_actions_toggle_folders_view (GtkAction *action,
5125 ModestMainWindow *main_window)
5127 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
5129 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
5130 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
5132 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
5136 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
5137 ModestWindow *window)
5139 gboolean active, fullscreen = FALSE;
5140 ModestWindowMgr *mgr;
5142 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
5144 /* Check if we want to toggle the toolbar view in fullscreen
5146 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
5147 "ViewShowToolbarFullScreen")) {
5151 /* Toggle toolbar */
5152 mgr = modest_runtime_get_window_mgr ();
5153 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
5157 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
5158 ModestMsgEditWindow *window)
5160 modest_msg_edit_window_select_font (window);
5165 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
5166 const gchar *display_name,
5169 /* don't update the display name if it was already set;
5170 * updating the display name apparently is expensive */
5171 const gchar* old_name = gtk_window_get_title (window);
5173 if (display_name == NULL)
5176 if (old_name && display_name && strcmp (old_name, display_name) == 0)
5177 return; /* don't do anything */
5179 /* This is usually used to change the title of the main window, which
5180 * is the one that holds the folder view. Note that this change can
5181 * happen even when the widget doesn't have the focus. */
5182 gtk_window_set_title (window, display_name);
5187 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
5189 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5190 modest_msg_edit_window_select_contacts (window);
5194 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
5196 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5197 modest_msg_edit_window_check_names (window, FALSE);
5200 #ifndef MODEST_TOOLKIT_HILDON2
5202 * This function is used to track changes in the selection of the
5203 * folder view that is inside the "move to" dialog to enable/disable
5204 * the OK button because we do not want the user to select a disallowed
5205 * destination for a folder.
5206 * The user also not desired to be able to use NEW button on items where
5207 * folder creation is not possibel.
5210 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
5211 TnyFolderStore *folder_store,
5215 GtkWidget *dialog = NULL;
5216 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
5217 gboolean moving_folder = FALSE;
5218 gboolean is_local_account = TRUE;
5219 GtkWidget *folder_view = NULL;
5220 ModestTnyFolderRules rules;
5222 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
5227 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
5231 /* check if folder_store is an remote account */
5232 if (TNY_IS_ACCOUNT (folder_store)) {
5233 TnyAccount *local_account = NULL;
5234 TnyAccount *mmc_account = NULL;
5235 ModestTnyAccountStore *account_store = NULL;
5237 account_store = modest_runtime_get_account_store ();
5238 local_account = modest_tny_account_store_get_local_folders_account (account_store);
5239 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
5241 if ((gpointer) local_account != (gpointer) folder_store &&
5242 (gpointer) mmc_account != (gpointer) folder_store) {
5243 ModestProtocolType proto;
5244 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
5245 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
5246 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
5248 is_local_account = FALSE;
5249 /* New button should be dimmed on remote
5251 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5253 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
5255 g_object_unref (local_account);
5257 /* It could not exist */
5259 g_object_unref (mmc_account);
5262 /* Check the target folder rules */
5263 if (TNY_IS_FOLDER (folder_store)) {
5264 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
5265 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
5266 ok_sensitive = FALSE;
5267 new_sensitive = FALSE;
5272 /* Check if we're moving a folder */
5273 if (MODEST_IS_MAIN_WINDOW (user_data)) {
5274 /* Get the widgets */
5275 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
5276 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5277 if (gtk_widget_is_focus (folder_view))
5278 moving_folder = TRUE;
5281 if (moving_folder) {
5282 TnyFolderStore *moved_folder = NULL, *parent = NULL;
5284 /* Get the folder to move */
5285 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5287 /* Check that we're not moving to the same folder */
5288 if (TNY_IS_FOLDER (moved_folder)) {
5289 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
5290 if (parent == folder_store)
5291 ok_sensitive = FALSE;
5292 g_object_unref (parent);
5295 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
5296 /* Do not allow to move to an account unless it's the
5297 local folders account */
5298 if (!is_local_account)
5299 ok_sensitive = FALSE;
5302 if (ok_sensitive && (moved_folder == folder_store)) {
5303 /* Do not allow to move to itself */
5304 ok_sensitive = FALSE;
5306 g_object_unref (moved_folder);
5308 TnyFolder *src_folder = NULL;
5310 /* Moving a message */
5311 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
5313 TnyHeader *header = NULL;
5314 header = modest_msg_view_window_get_header
5315 (MODEST_MSG_VIEW_WINDOW (user_data));
5316 if (!TNY_IS_HEADER(header))
5317 g_warning ("%s: could not get source header", __FUNCTION__);
5319 src_folder = tny_header_get_folder (header);
5322 g_object_unref (header);
5325 TNY_FOLDER (modest_folder_view_get_selected
5326 (MODEST_FOLDER_VIEW (folder_view)));
5329 if (TNY_IS_FOLDER(src_folder)) {
5330 /* Do not allow to move the msg to the same folder */
5331 /* Do not allow to move the msg to an account */
5332 if ((gpointer) src_folder == (gpointer) folder_store ||
5333 TNY_IS_ACCOUNT (folder_store))
5334 ok_sensitive = FALSE;
5335 g_object_unref (src_folder);
5337 g_warning ("%s: could not get source folder", __FUNCTION__);
5341 /* Set sensitivity of the OK and NEW button */
5342 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
5343 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
5348 on_move_to_dialog_response (GtkDialog *dialog,
5352 GtkWidget *parent_win;
5353 MoveToInfo *helper = NULL;
5354 ModestFolderView *folder_view;
5355 gboolean unset_edit_mode = FALSE;
5357 helper = (MoveToInfo *) user_data;
5359 parent_win = (GtkWidget *) helper->win;
5360 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
5361 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
5363 TnyFolderStore *dst_folder;
5364 TnyFolderStore *selected;
5366 case MODEST_GTK_RESPONSE_NEW_FOLDER:
5367 selected = modest_folder_view_get_selected (folder_view);
5368 modest_ui_actions_create_folder (GTK_WIDGET (dialog), GTK_WIDGET (folder_view), selected);
5369 g_object_unref (selected);
5371 case GTK_RESPONSE_NONE:
5372 case GTK_RESPONSE_CANCEL:
5373 case GTK_RESPONSE_DELETE_EVENT:
5375 case GTK_RESPONSE_OK:
5376 dst_folder = modest_folder_view_get_selected (folder_view);
5378 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
5379 /* Clean list to move used for filtering */
5380 modest_folder_view_set_list_to_move (folder_view, NULL);
5382 modest_ui_actions_on_main_window_move_to (NULL,
5383 GTK_WIDGET (folder_view),
5385 MODEST_MAIN_WINDOW (parent_win));
5386 #ifdef MODEST_TOOLKIT_HILDON2
5387 } else if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
5388 /* Clean list to move used for filtering */
5389 modest_folder_view_set_list_to_move (folder_view, NULL);
5391 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
5394 GTK_WINDOW (parent_win));
5397 /* if the user selected a root folder
5398 (account) then do not perform any action */
5399 if (TNY_IS_ACCOUNT (dst_folder)) {
5400 g_signal_stop_emission_by_name (dialog, "response");
5404 /* Clean list to move used for filtering */
5405 modest_folder_view_set_list_to_move (folder_view, NULL);
5407 /* Moving from headers window in edit mode */
5408 modest_ui_actions_on_window_move_to (NULL, helper->list,
5410 MODEST_WINDOW (parent_win));
5414 g_object_unref (dst_folder);
5416 unset_edit_mode = TRUE;
5419 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
5422 /* Free the helper and exit */
5424 g_object_unref (helper->list);
5425 if (unset_edit_mode) {
5426 #ifdef MODEST_TOOLKIT_HILDON2
5427 modest_hildon2_window_unset_edit_mode (MODEST_HILDON2_WINDOW (helper->win));
5430 g_slice_free (MoveToInfo, helper);
5431 gtk_widget_destroy (GTK_WIDGET (dialog));
5435 create_move_to_dialog (GtkWindow *win,
5436 GtkWidget *folder_view,
5437 TnyList *list_to_move)
5439 GtkWidget *dialog, *tree_view = NULL;
5441 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
5443 #ifndef MODEST_TOOLKIT_HILDON2
5444 /* Track changes in the selection to
5445 * disable the OK button whenever "Move to" is not possible
5446 * disbale NEW button whenever New is not possible */
5447 g_signal_connect (tree_view,
5448 "folder_selection_changed",
5449 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
5453 /* It could happen that we're trying to move a message from a
5454 window (msg window for example) after the main window was
5455 closed, so we can not just get the model of the folder
5457 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
5458 const gchar *visible_id = NULL;
5460 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5461 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5462 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
5463 MODEST_FOLDER_VIEW(tree_view));
5466 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
5468 /* Show the same account than the one that is shown in the main window */
5469 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
5472 const gchar *active_account_name = NULL;
5473 ModestAccountMgr *mgr = NULL;
5474 ModestAccountSettings *settings = NULL;
5475 ModestServerAccountSettings *store_settings = NULL;
5477 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5478 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5480 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
5481 mgr = modest_runtime_get_account_mgr ();
5482 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
5485 const gchar *store_account_name;
5486 store_settings = modest_account_settings_get_store_settings (settings);
5487 store_account_name = modest_server_account_settings_get_account_name (store_settings);
5489 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
5490 store_account_name);
5491 g_object_unref (store_settings);
5492 g_object_unref (settings);
5496 /* we keep a pointer to the embedded folder view, so we can
5497 * retrieve it with get_folder_view_from_move_to_dialog (see
5498 * above) later (needed for focus handling)
5500 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
5502 /* Hide special folders */
5503 #ifndef MODEST_TOOLKIT_HILDON2
5504 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
5507 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
5508 #ifndef MODEST_TOOLKIT_HILDON2
5509 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5512 gtk_widget_show (GTK_WIDGET (tree_view));
5518 * Shows a confirmation dialog to the user when we're moving messages
5519 * from a remote server to the local storage. Returns the dialog
5520 * response. If it's other kind of movement then it always returns
5523 * This one is used by the next functions:
5524 * modest_ui_actions_on_paste - commented out
5525 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
5528 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
5529 TnyFolder *dest_folder,
5533 gint response = GTK_RESPONSE_OK;
5534 TnyAccount *account = NULL;
5535 TnyFolder *src_folder = NULL;
5536 TnyIterator *iter = NULL;
5537 TnyHeader *header = NULL;
5539 /* return with OK if the destination is a remote folder */
5540 if (modest_tny_folder_is_remote_folder (dest_folder))
5541 return GTK_RESPONSE_OK;
5543 /* Get source folder */
5544 iter = tny_list_create_iterator (headers);
5545 header = TNY_HEADER (tny_iterator_get_current (iter));
5547 src_folder = tny_header_get_folder (header);
5548 g_object_unref (header);
5550 g_object_unref (iter);
5552 /* if no src_folder, message may be an attahcment */
5553 if (src_folder == NULL)
5554 return GTK_RESPONSE_CANCEL;
5556 /* If the source is a local or MMC folder */
5557 if (!modest_tny_folder_is_remote_folder (src_folder)) {
5558 g_object_unref (src_folder);
5559 return GTK_RESPONSE_OK;
5562 /* Get the account */
5563 account = tny_folder_get_account (src_folder);
5565 /* now if offline we ask the user */
5566 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
5567 response = GTK_RESPONSE_OK;
5569 response = GTK_RESPONSE_CANCEL;
5572 g_object_unref (src_folder);
5573 g_object_unref (account);
5579 move_to_helper_destroyer (gpointer user_data)
5581 MoveToHelper *helper = (MoveToHelper *) user_data;
5583 /* Close the "Pasting" information banner */
5584 if (helper->banner) {
5585 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5586 g_object_unref (helper->banner);
5588 if (gtk_tree_row_reference_valid (helper->reference)) {
5589 gtk_tree_row_reference_free (helper->reference);
5590 helper->reference = NULL;
5596 move_to_cb (ModestMailOperation *mail_op,
5599 MoveToHelper *helper = (MoveToHelper *) user_data;
5600 GObject *object = modest_mail_operation_get_source (mail_op);
5602 /* Note that the operation could have failed, in that case do
5604 if (modest_mail_operation_get_status (mail_op) !=
5605 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5608 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5609 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5611 if (!modest_msg_view_window_select_next_message (self) &&
5612 !modest_msg_view_window_select_previous_message (self)) {
5613 /* No more messages to view, so close this window */
5614 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5616 } else if (MODEST_IS_MAIN_WINDOW (object) &&
5617 gtk_tree_row_reference_valid (helper->reference)) {
5618 GtkWidget *header_view;
5620 GtkTreeSelection *sel;
5622 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5623 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5624 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5625 path = gtk_tree_row_reference_get_path (helper->reference);
5626 /* We need to unselect the previous one
5627 because we could be copying instead of
5629 gtk_tree_selection_unselect_all (sel);
5630 gtk_tree_selection_select_path (sel, path);
5631 gtk_tree_path_free (path);
5633 g_object_unref (object);
5636 /* Destroy the helper */
5637 move_to_helper_destroyer (helper);
5641 folder_move_to_cb (ModestMailOperation *mail_op,
5642 TnyFolder *new_folder,
5645 GtkWidget *folder_view;
5648 object = modest_mail_operation_get_source (mail_op);
5649 if (MODEST_IS_MAIN_WINDOW (object)) {
5650 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5651 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5652 g_object_ref (folder_view);
5653 g_object_unref (object);
5654 move_to_cb (mail_op, user_data);
5655 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5656 g_object_unref (folder_view);
5658 move_to_cb (mail_op, user_data);
5663 msgs_move_to_cb (ModestMailOperation *mail_op,
5666 move_to_cb (mail_op, user_data);
5670 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5673 GObject *win = NULL;
5674 const GError *error;
5675 TnyAccount *account = NULL;
5677 #ifndef MODEST_TOOLKIT_HILDON2
5678 ModestWindow *main_window = NULL;
5680 /* Disable next automatic folder selection */
5681 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5682 FALSE); /* don't create */
5684 /* Show notification dialog only if the main window exists */
5686 GtkWidget *folder_view = NULL;
5688 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5689 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5690 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5692 if (user_data && TNY_IS_FOLDER (user_data)) {
5693 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5694 TNY_FOLDER (user_data), FALSE);
5698 win = modest_mail_operation_get_source (mail_op);
5699 error = modest_mail_operation_get_error (mail_op);
5701 if (TNY_IS_FOLDER (user_data))
5702 account = modest_tny_folder_get_account (TNY_FOLDER (user_data));
5703 else if (TNY_IS_ACCOUNT (user_data))
5704 account = g_object_ref (user_data);
5706 /* If it's not a disk full error then show a generic error */
5707 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5708 (GtkWidget *) win, (GError *) error,
5710 modest_platform_run_information_dialog ((GtkWindow *) win,
5711 _("mail_in_ui_folder_move_target_error"),
5714 g_object_unref (account);
5716 g_object_unref (win);
5720 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5729 gint pending_purges = 0;
5730 gboolean some_purged = FALSE;
5731 ModestWindow *win = MODEST_WINDOW (user_data);
5732 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5734 /* If there was any error */
5735 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5736 modest_window_mgr_unregister_header (mgr, header);
5740 /* Once the message has been retrieved for purging, we check if
5741 * it's all ok for purging */
5743 parts = tny_simple_list_new ();
5744 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5745 iter = tny_list_create_iterator (parts);
5747 while (!tny_iterator_is_done (iter)) {
5749 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5750 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5751 if (tny_mime_part_is_purged (part))
5758 g_object_unref (part);
5760 tny_iterator_next (iter);
5762 g_object_unref (iter);
5765 if (pending_purges>0) {
5767 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5769 if (response == GTK_RESPONSE_OK) {
5772 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5773 iter = tny_list_create_iterator (parts);
5774 while (!tny_iterator_is_done (iter)) {
5777 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5778 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5779 tny_mime_part_set_purged (part);
5782 g_object_unref (part);
5784 tny_iterator_next (iter);
5786 g_object_unref (iter);
5788 tny_msg_rewrite_cache (msg);
5790 gtk_widget_destroy (info);
5794 modest_window_mgr_unregister_header (mgr, header);
5796 g_object_unref (parts);
5800 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5801 ModestMainWindow *win)
5803 GtkWidget *header_view;
5804 TnyList *header_list;
5806 TnyHeaderFlags flags;
5807 ModestWindow *msg_view_window = NULL;
5810 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5812 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5813 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5815 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5817 g_warning ("%s: no header selected", __FUNCTION__);
5821 if (tny_list_get_length (header_list) == 1) {
5822 TnyIterator *iter = tny_list_create_iterator (header_list);
5823 header = TNY_HEADER (tny_iterator_get_current (iter));
5824 g_object_unref (iter);
5828 if (!header || !TNY_IS_HEADER(header)) {
5829 g_warning ("%s: header is not valid", __FUNCTION__);
5833 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5834 header, &msg_view_window);
5835 flags = tny_header_get_flags (header);
5836 if (!(flags & TNY_HEADER_FLAG_CACHED))
5839 if (msg_view_window != NULL)
5840 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5842 /* do nothing; uid was registered before, so window is probably on it's way */
5843 g_debug ("header %p has already been registered", header);
5846 ModestMailOperation *mail_op = NULL;
5847 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5848 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5849 modest_ui_actions_disk_operations_error_handler,
5851 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5852 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5854 g_object_unref (mail_op);
5857 g_object_unref (header);
5859 g_object_unref (header_list);
5863 * Checks if we need a connection to do the transfer and if the user
5864 * wants to connect to complete it
5867 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5868 TnyFolderStore *src_folder,
5870 TnyFolder *dst_folder,
5871 gboolean delete_originals,
5872 gboolean *need_connection,
5875 TnyAccount *src_account;
5876 gint uncached_msgs = 0;
5878 /* We don't need any further check if
5880 * 1- the source folder is local OR
5881 * 2- the device is already online
5883 if (!modest_tny_folder_store_is_remote (src_folder) ||
5884 tny_device_is_online (modest_runtime_get_device())) {
5885 *need_connection = FALSE;
5890 /* We must ask for a connection when
5892 * - the message(s) is not already cached OR
5893 * - the message(s) is cached but the leave_on_server setting
5894 * is FALSE (because we need to sync the source folder to
5895 * delete the message from the server (for IMAP we could do it
5896 * offline, it'll take place the next time we get a
5899 uncached_msgs = header_list_count_uncached_msgs (headers);
5900 src_account = get_account_from_folder_store (src_folder);
5901 if (uncached_msgs > 0) {
5905 *need_connection = TRUE;
5906 num_headers = tny_list_get_length (headers);
5907 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5909 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5910 GTK_RESPONSE_CANCEL) {
5916 /* The transfer is possible and the user wants to */
5919 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5920 const gchar *account_name;
5921 gboolean leave_on_server;
5923 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5924 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5927 if (leave_on_server == TRUE) {
5928 *need_connection = FALSE;
5930 *need_connection = TRUE;
5933 *need_connection = FALSE;
5938 g_object_unref (src_account);
5942 xfer_messages_error_handler (ModestMailOperation *mail_op,
5946 const GError *error;
5947 TnyAccount *account;
5949 win = modest_mail_operation_get_source (mail_op);
5950 error = modest_mail_operation_get_error (mail_op);
5952 /* We cannot get the account from the mail op as that is the
5953 source account and for checking memory full conditions we
5954 need the destination one */
5955 account = TNY_ACCOUNT (user_data);
5958 !modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5959 (GtkWidget *) win, (GError*) error,
5960 account, _KR("cerm_memory_card_full"))) {
5961 modest_platform_run_information_dialog ((GtkWindow *) win,
5962 _("mail_in_ui_folder_move_target_error"),
5966 g_object_unref (win);
5970 TnyFolderStore *dst_folder;
5975 * Utility function that transfer messages from both the main window
5976 * and the msg view window when using the "Move to" dialog
5979 xfer_messages_performer (gboolean canceled,
5981 GtkWindow *parent_window,
5982 TnyAccount *account,
5985 ModestWindow *win = MODEST_WINDOW (parent_window);
5986 TnyAccount *dst_account = NULL;
5987 gboolean dst_forbids_message_add = FALSE;
5988 XferMsgsHelper *helper;
5989 MoveToHelper *movehelper;
5990 ModestMailOperation *mail_op;
5992 helper = (XferMsgsHelper *) user_data;
5994 if (canceled || err) {
5995 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5996 (GtkWidget *) parent_window, err,
5998 /* Show the proper error message */
5999 modest_ui_actions_on_account_connection_error (parent_window, account);
6004 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
6006 /* tinymail will return NULL for local folders it seems */
6007 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
6008 modest_tny_account_get_protocol_type (dst_account),
6009 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
6011 if (dst_forbids_message_add) {
6012 modest_platform_information_banner (GTK_WIDGET (win),
6014 ngettext("mail_in_ui_folder_move_target_error",
6015 "mail_in_ui_folder_move_targets_error",
6016 tny_list_get_length (helper->headers)));
6020 movehelper = g_new0 (MoveToHelper, 1);
6022 #ifndef MODEST_TOOLKIT_HILDON2
6023 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
6024 _CS("ckct_nw_pasting"));
6025 if (movehelper->banner != NULL) {
6026 g_object_ref (movehelper->banner);
6027 gtk_widget_show (GTK_WIDGET (movehelper->banner));
6031 if (MODEST_IS_MAIN_WINDOW (win)) {
6032 GtkWidget *header_view =
6033 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6034 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6035 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
6038 /* Perform the mail operation */
6039 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
6040 xfer_messages_error_handler,
6041 g_object_ref (dst_account),
6043 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
6046 modest_mail_operation_xfer_msgs (mail_op,
6048 TNY_FOLDER (helper->dst_folder),
6053 g_object_unref (G_OBJECT (mail_op));
6056 g_object_unref (dst_account);
6057 g_object_unref (helper->dst_folder);
6058 g_object_unref (helper->headers);
6059 g_slice_free (XferMsgsHelper, helper);
6063 TnyFolder *src_folder;
6064 TnyFolderStore *dst_folder;
6065 gboolean delete_original;
6066 GtkWidget *folder_view;
6070 on_move_folder_cb (gboolean canceled,
6072 GtkWindow *parent_window,
6073 TnyAccount *account,
6076 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
6077 GtkTreeSelection *sel;
6078 ModestMailOperation *mail_op = NULL;
6080 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
6081 /* Note that the connection process can fail due to
6082 memory low conditions as it can not successfully
6083 store the summary */
6084 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6085 (GtkWidget*) parent_window, err,
6087 g_debug ("Error connecting when trying to move a folder");
6089 g_object_unref (G_OBJECT (info->src_folder));
6090 g_object_unref (G_OBJECT (info->dst_folder));
6095 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
6096 #ifndef MODEST_TOOLKIT_HILDON2
6097 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
6098 _CS("ckct_nw_pasting"));
6099 if (helper->banner != NULL) {
6100 g_object_ref (helper->banner);
6101 gtk_widget_show (GTK_WIDGET(helper->banner));
6104 /* Clean folder on header view before moving it */
6105 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
6106 gtk_tree_selection_unselect_all (sel);
6108 /* Let gtk events run. We need that the folder
6109 view frees its reference to the source
6110 folder *before* issuing the mail operation
6111 so we need the signal handler of selection
6112 changed to happen before the mail
6114 while (gtk_events_pending ())
6115 gtk_main_iteration (); */
6118 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
6119 modest_ui_actions_move_folder_error_handler,
6120 g_object_ref (info->dst_folder), g_object_unref);
6121 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
6124 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
6125 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
6126 TNY_FOLDER (info->dst_folder), TRUE);
6128 modest_mail_operation_xfer_folder (mail_op,
6129 TNY_FOLDER (info->src_folder),
6131 info->delete_original,
6134 g_object_unref (G_OBJECT (info->src_folder));
6136 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
6139 /* Unref mail operation */
6140 g_object_unref (G_OBJECT (mail_op));
6141 g_object_unref (G_OBJECT (info->dst_folder));
6146 get_account_from_folder_store (TnyFolderStore *folder_store)
6148 if (TNY_IS_ACCOUNT (folder_store))
6149 return g_object_ref (folder_store);
6151 return tny_folder_get_account (TNY_FOLDER (folder_store));
6155 * UI handler for the "Move to" action when invoked from the
6159 modest_ui_actions_on_main_window_move_to (GtkAction *action,
6160 GtkWidget *folder_view,
6161 TnyFolderStore *dst_folder,
6162 ModestMainWindow *win)
6164 ModestHeaderView *header_view = NULL;
6165 TnyFolderStore *src_folder = NULL;
6167 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
6169 /* Get the source folder */
6170 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6172 /* Get header view */
6173 header_view = (ModestHeaderView *)
6174 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6176 /* Get folder or messages to transfer */
6177 if (gtk_widget_is_focus (folder_view)) {
6178 gboolean do_xfer = TRUE;
6180 /* Allow only to transfer folders to the local root folder */
6181 if (TNY_IS_ACCOUNT (dst_folder) &&
6182 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
6183 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
6185 } else if (!TNY_IS_FOLDER (src_folder)) {
6186 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
6191 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
6192 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6194 info->src_folder = g_object_ref (src_folder);
6195 info->dst_folder = g_object_ref (dst_folder);
6196 info->delete_original = TRUE;
6197 info->folder_view = folder_view;
6199 connect_info->callback = on_move_folder_cb;
6200 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6201 connect_info->data = info;
6203 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6204 TNY_FOLDER_STORE (src_folder),
6207 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
6210 headers = modest_header_view_get_selected_headers(header_view);
6212 /* Transfer the messages */
6213 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
6214 headers, TNY_FOLDER (dst_folder));
6216 g_object_unref (headers);
6220 g_object_unref (src_folder);
6223 #ifdef MODEST_TOOLKIT_HILDON2
6225 * UI handler for the "Move to" action when invoked from the
6226 * ModestFolderWindow
6229 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
6230 TnyFolderStore *dst_folder,
6234 TnyFolderStore *src_folder = NULL;
6235 TnyIterator *iterator;
6237 if (tny_list_get_length (selection) != 1)
6240 iterator = tny_list_create_iterator (selection);
6241 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
6242 g_object_unref (iterator);
6245 gboolean do_xfer = TRUE;
6247 /* Allow only to transfer folders to the local root folder */
6248 if (TNY_IS_ACCOUNT (dst_folder) &&
6249 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
6250 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
6253 modest_platform_run_information_dialog (win,
6254 _("mail_in_ui_folder_move_target_error"),
6256 } else if (!TNY_IS_FOLDER (src_folder)) {
6257 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
6262 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
6263 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6265 info->src_folder = g_object_ref (src_folder);
6266 info->dst_folder = g_object_ref (dst_folder);
6267 info->delete_original = TRUE;
6268 info->folder_view = folder_view;
6270 connect_info->callback = on_move_folder_cb;
6271 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6272 connect_info->data = info;
6274 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6275 TNY_FOLDER_STORE (src_folder),
6280 g_object_unref (src_folder);
6286 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
6287 TnyFolder *src_folder,
6289 TnyFolder *dst_folder)
6291 gboolean need_connection = TRUE;
6292 gboolean do_xfer = TRUE;
6293 XferMsgsHelper *helper;
6295 g_return_if_fail (TNY_IS_FOLDER (src_folder));
6296 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6297 g_return_if_fail (TNY_IS_LIST (headers));
6299 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
6300 headers, TNY_FOLDER (dst_folder),
6301 TRUE, &need_connection,
6304 /* If we don't want to transfer just return */
6308 /* Create the helper */
6309 helper = g_slice_new (XferMsgsHelper);
6310 helper->dst_folder = g_object_ref (dst_folder);
6311 helper->headers = g_object_ref (headers);
6313 if (need_connection) {
6314 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6315 connect_info->callback = xfer_messages_performer;
6316 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
6317 connect_info->data = helper;
6319 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6320 TNY_FOLDER_STORE (src_folder),
6323 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
6324 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
6325 src_account, helper);
6326 g_object_unref (src_account);
6331 * UI handler for the "Move to" action when invoked from the
6332 * ModestMsgViewWindow
6335 modest_ui_actions_on_window_move_to (GtkAction *action,
6337 TnyFolderStore *dst_folder,
6340 TnyFolder *src_folder = NULL;
6342 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6345 TnyHeader *header = NULL;
6348 iter = tny_list_create_iterator (headers);
6349 header = (TnyHeader *) tny_iterator_get_current (iter);
6350 src_folder = tny_header_get_folder (header);
6352 /* Transfer the messages */
6353 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
6355 TNY_FOLDER (dst_folder));
6358 g_object_unref (header);
6359 g_object_unref (iter);
6360 g_object_unref (src_folder);
6365 modest_ui_actions_on_move_to (GtkAction *action,
6368 modest_ui_actions_on_edit_mode_move_to (win);
6372 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
6374 GtkWidget *dialog = NULL;
6375 MoveToInfo *helper = NULL;
6376 TnyList *list_to_move;
6378 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
6380 #ifndef MODEST_TOOLKIT_HILDON2
6381 /* Get the main window if exists */
6382 ModestMainWindow *main_window;
6383 if (MODEST_IS_MAIN_WINDOW (win))
6384 main_window = MODEST_MAIN_WINDOW (win);
6387 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
6388 FALSE)); /* don't create */
6391 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
6396 if (tny_list_get_length (list_to_move) < 1) {
6397 g_object_unref (list_to_move);
6401 /* Create and run the dialog */
6402 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
6403 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
6404 GTK_WINDOW (dialog),
6408 helper = g_slice_new0 (MoveToInfo);
6409 helper->list = list_to_move;
6412 /* Listen to response signal */
6413 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
6415 /* Show the dialog */
6416 gtk_widget_show (dialog);
6422 * Calls #HeadersFunc for each header already selected in the main
6423 * window or the message currently being shown in the msg view window
6426 do_headers_action (ModestWindow *win,
6430 TnyList *headers_list = NULL;
6431 TnyIterator *iter = NULL;
6432 TnyHeader *header = NULL;
6433 TnyFolder *folder = NULL;
6436 headers_list = get_selected_headers (win);
6440 /* Get the folder */
6441 iter = tny_list_create_iterator (headers_list);
6442 header = TNY_HEADER (tny_iterator_get_current (iter));
6444 folder = tny_header_get_folder (header);
6445 g_object_unref (header);
6448 /* Call the function for each header */
6449 while (!tny_iterator_is_done (iter)) {
6450 header = TNY_HEADER (tny_iterator_get_current (iter));
6451 func (header, win, user_data);
6452 g_object_unref (header);
6453 tny_iterator_next (iter);
6456 /* Trick: do a poke status in order to speed up the signaling
6459 tny_folder_poke_status (folder);
6460 g_object_unref (folder);
6464 g_object_unref (iter);
6465 g_object_unref (headers_list);
6469 modest_ui_actions_view_attachment (GtkAction *action,
6470 ModestWindow *window)
6472 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6473 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
6475 /* not supported window for this action */
6476 g_return_if_reached ();
6481 modest_ui_actions_save_attachments (GtkAction *action,
6482 ModestWindow *window)
6484 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6486 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
6489 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
6491 /* not supported window for this action */
6492 g_return_if_reached ();
6497 modest_ui_actions_remove_attachments (GtkAction *action,
6498 ModestWindow *window)
6500 if (MODEST_IS_MAIN_WINDOW (window)) {
6501 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
6502 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6503 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
6505 /* not supported window for this action */
6506 g_return_if_reached ();
6511 modest_ui_actions_on_settings (GtkAction *action,
6516 dialog = modest_platform_get_global_settings_dialog ();
6517 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
6518 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
6519 gtk_widget_show_all (dialog);
6521 gtk_dialog_run (GTK_DIALOG (dialog));
6523 gtk_widget_destroy (dialog);
6527 modest_ui_actions_on_help (GtkAction *action,
6530 /* Help app is not available at all in fremantle */
6531 #ifndef MODEST_TOOLKIT_HILDON2
6532 const gchar *help_id;
6534 g_return_if_fail (win && GTK_IS_WINDOW(win));
6536 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
6539 modest_platform_show_help (GTK_WINDOW (win), help_id);
6544 modest_ui_actions_on_csm_help (GtkAction *action,
6547 /* Help app is not available at all in fremantle */
6548 #ifndef MODEST_TOOLKIT_HILDON2
6550 const gchar* help_id = NULL;
6551 GtkWidget *folder_view;
6552 TnyFolderStore *folder_store;
6554 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
6556 /* Get selected folder */
6557 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
6558 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6559 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6561 /* Switch help_id */
6562 if (folder_store && TNY_IS_FOLDER (folder_store))
6563 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
6566 g_object_unref (folder_store);
6569 modest_platform_show_help (GTK_WINDOW (win), help_id);
6571 modest_ui_actions_on_help (action, win);
6576 retrieve_contents_cb (ModestMailOperation *mail_op,
6583 /* We only need this callback to show an error in case of
6584 memory low condition */
6585 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
6586 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
6591 retrieve_msg_contents_performer (gboolean canceled,
6593 GtkWindow *parent_window,
6594 TnyAccount *account,
6597 ModestMailOperation *mail_op;
6598 TnyList *headers = TNY_LIST (user_data);
6600 if (err || canceled) {
6601 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6602 (GtkWidget *) parent_window, err,
6607 /* Create mail operation */
6608 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
6609 modest_ui_actions_disk_operations_error_handler,
6611 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
6612 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
6615 g_object_unref (mail_op);
6617 g_object_unref (headers);
6618 g_object_unref (account);
6622 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
6623 ModestWindow *window)
6625 TnyList *headers = NULL;
6626 TnyAccount *account = NULL;
6627 TnyIterator *iter = NULL;
6628 TnyHeader *header = NULL;
6629 TnyFolder *folder = NULL;
6632 headers = get_selected_headers (window);
6636 /* Pick the account */
6637 iter = tny_list_create_iterator (headers);
6638 header = TNY_HEADER (tny_iterator_get_current (iter));
6639 folder = tny_header_get_folder (header);
6640 account = tny_folder_get_account (folder);
6641 g_object_unref (folder);
6642 g_object_unref (header);
6643 g_object_unref (iter);
6645 /* Connect and perform the message retrieval */
6646 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6647 g_object_ref (account),
6648 retrieve_msg_contents_performer,
6649 g_object_ref (headers));
6652 g_object_unref (account);
6653 g_object_unref (headers);
6657 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6659 g_return_if_fail (MODEST_IS_WINDOW (window));
6662 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6666 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6668 g_return_if_fail (MODEST_IS_WINDOW (window));
6671 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6675 modest_ui_actions_on_email_menu_activated (GtkAction *action,
6676 ModestWindow *window)
6678 g_return_if_fail (MODEST_IS_WINDOW (window));
6681 modest_ui_actions_check_menu_dimming_rules (window);
6685 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
6686 ModestWindow *window)
6688 g_return_if_fail (MODEST_IS_WINDOW (window));
6691 modest_ui_actions_check_menu_dimming_rules (window);
6695 modest_ui_actions_on_view_menu_activated (GtkAction *action,
6696 ModestWindow *window)
6698 g_return_if_fail (MODEST_IS_WINDOW (window));
6701 modest_ui_actions_check_menu_dimming_rules (window);
6705 modest_ui_actions_on_format_menu_activated (GtkAction *action,
6706 ModestWindow *window)
6708 g_return_if_fail (MODEST_IS_WINDOW (window));
6711 modest_ui_actions_check_menu_dimming_rules (window);
6715 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
6716 ModestWindow *window)
6718 g_return_if_fail (MODEST_IS_WINDOW (window));
6721 modest_ui_actions_check_menu_dimming_rules (window);
6725 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
6726 ModestWindow *window)
6728 g_return_if_fail (MODEST_IS_WINDOW (window));
6731 modest_ui_actions_check_menu_dimming_rules (window);
6735 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
6736 ModestWindow *window)
6738 g_return_if_fail (MODEST_IS_WINDOW (window));
6741 modest_ui_actions_check_menu_dimming_rules (window);
6745 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
6746 ModestWindow *window)
6748 g_return_if_fail (MODEST_IS_WINDOW (window));
6751 modest_ui_actions_check_menu_dimming_rules (window);
6755 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
6756 ModestWindow *window)
6758 g_return_if_fail (MODEST_IS_WINDOW (window));
6761 modest_ui_actions_check_menu_dimming_rules (window);
6765 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6767 g_return_if_fail (MODEST_IS_WINDOW (window));
6769 /* we check for low-mem; in that case, show a warning, and don't allow
6772 if (modest_platform_check_memory_low (window, TRUE))
6775 modest_platform_show_search_messages (GTK_WINDOW (window));
6779 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6781 g_return_if_fail (MODEST_IS_WINDOW (win));
6784 /* we check for low-mem; in that case, show a warning, and don't allow
6785 * for the addressbook
6787 if (modest_platform_check_memory_low (win, TRUE))
6791 modest_platform_show_addressbook (GTK_WINDOW (win));
6796 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6797 ModestWindow *window)
6800 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6802 if (GTK_IS_TOGGLE_ACTION (action))
6803 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6807 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window),
6812 on_send_receive_finished (ModestMailOperation *mail_op,
6815 GtkWidget *header_view, *folder_view;
6816 TnyFolderStore *folder_store;
6817 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6819 /* Set send/receive operation finished */
6820 modest_main_window_notify_send_receive_completed (main_win);
6822 /* Don't refresh the current folder if there were any errors */
6823 if (modest_mail_operation_get_status (mail_op) !=
6824 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6827 /* Refresh the current folder if we're viewing a window. We do
6828 this because the user won't be able to see the new mails in
6829 the selected folder after a Send&Receive because it only
6830 performs a poke_status, i.e, only the number of read/unread
6831 messages is updated, but the new headers are not
6833 folder_view = modest_main_window_get_child_widget (main_win,
6834 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6838 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6840 /* Do not need to refresh INBOX again because the
6841 update_account does it always automatically */
6842 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6843 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6844 ModestMailOperation *refresh_op;
6846 header_view = modest_main_window_get_child_widget (main_win,
6847 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6849 /* We do not need to set the contents style
6850 because it hasn't changed. We also do not
6851 need to save the widget status. Just force
6853 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6854 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6855 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6856 folder_refreshed_cb, main_win);
6857 g_object_unref (refresh_op);
6861 g_object_unref (folder_store);
6866 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6872 const gchar* server_name = NULL;
6873 TnyTransportAccount *transport;
6874 gchar *message = NULL;
6875 ModestProtocol *protocol;
6877 /* Don't show anything if the user cancelled something or the
6878 * send receive request is not interactive. Authentication
6879 * errors are managed by the account store so no need to show
6880 * a dialog here again */
6881 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6882 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6883 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6887 /* Get the server name. Note that we could be using a
6888 connection specific transport account */
6889 transport = (TnyTransportAccount *)
6890 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
6892 ModestTnyAccountStore *acc_store;
6893 const gchar *acc_name;
6894 TnyTransportAccount *conn_specific;
6896 acc_store = modest_runtime_get_account_store();
6897 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
6898 conn_specific = (TnyTransportAccount *)
6899 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
6900 if (conn_specific) {
6901 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
6902 g_object_unref (conn_specific);
6904 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
6906 g_object_unref (transport);
6910 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
6911 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
6912 tny_account_get_proto (TNY_ACCOUNT (transport)));
6914 g_warning ("%s: Account with no proto", __FUNCTION__);
6918 /* Show the appropriate message text for the GError: */
6919 switch (err->code) {
6920 case TNY_SERVICE_ERROR_CONNECT:
6921 message = modest_protocol_get_translation (protocol,
6922 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
6925 case TNY_SERVICE_ERROR_SEND:
6926 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6928 case TNY_SERVICE_ERROR_UNAVAILABLE:
6929 message = modest_protocol_get_translation (protocol,
6930 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
6934 g_warning ("%s: unexpected ERROR %d",
6935 __FUNCTION__, err->code);
6936 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6940 modest_platform_run_information_dialog (NULL, message, FALSE);
6945 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6950 ModestWindow *top_window = NULL;
6951 ModestWindowMgr *mgr = NULL;
6952 GtkWidget *header_view = NULL;
6953 TnyFolder *selected_folder = NULL;
6954 TnyFolderType folder_type;
6956 mgr = modest_runtime_get_window_mgr ();
6957 top_window = modest_window_mgr_get_current_top (mgr);
6962 #ifndef MODEST_TOOLKIT_HILDON2
6963 if (MODEST_IS_MAIN_WINDOW (top_window)) {
6964 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (top_window),
6965 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6968 if (MODEST_IS_HEADER_WINDOW (top_window)) {
6969 header_view = (GtkWidget *)
6970 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
6974 /* Get selected folder */
6976 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
6977 if (!selected_folder)
6980 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6981 #if GTK_CHECK_VERSION(2, 8, 0)
6982 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
6983 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6984 GtkTreeViewColumn *tree_column;
6986 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6987 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6989 gtk_tree_view_column_queue_resize (tree_column);
6991 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
6992 gtk_widget_queue_draw (header_view);
6995 #ifndef MODEST_TOOLKIT_HILDON2
6996 /* Rerun dimming rules, because the message could become deletable for example */
6997 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6998 MODEST_DIMMING_RULES_TOOLBAR);
6999 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
7000 MODEST_DIMMING_RULES_MENU);
7004 g_object_unref (selected_folder);
7008 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
7009 TnyAccount *account)
7011 ModestProtocolType protocol_type;
7012 ModestProtocol *protocol;
7013 gchar *error_note = NULL;
7015 protocol_type = modest_tny_account_get_protocol_type (account);
7016 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
7019 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
7020 if (error_note == NULL) {
7021 g_warning ("%s: This should not be reached", __FUNCTION__);
7023 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
7024 g_free (error_note);
7029 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
7033 TnyFolderStore *folder = NULL;
7034 TnyAccount *account = NULL;
7035 ModestProtocolType proto;
7036 ModestProtocol *protocol;
7037 TnyHeader *header = NULL;
7039 if (MODEST_IS_MAIN_WINDOW (win)) {
7040 GtkWidget *header_view;
7041 TnyList* headers = NULL;
7043 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
7044 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
7045 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
7046 if (!headers || tny_list_get_length (headers) == 0) {
7048 g_object_unref (headers);
7051 iter = tny_list_create_iterator (headers);
7052 header = TNY_HEADER (tny_iterator_get_current (iter));
7053 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
7054 g_object_unref (iter);
7055 g_object_unref (headers);
7056 #ifdef MODEST_TOOLKIT_HILDON2
7057 } else if (MODEST_IS_HEADER_WINDOW (win)) {
7058 GtkWidget *header_view;
7059 TnyList* headers = NULL;
7061 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
7062 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
7063 if (!headers || tny_list_get_length (headers) == 0) {
7065 g_object_unref (headers);
7068 iter = tny_list_create_iterator (headers);
7069 header = TNY_HEADER (tny_iterator_get_current (iter));
7071 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
7073 g_warning ("List should contain headers");
7075 g_object_unref (iter);
7076 g_object_unref (headers);
7078 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
7079 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
7081 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
7084 if (!header || !folder)
7087 /* Get the account type */
7088 account = tny_folder_get_account (TNY_FOLDER (folder));
7089 proto = modest_tny_account_get_protocol_type (account);
7090 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
7093 subject = tny_header_dup_subject (header);
7094 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
7098 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
7104 g_object_unref (account);
7106 g_object_unref (folder);
7108 g_object_unref (header);
7114 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
7115 const gchar *account_name,
7116 const gchar *account_title)
7118 ModestAccountMgr *account_mgr;
7121 ModestProtocol *protocol;
7122 gboolean removed = FALSE;
7124 g_return_val_if_fail (account_name, FALSE);
7125 g_return_val_if_fail (account_title, FALSE);
7127 account_mgr = modest_runtime_get_account_mgr();
7129 /* The warning text depends on the account type: */
7130 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
7131 modest_account_mgr_get_store_protocol (account_mgr,
7133 txt = modest_protocol_get_translation (protocol,
7134 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
7137 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
7139 response = modest_platform_run_confirmation_dialog (parent_window, txt);
7143 if (response == GTK_RESPONSE_OK) {
7144 /* Remove account. If it succeeds then it also removes
7145 the account from the ModestAccountView: */
7146 gboolean is_default = FALSE;
7147 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
7148 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
7150 g_free (default_account_name);
7152 removed = modest_account_mgr_remove_account (account_mgr, account_name);
7154 #ifdef MODEST_TOOLKIT_HILDON2
7155 hildon_gtk_window_take_screenshot (parent_window, FALSE);
7157 /* Close all email notifications, we cannot
7158 distinguish if the notification belongs to
7159 this account or not, so for safety reasons
7160 we remove them all */
7161 modest_platform_remove_new_mail_notifications (FALSE, account_name);
7163 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
7170 on_fetch_images_performer (gboolean canceled,
7172 GtkWindow *parent_window,
7173 TnyAccount *account,
7176 if (err || canceled) {
7177 /* Show an unable to retrieve images ??? */
7181 /* Note that the user could have closed the window while connecting */
7182 if (GTK_WIDGET_VISIBLE (parent_window))
7183 modest_msg_view_window_fetch_images ((ModestMsgViewWindow *) parent_window);
7184 g_object_unref ((GObject *) user_data);
7188 modest_ui_actions_on_fetch_images (GtkAction *action,
7189 ModestWindow *window)
7191 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
7193 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
7195 on_fetch_images_performer,
7196 g_object_ref (window));
7200 modest_ui_actions_on_reload_message (const gchar *msg_id)
7202 ModestWindow *window = NULL;
7204 g_return_if_fail (msg_id && msg_id[0] != '\0');
7205 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
7211 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
7214 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));
7217 /** Check whether any connections are active, and cancel them if
7219 * Returns TRUE is there was no problem,
7220 * or if an operation was cancelled so we can continue.
7221 * Returns FALSE if the user chose to cancel his request instead.
7225 modest_ui_actions_check_for_active_account (ModestWindow *self,
7226 const gchar* account_name)
7228 ModestTnySendQueue *send_queue;
7229 ModestTnyAccountStore *acc_store;
7230 ModestMailOperationQueue* queue;
7231 TnyConnectionStatus store_conn_status;
7232 TnyAccount *store_account = NULL, *transport_account = NULL;
7233 gboolean retval = TRUE, sending = FALSE;
7235 acc_store = modest_runtime_get_account_store ();
7236 queue = modest_runtime_get_mail_operation_queue ();
7239 modest_tny_account_store_get_server_account (acc_store,
7241 TNY_ACCOUNT_TYPE_STORE);
7243 /* This could happen if the account was deleted before the
7244 call to this function */
7249 modest_tny_account_store_get_server_account (acc_store,
7251 TNY_ACCOUNT_TYPE_TRANSPORT);
7253 /* This could happen if the account was deleted before the
7254 call to this function */
7255 if (!transport_account) {
7256 g_object_unref (store_account);
7260 /* If the transport account was not used yet, then the send
7261 queue could not exist (it's created on demand) */
7262 send_queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (transport_account), FALSE);
7263 if (TNY_IS_SEND_QUEUE (send_queue))
7264 sending = modest_tny_send_queue_sending_in_progress (send_queue);
7266 store_conn_status = tny_account_get_connection_status (store_account);
7267 if (store_conn_status == TNY_CONNECTION_STATUS_CONNECTED || sending) {
7270 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (self),
7271 _("emev_nc_disconnect_account"));
7272 if (response == GTK_RESPONSE_OK) {
7281 /* FIXME: We should only cancel those of this account */
7282 modest_mail_operation_queue_cancel_all (queue);
7284 /* Also disconnect the account */
7285 if ((tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED) &&
7286 (tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)) {
7287 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
7291 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (transport_account),
7297 g_object_unref (store_account);
7298 g_object_unref (transport_account);