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;
845 TnyList *header_pairs;
847 /* we check for low-mem */
848 if (modest_platform_check_memory_low (win, TRUE))
851 available_disk = modest_utils_get_available_space (NULL);
852 parts_count = g_slist_length (attachments);
853 parts_size = count_parts_size (attachments);
854 expected_size = modest_tny_msg_estimate_size (body, NULL, parts_count, parts_size);
856 /* Double check: disk full condition or message too big */
857 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
858 expected_size > available_disk) {
859 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
860 modest_platform_system_banner (NULL, NULL, msg);
866 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
867 modest_platform_run_information_dialog (
869 _("mail_ib_error_attachment_size"),
875 #ifdef MODEST_TOOLKIT_HILDON2
877 account_name = g_strdup (modest_window_get_active_account(win));
880 account_name = modest_account_mgr_get_default_account(mgr);
883 g_printerr ("modest: no account found\n");
888 mailbox = modest_window_get_active_mailbox (win);
891 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
893 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
896 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
898 g_printerr ("modest: failed to find Drafts folder\n");
901 from_str = modest_account_mgr_get_from_string (mgr, account_name, mailbox);
903 g_printerr ("modest: failed get from string for '%s'\n", account_name);
908 recipient = modest_text_utils_get_email_address (from_str);
909 tmp = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr (),
912 signature = modest_text_utils_create_colored_signature (tmp);
916 body = use_signature ? g_strconcat ((body_str) ? body_str : "", signature, NULL) :
919 header_pairs = TNY_LIST (tny_simple_list_new ());
920 msg = modest_tny_msg_new_html_plain (to_str, from_str, cc_str, bcc_str, subject_str,
921 NULL, NULL, body, NULL, NULL, NULL, NULL, header_pairs, NULL);
922 g_object_unref (header_pairs);
925 g_printerr ("modest: failed to create new msg\n");
929 /* Create and register edit window */
930 /* This is destroyed by TODO. */
932 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
933 msg_win = modest_msg_edit_window_new (msg, account_name, mailbox, FALSE);
935 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, win)) {
936 gtk_widget_destroy (GTK_WIDGET (msg_win));
939 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
940 gtk_widget_show_all (GTK_WIDGET (msg_win));
942 while (attachments) {
943 GnomeVFSFileSize att_size;
945 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
946 attachments->data, allowed_size);
947 total_size += att_size;
949 if (att_size > allowed_size) {
950 g_debug ("%s: total size: %u",
951 __FUNCTION__, (unsigned int)total_size);
954 allowed_size -= att_size;
956 attachments = g_slist_next(attachments);
963 g_free (account_name);
965 g_object_unref (G_OBJECT(account));
967 g_object_unref (G_OBJECT(folder));
969 g_object_unref (G_OBJECT(msg));
973 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
975 /* if there are no accounts yet, just show the wizard */
976 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
977 if (!modest_ui_actions_run_account_setup_wizard (win))
980 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
985 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
989 ModestMailOperationStatus status;
991 /* If there is no message or the operation was not successful */
992 status = modest_mail_operation_get_status (mail_op);
993 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
996 /* If it's a memory low issue, then show a banner */
997 error = modest_mail_operation_get_error (mail_op);
998 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
999 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
1000 GObject *source = modest_mail_operation_get_source (mail_op);
1001 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
1002 _KR("memr_ib_operation_disabled"),
1004 g_object_unref (source);
1007 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
1008 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
1009 gchar *subject, *msg, *format = NULL;
1010 TnyAccount *account;
1012 subject = (header) ? tny_header_dup_subject (header) : NULL;
1014 subject = g_strdup (_("mail_va_no_subject"));
1016 account = modest_mail_operation_get_account (mail_op);
1018 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
1019 ModestProtocol *protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), proto);
1022 if (tny_account_get_connection_status (account) ==
1023 TNY_CONNECTION_STATUS_CONNECTED) {
1025 format = modest_protocol_get_translation (protocol,
1026 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE,
1029 format = modest_protocol_get_translation (protocol,
1030 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE_LOST_HEADER);
1033 format = g_strdup_printf (_("mail_ib_backend_server_invalid"),
1034 tny_account_get_hostname (account));
1037 g_object_unref (account);
1042 format = g_strdup (_("emev_ni_ui_imap_message_not_available_in_server"));
1044 format = g_strdup (_("emev_ni_ui_pop3_msg_recv_error"));
1048 msg = g_strdup_printf (format, subject);
1049 modest_platform_run_information_dialog (NULL, msg, FALSE);
1055 /* Remove the header from the preregistered uids */
1056 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1069 } OpenMsgBannerInfo;
1072 GtkTreeModel *model;
1074 ModestWindow *caller_window;
1075 OpenMsgBannerInfo *banner_info;
1076 GtkTreeRowReference *rowref;
1080 open_msg_banner_idle (gpointer userdata)
1082 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
1084 gdk_threads_enter ();
1085 banner_info->idle_handler = 0;
1086 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
1087 if (banner_info->banner)
1088 g_object_ref (banner_info->banner);
1090 gdk_threads_leave ();
1096 get_header_view_from_window (ModestWindow *window)
1098 GtkWidget *header_view;
1100 if (MODEST_IS_MAIN_WINDOW (window)) {
1101 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
1102 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1103 #ifdef MODEST_TOOLKIT_HILDON2
1104 } else if (MODEST_IS_HEADER_WINDOW (window)){
1105 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
1115 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
1118 gchar *account = NULL;
1119 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
1124 folder = tny_header_get_folder (header);
1125 /* Gets folder type (OUTBOX headers will be opened in edit window */
1126 if (modest_tny_folder_is_local_folder (folder)) {
1127 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1128 if (folder_type == TNY_FOLDER_TYPE_INVALID)
1129 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1132 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
1133 TnyTransportAccount *traccount = NULL;
1134 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
1135 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
1137 ModestTnySendQueue *send_queue = NULL;
1138 ModestTnySendQueueStatus status;
1140 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
1141 TNY_ACCOUNT(traccount)));
1142 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
1143 if (TNY_IS_SEND_QUEUE (send_queue)) {
1144 msg_id = modest_tny_send_queue_get_msg_id (header);
1145 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
1147 /* Only open messages in outbox with the editor if they are in Failed state */
1148 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
1151 #ifdef MODEST_TOOLKIT_HILDON2
1153 /* In Fremantle we can not
1154 open any message from
1155 outbox which is not in
1161 g_object_unref(traccount);
1163 g_warning("Cannot get transport account for message in outbox!!");
1165 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
1166 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
1170 TnyAccount *acc = tny_folder_get_account (folder);
1173 g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (acc));
1174 g_object_unref (acc);
1178 g_object_unref (folder);
1184 open_msg_cb (ModestMailOperation *mail_op,
1191 ModestWindowMgr *mgr = NULL;
1192 ModestWindow *parent_win = NULL;
1193 ModestWindow *win = NULL;
1194 gchar *account = NULL;
1195 gboolean open_in_editor = FALSE;
1197 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1199 /* Do nothing if there was any problem with the mail
1200 operation. The error will be shown by the error_handler of
1201 the mail operation */
1202 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1205 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1207 /* Mark header as read */
1208 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1210 account = get_info_from_header (header, &open_in_editor, &can_open);
1214 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1216 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1218 if (open_in_editor) {
1219 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1220 gchar *from_header = NULL, *acc_name;
1221 gchar *mailbox = NULL;
1223 from_header = tny_header_dup_from (header);
1225 /* we cannot edit without a valid account... */
1226 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1227 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1228 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1230 g_free (from_header);
1235 acc_name = modest_utils_get_account_name_from_recipient (from_header, &mailbox);
1236 g_free (from_header);
1242 win = modest_msg_edit_window_new (msg, account, mailbox, TRUE);
1246 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1247 const gchar *mailbox = NULL;
1249 if (parent_win && MODEST_IS_WINDOW (parent_win))
1250 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_win));
1252 if (helper->rowref && helper->model) {
1253 win = modest_msg_view_window_new_with_header_model (msg, account, mailbox, (const gchar*) uid,
1254 helper->model, helper->rowref);
1256 win = modest_msg_view_window_new_for_attachment (msg, NULL, account, mailbox, (const gchar*) uid);
1261 /* Register and show new window */
1263 mgr = modest_runtime_get_window_mgr ();
1264 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1265 gtk_widget_destroy (GTK_WIDGET (win));
1268 gtk_widget_show_all (GTK_WIDGET(win));
1271 /* Update toolbar dimming state */
1272 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1273 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1279 g_object_unref (parent_win);
1283 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1286 const GError *error;
1287 GObject *win = NULL;
1288 ModestMailOperationStatus status;
1290 win = modest_mail_operation_get_source (mail_op);
1291 error = modest_mail_operation_get_error (mail_op);
1292 status = modest_mail_operation_get_status (mail_op);
1294 /* If the mail op has been cancelled then it's not an error:
1295 don't show any message */
1296 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1297 TnyAccount *account = modest_mail_operation_get_account (mail_op);
1298 if (modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
1299 (GError *) error, account)) {
1300 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
1301 modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
1303 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1304 modest_platform_information_banner ((GtkWidget *) win,
1305 NULL, _("emev_ui_imap_inbox_select_error"));
1306 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1307 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1308 modest_platform_information_banner ((GtkWidget *) win,
1309 NULL, _CS ("sfil_ni_unable_to_open_file_not_found"));
1310 } else if (user_data) {
1311 modest_platform_information_banner ((GtkWidget *) win,
1315 g_object_unref (account);
1319 g_object_unref (win);
1323 * Returns the account a list of headers belongs to. It returns a
1324 * *new* reference so don't forget to unref it
1327 get_account_from_header_list (TnyList *headers)
1329 TnyAccount *account = NULL;
1331 if (tny_list_get_length (headers) > 0) {
1332 TnyIterator *iter = tny_list_create_iterator (headers);
1333 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1334 TnyFolder *folder = tny_header_get_folder (header);
1337 g_object_unref (header);
1339 while (!tny_iterator_is_done (iter)) {
1340 header = TNY_HEADER (tny_iterator_get_current (iter));
1341 folder = tny_header_get_folder (header);
1344 g_object_unref (header);
1346 tny_iterator_next (iter);
1351 account = tny_folder_get_account (folder);
1352 g_object_unref (folder);
1356 g_object_unref (header);
1358 g_object_unref (iter);
1364 get_account_from_header (TnyHeader *header)
1366 TnyAccount *account = NULL;
1369 folder = tny_header_get_folder (header);
1372 account = tny_folder_get_account (folder);
1373 g_object_unref (folder);
1379 caller_win_destroyed (OpenMsgHelper *helper, GObject *object)
1381 if (helper->caller_window)
1382 helper->caller_window = NULL;
1386 open_msg_helper_destroyer (gpointer user_data)
1388 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1390 if (helper->caller_window) {
1391 g_object_weak_unref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1392 helper->caller_window = NULL;
1395 if (helper->banner_info) {
1396 g_free (helper->banner_info->message);
1397 if (helper->banner_info->idle_handler > 0) {
1398 g_source_remove (helper->banner_info->idle_handler);
1399 helper->banner_info->idle_handler = 0;
1401 if (helper->banner_info->banner != NULL) {
1402 gtk_widget_destroy (helper->banner_info->banner);
1403 g_object_unref (helper->banner_info->banner);
1404 helper->banner_info->banner = NULL;
1406 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1407 helper->banner_info = NULL;
1409 g_object_unref (helper->model);
1410 g_object_unref (helper->header);
1411 gtk_tree_row_reference_free (helper->rowref);
1412 g_slice_free (OpenMsgHelper, helper);
1416 open_msg_performer(gboolean canceled,
1418 GtkWindow *parent_window,
1419 TnyAccount *account,
1422 ModestMailOperation *mail_op = NULL;
1423 gchar *error_msg = NULL;
1424 ModestProtocolType proto;
1425 TnyConnectionStatus status;
1426 OpenMsgHelper *helper = NULL;
1427 ModestProtocol *protocol;
1428 ModestProtocolRegistry *protocol_registry;
1431 helper = (OpenMsgHelper *) user_data;
1433 status = tny_account_get_connection_status (account);
1434 if (err || canceled || helper->caller_window == NULL) {
1435 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1436 /* Free the helper */
1437 open_msg_helper_destroyer (helper);
1439 /* In disk full conditions we could get this error here */
1440 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
1441 (GtkWidget *) parent_window, err,
1447 /* Get the error message depending on the protocol */
1448 proto = modest_tny_account_get_protocol_type (account);
1449 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1450 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1453 protocol_registry = modest_runtime_get_protocol_registry ();
1454 subject = tny_header_dup_subject (helper->header);
1456 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1457 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1461 if (error_msg == NULL) {
1462 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1465 #ifndef MODEST_TOOLKIT_HILDON2
1466 gboolean show_open_draft = FALSE;
1467 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1469 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1471 TnyFolderType folder_type;
1473 folder = tny_header_get_folder (helper->header);
1474 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1475 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1476 g_object_unref (folder);
1480 #ifdef MODEST_TOOLKIT_HILDON2
1483 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1485 if (!g_strcmp0 (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) ||
1486 !g_strcmp0 (account_name, MODEST_MMC_ACCOUNT_ID)) {
1487 g_free (account_name);
1488 account_name = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_window)));
1492 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1493 g_free (account_name);
1494 open_msg_helper_destroyer (helper);
1499 ModestWindow *window;
1500 GtkWidget *header_view;
1503 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1504 uid = modest_tny_folder_get_header_unique_id (helper->header);
1506 const gchar *mailbox = NULL;
1507 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_window));
1508 window = modest_msg_view_window_new_from_header_view
1509 (MODEST_HEADER_VIEW (header_view), account_name, mailbox, uid, helper->rowref);
1510 if (window != NULL) {
1511 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1513 gtk_widget_destroy (GTK_WIDGET (window));
1515 gtk_widget_show_all (GTK_WIDGET(window));
1519 g_free (account_name);
1521 open_msg_helper_destroyer (helper);
1524 g_free (account_name);
1526 /* Create the mail operation */
1528 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1529 modest_ui_actions_disk_operations_error_handler,
1530 g_strdup (error_msg), g_free);
1531 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1535 #ifndef MODEST_TOOLKIT_HILDON2
1536 if (show_open_draft) {
1537 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1538 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1539 helper->banner_info->banner = NULL;
1540 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1541 helper->banner_info);
1547 headers = TNY_LIST (tny_simple_list_new ());
1548 tny_list_prepend (headers, G_OBJECT (helper->header));
1549 modest_mail_operation_get_msgs_full (mail_op,
1553 open_msg_helper_destroyer);
1554 g_object_unref (headers);
1561 g_object_unref (mail_op);
1562 g_object_unref (account);
1566 * This function is used by both modest_ui_actions_on_open and
1567 * modest_ui_actions_on_header_activated. This way we always do the
1568 * same when trying to open messages.
1571 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1573 ModestWindowMgr *mgr = NULL;
1574 TnyAccount *account;
1575 gboolean cached = FALSE;
1577 GtkWidget *header_view = NULL;
1578 OpenMsgHelper *helper;
1579 ModestWindow *window;
1581 g_return_if_fail (header != NULL && rowref != NULL && gtk_tree_row_reference_valid (rowref));
1583 mgr = modest_runtime_get_window_mgr ();
1586 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1587 if (header_view == NULL)
1590 /* Get the account */
1591 account = get_account_from_header (header);
1596 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1598 /* Do not open again the message and present the
1599 window to the user */
1602 #ifndef MODEST_TOOLKIT_HILDON2
1603 gtk_window_present (GTK_WINDOW (window));
1606 /* the header has been registered already, we don't do
1607 * anything but wait for the window to come up*/
1608 g_debug ("header %p already registered, waiting for window", header);
1613 /* Open each message */
1614 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1616 /* Allways download if we are online. */
1617 if (!tny_device_is_online (modest_runtime_get_device ())) {
1620 /* If ask for user permission to download the messages */
1621 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1622 _("mcen_nc_get_msg"));
1624 /* End if the user does not want to continue */
1625 if (response == GTK_RESPONSE_CANCEL) {
1631 /* We register the window for opening */
1632 modest_window_mgr_register_header (mgr, header, NULL);
1634 /* Create the helper. We need to get a reference to the model
1635 here because it could change while the message is readed
1636 (the user could switch between folders) */
1637 helper = g_slice_new (OpenMsgHelper);
1638 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1639 helper->caller_window = win;
1640 g_object_weak_ref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1641 helper->header = g_object_ref (header);
1642 helper->rowref = gtk_tree_row_reference_copy (rowref);
1643 helper->banner_info = NULL;
1645 /* Connect to the account and perform */
1647 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1648 open_msg_performer, helper);
1650 /* Call directly the performer, do not need to connect */
1651 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1652 g_object_ref (account), helper);
1657 g_object_unref (account);
1661 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1668 /* we check for low-mem; in that case, show a warning, and don't allow
1671 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1675 headers = get_selected_headers (win);
1679 headers_count = tny_list_get_length (headers);
1680 if (headers_count != 1) {
1681 if (headers_count > 1) {
1682 /* Don't allow activation if there are more than one message selected */
1683 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1686 g_object_unref (headers);
1690 iter = tny_list_create_iterator (headers);
1691 header = TNY_HEADER (tny_iterator_get_current (iter));
1692 g_object_unref (iter);
1696 open_msg_from_header (header, NULL, win);
1697 g_object_unref (header);
1700 g_object_unref(headers);
1704 rf_helper_window_closed (gpointer data,
1707 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1709 helper->parent_window = NULL;
1712 static ReplyForwardHelper*
1713 create_reply_forward_helper (ReplyForwardAction action,
1715 guint reply_forward_type,
1718 TnyHeader *top_header,
1721 ReplyForwardHelper *rf_helper = NULL;
1722 const gchar *active_acc = modest_window_get_active_account (win);
1723 const gchar *active_mailbox = modest_window_get_active_mailbox (win);
1725 rf_helper = g_slice_new0 (ReplyForwardHelper);
1726 rf_helper->reply_forward_type = reply_forward_type;
1727 rf_helper->action = action;
1728 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1729 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1730 rf_helper->top_header = (top_header) ? g_object_ref (top_header) : NULL;
1731 rf_helper->msg_part = (msg_part) ? g_object_ref (msg_part) : NULL;
1732 rf_helper->account_name = (active_acc) ?
1733 g_strdup (active_acc) :
1734 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1735 rf_helper->mailbox = g_strdup (active_mailbox);
1737 rf_helper->parts = g_object_ref (parts);
1739 rf_helper->parts = NULL;
1741 /* Note that window could be destroyed just AFTER calling
1742 register_window so we must ensure that this pointer does
1743 not hold invalid references */
1744 if (rf_helper->parent_window)
1745 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1746 rf_helper_window_closed, rf_helper);
1752 free_reply_forward_helper (gpointer data)
1754 ReplyForwardHelper *helper;
1756 helper = (ReplyForwardHelper *) data;
1757 g_free (helper->account_name);
1758 g_free (helper->mailbox);
1760 g_object_unref (helper->header);
1761 if (helper->top_header)
1762 g_object_unref (helper->top_header);
1763 if (helper->msg_part)
1764 g_object_unref (helper->msg_part);
1766 g_object_unref (helper->parts);
1767 if (helper->parent_window)
1768 g_object_weak_unref (G_OBJECT (helper->parent_window),
1769 rf_helper_window_closed, helper);
1770 g_slice_free (ReplyForwardHelper, helper);
1774 reply_forward_cb (ModestMailOperation *mail_op,
1781 TnyMsg *new_msg = NULL;
1782 ReplyForwardHelper *rf_helper;
1783 ModestWindow *msg_win = NULL;
1784 ModestEditType edit_type;
1786 TnyAccount *account = NULL;
1787 ModestWindowMgr *mgr = NULL;
1788 gchar *signature = NULL, *recipient = NULL;
1789 gboolean use_signature;
1791 /* If there was any error. The mail operation could be NULL,
1792 this means that we already have the message downloaded and
1793 that we didn't do a mail operation to retrieve it */
1794 rf_helper = (ReplyForwardHelper *) user_data;
1795 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1798 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1799 rf_helper->account_name, rf_helper->mailbox);
1801 recipient = modest_text_utils_get_email_address (from);
1802 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr (),
1807 /* Create reply mail */
1808 switch (rf_helper->action) {
1809 /* Use the msg_header to ensure that we have all the
1810 information. The summary can lack some data */
1811 TnyHeader *msg_header;
1813 msg_header = tny_msg_get_header (rf_helper->msg_part?rf_helper->msg_part:msg);
1815 modest_tny_msg_create_reply_msg (rf_helper->msg_part?rf_helper->msg_part:msg, msg_header, from,
1816 (use_signature) ? signature : NULL,
1817 rf_helper->reply_forward_type,
1818 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1819 g_object_unref (msg_header);
1821 case ACTION_REPLY_TO_ALL:
1822 msg_header = tny_msg_get_header (rf_helper->msg_part?rf_helper->msg_part:msg);
1824 modest_tny_msg_create_reply_msg (rf_helper->msg_part?rf_helper->msg_part:msg, msg_header, from,
1825 (use_signature) ? signature : NULL,
1826 rf_helper->reply_forward_type,
1827 MODEST_TNY_MSG_REPLY_MODE_ALL);
1828 edit_type = MODEST_EDIT_TYPE_REPLY;
1829 g_object_unref (msg_header);
1831 case ACTION_FORWARD:
1833 modest_tny_msg_create_forward_msg (rf_helper->msg_part?rf_helper->msg_part:msg, from,
1834 (use_signature) ? signature : NULL,
1835 rf_helper->reply_forward_type);
1836 edit_type = MODEST_EDIT_TYPE_FORWARD;
1839 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1841 g_return_if_reached ();
1849 g_warning ("%s: failed to create message\n", __FUNCTION__);
1853 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1854 rf_helper->account_name,
1855 TNY_ACCOUNT_TYPE_STORE);
1857 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1861 /* Create and register the windows */
1862 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, rf_helper->mailbox, FALSE);
1863 mgr = modest_runtime_get_window_mgr ();
1864 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1866 /* Note that register_window could have deleted the account */
1867 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1868 gdouble parent_zoom;
1870 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1871 modest_window_set_zoom (msg_win, parent_zoom);
1874 /* Show edit window */
1875 gtk_widget_show_all (GTK_WIDGET (msg_win));
1878 /* We always unregister the header because the message is
1879 forwarded or replied so the original one is no longer
1881 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1884 g_object_unref (G_OBJECT (new_msg));
1886 g_object_unref (G_OBJECT (account));
1887 free_reply_forward_helper (rf_helper);
1890 /* Checks a list of headers. If any of them are not currently
1891 * downloaded (CACHED) then returns TRUE else returns FALSE.
1894 header_list_count_uncached_msgs (TnyList *header_list)
1897 gint uncached_messages = 0;
1899 iter = tny_list_create_iterator (header_list);
1900 while (!tny_iterator_is_done (iter)) {
1903 header = TNY_HEADER (tny_iterator_get_current (iter));
1905 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1906 uncached_messages ++;
1907 g_object_unref (header);
1910 tny_iterator_next (iter);
1912 g_object_unref (iter);
1914 return uncached_messages;
1917 /* Returns FALSE if the user does not want to download the
1918 * messages. Returns TRUE if the user allowed the download.
1921 connect_to_get_msg (ModestWindow *win,
1922 gint num_of_uncached_msgs,
1923 TnyAccount *account)
1925 GtkResponseType response;
1927 /* Allways download if we are online. */
1928 if (tny_device_is_online (modest_runtime_get_device ()))
1931 /* If offline, then ask for user permission to download the messages */
1932 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1933 ngettext("mcen_nc_get_msg",
1935 num_of_uncached_msgs));
1937 if (response == GTK_RESPONSE_CANCEL)
1940 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1944 reply_forward_performer (gboolean canceled,
1946 GtkWindow *parent_window,
1947 TnyAccount *account,
1950 ReplyForwardHelper *rf_helper = NULL;
1951 ModestMailOperation *mail_op;
1953 rf_helper = (ReplyForwardHelper *) user_data;
1955 if (canceled || err) {
1956 free_reply_forward_helper (rf_helper);
1960 /* Retrieve the message */
1961 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1962 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1963 modest_ui_actions_disk_operations_error_handler,
1965 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1966 modest_mail_operation_get_msg_and_parts (mail_op, rf_helper->top_header, rf_helper->parts, TRUE, reply_forward_cb, rf_helper);
1969 g_object_unref(mail_op);
1973 all_parts_retrieved (TnyMimePart *part)
1975 if (!TNY_IS_CAMEL_BS_MIME_PART (part)) {
1978 TnyList *pending_parts;
1979 TnyIterator *iterator;
1980 gboolean all_retrieved = TRUE;
1982 pending_parts = TNY_LIST (tny_simple_list_new ());
1983 tny_mime_part_get_parts (part, pending_parts);
1984 iterator = tny_list_create_iterator (pending_parts);
1985 while (all_retrieved && !tny_iterator_is_done (iterator)) {
1988 child = TNY_MIME_PART (tny_iterator_get_current (iterator));
1990 if (tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (child))) {
1991 all_retrieved = all_parts_retrieved (TNY_MIME_PART (child));
1993 all_retrieved = FALSE;
1996 g_object_unref (child);
1997 tny_iterator_next (iterator);
1999 g_object_unref (iterator);
2000 g_object_unref (pending_parts);
2001 return all_retrieved;
2006 forward_pending_parts_helper (TnyMimePart *part, TnyList *list)
2009 TnyIterator *iterator;
2011 if (!tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (part))) {
2012 tny_list_append (list, G_OBJECT (part));
2014 parts = TNY_LIST (tny_simple_list_new ());
2015 tny_mime_part_get_parts (part, parts);
2016 for (iterator = tny_list_create_iterator (parts);
2017 !tny_iterator_is_done (iterator);
2018 tny_iterator_next (iterator)) {
2021 child = TNY_MIME_PART (tny_iterator_get_current (iterator));
2022 forward_pending_parts_helper (child, list);
2023 g_object_unref (child);
2025 g_object_unref (iterator);
2026 g_object_unref (parts);
2030 forward_pending_parts (TnyMsg *msg)
2032 TnyList *result = TNY_LIST (tny_simple_list_new ());
2033 if (TNY_IS_CAMEL_BS_MIME_PART (msg)) {
2034 forward_pending_parts_helper (TNY_MIME_PART (msg), result);
2041 * Common code for the reply and forward actions
2044 reply_forward (ReplyForwardAction action, ModestWindow *win)
2046 ReplyForwardHelper *rf_helper = NULL;
2047 guint reply_forward_type;
2049 g_return_if_fail (win && MODEST_IS_WINDOW(win));
2051 /* we check for low-mem; in that case, show a warning, and don't allow
2052 * reply/forward (because it could potentially require a lot of memory */
2053 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2057 /* we need an account when editing */
2058 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
2059 if (!modest_ui_actions_run_account_setup_wizard (win))
2063 reply_forward_type =
2064 modest_conf_get_int (modest_runtime_get_conf (),
2065 (action == ACTION_FORWARD) ?
2066 MODEST_CONF_FORWARD_TYPE :
2067 MODEST_CONF_REPLY_TYPE,
2070 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2072 TnyMsg *top_msg = NULL;
2073 TnyHeader *header = NULL;
2074 /* Get header and message. Do not free them here, the
2075 reply_forward_cb must do it */
2076 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
2077 top_msg = modest_msg_view_window_get_top_message (MODEST_MSG_VIEW_WINDOW(win));
2078 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
2080 if (msg && header && (action != ACTION_FORWARD || all_parts_retrieved (TNY_MIME_PART (msg)))) {
2082 rf_helper = create_reply_forward_helper (action, win,
2083 reply_forward_type, header, NULL, NULL, NULL);
2084 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
2086 gboolean do_download = TRUE;
2088 if (msg && header && action == ACTION_FORWARD) {
2089 if (top_msg == NULL)
2090 top_msg = g_object_ref (msg);
2091 /* Not all parts retrieved. Then we have to retrieve them all before
2092 * creating the forward message */
2093 if (!tny_device_is_online (modest_runtime_get_device ())) {
2096 /* If ask for user permission to download the messages */
2097 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2098 ngettext("mcen_nc_get_msg",
2102 /* End if the user does not want to continue */
2103 if (response == GTK_RESPONSE_CANCEL)
2104 do_download = FALSE;
2108 TnyList *pending_parts;
2110 TnyAccount *account;
2111 TnyHeader *top_header;
2114 top_header = tny_msg_get_header (top_msg);
2115 pending_parts = forward_pending_parts (top_msg);
2116 rf_helper = create_reply_forward_helper (action, win,
2117 reply_forward_type, header, msg, top_header, pending_parts);
2118 g_object_unref (pending_parts);
2120 folder = tny_header_get_folder (top_header);
2121 account = tny_folder_get_account (folder);
2122 modest_platform_connect_and_perform (GTK_WINDOW (win),
2124 reply_forward_performer,
2126 if (folder) g_object_unref (folder);
2127 g_object_unref (account);
2128 if (top_header) g_object_unref (top_header);
2132 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
2137 g_object_unref (msg);
2139 g_object_unref (top_msg);
2141 g_object_unref (header);
2143 TnyHeader *header = NULL;
2145 gboolean do_retrieve = TRUE;
2146 TnyList *header_list = NULL;
2148 header_list = get_selected_headers (win);
2151 /* Check that only one message is selected for replying */
2152 if (tny_list_get_length (header_list) != 1) {
2153 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
2154 NULL, _("mcen_ib_select_one_message"));
2155 g_object_unref (header_list);
2159 /* Only reply/forward to one message */
2160 iter = tny_list_create_iterator (header_list);
2161 header = TNY_HEADER (tny_iterator_get_current (iter));
2162 g_object_unref (iter);
2164 /* Retrieve messages */
2165 do_retrieve = (action == ACTION_FORWARD) ||
2166 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
2169 TnyAccount *account = NULL;
2170 TnyFolder *folder = NULL;
2171 gdouble download = TRUE;
2172 guint uncached_msgs = 0;
2174 folder = tny_header_get_folder (header);
2176 goto do_retrieve_frees;
2177 account = tny_folder_get_account (folder);
2179 goto do_retrieve_frees;
2181 uncached_msgs = header_list_count_uncached_msgs (header_list);
2183 if (uncached_msgs > 0) {
2184 /* Allways download if we are online. */
2185 if (!tny_device_is_online (modest_runtime_get_device ())) {
2188 /* If ask for user permission to download the messages */
2189 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2190 ngettext("mcen_nc_get_msg",
2194 /* End if the user does not want to continue */
2195 if (response == GTK_RESPONSE_CANCEL)
2202 rf_helper = create_reply_forward_helper (action, win,
2203 reply_forward_type, header, NULL, NULL, NULL);
2204 if (uncached_msgs > 0) {
2205 modest_platform_connect_and_perform (GTK_WINDOW (win),
2207 reply_forward_performer,
2210 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
2211 account, rf_helper);
2216 g_object_unref (account);
2218 g_object_unref (folder);
2220 reply_forward_cb (NULL, header, FALSE, NULL, NULL, NULL);
2223 g_object_unref (header_list);
2224 g_object_unref (header);
2229 modest_ui_actions_reply_calendar (ModestWindow *win, TnyList *header_pairs)
2234 gboolean use_signature;
2237 const gchar *account_name;
2238 const gchar *mailbox;
2239 TnyHeader *msg_header;
2240 ModestWindowMgr *mgr;
2243 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW(win));
2245 /* we check for low-mem; in that case, show a warning, and don't allow
2246 * reply/forward (because it could potentially require a lot of memory */
2247 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2250 account_name = modest_window_get_active_account (MODEST_WINDOW (win));
2251 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (win));
2252 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
2253 account_name, mailbox);
2254 recipient = modest_text_utils_get_email_address (from);
2255 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr(),
2260 msg = modest_msg_view_window_get_message(MODEST_MSG_VIEW_WINDOW(win));
2261 g_return_if_fail(msg);
2263 msg_header = tny_msg_get_header (msg);
2265 modest_tny_msg_create_reply_calendar_msg (msg, msg_header, from,
2266 (use_signature) ? signature : NULL,
2268 g_object_unref (msg_header);
2274 g_warning ("%s: failed to create message\n", __FUNCTION__);
2278 msg_win = (GtkWidget *) modest_msg_edit_window_new (new_msg, account_name, mailbox, FALSE);
2279 mgr = modest_runtime_get_window_mgr ();
2280 modest_window_mgr_register_window (mgr, MODEST_WINDOW (msg_win), (ModestWindow *) win);
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 data->custom_header_pairs,
3310 on_save_to_drafts_cb,
3311 g_object_ref(edit_window));
3313 #ifdef MODEST_TOOLKIT_HILDON2
3314 /* In hildon2 we always show the information banner on saving to drafts.
3315 * It will be a system information banner in this case.
3317 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3318 modest_platform_information_banner (NULL, NULL, text);
3321 /* Use the main window as the parent of the banner, if the
3322 main window does not exist it won't be shown, if the parent
3323 window exists then it's properly shown. We don't use the
3324 editor window because it could be closed (save to drafts
3325 could happen after closing the window */
3326 win = (ModestMainWindow *)
3327 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
3329 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3330 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
3334 modest_msg_edit_window_set_modified (edit_window, FALSE);
3337 g_free (account_name);
3338 g_object_unref (G_OBJECT (transport_account));
3339 g_object_unref (G_OBJECT (mail_operation));
3341 modest_msg_edit_window_free_msg_data (edit_window, data);
3344 * If the drafts folder is selected then make the header view
3345 * insensitive while the message is being saved to drafts
3346 * (it'll be sensitive again in on_save_to_drafts_cb()). This
3347 * is not very clean but it avoids letting the drafts folder
3348 * in an inconsistent state: the user could edit the message
3349 * being saved and undesirable things would happen.
3350 * In the average case the user won't notice anything at
3351 * all. In the worst case (the user is editing a really big
3352 * file from Drafts) the header view will be insensitive
3353 * during the saving process (10 or 20 seconds, depending on
3354 * the message). Anyway this is just a quick workaround: once
3355 * we find a better solution it should be removed
3356 * See NB#65125 (commend #18) for details.
3358 if (!had_error && win != NULL) {
3359 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
3360 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
3362 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
3364 if (modest_tny_folder_is_local_folder(folder)) {
3365 TnyFolderType folder_type;
3366 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
3367 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
3368 GtkWidget *hdrview = modest_main_window_get_child_widget(
3369 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3370 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
3374 if (folder != NULL) g_object_unref(folder);
3381 /* For instance, when clicking the Send toolbar button when editing a message: */
3383 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3385 TnyTransportAccount *transport_account = NULL;
3386 gboolean had_error = FALSE, add_to_contacts;
3388 ModestAccountMgr *account_mgr;
3389 gchar *account_name;
3390 ModestMailOperation *mail_operation;
3393 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
3395 /* Check whether to automatically add new contacts to addressbook or not */
3396 add_to_contacts = modest_conf_get_bool (modest_runtime_get_conf (),
3397 MODEST_CONF_AUTO_ADD_TO_CONTACTS, NULL);
3398 if (!modest_msg_edit_window_check_names (edit_window, add_to_contacts))
3401 data = modest_msg_edit_window_get_msg_data (edit_window);
3403 recipients = g_strconcat (data->to?data->to:"",
3404 data->cc?data->cc:"",
3405 data->bcc?data->bcc:"",
3407 if (recipients == NULL || recipients[0] == '\0') {
3408 /* Empty subject -> no send */
3409 g_free (recipients);
3410 modest_msg_edit_window_free_msg_data (edit_window, data);
3413 g_free (recipients);
3416 if (!enough_space_for_message (edit_window, data)) {
3417 modest_msg_edit_window_free_msg_data (edit_window, data);
3421 account_mgr = modest_runtime_get_account_mgr();
3422 account_name = g_strdup (data->account_name);
3424 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3427 account_name = modest_account_mgr_get_default_account (account_mgr);
3429 if (!account_name) {
3430 modest_msg_edit_window_free_msg_data (edit_window, data);
3431 /* Run account setup wizard */
3432 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
3437 /* Get the currently-active transport account for this modest account: */
3438 if (account_name && strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
3440 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3441 (modest_runtime_get_account_store (),
3442 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
3445 if (!transport_account) {
3446 modest_msg_edit_window_free_msg_data (edit_window, data);
3447 /* Run account setup wizard */
3448 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
3453 /* Create the mail operation */
3454 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
3455 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3457 modest_mail_operation_send_new_mail (mail_operation,
3471 data->priority_flags,
3472 data->custom_header_pairs);
3474 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3475 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
3477 if (modest_mail_operation_get_error (mail_operation) != NULL) {
3478 const GError *error = modest_mail_operation_get_error (mail_operation);
3479 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3480 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3481 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3482 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3488 g_free (account_name);
3489 g_object_unref (G_OBJECT (transport_account));
3490 g_object_unref (G_OBJECT (mail_operation));
3492 modest_msg_edit_window_free_msg_data (edit_window, data);
3495 modest_msg_edit_window_set_sent (edit_window, TRUE);
3497 /* Save settings and close the window: */
3498 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3505 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3506 ModestMsgEditWindow *window)
3508 ModestMsgEditFormatState *format_state = NULL;
3510 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3511 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3513 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3516 format_state = modest_msg_edit_window_get_format_state (window);
3517 g_return_if_fail (format_state != NULL);
3519 format_state->bold = gtk_toggle_action_get_active (action);
3520 modest_msg_edit_window_set_format_state (window, format_state);
3521 g_free (format_state);
3526 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3527 ModestMsgEditWindow *window)
3529 ModestMsgEditFormatState *format_state = NULL;
3531 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3532 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3534 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3537 format_state = modest_msg_edit_window_get_format_state (window);
3538 g_return_if_fail (format_state != NULL);
3540 format_state->italics = gtk_toggle_action_get_active (action);
3541 modest_msg_edit_window_set_format_state (window, format_state);
3542 g_free (format_state);
3547 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3548 ModestMsgEditWindow *window)
3550 ModestMsgEditFormatState *format_state = NULL;
3552 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3553 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3555 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3558 format_state = modest_msg_edit_window_get_format_state (window);
3559 g_return_if_fail (format_state != NULL);
3561 format_state->bullet = gtk_toggle_action_get_active (action);
3562 modest_msg_edit_window_set_format_state (window, format_state);
3563 g_free (format_state);
3568 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3569 GtkRadioAction *selected,
3570 ModestMsgEditWindow *window)
3572 ModestMsgEditFormatState *format_state = NULL;
3573 GtkJustification value;
3575 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3577 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3580 value = gtk_radio_action_get_current_value (selected);
3582 format_state = modest_msg_edit_window_get_format_state (window);
3583 g_return_if_fail (format_state != NULL);
3585 format_state->justification = value;
3586 modest_msg_edit_window_set_format_state (window, format_state);
3587 g_free (format_state);
3591 modest_ui_actions_on_select_editor_color (GtkAction *action,
3592 ModestMsgEditWindow *window)
3594 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3595 g_return_if_fail (GTK_IS_ACTION (action));
3597 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3600 modest_msg_edit_window_select_color (window);
3604 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3605 ModestMsgEditWindow *window)
3607 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3608 g_return_if_fail (GTK_IS_ACTION (action));
3610 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3613 modest_msg_edit_window_select_background_color (window);
3617 modest_ui_actions_on_insert_image (GObject *object,
3618 ModestMsgEditWindow *window)
3620 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3623 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3626 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3629 modest_msg_edit_window_insert_image (window);
3633 modest_ui_actions_on_attach_file (GtkAction *action,
3634 ModestMsgEditWindow *window)
3636 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3637 g_return_if_fail (GTK_IS_ACTION (action));
3639 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3642 modest_msg_edit_window_offer_attach_file (window);
3646 modest_ui_actions_on_remove_attachments (GtkAction *action,
3647 ModestMsgEditWindow *window)
3649 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3651 modest_msg_edit_window_remove_attachments (window, NULL);
3655 do_create_folder_cb (ModestMailOperation *mail_op,
3656 TnyFolderStore *parent_folder,
3657 TnyFolder *new_folder,
3660 gchar *suggested_name = (gchar *) user_data;
3661 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3662 const GError *error;
3664 error = modest_mail_operation_get_error (mail_op);
3666 gboolean disk_full = FALSE;
3667 TnyAccount *account;
3668 /* Show an error. If there was some problem writing to
3669 disk, show it, otherwise show the generic folder
3670 create error. We do it here and not in an error
3671 handler because the call to do_create_folder will
3672 stop the main loop in a gtk_dialog_run and then,
3673 the message won't be shown until that dialog is
3675 account = modest_mail_operation_get_account (mail_op);
3678 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3679 (GtkWidget *) source_win,
3682 _("mail_in_ui_folder_create_error_memory"));
3683 g_object_unref (account);
3686 /* Show an error and try again if there is no
3687 full memory condition */
3688 modest_platform_information_banner ((GtkWidget *) source_win, NULL,
3689 _("mail_in_ui_folder_create_error"));
3690 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3694 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3695 * FIXME: any other? */
3696 GtkWidget *folder_view;
3698 if (MODEST_IS_MAIN_WINDOW(source_win))
3700 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3701 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3703 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3704 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3706 /* Select the newly created folder. It could happen
3707 that the widget is no longer there (i.e. the window
3708 has been destroyed, so we need to check this */
3710 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3712 g_object_unref (new_folder);
3714 /* Free. Note that the first time it'll be NULL so noop */
3715 g_free (suggested_name);
3716 g_object_unref (source_win);
3721 TnyFolderStore *parent;
3722 } CreateFolderConnect;
3725 do_create_folder_performer (gboolean canceled,
3727 GtkWindow *parent_window,
3728 TnyAccount *account,
3731 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3732 ModestMailOperation *mail_op;
3734 if (canceled || err) {
3735 /* In disk full conditions we could get this error here */
3736 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3737 (GtkWidget *) parent_window, err,
3738 NULL, _("mail_in_ui_folder_create_error_memory"));
3740 /* This happens if we have selected the outbox folder
3742 if (err && err->code == TNY_SERVICE_ERROR_UNKNOWN &&
3743 TNY_IS_MERGE_FOLDER (helper->parent)) {
3744 /* Show an error and retry */
3745 modest_platform_information_banner ((GtkWidget *) parent_window,
3747 _("mail_in_ui_folder_create_error"));
3749 do_create_folder (parent_window, helper->parent, helper->folder_name);
3755 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3756 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3758 modest_mail_operation_create_folder (mail_op,
3760 (const gchar *) helper->folder_name,
3761 do_create_folder_cb,
3762 g_strdup (helper->folder_name));
3763 g_object_unref (mail_op);
3767 g_object_unref (helper->parent);
3768 if (helper->folder_name)
3769 g_free (helper->folder_name);
3770 g_slice_free (CreateFolderConnect, helper);
3775 do_create_folder (GtkWindow *parent_window,
3776 TnyFolderStore *suggested_parent,
3777 const gchar *suggested_name)
3780 gchar *folder_name = NULL;
3781 TnyFolderStore *parent_folder = NULL;
3783 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3785 (gchar *) suggested_name,
3789 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3790 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3791 helper->folder_name = g_strdup (folder_name);
3792 helper->parent = g_object_ref (parent_folder);
3794 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3797 do_create_folder_performer,
3802 g_free (folder_name);
3804 g_object_unref (parent_folder);
3808 modest_ui_actions_create_folder(GtkWidget *parent_window,
3809 GtkWidget *folder_view,
3810 TnyFolderStore *parent_folder)
3812 if (!parent_folder) {
3813 #ifdef MODEST_TOOLKIT_HILDON2
3814 ModestTnyAccountStore *acc_store;
3816 acc_store = modest_runtime_get_account_store ();
3818 parent_folder = (TnyFolderStore *)
3819 modest_tny_account_store_get_local_folders_account (acc_store);
3821 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3825 if (parent_folder) {
3826 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3827 g_object_unref (parent_folder);
3832 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3835 g_return_if_fail (MODEST_IS_WINDOW(window));
3837 if (MODEST_IS_MAIN_WINDOW (window)) {
3838 GtkWidget *folder_view;
3840 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3841 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3845 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3846 #ifdef MODEST_TOOLKIT_HILDON2
3847 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3848 GtkWidget *folder_view;
3850 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3851 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3854 g_assert_not_reached ();
3859 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3862 const GError *error = NULL;
3863 gchar *message = NULL;
3865 TnyAccount *account = modest_mail_operation_get_account (mail_op);
3867 /* Get error message */
3868 error = modest_mail_operation_get_error (mail_op);
3870 g_return_if_reached ();
3872 mem_full = modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
3873 (GError *) error, account);
3875 message = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3876 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3877 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3878 message = _CS("ckdg_ib_folder_already_exists");
3879 } else if (error->domain == TNY_ERROR_DOMAIN &&
3880 error->code == TNY_SERVICE_ERROR_STATE) {
3881 /* This means that the folder is already in use (a
3882 message is opened for example */
3883 message = _("emev_ni_internal_error");
3885 message = _CS("ckdg_ib_unable_to_rename");
3888 /* We don't set a parent for the dialog because the dialog
3889 will be destroyed so the banner won't appear */
3890 modest_platform_information_banner (NULL, NULL, message);
3893 g_object_unref (account);
3899 TnyFolderStore *folder;
3904 on_rename_folder_cb (ModestMailOperation *mail_op,
3905 TnyFolder *new_folder,
3908 ModestFolderView *folder_view;
3910 /* If the window was closed when renaming a folder, or if
3911 * it's not a main window this will happen */
3912 if (!MODEST_IS_FOLDER_VIEW (user_data))
3915 folder_view = MODEST_FOLDER_VIEW (user_data);
3916 /* Note that if the rename fails new_folder will be NULL */
3918 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3920 modest_folder_view_select_first_inbox_or_local (folder_view);
3922 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3926 on_rename_folder_performer (gboolean canceled,
3928 GtkWindow *parent_window,
3929 TnyAccount *account,
3932 ModestMailOperation *mail_op = NULL;
3933 GtkTreeSelection *sel = NULL;
3934 GtkWidget *folder_view = NULL;
3935 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3937 if (canceled || err) {
3938 /* In disk full conditions we could get this error here */
3939 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3940 (GtkWidget *) parent_window, err,
3945 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3946 modest_ui_actions_rename_folder_error_handler,
3947 parent_window, NULL);
3949 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3952 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3954 folder_view = modest_main_window_get_child_widget (
3955 MODEST_MAIN_WINDOW (parent_window),
3956 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3958 #ifdef MODEST_TOOLKIT_HILDON2
3959 else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3960 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3961 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3965 /* Clear the folders view */
3966 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3967 gtk_tree_selection_unselect_all (sel);
3969 /* Actually rename the folder */
3970 modest_mail_operation_rename_folder (mail_op,
3971 TNY_FOLDER (data->folder),
3972 (const gchar *) (data->new_name),
3973 on_rename_folder_cb,
3975 g_object_unref (mail_op);
3978 g_object_unref (data->folder);
3979 g_free (data->new_name);
3984 modest_ui_actions_on_rename_folder (GtkAction *action,
3985 ModestWindow *window)
3987 modest_ui_actions_on_edit_mode_rename_folder (window);
3991 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3993 TnyFolderStore *folder;
3994 GtkWidget *folder_view;
3995 gboolean do_rename = TRUE;
3997 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3999 if (MODEST_IS_MAIN_WINDOW (window)) {
4000 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4001 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4005 #ifdef MODEST_TOOLKIT_HILDON2
4006 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
4007 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
4013 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
4018 if (TNY_IS_FOLDER (folder)) {
4019 gchar *folder_name = NULL;
4021 const gchar *current_name;
4022 TnyFolderStore *parent;
4024 current_name = tny_folder_get_name (TNY_FOLDER (folder));
4025 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
4026 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
4027 parent, current_name,
4029 g_object_unref (parent);
4031 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
4034 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
4035 rename_folder_data->folder = g_object_ref (folder);
4036 rename_folder_data->new_name = folder_name;
4037 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
4038 folder, on_rename_folder_performer, rename_folder_data);
4041 g_object_unref (folder);
4046 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
4049 GObject *win = modest_mail_operation_get_source (mail_op);
4051 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
4052 _("mail_in_ui_folder_delete_error"),
4054 g_object_unref (win);
4058 TnyFolderStore *folder;
4059 gboolean move_to_trash;
4063 on_delete_folder_cb (gboolean canceled,
4065 GtkWindow *parent_window,
4066 TnyAccount *account,
4069 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
4070 GtkWidget *folder_view;
4071 ModestMailOperation *mail_op;
4072 GtkTreeSelection *sel;
4074 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
4075 /* Note that the connection process can fail due to
4076 memory low conditions as it can not successfully
4077 store the summary */
4078 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4079 (GtkWidget*) parent_window, err,
4081 g_debug ("Error connecting when trying to delete a folder");
4082 g_object_unref (G_OBJECT (info->folder));
4087 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
4088 folder_view = modest_main_window_get_child_widget (
4089 MODEST_MAIN_WINDOW (parent_window),
4090 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4091 #ifdef MODEST_TOOLKIT_HILDON2
4092 } else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
4093 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
4096 g_object_unref (G_OBJECT (info->folder));
4101 /* Unselect the folder before deleting it to free the headers */
4102 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
4103 gtk_tree_selection_unselect_all (sel);
4105 /* Create the mail operation */
4107 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
4108 modest_ui_actions_delete_folder_error_handler,
4111 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4113 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
4115 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
4117 g_object_unref (mail_op);
4118 g_object_unref (info->folder);
4123 delete_folder (ModestWindow *window, gboolean move_to_trash)
4125 TnyFolderStore *folder;
4126 GtkWidget *folder_view;
4130 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
4132 if (MODEST_IS_MAIN_WINDOW (window)) {
4134 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4135 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4136 #ifdef MODEST_TOOLKIT_HILDON2
4137 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
4138 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
4146 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4151 /* Show an error if it's an account */
4152 if (!TNY_IS_FOLDER (folder)) {
4153 modest_platform_run_information_dialog (GTK_WINDOW (window),
4154 _("mail_in_ui_folder_delete_error"),
4156 g_object_unref (G_OBJECT (folder));
4161 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
4162 tny_folder_get_name (TNY_FOLDER (folder)));
4163 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
4164 (const gchar *) message);
4167 if (response == GTK_RESPONSE_OK) {
4168 TnyAccount *account = NULL;
4169 DeleteFolderInfo *info = NULL;
4170 info = g_new0(DeleteFolderInfo, 1);
4171 info->folder = g_object_ref (folder);
4172 info->move_to_trash = move_to_trash;
4174 account = tny_folder_get_account (TNY_FOLDER (folder));
4175 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
4177 TNY_FOLDER_STORE (account),
4178 on_delete_folder_cb, info);
4179 g_object_unref (account);
4180 g_object_unref (folder);
4188 modest_ui_actions_on_delete_folder (GtkAction *action,
4189 ModestWindow *window)
4191 modest_ui_actions_on_edit_mode_delete_folder (window);
4195 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
4197 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
4199 return delete_folder (window, FALSE);
4203 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
4205 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4207 delete_folder (MODEST_WINDOW (main_window), TRUE);
4211 typedef struct _PasswordDialogFields {
4212 GtkWidget *username;
4213 GtkWidget *password;
4215 } PasswordDialogFields;
4218 password_dialog_check_field (GtkEditable *editable,
4219 PasswordDialogFields *fields)
4222 gboolean any_value_empty = FALSE;
4224 #ifdef MODEST_TOOLKIT_HILDON2
4225 value = hildon_entry_get_text (HILDON_ENTRY (fields->username));
4227 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
4229 if ((value == NULL) || value[0] == '\0') {
4230 any_value_empty = TRUE;
4232 #ifdef MODEST_TOOLKIT_HILDON2
4233 value = hildon_entry_get_text (HILDON_ENTRY (fields->password));
4235 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
4237 if ((value == NULL) || value[0] == '\0') {
4238 any_value_empty = TRUE;
4240 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
4244 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
4245 const gchar* server_account_name,
4250 ModestMainWindow *main_window)
4252 g_return_if_fail(server_account_name);
4253 gboolean completed = FALSE;
4254 PasswordDialogFields *fields = NULL;
4256 /* Initalize output parameters: */
4263 #ifndef MODEST_TOOLKIT_GTK
4264 /* Maemo uses a different (awkward) button order,
4265 * It should probably just use gtk_alternative_dialog_button_order ().
4267 #ifdef MODEST_TOOLKIT_HILDON2
4269 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4272 _HL("wdgt_bd_done"),
4273 GTK_RESPONSE_ACCEPT,
4275 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
4276 HILDON_MARGIN_DOUBLE);
4279 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4282 _("mcen_bd_dialog_ok"),
4283 GTK_RESPONSE_ACCEPT,
4284 _("mcen_bd_dialog_cancel"),
4285 GTK_RESPONSE_REJECT,
4287 #endif /* MODEST_TOOLKIT_HILDON2 */
4290 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4294 GTK_RESPONSE_REJECT,
4296 GTK_RESPONSE_ACCEPT,
4298 #endif /* MODEST_TOOLKIT_GTK */
4300 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
4302 gchar *server_name = modest_account_mgr_get_server_account_hostname (
4303 modest_runtime_get_account_mgr(), server_account_name);
4304 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
4305 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
4308 gtk_widget_destroy (dialog);
4312 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
4313 GtkWidget *label = gtk_label_new (txt);
4314 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
4316 g_free (server_name);
4317 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
4322 gchar *initial_username = modest_account_mgr_get_server_account_username (
4323 modest_runtime_get_account_mgr(), server_account_name);
4325 #ifdef MODEST_TOOLKIT_HILDON2
4326 GtkWidget *entry_username = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4327 if (initial_username)
4328 hildon_entry_set_text (HILDON_ENTRY (entry_username), initial_username);
4330 GtkWidget *entry_username = gtk_entry_new ();
4331 if (initial_username)
4332 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
4334 /* Dim this if a connection has ever succeeded with this username,
4335 * as per the UI spec: */
4336 /* const gboolean username_known = */
4337 /* modest_account_mgr_get_server_account_username_has_succeeded( */
4338 /* modest_runtime_get_account_mgr(), server_account_name); */
4339 /* gtk_widget_set_sensitive (entry_username, !username_known); */
4341 /* We drop the username sensitive code and disallow changing it here
4342 * as tinymail does not support really changing the username in the callback
4344 gtk_widget_set_sensitive (entry_username, FALSE);
4346 #ifndef MODEST_TOOLKIT_GTK
4347 /* Auto-capitalization is the default, so let's turn it off: */
4348 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
4350 /* Create a size group to be used by all captions.
4351 * Note that HildonCaption does not create a default size group if we do not specify one.
4352 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
4353 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
4355 #ifdef MODEST_TOOLKIT_HILDON2
4356 GtkWidget *caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4357 _("mail_fi_username"), FALSE,
4360 GtkWidget *caption = hildon_caption_new (sizegroup,
4361 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
4363 gtk_widget_show (entry_username);
4364 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4365 FALSE, FALSE, MODEST_MARGIN_HALF);
4366 gtk_widget_show (caption);
4368 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
4370 #endif /* !MODEST_TOOLKIT_GTK */
4373 #ifdef MODEST_TOOLKIT_HILDON2
4374 GtkWidget *entry_password = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4376 GtkWidget *entry_password = gtk_entry_new ();
4378 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
4379 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
4381 #ifndef MODEST_TOOLKIT_GTK
4382 /* Auto-capitalization is the default, so let's turn it off: */
4383 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
4384 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
4386 #ifdef MODEST_TOOLKIT_HILDON2
4387 caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4388 _("mail_fi_password"), FALSE,
4391 caption = hildon_caption_new (sizegroup,
4392 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
4394 gtk_widget_show (entry_password);
4395 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4396 FALSE, FALSE, MODEST_MARGIN_HALF);
4397 gtk_widget_show (caption);
4398 g_object_unref (sizegroup);
4400 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
4402 #endif /* !MODEST_TOOLKIT_GTK */
4404 if (initial_username != NULL)
4405 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
4407 /* This is not in the Maemo UI spec:
4408 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
4409 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
4413 fields = g_slice_new0 (PasswordDialogFields);
4414 fields->username = entry_username;
4415 fields->password = entry_password;
4416 fields->dialog = dialog;
4418 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
4419 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
4420 password_dialog_check_field (NULL, fields);
4422 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4424 while (!completed) {
4426 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
4428 #ifdef MODEST_TOOLKIT_HILDON2
4429 *username = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_username)));
4431 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
4434 /* Note that an empty field becomes the "" string */
4435 if (*username && strlen (*username) > 0) {
4436 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
4437 server_account_name,
4441 const gboolean username_was_changed =
4442 (strcmp (*username, initial_username) != 0);
4443 if (username_was_changed) {
4444 g_warning ("%s: tinymail does not yet support changing the "
4445 "username in the get_password() callback.\n", __FUNCTION__);
4451 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
4452 _("mcen_ib_username_pw_incorrect"));
4458 #ifdef MODEST_TOOLKIT_HILDON2
4459 *password = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_password)));
4461 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
4464 /* We do not save the password in the configuration,
4465 * because this function is only called for passwords that should
4466 * not be remembered:
4467 modest_server_account_set_password (
4468 modest_runtime_get_account_mgr(), server_account_name,
4475 #ifndef MODEST_TOOLKIT_HILDON2
4476 /* Set parent to NULL or the banner will disappear with its parent dialog */
4477 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
4489 /* This is not in the Maemo UI spec:
4490 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
4496 g_free (initial_username);
4497 gtk_widget_destroy (dialog);
4498 g_slice_free (PasswordDialogFields, fields);
4500 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
4504 modest_ui_actions_on_cut (GtkAction *action,
4505 ModestWindow *window)
4507 GtkWidget *focused_widget;
4508 GtkClipboard *clipboard;
4510 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4511 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4512 if (GTK_IS_EDITABLE (focused_widget)) {
4513 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
4514 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4515 gtk_clipboard_store (clipboard);
4516 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4517 GtkTextBuffer *buffer;
4519 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4520 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4521 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
4522 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4523 gtk_clipboard_store (clipboard);
4525 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4526 TnyList *header_list = modest_header_view_get_selected_headers (
4527 MODEST_HEADER_VIEW (focused_widget));
4528 gboolean continue_download = FALSE;
4529 gint num_of_unc_msgs;
4531 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4533 if (num_of_unc_msgs) {
4534 TnyAccount *account = get_account_from_header_list (header_list);
4536 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4537 g_object_unref (account);
4541 if (num_of_unc_msgs == 0 || continue_download) {
4542 /* modest_platform_information_banner (
4543 NULL, NULL, _CS("mcen_ib_getting_items"));*/
4544 modest_header_view_cut_selection (
4545 MODEST_HEADER_VIEW (focused_widget));
4548 g_object_unref (header_list);
4549 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4550 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4555 modest_ui_actions_on_copy (GtkAction *action,
4556 ModestWindow *window)
4558 GtkClipboard *clipboard;
4559 GtkWidget *focused_widget;
4560 gboolean copied = TRUE;
4562 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4563 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4565 if (GTK_IS_LABEL (focused_widget)) {
4567 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4568 gtk_clipboard_set_text (clipboard, selection, -1);
4570 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4571 gtk_clipboard_store (clipboard);
4572 } else if (GTK_IS_EDITABLE (focused_widget)) {
4573 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4574 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4575 gtk_clipboard_store (clipboard);
4576 } else if (GTK_IS_HTML (focused_widget)) {
4579 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4580 if ((sel == NULL) || (sel[0] == '\0')) {
4583 gtk_html_copy (GTK_HTML (focused_widget));
4584 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4585 gtk_clipboard_store (clipboard);
4587 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4588 GtkTextBuffer *buffer;
4589 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4590 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4591 gtk_text_buffer_copy_clipboard (buffer, clipboard);
4592 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4593 gtk_clipboard_store (clipboard);
4595 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4596 TnyList *header_list = modest_header_view_get_selected_headers (
4597 MODEST_HEADER_VIEW (focused_widget));
4598 gboolean continue_download = FALSE;
4599 gint num_of_unc_msgs;
4601 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4603 if (num_of_unc_msgs) {
4604 TnyAccount *account = get_account_from_header_list (header_list);
4606 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4607 g_object_unref (account);
4611 if (num_of_unc_msgs == 0 || continue_download) {
4612 modest_platform_information_banner (
4613 NULL, NULL, _CS("mcen_ib_getting_items"));
4614 modest_header_view_copy_selection (
4615 MODEST_HEADER_VIEW (focused_widget));
4619 g_object_unref (header_list);
4621 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4622 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4625 /* Show information banner if there was a copy to clipboard */
4627 modest_platform_information_banner (
4628 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4632 modest_ui_actions_on_undo (GtkAction *action,
4633 ModestWindow *window)
4635 ModestEmailClipboard *clipboard = NULL;
4637 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4638 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4639 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4640 /* Clear clipboard source */
4641 clipboard = modest_runtime_get_email_clipboard ();
4642 modest_email_clipboard_clear (clipboard);
4645 g_return_if_reached ();
4650 modest_ui_actions_on_redo (GtkAction *action,
4651 ModestWindow *window)
4653 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4654 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4657 g_return_if_reached ();
4663 destroy_information_note (ModestMailOperation *mail_op,
4666 /* destroy information note */
4667 gtk_widget_destroy (GTK_WIDGET(user_data));
4671 destroy_folder_information_note (ModestMailOperation *mail_op,
4672 TnyFolder *new_folder,
4675 /* destroy information note */
4676 gtk_widget_destroy (GTK_WIDGET(user_data));
4681 paste_as_attachment_free (gpointer data)
4683 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4685 if (helper->banner) {
4686 gtk_widget_destroy (helper->banner);
4687 g_object_unref (helper->banner);
4693 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4698 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4699 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4704 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4709 modest_ui_actions_on_paste (GtkAction *action,
4710 ModestWindow *window)
4712 GtkWidget *focused_widget = NULL;
4713 GtkWidget *inf_note = NULL;
4714 ModestMailOperation *mail_op = NULL;
4716 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4717 if (GTK_IS_EDITABLE (focused_widget)) {
4718 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4719 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4720 ModestEmailClipboard *e_clipboard = NULL;
4721 e_clipboard = modest_runtime_get_email_clipboard ();
4722 if (modest_email_clipboard_cleared (e_clipboard)) {
4723 GtkTextBuffer *buffer;
4724 GtkClipboard *clipboard;
4726 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4727 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4728 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4729 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4730 ModestMailOperation *mail_op;
4731 TnyFolder *src_folder = NULL;
4732 TnyList *data = NULL;
4734 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4735 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4736 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4737 _CS("ckct_nw_pasting"));
4738 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4739 mail_op = modest_mail_operation_new (G_OBJECT (window));
4740 if (helper->banner != NULL) {
4741 g_object_ref (G_OBJECT (helper->banner));
4742 gtk_widget_show (GTK_WIDGET (helper->banner));
4746 modest_mail_operation_get_msgs_full (mail_op,
4748 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4750 paste_as_attachment_free);
4754 g_object_unref (data);
4756 g_object_unref (src_folder);
4759 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4760 ModestEmailClipboard *clipboard = NULL;
4761 TnyFolder *src_folder = NULL;
4762 TnyFolderStore *folder_store = NULL;
4763 TnyList *data = NULL;
4764 gboolean delete = FALSE;
4766 /* Check clipboard source */
4767 clipboard = modest_runtime_get_email_clipboard ();
4768 if (modest_email_clipboard_cleared (clipboard))
4771 /* Get elements to paste */
4772 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4774 /* Create a new mail operation */
4775 mail_op = modest_mail_operation_new (G_OBJECT(window));
4777 /* Get destination folder */
4778 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4780 /* transfer messages */
4784 /* Ask for user confirmation */
4786 modest_ui_actions_msgs_move_to_confirmation (window,
4787 TNY_FOLDER (folder_store),
4791 if (response == GTK_RESPONSE_OK) {
4792 /* Launch notification */
4793 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4794 _CS("ckct_nw_pasting"));
4795 if (inf_note != NULL) {
4796 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4797 gtk_widget_show (GTK_WIDGET(inf_note));
4800 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4801 modest_mail_operation_xfer_msgs (mail_op,
4803 TNY_FOLDER (folder_store),
4805 destroy_information_note,
4808 g_object_unref (mail_op);
4811 } else if (src_folder != NULL) {
4812 /* Launch notification */
4813 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4814 _CS("ckct_nw_pasting"));
4815 if (inf_note != NULL) {
4816 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4817 gtk_widget_show (GTK_WIDGET(inf_note));
4820 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4821 modest_mail_operation_xfer_folder (mail_op,
4825 destroy_folder_information_note,
4831 g_object_unref (data);
4832 if (src_folder != NULL)
4833 g_object_unref (src_folder);
4834 if (folder_store != NULL)
4835 g_object_unref (folder_store);
4841 modest_ui_actions_on_select_all (GtkAction *action,
4842 ModestWindow *window)
4844 GtkWidget *focused_widget;
4846 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4847 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4848 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4849 } else if (GTK_IS_LABEL (focused_widget)) {
4850 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4851 } else if (GTK_IS_EDITABLE (focused_widget)) {
4852 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4853 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4854 GtkTextBuffer *buffer;
4855 GtkTextIter start, end;
4857 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4858 gtk_text_buffer_get_start_iter (buffer, &start);
4859 gtk_text_buffer_get_end_iter (buffer, &end);
4860 gtk_text_buffer_select_range (buffer, &start, &end);
4861 } else if (GTK_IS_HTML (focused_widget)) {
4862 gtk_html_select_all (GTK_HTML (focused_widget));
4863 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4864 GtkWidget *header_view = focused_widget;
4865 GtkTreeSelection *selection = NULL;
4867 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4868 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4869 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4872 /* Disable window dimming management */
4873 modest_window_disable_dimming (MODEST_WINDOW(window));
4875 /* Select all messages */
4876 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4877 gtk_tree_selection_select_all (selection);
4879 /* Set focuse on header view */
4880 gtk_widget_grab_focus (header_view);
4882 /* Enable window dimming management */
4883 modest_window_enable_dimming (MODEST_WINDOW(window));
4884 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4885 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4891 modest_ui_actions_on_mark_as_read (GtkAction *action,
4892 ModestWindow *window)
4894 g_return_if_fail (MODEST_IS_WINDOW(window));
4896 /* Mark each header as read */
4897 do_headers_action (window, headers_action_mark_as_read, NULL);
4901 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4902 ModestWindow *window)
4904 g_return_if_fail (MODEST_IS_WINDOW(window));
4906 /* Mark each header as read */
4907 do_headers_action (window, headers_action_mark_as_unread, NULL);
4911 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4912 GtkRadioAction *selected,
4913 ModestWindow *window)
4917 value = gtk_radio_action_get_current_value (selected);
4918 if (MODEST_IS_WINDOW (window)) {
4919 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4924 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4925 GtkRadioAction *selected,
4926 ModestWindow *window)
4928 TnyHeaderFlags flags;
4929 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4931 flags = gtk_radio_action_get_current_value (selected);
4932 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4936 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4937 GtkRadioAction *selected,
4938 ModestWindow *window)
4942 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4944 file_format = gtk_radio_action_get_current_value (selected);
4945 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4950 modest_ui_actions_on_zoom_plus (GtkAction *action,
4951 ModestWindow *window)
4953 g_return_if_fail (MODEST_IS_WINDOW (window));
4955 modest_window_zoom_plus (MODEST_WINDOW (window));
4959 modest_ui_actions_on_zoom_minus (GtkAction *action,
4960 ModestWindow *window)
4962 g_return_if_fail (MODEST_IS_WINDOW (window));
4964 modest_window_zoom_minus (MODEST_WINDOW (window));
4968 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4969 ModestWindow *window)
4971 ModestWindowMgr *mgr;
4972 gboolean fullscreen, active;
4973 g_return_if_fail (MODEST_IS_WINDOW (window));
4975 mgr = modest_runtime_get_window_mgr ();
4977 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4978 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4980 if (active != fullscreen) {
4981 modest_window_mgr_set_fullscreen_mode (mgr, active);
4982 #ifndef MODEST_TOOLKIT_HILDON2
4983 gtk_window_present (GTK_WINDOW (window));
4989 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4990 ModestWindow *window)
4992 ModestWindowMgr *mgr;
4993 gboolean fullscreen;
4995 g_return_if_fail (MODEST_IS_WINDOW (window));
4997 mgr = modest_runtime_get_window_mgr ();
4998 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4999 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
5001 #ifndef MODEST_TOOLKIT_HILDON2
5002 gtk_window_present (GTK_WINDOW (window));
5007 * Used by modest_ui_actions_on_details to call do_headers_action
5010 headers_action_show_details (TnyHeader *header,
5011 ModestWindow *window,
5015 gboolean async_retrieval;
5018 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5019 async_retrieval = TRUE;
5020 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
5021 async_retrieval = !TNY_IS_CAMEL_BS_MSG (msg);
5023 async_retrieval = FALSE;
5025 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header, async_retrieval, msg);
5027 g_object_unref (msg);
5031 * Show the header details in a ModestDetailsDialog widget
5034 modest_ui_actions_on_details (GtkAction *action,
5037 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
5041 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
5045 header = tny_msg_get_header (msg);
5047 headers_action_show_details (header, win, NULL);
5048 g_object_unref (header);
5050 g_object_unref (msg);
5052 } else if (MODEST_IS_MAIN_WINDOW (win)) {
5053 GtkWidget *folder_view, *header_view;
5055 /* Check which widget has the focus */
5056 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5057 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5058 if (gtk_widget_is_focus (folder_view)) {
5059 TnyFolderStore *folder_store
5060 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5061 if (!folder_store) {
5062 g_warning ("%s: No item was selected.\n", __FUNCTION__);
5065 /* Show only when it's a folder */
5066 /* This function should not be called for account items,
5067 * because we dim the menu item for them. */
5068 if (TNY_IS_FOLDER (folder_store)) {
5069 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
5070 TNY_FOLDER (folder_store));
5073 g_object_unref (folder_store);
5076 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5077 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5078 /* Show details of each header */
5079 do_headers_action (win, headers_action_show_details, header_view);
5081 #ifdef MODEST_TOOLKIT_HILDON2
5082 } else if (MODEST_IS_HEADER_WINDOW (win)) {
5084 GtkWidget *header_view;
5086 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
5087 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
5089 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
5091 g_object_unref (folder);
5098 modest_ui_actions_on_limit_error (GtkAction *action,
5101 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
5103 modest_platform_information_banner ((GtkWidget *) win, NULL, _CS("ckdg_ib_maximum_characters_reached"));
5108 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
5109 ModestMsgEditWindow *window)
5111 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5113 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
5117 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
5118 ModestMsgEditWindow *window)
5120 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5122 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
5126 modest_ui_actions_toggle_folders_view (GtkAction *action,
5127 ModestMainWindow *main_window)
5129 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
5131 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
5132 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
5134 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
5138 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
5139 ModestWindow *window)
5141 gboolean active, fullscreen = FALSE;
5142 ModestWindowMgr *mgr;
5144 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
5146 /* Check if we want to toggle the toolbar view in fullscreen
5148 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
5149 "ViewShowToolbarFullScreen")) {
5153 /* Toggle toolbar */
5154 mgr = modest_runtime_get_window_mgr ();
5155 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
5159 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
5160 ModestMsgEditWindow *window)
5162 modest_msg_edit_window_select_font (window);
5167 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
5168 const gchar *display_name,
5171 /* don't update the display name if it was already set;
5172 * updating the display name apparently is expensive */
5173 const gchar* old_name = gtk_window_get_title (window);
5175 if (display_name == NULL)
5178 if (old_name && display_name && strcmp (old_name, display_name) == 0)
5179 return; /* don't do anything */
5181 /* This is usually used to change the title of the main window, which
5182 * is the one that holds the folder view. Note that this change can
5183 * happen even when the widget doesn't have the focus. */
5184 gtk_window_set_title (window, display_name);
5189 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
5191 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5192 modest_msg_edit_window_select_contacts (window);
5196 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
5198 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5199 modest_msg_edit_window_check_names (window, FALSE);
5202 #ifndef MODEST_TOOLKIT_HILDON2
5204 * This function is used to track changes in the selection of the
5205 * folder view that is inside the "move to" dialog to enable/disable
5206 * the OK button because we do not want the user to select a disallowed
5207 * destination for a folder.
5208 * The user also not desired to be able to use NEW button on items where
5209 * folder creation is not possibel.
5212 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
5213 TnyFolderStore *folder_store,
5217 GtkWidget *dialog = NULL;
5218 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
5219 gboolean moving_folder = FALSE;
5220 gboolean is_local_account = TRUE;
5221 GtkWidget *folder_view = NULL;
5222 ModestTnyFolderRules rules;
5224 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
5229 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
5233 /* check if folder_store is an remote account */
5234 if (TNY_IS_ACCOUNT (folder_store)) {
5235 TnyAccount *local_account = NULL;
5236 TnyAccount *mmc_account = NULL;
5237 ModestTnyAccountStore *account_store = NULL;
5239 account_store = modest_runtime_get_account_store ();
5240 local_account = modest_tny_account_store_get_local_folders_account (account_store);
5241 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
5243 if ((gpointer) local_account != (gpointer) folder_store &&
5244 (gpointer) mmc_account != (gpointer) folder_store) {
5245 ModestProtocolType proto;
5246 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
5247 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
5248 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
5250 is_local_account = FALSE;
5251 /* New button should be dimmed on remote
5253 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5255 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
5257 g_object_unref (local_account);
5259 /* It could not exist */
5261 g_object_unref (mmc_account);
5264 /* Check the target folder rules */
5265 if (TNY_IS_FOLDER (folder_store)) {
5266 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
5267 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
5268 ok_sensitive = FALSE;
5269 new_sensitive = FALSE;
5274 /* Check if we're moving a folder */
5275 if (MODEST_IS_MAIN_WINDOW (user_data)) {
5276 /* Get the widgets */
5277 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
5278 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5279 if (gtk_widget_is_focus (folder_view))
5280 moving_folder = TRUE;
5283 if (moving_folder) {
5284 TnyFolderStore *moved_folder = NULL, *parent = NULL;
5286 /* Get the folder to move */
5287 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5289 /* Check that we're not moving to the same folder */
5290 if (TNY_IS_FOLDER (moved_folder)) {
5291 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
5292 if (parent == folder_store)
5293 ok_sensitive = FALSE;
5294 g_object_unref (parent);
5297 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
5298 /* Do not allow to move to an account unless it's the
5299 local folders account */
5300 if (!is_local_account)
5301 ok_sensitive = FALSE;
5304 if (ok_sensitive && (moved_folder == folder_store)) {
5305 /* Do not allow to move to itself */
5306 ok_sensitive = FALSE;
5308 g_object_unref (moved_folder);
5310 TnyFolder *src_folder = NULL;
5312 /* Moving a message */
5313 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
5315 TnyHeader *header = NULL;
5316 header = modest_msg_view_window_get_header
5317 (MODEST_MSG_VIEW_WINDOW (user_data));
5318 if (!TNY_IS_HEADER(header))
5319 g_warning ("%s: could not get source header", __FUNCTION__);
5321 src_folder = tny_header_get_folder (header);
5324 g_object_unref (header);
5327 TNY_FOLDER (modest_folder_view_get_selected
5328 (MODEST_FOLDER_VIEW (folder_view)));
5331 if (TNY_IS_FOLDER(src_folder)) {
5332 /* Do not allow to move the msg to the same folder */
5333 /* Do not allow to move the msg to an account */
5334 if ((gpointer) src_folder == (gpointer) folder_store ||
5335 TNY_IS_ACCOUNT (folder_store))
5336 ok_sensitive = FALSE;
5337 g_object_unref (src_folder);
5339 g_warning ("%s: could not get source folder", __FUNCTION__);
5343 /* Set sensitivity of the OK and NEW button */
5344 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
5345 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
5350 on_move_to_dialog_response (GtkDialog *dialog,
5354 GtkWidget *parent_win;
5355 MoveToInfo *helper = NULL;
5356 ModestFolderView *folder_view;
5357 gboolean unset_edit_mode = FALSE;
5359 helper = (MoveToInfo *) user_data;
5361 parent_win = (GtkWidget *) helper->win;
5362 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
5363 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
5365 TnyFolderStore *dst_folder;
5366 TnyFolderStore *selected;
5368 case MODEST_GTK_RESPONSE_NEW_FOLDER:
5369 selected = modest_folder_view_get_selected (folder_view);
5370 modest_ui_actions_create_folder (GTK_WIDGET (dialog), GTK_WIDGET (folder_view), selected);
5371 g_object_unref (selected);
5373 case GTK_RESPONSE_NONE:
5374 case GTK_RESPONSE_CANCEL:
5375 case GTK_RESPONSE_DELETE_EVENT:
5377 case GTK_RESPONSE_OK:
5378 dst_folder = modest_folder_view_get_selected (folder_view);
5380 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
5381 /* Clean list to move used for filtering */
5382 modest_folder_view_set_list_to_move (folder_view, NULL);
5384 modest_ui_actions_on_main_window_move_to (NULL,
5385 GTK_WIDGET (folder_view),
5387 MODEST_MAIN_WINDOW (parent_win));
5388 #ifdef MODEST_TOOLKIT_HILDON2
5389 } else if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
5390 /* Clean list to move used for filtering */
5391 modest_folder_view_set_list_to_move (folder_view, NULL);
5393 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
5396 GTK_WINDOW (parent_win));
5399 /* if the user selected a root folder
5400 (account) then do not perform any action */
5401 if (TNY_IS_ACCOUNT (dst_folder)) {
5402 g_signal_stop_emission_by_name (dialog, "response");
5406 /* Clean list to move used for filtering */
5407 modest_folder_view_set_list_to_move (folder_view, NULL);
5409 /* Moving from headers window in edit mode */
5410 modest_ui_actions_on_window_move_to (NULL, helper->list,
5412 MODEST_WINDOW (parent_win));
5416 g_object_unref (dst_folder);
5418 unset_edit_mode = TRUE;
5421 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
5424 /* Free the helper and exit */
5426 g_object_unref (helper->list);
5427 if (unset_edit_mode) {
5428 #ifdef MODEST_TOOLKIT_HILDON2
5429 modest_hildon2_window_unset_edit_mode (MODEST_HILDON2_WINDOW (helper->win));
5432 g_slice_free (MoveToInfo, helper);
5433 gtk_widget_destroy (GTK_WIDGET (dialog));
5437 create_move_to_dialog (GtkWindow *win,
5438 GtkWidget *folder_view,
5439 TnyList *list_to_move)
5441 GtkWidget *dialog, *tree_view = NULL;
5443 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
5445 #ifndef MODEST_TOOLKIT_HILDON2
5446 /* Track changes in the selection to
5447 * disable the OK button whenever "Move to" is not possible
5448 * disbale NEW button whenever New is not possible */
5449 g_signal_connect (tree_view,
5450 "folder_selection_changed",
5451 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
5455 /* It could happen that we're trying to move a message from a
5456 window (msg window for example) after the main window was
5457 closed, so we can not just get the model of the folder
5459 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
5460 const gchar *visible_id = NULL;
5462 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5463 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5464 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
5465 MODEST_FOLDER_VIEW(tree_view));
5468 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
5470 /* Show the same account than the one that is shown in the main window */
5471 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
5474 const gchar *active_account_name = NULL;
5475 ModestAccountMgr *mgr = NULL;
5476 ModestAccountSettings *settings = NULL;
5477 ModestServerAccountSettings *store_settings = NULL;
5479 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5480 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5482 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
5483 mgr = modest_runtime_get_account_mgr ();
5484 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
5487 const gchar *store_account_name;
5488 store_settings = modest_account_settings_get_store_settings (settings);
5489 store_account_name = modest_server_account_settings_get_account_name (store_settings);
5491 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
5492 store_account_name);
5493 g_object_unref (store_settings);
5494 g_object_unref (settings);
5498 /* we keep a pointer to the embedded folder view, so we can
5499 * retrieve it with get_folder_view_from_move_to_dialog (see
5500 * above) later (needed for focus handling)
5502 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
5504 /* Hide special folders */
5505 #ifndef MODEST_TOOLKIT_HILDON2
5506 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
5509 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
5510 #ifndef MODEST_TOOLKIT_HILDON2
5511 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5514 gtk_widget_show (GTK_WIDGET (tree_view));
5520 * Shows a confirmation dialog to the user when we're moving messages
5521 * from a remote server to the local storage. Returns the dialog
5522 * response. If it's other kind of movement then it always returns
5525 * This one is used by the next functions:
5526 * modest_ui_actions_on_paste - commented out
5527 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
5530 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
5531 TnyFolder *dest_folder,
5535 gint response = GTK_RESPONSE_OK;
5536 TnyAccount *account = NULL;
5537 TnyFolder *src_folder = NULL;
5538 TnyIterator *iter = NULL;
5539 TnyHeader *header = NULL;
5541 /* return with OK if the destination is a remote folder */
5542 if (modest_tny_folder_is_remote_folder (dest_folder))
5543 return GTK_RESPONSE_OK;
5545 /* Get source folder */
5546 iter = tny_list_create_iterator (headers);
5547 header = TNY_HEADER (tny_iterator_get_current (iter));
5549 src_folder = tny_header_get_folder (header);
5550 g_object_unref (header);
5552 g_object_unref (iter);
5554 /* if no src_folder, message may be an attahcment */
5555 if (src_folder == NULL)
5556 return GTK_RESPONSE_CANCEL;
5558 /* If the source is a local or MMC folder */
5559 if (!modest_tny_folder_is_remote_folder (src_folder)) {
5560 g_object_unref (src_folder);
5561 return GTK_RESPONSE_OK;
5564 /* Get the account */
5565 account = tny_folder_get_account (src_folder);
5567 /* now if offline we ask the user */
5568 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
5569 response = GTK_RESPONSE_OK;
5571 response = GTK_RESPONSE_CANCEL;
5574 g_object_unref (src_folder);
5575 g_object_unref (account);
5581 move_to_helper_destroyer (gpointer user_data)
5583 MoveToHelper *helper = (MoveToHelper *) user_data;
5585 /* Close the "Pasting" information banner */
5586 if (helper->banner) {
5587 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5588 g_object_unref (helper->banner);
5590 if (gtk_tree_row_reference_valid (helper->reference)) {
5591 gtk_tree_row_reference_free (helper->reference);
5592 helper->reference = NULL;
5598 move_to_cb (ModestMailOperation *mail_op,
5601 MoveToHelper *helper = (MoveToHelper *) user_data;
5602 GObject *object = modest_mail_operation_get_source (mail_op);
5604 /* Note that the operation could have failed, in that case do
5606 if (modest_mail_operation_get_status (mail_op) !=
5607 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5610 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5611 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5613 if (!modest_msg_view_window_select_next_message (self) &&
5614 !modest_msg_view_window_select_previous_message (self)) {
5615 /* No more messages to view, so close this window */
5616 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5618 } else if (MODEST_IS_MAIN_WINDOW (object) &&
5619 gtk_tree_row_reference_valid (helper->reference)) {
5620 GtkWidget *header_view;
5622 GtkTreeSelection *sel;
5624 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5625 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5626 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5627 path = gtk_tree_row_reference_get_path (helper->reference);
5628 /* We need to unselect the previous one
5629 because we could be copying instead of
5631 gtk_tree_selection_unselect_all (sel);
5632 gtk_tree_selection_select_path (sel, path);
5633 gtk_tree_path_free (path);
5635 g_object_unref (object);
5638 /* Destroy the helper */
5639 move_to_helper_destroyer (helper);
5643 folder_move_to_cb (ModestMailOperation *mail_op,
5644 TnyFolder *new_folder,
5647 GtkWidget *folder_view;
5650 object = modest_mail_operation_get_source (mail_op);
5651 if (MODEST_IS_MAIN_WINDOW (object)) {
5652 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5653 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5654 g_object_ref (folder_view);
5655 g_object_unref (object);
5656 move_to_cb (mail_op, user_data);
5657 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5658 g_object_unref (folder_view);
5660 move_to_cb (mail_op, user_data);
5665 msgs_move_to_cb (ModestMailOperation *mail_op,
5668 move_to_cb (mail_op, user_data);
5672 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5675 GObject *win = NULL;
5676 const GError *error;
5677 TnyAccount *account = NULL;
5679 #ifndef MODEST_TOOLKIT_HILDON2
5680 ModestWindow *main_window = NULL;
5682 /* Disable next automatic folder selection */
5683 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5684 FALSE); /* don't create */
5686 /* Show notification dialog only if the main window exists */
5688 GtkWidget *folder_view = NULL;
5690 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5691 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5692 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5694 if (user_data && TNY_IS_FOLDER (user_data)) {
5695 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5696 TNY_FOLDER (user_data), FALSE);
5700 win = modest_mail_operation_get_source (mail_op);
5701 error = modest_mail_operation_get_error (mail_op);
5703 if (TNY_IS_FOLDER (user_data))
5704 account = modest_tny_folder_get_account (TNY_FOLDER (user_data));
5705 else if (TNY_IS_ACCOUNT (user_data))
5706 account = g_object_ref (user_data);
5708 /* If it's not a disk full error then show a generic error */
5709 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5710 (GtkWidget *) win, (GError *) error,
5712 modest_platform_run_information_dialog ((GtkWindow *) win,
5713 _("mail_in_ui_folder_move_target_error"),
5716 g_object_unref (account);
5718 g_object_unref (win);
5722 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5731 gint pending_purges = 0;
5732 gboolean some_purged = FALSE;
5733 ModestWindow *win = MODEST_WINDOW (user_data);
5734 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5736 /* If there was any error */
5737 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5738 modest_window_mgr_unregister_header (mgr, header);
5742 /* Once the message has been retrieved for purging, we check if
5743 * it's all ok for purging */
5745 parts = tny_simple_list_new ();
5746 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5747 iter = tny_list_create_iterator (parts);
5749 while (!tny_iterator_is_done (iter)) {
5751 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5752 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5753 if (tny_mime_part_is_purged (part))
5760 g_object_unref (part);
5762 tny_iterator_next (iter);
5764 g_object_unref (iter);
5767 if (pending_purges>0) {
5769 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5771 if (response == GTK_RESPONSE_OK) {
5774 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5775 iter = tny_list_create_iterator (parts);
5776 while (!tny_iterator_is_done (iter)) {
5779 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5780 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5781 tny_mime_part_set_purged (part);
5784 g_object_unref (part);
5786 tny_iterator_next (iter);
5788 g_object_unref (iter);
5790 tny_msg_rewrite_cache (msg);
5792 gtk_widget_destroy (info);
5796 modest_window_mgr_unregister_header (mgr, header);
5798 g_object_unref (parts);
5802 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5803 ModestMainWindow *win)
5805 GtkWidget *header_view;
5806 TnyList *header_list;
5808 TnyHeaderFlags flags;
5809 ModestWindow *msg_view_window = NULL;
5812 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5814 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5815 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5817 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5819 g_warning ("%s: no header selected", __FUNCTION__);
5823 if (tny_list_get_length (header_list) == 1) {
5824 TnyIterator *iter = tny_list_create_iterator (header_list);
5825 header = TNY_HEADER (tny_iterator_get_current (iter));
5826 g_object_unref (iter);
5830 if (!header || !TNY_IS_HEADER(header)) {
5831 g_warning ("%s: header is not valid", __FUNCTION__);
5835 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5836 header, &msg_view_window);
5837 flags = tny_header_get_flags (header);
5838 if (!(flags & TNY_HEADER_FLAG_CACHED))
5841 if (msg_view_window != NULL)
5842 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5844 /* do nothing; uid was registered before, so window is probably on it's way */
5845 g_debug ("header %p has already been registered", header);
5848 ModestMailOperation *mail_op = NULL;
5849 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5850 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5851 modest_ui_actions_disk_operations_error_handler,
5853 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5854 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5856 g_object_unref (mail_op);
5859 g_object_unref (header);
5861 g_object_unref (header_list);
5865 * Checks if we need a connection to do the transfer and if the user
5866 * wants to connect to complete it
5869 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5870 TnyFolderStore *src_folder,
5872 TnyFolder *dst_folder,
5873 gboolean delete_originals,
5874 gboolean *need_connection,
5877 TnyAccount *src_account;
5878 gint uncached_msgs = 0;
5880 /* We don't need any further check if
5882 * 1- the source folder is local OR
5883 * 2- the device is already online
5885 if (!modest_tny_folder_store_is_remote (src_folder) ||
5886 tny_device_is_online (modest_runtime_get_device())) {
5887 *need_connection = FALSE;
5892 /* We must ask for a connection when
5894 * - the message(s) is not already cached OR
5895 * - the message(s) is cached but the leave_on_server setting
5896 * is FALSE (because we need to sync the source folder to
5897 * delete the message from the server (for IMAP we could do it
5898 * offline, it'll take place the next time we get a
5901 uncached_msgs = header_list_count_uncached_msgs (headers);
5902 src_account = get_account_from_folder_store (src_folder);
5903 if (uncached_msgs > 0) {
5907 *need_connection = TRUE;
5908 num_headers = tny_list_get_length (headers);
5909 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5911 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5912 GTK_RESPONSE_CANCEL) {
5918 /* The transfer is possible and the user wants to */
5921 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5922 const gchar *account_name;
5923 gboolean leave_on_server;
5925 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5926 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5929 if (leave_on_server == TRUE) {
5930 *need_connection = FALSE;
5932 *need_connection = TRUE;
5935 *need_connection = FALSE;
5940 g_object_unref (src_account);
5944 xfer_messages_error_handler (ModestMailOperation *mail_op,
5948 const GError *error;
5949 TnyAccount *account;
5951 win = modest_mail_operation_get_source (mail_op);
5952 error = modest_mail_operation_get_error (mail_op);
5954 /* We cannot get the account from the mail op as that is the
5955 source account and for checking memory full conditions we
5956 need the destination one */
5957 account = TNY_ACCOUNT (user_data);
5960 !modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5961 (GtkWidget *) win, (GError*) error,
5962 account, _KR("cerm_memory_card_full"))) {
5963 modest_platform_run_information_dialog ((GtkWindow *) win,
5964 _("mail_in_ui_folder_move_target_error"),
5968 g_object_unref (win);
5972 TnyFolderStore *dst_folder;
5977 * Utility function that transfer messages from both the main window
5978 * and the msg view window when using the "Move to" dialog
5981 xfer_messages_performer (gboolean canceled,
5983 GtkWindow *parent_window,
5984 TnyAccount *account,
5987 ModestWindow *win = MODEST_WINDOW (parent_window);
5988 TnyAccount *dst_account = NULL;
5989 gboolean dst_forbids_message_add = FALSE;
5990 XferMsgsHelper *helper;
5991 MoveToHelper *movehelper;
5992 ModestMailOperation *mail_op;
5994 helper = (XferMsgsHelper *) user_data;
5996 if (canceled || err) {
5997 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5998 (GtkWidget *) parent_window, err,
6000 /* Show the proper error message */
6001 modest_ui_actions_on_account_connection_error (parent_window, account);
6006 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
6008 /* tinymail will return NULL for local folders it seems */
6009 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
6010 modest_tny_account_get_protocol_type (dst_account),
6011 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
6013 if (dst_forbids_message_add) {
6014 modest_platform_information_banner (GTK_WIDGET (win),
6016 ngettext("mail_in_ui_folder_move_target_error",
6017 "mail_in_ui_folder_move_targets_error",
6018 tny_list_get_length (helper->headers)));
6022 movehelper = g_new0 (MoveToHelper, 1);
6024 #ifndef MODEST_TOOLKIT_HILDON2
6025 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
6026 _CS("ckct_nw_pasting"));
6027 if (movehelper->banner != NULL) {
6028 g_object_ref (movehelper->banner);
6029 gtk_widget_show (GTK_WIDGET (movehelper->banner));
6033 if (MODEST_IS_MAIN_WINDOW (win)) {
6034 GtkWidget *header_view =
6035 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6036 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6037 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
6040 /* Perform the mail operation */
6041 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
6042 xfer_messages_error_handler,
6043 g_object_ref (dst_account),
6045 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
6048 modest_mail_operation_xfer_msgs (mail_op,
6050 TNY_FOLDER (helper->dst_folder),
6055 g_object_unref (G_OBJECT (mail_op));
6058 g_object_unref (dst_account);
6059 g_object_unref (helper->dst_folder);
6060 g_object_unref (helper->headers);
6061 g_slice_free (XferMsgsHelper, helper);
6065 TnyFolder *src_folder;
6066 TnyFolderStore *dst_folder;
6067 gboolean delete_original;
6068 GtkWidget *folder_view;
6072 on_move_folder_cb (gboolean canceled,
6074 GtkWindow *parent_window,
6075 TnyAccount *account,
6078 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
6079 GtkTreeSelection *sel;
6080 ModestMailOperation *mail_op = NULL;
6082 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
6083 /* Note that the connection process can fail due to
6084 memory low conditions as it can not successfully
6085 store the summary */
6086 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6087 (GtkWidget*) parent_window, err,
6089 g_debug ("Error connecting when trying to move a folder");
6091 g_object_unref (G_OBJECT (info->src_folder));
6092 g_object_unref (G_OBJECT (info->dst_folder));
6097 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
6098 #ifndef MODEST_TOOLKIT_HILDON2
6099 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
6100 _CS("ckct_nw_pasting"));
6101 if (helper->banner != NULL) {
6102 g_object_ref (helper->banner);
6103 gtk_widget_show (GTK_WIDGET(helper->banner));
6106 /* Clean folder on header view before moving it */
6107 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
6108 gtk_tree_selection_unselect_all (sel);
6110 /* Let gtk events run. We need that the folder
6111 view frees its reference to the source
6112 folder *before* issuing the mail operation
6113 so we need the signal handler of selection
6114 changed to happen before the mail
6116 while (gtk_events_pending ())
6117 gtk_main_iteration (); */
6120 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
6121 modest_ui_actions_move_folder_error_handler,
6122 g_object_ref (info->dst_folder), g_object_unref);
6123 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
6126 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
6127 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
6128 TNY_FOLDER (info->dst_folder), TRUE);
6130 modest_mail_operation_xfer_folder (mail_op,
6131 TNY_FOLDER (info->src_folder),
6133 info->delete_original,
6136 g_object_unref (G_OBJECT (info->src_folder));
6138 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
6141 /* Unref mail operation */
6142 g_object_unref (G_OBJECT (mail_op));
6143 g_object_unref (G_OBJECT (info->dst_folder));
6148 get_account_from_folder_store (TnyFolderStore *folder_store)
6150 if (TNY_IS_ACCOUNT (folder_store))
6151 return g_object_ref (folder_store);
6153 return tny_folder_get_account (TNY_FOLDER (folder_store));
6157 * UI handler for the "Move to" action when invoked from the
6161 modest_ui_actions_on_main_window_move_to (GtkAction *action,
6162 GtkWidget *folder_view,
6163 TnyFolderStore *dst_folder,
6164 ModestMainWindow *win)
6166 ModestHeaderView *header_view = NULL;
6167 TnyFolderStore *src_folder = NULL;
6169 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
6171 /* Get the source folder */
6172 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6174 /* Get header view */
6175 header_view = (ModestHeaderView *)
6176 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6178 /* Get folder or messages to transfer */
6179 if (gtk_widget_is_focus (folder_view)) {
6180 gboolean do_xfer = TRUE;
6182 /* Allow only to transfer folders to the local root folder */
6183 if (TNY_IS_ACCOUNT (dst_folder) &&
6184 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
6185 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
6187 } else if (!TNY_IS_FOLDER (src_folder)) {
6188 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
6193 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
6194 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6196 info->src_folder = g_object_ref (src_folder);
6197 info->dst_folder = g_object_ref (dst_folder);
6198 info->delete_original = TRUE;
6199 info->folder_view = folder_view;
6201 connect_info->callback = on_move_folder_cb;
6202 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6203 connect_info->data = info;
6205 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6206 TNY_FOLDER_STORE (src_folder),
6209 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
6212 headers = modest_header_view_get_selected_headers(header_view);
6214 /* Transfer the messages */
6215 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
6216 headers, TNY_FOLDER (dst_folder));
6218 g_object_unref (headers);
6222 g_object_unref (src_folder);
6225 #ifdef MODEST_TOOLKIT_HILDON2
6227 * UI handler for the "Move to" action when invoked from the
6228 * ModestFolderWindow
6231 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
6232 TnyFolderStore *dst_folder,
6236 TnyFolderStore *src_folder = NULL;
6237 TnyIterator *iterator;
6239 if (tny_list_get_length (selection) != 1)
6242 iterator = tny_list_create_iterator (selection);
6243 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
6244 g_object_unref (iterator);
6247 gboolean do_xfer = TRUE;
6249 /* Allow only to transfer folders to the local root folder */
6250 if (TNY_IS_ACCOUNT (dst_folder) &&
6251 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
6252 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
6255 modest_platform_run_information_dialog (win,
6256 _("mail_in_ui_folder_move_target_error"),
6258 } else if (!TNY_IS_FOLDER (src_folder)) {
6259 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
6264 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
6265 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6267 info->src_folder = g_object_ref (src_folder);
6268 info->dst_folder = g_object_ref (dst_folder);
6269 info->delete_original = TRUE;
6270 info->folder_view = folder_view;
6272 connect_info->callback = on_move_folder_cb;
6273 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6274 connect_info->data = info;
6276 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6277 TNY_FOLDER_STORE (src_folder),
6282 g_object_unref (src_folder);
6288 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
6289 TnyFolder *src_folder,
6291 TnyFolder *dst_folder)
6293 gboolean need_connection = TRUE;
6294 gboolean do_xfer = TRUE;
6295 XferMsgsHelper *helper;
6297 g_return_if_fail (TNY_IS_FOLDER (src_folder));
6298 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6299 g_return_if_fail (TNY_IS_LIST (headers));
6301 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
6302 headers, TNY_FOLDER (dst_folder),
6303 TRUE, &need_connection,
6306 /* If we don't want to transfer just return */
6310 /* Create the helper */
6311 helper = g_slice_new (XferMsgsHelper);
6312 helper->dst_folder = g_object_ref (dst_folder);
6313 helper->headers = g_object_ref (headers);
6315 if (need_connection) {
6316 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6317 connect_info->callback = xfer_messages_performer;
6318 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
6319 connect_info->data = helper;
6321 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6322 TNY_FOLDER_STORE (src_folder),
6325 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
6326 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
6327 src_account, helper);
6328 g_object_unref (src_account);
6333 * UI handler for the "Move to" action when invoked from the
6334 * ModestMsgViewWindow
6337 modest_ui_actions_on_window_move_to (GtkAction *action,
6339 TnyFolderStore *dst_folder,
6342 TnyFolder *src_folder = NULL;
6344 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6347 TnyHeader *header = NULL;
6350 iter = tny_list_create_iterator (headers);
6351 header = (TnyHeader *) tny_iterator_get_current (iter);
6352 src_folder = tny_header_get_folder (header);
6354 /* Transfer the messages */
6355 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
6357 TNY_FOLDER (dst_folder));
6360 g_object_unref (header);
6361 g_object_unref (iter);
6362 g_object_unref (src_folder);
6367 modest_ui_actions_on_move_to (GtkAction *action,
6370 modest_ui_actions_on_edit_mode_move_to (win);
6374 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
6376 GtkWidget *dialog = NULL;
6377 MoveToInfo *helper = NULL;
6378 TnyList *list_to_move;
6380 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
6382 #ifndef MODEST_TOOLKIT_HILDON2
6383 /* Get the main window if exists */
6384 ModestMainWindow *main_window;
6385 if (MODEST_IS_MAIN_WINDOW (win))
6386 main_window = MODEST_MAIN_WINDOW (win);
6389 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
6390 FALSE)); /* don't create */
6393 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
6398 if (tny_list_get_length (list_to_move) < 1) {
6399 g_object_unref (list_to_move);
6403 /* Create and run the dialog */
6404 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
6405 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
6406 GTK_WINDOW (dialog),
6410 helper = g_slice_new0 (MoveToInfo);
6411 helper->list = list_to_move;
6414 /* Listen to response signal */
6415 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
6417 /* Show the dialog */
6418 gtk_widget_show (dialog);
6424 * Calls #HeadersFunc for each header already selected in the main
6425 * window or the message currently being shown in the msg view window
6428 do_headers_action (ModestWindow *win,
6432 TnyList *headers_list = NULL;
6433 TnyIterator *iter = NULL;
6434 TnyHeader *header = NULL;
6435 TnyFolder *folder = NULL;
6438 headers_list = get_selected_headers (win);
6442 /* Get the folder */
6443 iter = tny_list_create_iterator (headers_list);
6444 header = TNY_HEADER (tny_iterator_get_current (iter));
6446 folder = tny_header_get_folder (header);
6447 g_object_unref (header);
6450 /* Call the function for each header */
6451 while (!tny_iterator_is_done (iter)) {
6452 header = TNY_HEADER (tny_iterator_get_current (iter));
6453 func (header, win, user_data);
6454 g_object_unref (header);
6455 tny_iterator_next (iter);
6458 /* Trick: do a poke status in order to speed up the signaling
6461 tny_folder_poke_status (folder);
6462 g_object_unref (folder);
6466 g_object_unref (iter);
6467 g_object_unref (headers_list);
6471 modest_ui_actions_view_attachment (GtkAction *action,
6472 ModestWindow *window)
6474 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6475 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
6477 /* not supported window for this action */
6478 g_return_if_reached ();
6483 modest_ui_actions_save_attachments (GtkAction *action,
6484 ModestWindow *window)
6486 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6488 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
6491 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
6493 /* not supported window for this action */
6494 g_return_if_reached ();
6499 modest_ui_actions_remove_attachments (GtkAction *action,
6500 ModestWindow *window)
6502 if (MODEST_IS_MAIN_WINDOW (window)) {
6503 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
6504 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6505 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
6507 /* not supported window for this action */
6508 g_return_if_reached ();
6513 modest_ui_actions_on_settings (GtkAction *action,
6518 dialog = modest_platform_get_global_settings_dialog ();
6519 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
6520 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
6521 gtk_widget_show_all (dialog);
6523 gtk_dialog_run (GTK_DIALOG (dialog));
6525 gtk_widget_destroy (dialog);
6529 modest_ui_actions_on_help (GtkAction *action,
6532 /* Help app is not available at all in fremantle */
6533 #ifndef MODEST_TOOLKIT_HILDON2
6534 const gchar *help_id;
6536 g_return_if_fail (win && GTK_IS_WINDOW(win));
6538 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
6541 modest_platform_show_help (GTK_WINDOW (win), help_id);
6546 modest_ui_actions_on_csm_help (GtkAction *action,
6549 /* Help app is not available at all in fremantle */
6550 #ifndef MODEST_TOOLKIT_HILDON2
6552 const gchar* help_id = NULL;
6553 GtkWidget *folder_view;
6554 TnyFolderStore *folder_store;
6556 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
6558 /* Get selected folder */
6559 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
6560 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6561 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6563 /* Switch help_id */
6564 if (folder_store && TNY_IS_FOLDER (folder_store))
6565 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
6568 g_object_unref (folder_store);
6571 modest_platform_show_help (GTK_WINDOW (win), help_id);
6573 modest_ui_actions_on_help (action, win);
6578 retrieve_contents_cb (ModestMailOperation *mail_op,
6585 /* We only need this callback to show an error in case of
6586 memory low condition */
6587 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
6588 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
6593 retrieve_msg_contents_performer (gboolean canceled,
6595 GtkWindow *parent_window,
6596 TnyAccount *account,
6599 ModestMailOperation *mail_op;
6600 TnyList *headers = TNY_LIST (user_data);
6602 if (err || canceled) {
6603 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6604 (GtkWidget *) parent_window, err,
6609 /* Create mail operation */
6610 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
6611 modest_ui_actions_disk_operations_error_handler,
6613 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
6614 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
6617 g_object_unref (mail_op);
6619 g_object_unref (headers);
6620 g_object_unref (account);
6624 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
6625 ModestWindow *window)
6627 TnyList *headers = NULL;
6628 TnyAccount *account = NULL;
6629 TnyIterator *iter = NULL;
6630 TnyHeader *header = NULL;
6631 TnyFolder *folder = NULL;
6634 headers = get_selected_headers (window);
6638 /* Pick the account */
6639 iter = tny_list_create_iterator (headers);
6640 header = TNY_HEADER (tny_iterator_get_current (iter));
6641 folder = tny_header_get_folder (header);
6642 account = tny_folder_get_account (folder);
6643 g_object_unref (folder);
6644 g_object_unref (header);
6645 g_object_unref (iter);
6647 /* Connect and perform the message retrieval */
6648 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6649 g_object_ref (account),
6650 retrieve_msg_contents_performer,
6651 g_object_ref (headers));
6654 g_object_unref (account);
6655 g_object_unref (headers);
6659 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6661 g_return_if_fail (MODEST_IS_WINDOW (window));
6664 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6668 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6670 g_return_if_fail (MODEST_IS_WINDOW (window));
6673 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6677 modest_ui_actions_on_email_menu_activated (GtkAction *action,
6678 ModestWindow *window)
6680 g_return_if_fail (MODEST_IS_WINDOW (window));
6683 modest_ui_actions_check_menu_dimming_rules (window);
6687 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
6688 ModestWindow *window)
6690 g_return_if_fail (MODEST_IS_WINDOW (window));
6693 modest_ui_actions_check_menu_dimming_rules (window);
6697 modest_ui_actions_on_view_menu_activated (GtkAction *action,
6698 ModestWindow *window)
6700 g_return_if_fail (MODEST_IS_WINDOW (window));
6703 modest_ui_actions_check_menu_dimming_rules (window);
6707 modest_ui_actions_on_format_menu_activated (GtkAction *action,
6708 ModestWindow *window)
6710 g_return_if_fail (MODEST_IS_WINDOW (window));
6713 modest_ui_actions_check_menu_dimming_rules (window);
6717 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
6718 ModestWindow *window)
6720 g_return_if_fail (MODEST_IS_WINDOW (window));
6723 modest_ui_actions_check_menu_dimming_rules (window);
6727 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
6728 ModestWindow *window)
6730 g_return_if_fail (MODEST_IS_WINDOW (window));
6733 modest_ui_actions_check_menu_dimming_rules (window);
6737 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
6738 ModestWindow *window)
6740 g_return_if_fail (MODEST_IS_WINDOW (window));
6743 modest_ui_actions_check_menu_dimming_rules (window);
6747 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
6748 ModestWindow *window)
6750 g_return_if_fail (MODEST_IS_WINDOW (window));
6753 modest_ui_actions_check_menu_dimming_rules (window);
6757 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
6758 ModestWindow *window)
6760 g_return_if_fail (MODEST_IS_WINDOW (window));
6763 modest_ui_actions_check_menu_dimming_rules (window);
6767 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6769 g_return_if_fail (MODEST_IS_WINDOW (window));
6771 /* we check for low-mem; in that case, show a warning, and don't allow
6774 if (modest_platform_check_memory_low (window, TRUE))
6777 modest_platform_show_search_messages (GTK_WINDOW (window));
6781 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6783 g_return_if_fail (MODEST_IS_WINDOW (win));
6786 /* we check for low-mem; in that case, show a warning, and don't allow
6787 * for the addressbook
6789 if (modest_platform_check_memory_low (win, TRUE))
6793 modest_platform_show_addressbook (GTK_WINDOW (win));
6798 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6799 ModestWindow *window)
6802 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6804 if (GTK_IS_TOGGLE_ACTION (action))
6805 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6809 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window),
6814 on_send_receive_finished (ModestMailOperation *mail_op,
6817 GtkWidget *header_view, *folder_view;
6818 TnyFolderStore *folder_store;
6819 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6821 /* Set send/receive operation finished */
6822 modest_main_window_notify_send_receive_completed (main_win);
6824 /* Don't refresh the current folder if there were any errors */
6825 if (modest_mail_operation_get_status (mail_op) !=
6826 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6829 /* Refresh the current folder if we're viewing a window. We do
6830 this because the user won't be able to see the new mails in
6831 the selected folder after a Send&Receive because it only
6832 performs a poke_status, i.e, only the number of read/unread
6833 messages is updated, but the new headers are not
6835 folder_view = modest_main_window_get_child_widget (main_win,
6836 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6840 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6842 /* Do not need to refresh INBOX again because the
6843 update_account does it always automatically */
6844 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6845 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6846 ModestMailOperation *refresh_op;
6848 header_view = modest_main_window_get_child_widget (main_win,
6849 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6851 /* We do not need to set the contents style
6852 because it hasn't changed. We also do not
6853 need to save the widget status. Just force
6855 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6856 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6857 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6858 folder_refreshed_cb, main_win);
6859 g_object_unref (refresh_op);
6863 g_object_unref (folder_store);
6868 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6874 const gchar* server_name = NULL;
6875 TnyTransportAccount *transport;
6876 gchar *message = NULL;
6877 ModestProtocol *protocol;
6879 /* Don't show anything if the user cancelled something or the
6880 * send receive request is not interactive. Authentication
6881 * errors are managed by the account store so no need to show
6882 * a dialog here again */
6883 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6884 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6885 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6889 /* Get the server name. Note that we could be using a
6890 connection specific transport account */
6891 transport = (TnyTransportAccount *)
6892 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
6894 ModestTnyAccountStore *acc_store;
6895 const gchar *acc_name;
6896 TnyTransportAccount *conn_specific;
6898 acc_store = modest_runtime_get_account_store();
6899 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
6900 conn_specific = (TnyTransportAccount *)
6901 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
6902 if (conn_specific) {
6903 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
6904 g_object_unref (conn_specific);
6906 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
6908 g_object_unref (transport);
6912 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
6913 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
6914 tny_account_get_proto (TNY_ACCOUNT (transport)));
6916 g_warning ("%s: Account with no proto", __FUNCTION__);
6920 /* Show the appropriate message text for the GError: */
6921 switch (err->code) {
6922 case TNY_SERVICE_ERROR_CONNECT:
6923 message = modest_protocol_get_translation (protocol,
6924 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
6927 case TNY_SERVICE_ERROR_SEND:
6928 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6930 case TNY_SERVICE_ERROR_UNAVAILABLE:
6931 message = modest_protocol_get_translation (protocol,
6932 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
6936 g_warning ("%s: unexpected ERROR %d",
6937 __FUNCTION__, err->code);
6938 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6942 modest_platform_run_information_dialog (NULL, message, FALSE);
6947 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6952 ModestWindow *top_window = NULL;
6953 ModestWindowMgr *mgr = NULL;
6954 GtkWidget *header_view = NULL;
6955 TnyFolder *selected_folder = NULL;
6956 TnyFolderType folder_type;
6958 mgr = modest_runtime_get_window_mgr ();
6959 top_window = modest_window_mgr_get_current_top (mgr);
6964 #ifndef MODEST_TOOLKIT_HILDON2
6965 if (MODEST_IS_MAIN_WINDOW (top_window)) {
6966 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (top_window),
6967 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6970 if (MODEST_IS_HEADER_WINDOW (top_window)) {
6971 header_view = (GtkWidget *)
6972 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
6976 /* Get selected folder */
6978 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
6979 if (!selected_folder)
6982 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6983 #if GTK_CHECK_VERSION(2, 8, 0)
6984 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
6985 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6986 GtkTreeViewColumn *tree_column;
6988 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6989 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6991 gtk_tree_view_column_queue_resize (tree_column);
6993 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
6994 gtk_widget_queue_draw (header_view);
6997 #ifndef MODEST_TOOLKIT_HILDON2
6998 /* Rerun dimming rules, because the message could become deletable for example */
6999 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
7000 MODEST_DIMMING_RULES_TOOLBAR);
7001 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
7002 MODEST_DIMMING_RULES_MENU);
7006 g_object_unref (selected_folder);
7010 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
7011 TnyAccount *account)
7013 ModestProtocolType protocol_type;
7014 ModestProtocol *protocol;
7015 gchar *error_note = NULL;
7017 protocol_type = modest_tny_account_get_protocol_type (account);
7018 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
7021 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
7022 if (error_note == NULL) {
7023 g_warning ("%s: This should not be reached", __FUNCTION__);
7025 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
7026 g_free (error_note);
7031 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
7035 TnyFolderStore *folder = NULL;
7036 TnyAccount *account = NULL;
7037 ModestProtocolType proto;
7038 ModestProtocol *protocol;
7039 TnyHeader *header = NULL;
7041 if (MODEST_IS_MAIN_WINDOW (win)) {
7042 GtkWidget *header_view;
7043 TnyList* headers = NULL;
7045 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
7046 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
7047 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
7048 if (!headers || tny_list_get_length (headers) == 0) {
7050 g_object_unref (headers);
7053 iter = tny_list_create_iterator (headers);
7054 header = TNY_HEADER (tny_iterator_get_current (iter));
7055 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
7056 g_object_unref (iter);
7057 g_object_unref (headers);
7058 #ifdef MODEST_TOOLKIT_HILDON2
7059 } else if (MODEST_IS_HEADER_WINDOW (win)) {
7060 GtkWidget *header_view;
7061 TnyList* headers = NULL;
7063 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
7064 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
7065 if (!headers || tny_list_get_length (headers) == 0) {
7067 g_object_unref (headers);
7070 iter = tny_list_create_iterator (headers);
7071 header = TNY_HEADER (tny_iterator_get_current (iter));
7073 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
7075 g_warning ("List should contain headers");
7077 g_object_unref (iter);
7078 g_object_unref (headers);
7080 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
7081 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
7083 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
7086 if (!header || !folder)
7089 /* Get the account type */
7090 account = tny_folder_get_account (TNY_FOLDER (folder));
7091 proto = modest_tny_account_get_protocol_type (account);
7092 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
7095 subject = tny_header_dup_subject (header);
7096 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
7100 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
7106 g_object_unref (account);
7108 g_object_unref (folder);
7110 g_object_unref (header);
7116 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
7117 const gchar *account_name,
7118 const gchar *account_title)
7120 ModestAccountMgr *account_mgr;
7123 ModestProtocol *protocol;
7124 gboolean removed = FALSE;
7126 g_return_val_if_fail (account_name, FALSE);
7127 g_return_val_if_fail (account_title, FALSE);
7129 account_mgr = modest_runtime_get_account_mgr();
7131 /* The warning text depends on the account type: */
7132 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
7133 modest_account_mgr_get_store_protocol (account_mgr,
7135 txt = modest_protocol_get_translation (protocol,
7136 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
7139 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
7141 response = modest_platform_run_confirmation_dialog (parent_window, txt);
7145 if (response == GTK_RESPONSE_OK) {
7146 /* Remove account. If it succeeds then it also removes
7147 the account from the ModestAccountView: */
7148 gboolean is_default = FALSE;
7149 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
7150 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
7152 g_free (default_account_name);
7154 removed = modest_account_mgr_remove_account (account_mgr, account_name);
7156 #ifdef MODEST_TOOLKIT_HILDON2
7157 hildon_gtk_window_take_screenshot (parent_window, FALSE);
7159 /* Close all email notifications, we cannot
7160 distinguish if the notification belongs to
7161 this account or not, so for safety reasons
7162 we remove them all */
7163 modest_platform_remove_new_mail_notifications (FALSE, account_name);
7165 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
7172 on_fetch_images_performer (gboolean canceled,
7174 GtkWindow *parent_window,
7175 TnyAccount *account,
7178 if (err || canceled) {
7179 /* Show an unable to retrieve images ??? */
7183 /* Note that the user could have closed the window while connecting */
7184 if (GTK_WIDGET_VISIBLE (parent_window))
7185 modest_msg_view_window_fetch_images ((ModestMsgViewWindow *) parent_window);
7186 g_object_unref ((GObject *) user_data);
7190 modest_ui_actions_on_fetch_images (GtkAction *action,
7191 ModestWindow *window)
7193 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
7195 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
7197 on_fetch_images_performer,
7198 g_object_ref (window));
7202 modest_ui_actions_on_reload_message (const gchar *msg_id)
7204 ModestWindow *window = NULL;
7206 g_return_if_fail (msg_id && msg_id[0] != '\0');
7207 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
7213 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
7216 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));
7219 /** Check whether any connections are active, and cancel them if
7221 * Returns TRUE is there was no problem,
7222 * or if an operation was cancelled so we can continue.
7223 * Returns FALSE if the user chose to cancel his request instead.
7227 modest_ui_actions_check_for_active_account (ModestWindow *self,
7228 const gchar* account_name)
7230 ModestTnySendQueue *send_queue;
7231 ModestTnyAccountStore *acc_store;
7232 ModestMailOperationQueue* queue;
7233 TnyConnectionStatus store_conn_status;
7234 TnyAccount *store_account = NULL, *transport_account = NULL;
7235 gboolean retval = TRUE, sending = FALSE;
7237 acc_store = modest_runtime_get_account_store ();
7238 queue = modest_runtime_get_mail_operation_queue ();
7241 modest_tny_account_store_get_server_account (acc_store,
7243 TNY_ACCOUNT_TYPE_STORE);
7245 /* This could happen if the account was deleted before the
7246 call to this function */
7251 modest_tny_account_store_get_server_account (acc_store,
7253 TNY_ACCOUNT_TYPE_TRANSPORT);
7255 /* This could happen if the account was deleted before the
7256 call to this function */
7257 if (!transport_account) {
7258 g_object_unref (store_account);
7262 /* If the transport account was not used yet, then the send
7263 queue could not exist (it's created on demand) */
7264 send_queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (transport_account), FALSE);
7265 if (TNY_IS_SEND_QUEUE (send_queue))
7266 sending = modest_tny_send_queue_sending_in_progress (send_queue);
7268 store_conn_status = tny_account_get_connection_status (store_account);
7269 if (store_conn_status == TNY_CONNECTION_STATUS_CONNECTED || sending) {
7272 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (self),
7273 _("emev_nc_disconnect_account"));
7274 if (response == GTK_RESPONSE_OK) {
7283 /* FIXME: We should only cancel those of this account */
7284 modest_mail_operation_queue_cancel_all (queue);
7286 /* Also disconnect the account */
7287 if ((tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED) &&
7288 (tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)) {
7289 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
7293 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (transport_account),
7299 g_object_unref (store_account);
7300 g_object_unref (transport_account);