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>
61 #include "modest-utils.h"
62 #include "widgets/modest-connection-specific-smtp-window.h"
63 #include "widgets/modest-ui-constants.h"
64 #include <widgets/modest-main-window.h>
65 #include <widgets/modest-msg-view-window.h>
66 #include <widgets/modest-account-view-window.h>
67 #include <widgets/modest-details-dialog.h>
68 #include <widgets/modest-attachments-view.h>
69 #include "widgets/modest-folder-view.h"
70 #include "widgets/modest-global-settings-dialog.h"
71 #include "modest-account-mgr-helpers.h"
72 #include "modest-mail-operation.h"
73 #include "modest-text-utils.h"
74 #include <modest-widget-memory.h>
75 #include <tny-error.h>
76 #include <tny-simple-list.h>
77 #include <tny-msg-view.h>
78 #include <tny-device.h>
79 #include <tny-merge-folder.h>
81 #include <gtkhtml/gtkhtml.h>
83 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
85 typedef struct _GetMsgAsyncHelper {
87 ModestMailOperation *mail_op;
94 typedef enum _ReplyForwardAction {
100 typedef struct _ReplyForwardHelper {
101 guint reply_forward_type;
102 ReplyForwardAction action;
105 GtkWidget *parent_window;
107 } ReplyForwardHelper;
109 typedef struct _MoveToHelper {
110 GtkTreeRowReference *reference;
114 typedef struct _PasteAsAttachmentHelper {
115 ModestMsgEditWindow *window;
117 } PasteAsAttachmentHelper;
125 * The do_headers_action uses this kind of functions to perform some
126 * action to each member of a list of headers
128 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
130 static void do_headers_action (ModestWindow *win,
134 static void open_msg_cb (ModestMailOperation *mail_op,
141 static void reply_forward_cb (ModestMailOperation *mail_op,
148 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
150 #ifndef MODEST_TOOLKIT_HILDON2
151 static void folder_refreshed_cb (ModestMailOperation *mail_op,
155 static void on_send_receive_finished (ModestMailOperation *mail_op,
159 static gint header_list_count_uncached_msgs (TnyList *header_list);
161 static gboolean connect_to_get_msg (ModestWindow *win,
162 gint num_of_uncached_msgs,
163 TnyAccount *account);
165 static gboolean remote_folder_has_leave_on_server (TnyFolderStore *folder);
167 static void do_create_folder (GtkWindow *window,
168 TnyFolderStore *parent_folder,
169 const gchar *suggested_name);
171 static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store);
173 #ifndef MODEST_TOOLKIT_HILDON2
174 static void modest_ui_actions_on_main_window_move_to (GtkAction *action,
175 GtkWidget *folder_view,
176 TnyFolderStore *dst_folder,
177 ModestMainWindow *win);
180 static void modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
181 TnyFolderStore *dst_folder,
186 static void modest_ui_actions_on_window_move_to (GtkAction *action,
187 TnyList *list_to_move,
188 TnyFolderStore *dst_folder,
192 * This function checks whether a TnyFolderStore is a pop account
195 remote_folder_has_leave_on_server (TnyFolderStore *folder)
200 g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
202 account = get_account_from_folder_store (folder);
203 result = (modest_protocol_registry_protocol_type_has_leave_on_server (modest_runtime_get_protocol_registry (),
204 modest_tny_account_get_protocol_type (account)));
205 g_object_unref (account);
210 /* FIXME: this should be merged with the similar code in modest-account-view-window */
211 /* Show the account creation wizard dialog.
212 * returns: TRUE if an account was created. FALSE if the user cancelled.
215 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
217 gboolean result = FALSE;
219 gint dialog_response;
221 /* there is no such wizard yet */
222 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
223 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (wizard), (GtkWindow *) win);
225 #ifndef MODEST_TOOLKIT_HILDON2
226 /* always present a main window in the background
227 * we do it here, so we cannot end up with two wizards (as this
228 * function might be called in modest_window_mgr_get_main_window as well */
230 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
231 TRUE); /* create if not existent */
235 ModestWindowMgr *mgr;
237 mgr = modest_runtime_get_window_mgr ();
239 window_list = modest_window_mgr_get_window_list (mgr);
240 if (window_list == NULL) {
241 win = MODEST_WINDOW (modest_accounts_window_new ());
242 if (modest_window_mgr_register_window (mgr, win, NULL)) {
243 gtk_widget_show_all (GTK_WIDGET (win));
245 gtk_widget_destroy (GTK_WIDGET (win));
250 g_list_free (window_list);
256 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
258 /* make sure the mainwindow is visible. We need to present the
259 wizard again to give it the focus back. show_all are needed
260 in order to get the widgets properly drawn (MainWindow main
261 paned won't be in its right position and the dialog will be
263 #ifndef MODEST_TOOLKIT_HILDON2
264 gtk_widget_show_all (GTK_WIDGET (win));
265 gtk_widget_show_all (GTK_WIDGET (wizard));
266 gtk_window_present (GTK_WINDOW (win));
267 gtk_window_present (GTK_WINDOW (wizard));
270 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
271 gtk_widget_destroy (GTK_WIDGET (wizard));
272 if (gtk_events_pending ())
273 gtk_main_iteration ();
275 if (dialog_response == GTK_RESPONSE_CANCEL) {
278 /* Check whether an account was created: */
279 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
286 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
289 const gchar *authors[] = {
290 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
293 about = gtk_about_dialog_new ();
294 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
295 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
296 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
297 _("Copyright (c) 2006, Nokia Corporation\n"
298 "All rights reserved."));
299 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
300 _("a modest e-mail client\n\n"
301 "design and implementation: Dirk-Jan C. Binnema\n"
302 "contributions from the fine people at KC and Ig\n"
303 "uses the tinymail email framework written by Philip van Hoof"));
304 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
305 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
306 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
307 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
309 gtk_dialog_run (GTK_DIALOG (about));
310 gtk_widget_destroy(about);
314 * Gets the list of currently selected messages. If the win is the
315 * main window, then it returns a newly allocated list of the headers
316 * selected in the header view. If win is the msg view window, then
317 * the value returned is a list with just a single header.
319 * The caller of this funcion must free the list.
322 get_selected_headers (ModestWindow *win)
324 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
325 /* for MsgViewWindows, we simply return a list with one element */
327 TnyList *list = NULL;
329 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
330 if (header != NULL) {
331 list = tny_simple_list_new ();
332 tny_list_prepend (list, G_OBJECT(header));
333 g_object_unref (G_OBJECT(header));
337 #ifndef MODEST_TOOLKIT_HILDON2
338 } else if (MODEST_IS_MAIN_WINDOW(win)) {
339 GtkWidget *header_view;
341 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
342 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
343 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
345 } else if (MODEST_IS_HEADER_WINDOW (win)) {
346 GtkWidget *header_view;
348 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
349 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
356 #ifndef MODEST_TOOLKIT_HILDON2
357 static GtkTreeRowReference *
358 get_next_after_selected_headers (ModestHeaderView *header_view)
360 GtkTreeSelection *sel;
361 GList *selected_rows, *node;
363 GtkTreeRowReference *result;
366 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
367 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
368 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
370 if (selected_rows == NULL)
373 node = g_list_last (selected_rows);
374 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
375 gtk_tree_path_next (path);
377 result = gtk_tree_row_reference_new (model, path);
379 gtk_tree_path_free (path);
380 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
381 g_list_free (selected_rows);
388 headers_action_mark_as_read (TnyHeader *header,
392 TnyHeaderFlags flags;
394 g_return_if_fail (TNY_IS_HEADER(header));
396 flags = tny_header_get_flags (header);
397 if (flags & TNY_HEADER_FLAG_SEEN) return;
398 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
402 headers_action_mark_as_unread (TnyHeader *header,
406 TnyHeaderFlags flags;
408 g_return_if_fail (TNY_IS_HEADER(header));
410 flags = tny_header_get_flags (header);
411 if (flags & TNY_HEADER_FLAG_SEEN) {
412 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
416 /** After deleing a message that is currently visible in a window,
417 * show the next message from the list, or close the window if there are no more messages.
420 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
422 /* Close msg view window or select next */
423 if (!modest_msg_view_window_select_next_message (win) &&
424 !modest_msg_view_window_select_previous_message (win)) {
426 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
432 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
434 modest_ui_actions_on_edit_mode_delete_message (win);
438 modest_ui_actions_on_edit_mode_delete_message (ModestWindow *win)
440 TnyList *header_list = NULL;
441 TnyIterator *iter = NULL;
442 TnyHeader *header = NULL;
443 gchar *message = NULL;
446 ModestWindowMgr *mgr;
447 gboolean retval = TRUE;
449 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
451 #ifndef MODEST_TOOLKIT_HILDON2
452 /* Check first if the header view has the focus */
453 if (MODEST_IS_MAIN_WINDOW (win)) {
454 GtkWidget *header_view = NULL;
457 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
458 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
459 if (!gtk_widget_is_focus (header_view))
463 /* Get the headers, either from the header view (if win is the main window),
464 * or from the message view window: */
465 header_list = get_selected_headers (win);
466 if (!header_list) return FALSE;
468 /* Check if any of the headers are already opened, or in the process of being opened */
469 #ifndef MODEST_TOOLKIT_HILDON2
470 if (MODEST_IS_MAIN_WINDOW (win)) {
471 gint opened_headers = 0;
473 iter = tny_list_create_iterator (header_list);
474 mgr = modest_runtime_get_window_mgr ();
475 while (!tny_iterator_is_done (iter)) {
476 header = TNY_HEADER (tny_iterator_get_current (iter));
478 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
480 g_object_unref (header);
482 tny_iterator_next (iter);
484 g_object_unref (iter);
486 if (opened_headers > 0) {
489 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
492 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg, FALSE);
495 g_object_unref (header_list);
502 if (tny_list_get_length(header_list) == 1) {
503 iter = tny_list_create_iterator (header_list);
504 header = TNY_HEADER (tny_iterator_get_current (iter));
507 subject = tny_header_dup_subject (header);
509 subject = g_strdup (_("mail_va_no_subject"));
510 desc = g_strdup_printf ("%s", subject);
512 g_object_unref (header);
515 g_object_unref (iter);
517 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
518 tny_list_get_length(header_list)), desc);
520 /* Confirmation dialog */
521 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
524 if (response == GTK_RESPONSE_OK) {
525 GtkTreeSelection *sel = NULL;
526 GList *sel_list = NULL;
527 ModestMailOperation *mail_op = NULL;
529 /* Find last selected row */
530 #ifndef MODEST_TOOLKIT_HILDON2
531 if (MODEST_IS_MAIN_WINDOW (win)) {
533 ModestWindowMgr *mgr = NULL;
534 GtkTreeModel *model = NULL;
535 GtkTreeRowReference *next_row_reference = NULL, *prev_row_reference = NULL;
536 GtkTreePath *next_path = NULL, *prev_path = NULL;
538 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
539 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
540 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
541 for (tmp=sel_list; tmp; tmp=tmp->next) {
542 if (tmp->next == NULL) {
543 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
544 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
546 gtk_tree_path_prev (prev_path);
547 gtk_tree_path_next (next_path);
549 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
550 next_row_reference = gtk_tree_row_reference_new (model, next_path);
556 /* Disable window dimming management */
557 modest_window_disable_dimming (win);
559 /* Remove each header. If it's a view window header_view == NULL */
560 mail_op = modest_mail_operation_new ((GObject *) win);
561 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
563 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
564 g_object_unref (mail_op);
566 /* Enable window dimming management */
568 gtk_tree_selection_unselect_all (sel);
570 modest_window_enable_dimming (win);
572 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
573 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
575 /* Get main window */
576 mgr = modest_runtime_get_window_mgr ();
577 #ifndef MODEST_TOOLKIT_HILDON2
578 } else if (MODEST_IS_MAIN_WINDOW (win)) {
579 /* Select next or previous row */
580 if (gtk_tree_row_reference_valid (next_row_reference)) {
581 gtk_tree_selection_select_path (sel, next_path);
583 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
584 gtk_tree_selection_select_path (sel, prev_path);
588 if (gtk_tree_row_reference_valid (next_row_reference))
589 gtk_tree_row_reference_free (next_row_reference);
590 if (next_path != NULL)
591 gtk_tree_path_free (next_path);
592 if (gtk_tree_row_reference_valid (prev_row_reference))
593 gtk_tree_row_reference_free (prev_row_reference);
594 if (prev_path != NULL)
595 gtk_tree_path_free (prev_path);
599 /* Update toolbar dimming state */
600 modest_ui_actions_check_menu_dimming_rules (win);
601 modest_ui_actions_check_toolbar_dimming_rules (win);
604 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
605 g_list_free (sel_list);
614 g_object_unref (header_list);
622 /* delete either message or folder, based on where we are */
624 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
626 g_return_if_fail (MODEST_IS_WINDOW(win));
628 /* Check first if the header view has the focus */
629 #ifndef MODEST_TOOLKIT_HILDON2
630 if (MODEST_IS_MAIN_WINDOW (win)) {
632 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
633 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
634 if (gtk_widget_is_focus (w)) {
635 modest_ui_actions_on_delete_folder (action, MODEST_WINDOW(win));
640 modest_ui_actions_on_delete_message (action, win);
644 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
646 ModestWindowMgr *mgr = NULL;
648 #ifdef MODEST_PLATFORM_MAEMO
649 modest_window_mgr_save_state_for_all_windows (modest_runtime_get_window_mgr ());
650 #endif /* MODEST_PLATFORM_MAEMO */
652 g_debug ("closing down, clearing %d item(s) from operation queue",
653 modest_mail_operation_queue_num_elements
654 (modest_runtime_get_mail_operation_queue()));
656 /* cancel all outstanding operations */
657 modest_mail_operation_queue_cancel_all
658 (modest_runtime_get_mail_operation_queue());
660 g_debug ("queue has been cleared");
663 /* Check if there are opened editing windows */
664 mgr = modest_runtime_get_window_mgr ();
665 modest_window_mgr_close_all_windows (mgr);
667 /* note: when modest-tny-account-store is finalized,
668 it will automatically set all network connections
671 /* gtk_main_quit (); */
675 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
679 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
681 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
682 /* gtk_widget_destroy (GTK_WIDGET (win)); */
683 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
684 /* gboolean ret_value; */
685 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
686 /* } else if (MODEST_IS_WINDOW (win)) { */
687 /* gtk_widget_destroy (GTK_WIDGET (win)); */
689 /* g_return_if_reached (); */
694 modest_ui_actions_add_to_contacts (GtkAction *action, ModestWindow *win)
696 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
698 modest_msg_view_window_add_to_contacts (MODEST_MSG_VIEW_WINDOW (win));
702 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
704 GtkClipboard *clipboard = NULL;
705 gchar *selection = NULL;
707 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
708 selection = gtk_clipboard_wait_for_text (clipboard);
711 modest_address_book_add_address (selection, (GtkWindow *) win);
717 modest_ui_actions_on_new_account (GtkAction *action,
718 ModestWindow *window)
720 if (!modest_ui_actions_run_account_setup_wizard (window)) {
721 g_debug ("%s: wizard was already running", __FUNCTION__);
726 modest_ui_actions_on_accounts (GtkAction *action,
729 /* This is currently only implemented for Maemo */
730 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
731 if (!modest_ui_actions_run_account_setup_wizard (win))
732 g_debug ("%s: wizard was already running", __FUNCTION__);
736 /* Show the list of accounts */
737 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
739 /* The accounts dialog must be modal */
740 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
741 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
746 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
748 /* This is currently only implemented for Maemo,
749 * because it requires an API (libconic) to detect different connection
752 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
754 /* Create the window if necessary: */
755 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
756 modest_connection_specific_smtp_window_fill_with_connections (
757 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
758 modest_runtime_get_account_mgr());
760 /* Show the window: */
761 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
762 GTK_WINDOW (specific_window), (GtkWindow *) win);
763 gtk_widget_show (specific_window);
764 #endif /* !MODEST_TOOLKIT_GTK */
768 count_part_size (const gchar *part)
770 GnomeVFSURI *vfs_uri;
771 gchar *escaped_filename;
773 GnomeVFSFileInfo *info;
776 /* Estimation of attachment size if we cannot get it from file info */
779 vfs_uri = gnome_vfs_uri_new (part);
781 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
782 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
783 g_free (escaped_filename);
784 gnome_vfs_uri_unref (vfs_uri);
786 info = gnome_vfs_file_info_new ();
788 if (gnome_vfs_get_file_info (part,
790 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
792 if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) {
797 gnome_vfs_file_info_unref (info);
803 count_parts_size (GSList *parts)
808 for (node = parts; node != NULL; node = g_slist_next (node)) {
809 result += count_part_size ((const gchar *) node->data);
816 modest_ui_actions_compose_msg(ModestWindow *win,
819 const gchar *bcc_str,
820 const gchar *subject_str,
821 const gchar *body_str,
823 gboolean set_as_modified)
825 gchar *account_name = NULL;
826 const gchar *mailbox;
828 TnyAccount *account = NULL;
829 TnyFolder *folder = NULL;
830 gchar *from_str = NULL, *signature = NULL, *body = NULL;
831 gchar *recipient = NULL;
832 gboolean use_signature = FALSE;
833 ModestWindow *msg_win = NULL;
834 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
835 ModestTnyAccountStore *store = modest_runtime_get_account_store();
836 GnomeVFSFileSize total_size, allowed_size;
837 guint64 available_disk, expected_size, parts_size;
840 /* we check for low-mem */
841 if (modest_platform_check_memory_low (win, TRUE))
844 available_disk = modest_utils_get_available_space (NULL);
845 parts_count = g_slist_length (attachments);
846 parts_size = count_parts_size (attachments);
847 expected_size = modest_tny_msg_estimate_size (body, NULL, parts_count, parts_size);
849 /* Double check: disk full condition or message too big */
850 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
851 expected_size > available_disk) {
852 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
853 modest_platform_system_banner (NULL, NULL, msg);
859 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
860 modest_platform_run_information_dialog (
862 _("mail_ib_error_attachment_size"),
868 #ifdef MODEST_TOOLKIT_HILDON2
870 account_name = g_strdup (modest_window_get_active_account(win));
873 account_name = modest_account_mgr_get_default_account(mgr);
876 g_printerr ("modest: no account found\n");
881 mailbox = modest_window_get_active_mailbox (win);
884 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
886 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
889 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
891 g_printerr ("modest: failed to find Drafts folder\n");
894 from_str = modest_account_mgr_get_from_string (mgr, account_name, mailbox);
896 g_printerr ("modest: failed get from string for '%s'\n", account_name);
900 recipient = modest_text_utils_get_email_address (from_str);
901 signature = modest_account_mgr_get_signature_from_recipient (mgr, recipient, &use_signature);
903 if (body_str != NULL) {
904 body = use_signature ? g_strconcat(body_str, "\n",
905 MODEST_TEXT_UTILS_SIGNATURE_MARKER,
906 "\n", signature, NULL) : g_strdup(body_str);
908 body = use_signature ? g_strconcat("\n", MODEST_TEXT_UTILS_SIGNATURE_MARKER,
909 "\n", signature, NULL) : g_strdup("");
912 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, NULL, NULL, body, NULL, NULL, NULL);
914 g_printerr ("modest: failed to create new msg\n");
918 /* Create and register edit window */
919 /* This is destroyed by TODO. */
921 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
922 msg_win = modest_msg_edit_window_new (msg, account_name, mailbox, FALSE);
924 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, win)) {
925 gtk_widget_destroy (GTK_WIDGET (msg_win));
928 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
929 gtk_widget_show_all (GTK_WIDGET (msg_win));
931 while (attachments) {
932 GnomeVFSFileSize att_size;
934 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
935 attachments->data, allowed_size);
936 total_size += att_size;
938 if (att_size > allowed_size) {
939 g_debug ("%s: total size: %u",
940 __FUNCTION__, (unsigned int)total_size);
943 allowed_size -= att_size;
945 attachments = g_slist_next(attachments);
952 g_free (account_name);
954 g_object_unref (G_OBJECT(account));
956 g_object_unref (G_OBJECT(folder));
958 g_object_unref (G_OBJECT(msg));
962 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
964 /* if there are no accounts yet, just show the wizard */
965 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
966 if (!modest_ui_actions_run_account_setup_wizard (win))
969 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
974 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
978 ModestMailOperationStatus status;
980 /* If there is no message or the operation was not successful */
981 status = modest_mail_operation_get_status (mail_op);
982 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
985 /* If it's a memory low issue, then show a banner */
986 error = modest_mail_operation_get_error (mail_op);
987 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
988 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
989 GObject *source = modest_mail_operation_get_source (mail_op);
990 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
991 _KR("memr_ib_operation_disabled"),
993 g_object_unref (source);
996 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
997 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
998 gchar *subject, *msg, *format = NULL;
1001 subject = (header) ? tny_header_dup_subject (header) : NULL;
1003 subject = g_strdup (_("mail_va_no_subject"));
1005 account = modest_mail_operation_get_account (mail_op);
1007 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
1008 ModestProtocol *protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), proto);
1011 if (tny_account_get_connection_status (account) ==
1012 TNY_CONNECTION_STATUS_CONNECTED) {
1013 format = modest_protocol_get_translation (protocol,
1014 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE,
1017 format = g_strdup_printf (_("mail_ib_backend_server_invalid"),
1018 tny_account_get_hostname (account));
1021 g_object_unref (account);
1025 format = g_strdup (_("emev_ni_ui_imap_message_not_available_in_server"));
1027 msg = g_strdup_printf (format, subject);
1028 modest_platform_run_information_dialog (NULL, msg, FALSE);
1034 /* Remove the header from the preregistered uids */
1035 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1048 } OpenMsgBannerInfo;
1051 GtkTreeModel *model;
1053 ModestWindow *caller_window;
1054 OpenMsgBannerInfo *banner_info;
1055 GtkTreeRowReference *rowref;
1059 open_msg_banner_idle (gpointer userdata)
1061 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
1063 gdk_threads_enter ();
1064 banner_info->idle_handler = 0;
1065 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
1066 if (banner_info->banner)
1067 g_object_ref (banner_info->banner);
1069 gdk_threads_leave ();
1075 get_header_view_from_window (ModestWindow *window)
1077 GtkWidget *header_view;
1079 #ifndef MODEST_TOOLKIT_HILDON2
1080 if (MODEST_IS_MAIN_WINDOW (window)) {
1081 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
1082 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1084 if (MODEST_IS_HEADER_WINDOW (window)){
1085 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
1095 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
1098 gchar *account = NULL;
1099 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
1104 folder = tny_header_get_folder (header);
1105 /* Gets folder type (OUTBOX headers will be opened in edit window */
1106 if (modest_tny_folder_is_local_folder (folder)) {
1107 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1108 if (folder_type == TNY_FOLDER_TYPE_INVALID)
1109 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1112 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
1113 TnyTransportAccount *traccount = NULL;
1114 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
1115 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
1117 ModestTnySendQueue *send_queue = NULL;
1118 ModestTnySendQueueStatus status;
1120 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
1121 TNY_ACCOUNT(traccount)));
1122 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
1123 if (TNY_IS_SEND_QUEUE (send_queue)) {
1124 msg_id = modest_tny_send_queue_get_msg_id (header);
1125 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
1127 /* Only open messages in outbox with the editor if they are in Failed state */
1128 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
1131 #ifdef MODEST_TOOLKIT_HILDON2
1133 /* In Fremantle we can not
1134 open any message from
1135 outbox which is not in
1141 g_object_unref(traccount);
1143 g_warning("Cannot get transport account for message in outbox!!");
1145 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
1146 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
1150 TnyAccount *acc = tny_folder_get_account (folder);
1153 g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (acc));
1154 g_object_unref (acc);
1158 g_object_unref (folder);
1164 open_msg_cb (ModestMailOperation *mail_op,
1171 ModestWindowMgr *mgr = NULL;
1172 ModestWindow *parent_win = NULL;
1173 ModestWindow *win = NULL;
1174 gchar *account = NULL;
1175 gboolean open_in_editor = FALSE;
1177 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1179 /* Do nothing if there was any problem with the mail
1180 operation. The error will be shown by the error_handler of
1181 the mail operation */
1182 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1185 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1187 /* Mark header as read */
1188 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1190 account = get_info_from_header (header, &open_in_editor, &can_open);
1194 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1196 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1198 if (open_in_editor) {
1199 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1200 gchar *from_header = NULL, *acc_name;
1201 gchar *mailbox = NULL;
1203 from_header = tny_header_dup_from (header);
1205 /* we cannot edit without a valid account... */
1206 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1207 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1208 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1210 g_free (from_header);
1215 acc_name = modest_utils_get_account_name_from_recipient (from_header, &mailbox);
1216 g_free (from_header);
1222 win = modest_msg_edit_window_new (msg, account, mailbox, TRUE);
1226 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1227 const gchar *mailbox = NULL;
1229 if (parent_win && MODEST_IS_WINDOW (parent_win))
1230 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_win));
1232 if (helper->rowref && helper->model) {
1233 win = modest_msg_view_window_new_with_header_model (msg, account, mailbox, (const gchar*) uid,
1234 helper->model, helper->rowref);
1236 win = modest_msg_view_window_new_for_attachment (msg, account, mailbox, (const gchar*) uid);
1241 /* Register and show new window */
1243 mgr = modest_runtime_get_window_mgr ();
1244 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1245 gtk_widget_destroy (GTK_WIDGET (win));
1248 gtk_widget_show_all (GTK_WIDGET(win));
1251 #ifndef MODEST_TOOLKIT_HILDON2
1252 /* Update toolbar dimming state */
1253 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1254 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1261 g_object_unref (parent_win);
1265 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1268 const GError *error;
1269 GObject *win = NULL;
1270 ModestMailOperationStatus status;
1272 win = modest_mail_operation_get_source (mail_op);
1273 error = modest_mail_operation_get_error (mail_op);
1274 status = modest_mail_operation_get_status (mail_op);
1276 /* If the mail op has been cancelled then it's not an error:
1277 don't show any message */
1278 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1279 TnyAccount *account = modest_mail_operation_get_account (mail_op);
1280 if (modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
1281 (GError *) error, account)) {
1282 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
1283 modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
1285 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1286 modest_platform_information_banner ((GtkWidget *) win,
1287 NULL, _("emev_ui_imap_inbox_select_error"));
1288 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1289 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1290 modest_platform_information_banner ((GtkWidget *) win,
1291 NULL, _CS ("sfil_ni_unable_to_open_file_not_found"));
1292 } else if (user_data) {
1293 modest_platform_information_banner ((GtkWidget *) win,
1297 g_object_unref (account);
1301 g_object_unref (win);
1305 * Returns the account a list of headers belongs to. It returns a
1306 * *new* reference so don't forget to unref it
1309 get_account_from_header_list (TnyList *headers)
1311 TnyAccount *account = NULL;
1313 if (tny_list_get_length (headers) > 0) {
1314 TnyIterator *iter = tny_list_create_iterator (headers);
1315 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1316 TnyFolder *folder = tny_header_get_folder (header);
1319 g_object_unref (header);
1321 while (!tny_iterator_is_done (iter)) {
1322 header = TNY_HEADER (tny_iterator_get_current (iter));
1323 folder = tny_header_get_folder (header);
1326 g_object_unref (header);
1328 tny_iterator_next (iter);
1333 account = tny_folder_get_account (folder);
1334 g_object_unref (folder);
1338 g_object_unref (header);
1340 g_object_unref (iter);
1346 get_account_from_header (TnyHeader *header)
1348 TnyAccount *account = NULL;
1351 folder = tny_header_get_folder (header);
1354 account = tny_folder_get_account (folder);
1355 g_object_unref (folder);
1361 caller_win_destroyed (OpenMsgHelper *helper, GObject *object)
1363 if (helper->caller_window)
1364 helper->caller_window = NULL;
1368 open_msg_helper_destroyer (gpointer user_data)
1370 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1372 if (helper->caller_window) {
1373 g_object_weak_unref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1374 helper->caller_window = NULL;
1377 if (helper->banner_info) {
1378 g_free (helper->banner_info->message);
1379 if (helper->banner_info->idle_handler > 0) {
1380 g_source_remove (helper->banner_info->idle_handler);
1381 helper->banner_info->idle_handler = 0;
1383 if (helper->banner_info->banner != NULL) {
1384 gtk_widget_destroy (helper->banner_info->banner);
1385 g_object_unref (helper->banner_info->banner);
1386 helper->banner_info->banner = NULL;
1388 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1389 helper->banner_info = NULL;
1391 g_object_unref (helper->model);
1392 g_object_unref (helper->header);
1393 gtk_tree_row_reference_free (helper->rowref);
1394 g_slice_free (OpenMsgHelper, helper);
1398 open_msg_performer(gboolean canceled,
1400 GtkWindow *parent_window,
1401 TnyAccount *account,
1404 ModestMailOperation *mail_op = NULL;
1405 gchar *error_msg = NULL;
1406 ModestProtocolType proto;
1407 TnyConnectionStatus status;
1408 OpenMsgHelper *helper = NULL;
1409 ModestProtocol *protocol;
1410 ModestProtocolRegistry *protocol_registry;
1413 helper = (OpenMsgHelper *) user_data;
1415 status = tny_account_get_connection_status (account);
1416 if (err || canceled || helper->caller_window == NULL) {
1417 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1418 /* Free the helper */
1419 open_msg_helper_destroyer (helper);
1421 /* In disk full conditions we could get this error here */
1422 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
1423 (GtkWidget *) parent_window, err,
1429 /* Get the error message depending on the protocol */
1430 proto = modest_tny_account_get_protocol_type (account);
1431 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1432 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1435 protocol_registry = modest_runtime_get_protocol_registry ();
1436 subject = tny_header_dup_subject (helper->header);
1438 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1439 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1443 if (error_msg == NULL) {
1444 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1447 #ifndef MODEST_TOOLKIT_HILDON2
1448 gboolean show_open_draft = FALSE;
1449 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1451 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1453 TnyFolderType folder_type;
1455 folder = tny_header_get_folder (helper->header);
1456 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1457 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1458 g_object_unref (folder);
1462 #ifdef MODEST_TOOLKIT_HILDON2
1465 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1468 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1469 g_free (account_name);
1470 open_msg_helper_destroyer (helper);
1475 ModestWindow *window;
1476 GtkWidget *header_view;
1479 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1480 uid = modest_tny_folder_get_header_unique_id (helper->header);
1482 const gchar *mailbox = NULL;
1483 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_window));
1484 window = modest_msg_view_window_new_from_header_view
1485 (MODEST_HEADER_VIEW (header_view), account_name, mailbox, uid, helper->rowref);
1486 if (window != NULL) {
1487 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1489 gtk_widget_destroy (GTK_WIDGET (window));
1491 gtk_widget_show_all (GTK_WIDGET(window));
1495 g_free (account_name);
1497 open_msg_helper_destroyer (helper);
1500 g_free (account_name);
1502 /* Create the mail operation */
1504 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1505 modest_ui_actions_disk_operations_error_handler,
1506 g_strdup (error_msg), g_free);
1507 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1511 #ifndef MODEST_TOOLKIT_HILDON2
1512 if (show_open_draft) {
1513 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1514 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1515 helper->banner_info->banner = NULL;
1516 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1517 helper->banner_info);
1523 headers = TNY_LIST (tny_simple_list_new ());
1524 tny_list_prepend (headers, G_OBJECT (helper->header));
1525 modest_mail_operation_get_msgs_full (mail_op,
1529 open_msg_helper_destroyer);
1530 g_object_unref (headers);
1537 g_object_unref (mail_op);
1538 g_object_unref (account);
1542 * This function is used by both modest_ui_actions_on_open and
1543 * modest_ui_actions_on_header_activated. This way we always do the
1544 * same when trying to open messages.
1547 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1549 ModestWindowMgr *mgr = NULL;
1550 TnyAccount *account;
1551 gboolean cached = FALSE;
1553 GtkWidget *header_view = NULL;
1554 OpenMsgHelper *helper;
1555 ModestWindow *window;
1557 g_return_if_fail (header != NULL && rowref != NULL && gtk_tree_row_reference_valid (rowref));
1559 mgr = modest_runtime_get_window_mgr ();
1562 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1563 if (header_view == NULL)
1566 /* Get the account */
1567 account = get_account_from_header (header);
1572 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1574 /* Do not open again the message and present the
1575 window to the user */
1578 #ifndef MODEST_TOOLKIT_HILDON2
1579 gtk_window_present (GTK_WINDOW (window));
1582 /* the header has been registered already, we don't do
1583 * anything but wait for the window to come up*/
1584 g_debug ("header %p already registered, waiting for window", header);
1589 /* Open each message */
1590 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1592 /* Allways download if we are online. */
1593 if (!tny_device_is_online (modest_runtime_get_device ())) {
1596 /* If ask for user permission to download the messages */
1597 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1598 _("mcen_nc_get_msg"));
1600 /* End if the user does not want to continue */
1601 if (response == GTK_RESPONSE_CANCEL) {
1607 /* We register the window for opening */
1608 modest_window_mgr_register_header (mgr, header, NULL);
1610 /* Create the helper. We need to get a reference to the model
1611 here because it could change while the message is readed
1612 (the user could switch between folders) */
1613 helper = g_slice_new (OpenMsgHelper);
1614 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1615 helper->caller_window = win;
1616 g_object_weak_ref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1617 helper->header = g_object_ref (header);
1618 helper->rowref = gtk_tree_row_reference_copy (rowref);
1619 helper->banner_info = NULL;
1621 /* Connect to the account and perform */
1623 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1624 open_msg_performer, helper);
1626 /* Call directly the performer, do not need to connect */
1627 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1628 g_object_ref (account), helper);
1633 g_object_unref (account);
1637 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1644 /* we check for low-mem; in that case, show a warning, and don't allow
1647 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1651 headers = get_selected_headers (win);
1655 headers_count = tny_list_get_length (headers);
1656 if (headers_count != 1) {
1657 if (headers_count > 1) {
1658 /* Don't allow activation if there are more than one message selected */
1659 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1662 g_object_unref (headers);
1666 iter = tny_list_create_iterator (headers);
1667 header = TNY_HEADER (tny_iterator_get_current (iter));
1668 g_object_unref (iter);
1672 open_msg_from_header (header, NULL, win);
1673 g_object_unref (header);
1676 g_object_unref(headers);
1680 rf_helper_window_closed (gpointer data,
1683 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1685 helper->parent_window = NULL;
1688 static ReplyForwardHelper*
1689 create_reply_forward_helper (ReplyForwardAction action,
1691 guint reply_forward_type,
1694 ReplyForwardHelper *rf_helper = NULL;
1695 const gchar *active_acc = modest_window_get_active_account (win);
1696 const gchar *active_mailbox = modest_window_get_active_mailbox (win);
1698 rf_helper = g_slice_new0 (ReplyForwardHelper);
1699 rf_helper->reply_forward_type = reply_forward_type;
1700 rf_helper->action = action;
1701 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1702 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1703 rf_helper->account_name = (active_acc) ?
1704 g_strdup (active_acc) :
1705 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1706 rf_helper->mailbox = g_strdup (active_mailbox);
1708 /* Note that window could be destroyed just AFTER calling
1709 register_window so we must ensure that this pointer does
1710 not hold invalid references */
1711 if (rf_helper->parent_window)
1712 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1713 rf_helper_window_closed, rf_helper);
1719 free_reply_forward_helper (gpointer data)
1721 ReplyForwardHelper *helper;
1723 helper = (ReplyForwardHelper *) data;
1724 g_free (helper->account_name);
1725 g_free (helper->mailbox);
1727 g_object_unref (helper->header);
1728 if (helper->parent_window)
1729 g_object_weak_unref (G_OBJECT (helper->parent_window),
1730 rf_helper_window_closed, helper);
1731 g_slice_free (ReplyForwardHelper, helper);
1735 reply_forward_cb (ModestMailOperation *mail_op,
1742 TnyMsg *new_msg = NULL;
1743 ReplyForwardHelper *rf_helper;
1744 ModestWindow *msg_win = NULL;
1745 ModestEditType edit_type;
1747 TnyAccount *account = NULL;
1748 ModestWindowMgr *mgr = NULL;
1749 gchar *signature = NULL;
1750 gboolean use_signature;
1753 /* If there was any error. The mail operation could be NULL,
1754 this means that we already have the message downloaded and
1755 that we didn't do a mail operation to retrieve it */
1756 rf_helper = (ReplyForwardHelper *) user_data;
1757 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1760 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1761 rf_helper->account_name, rf_helper->mailbox);
1762 recipient = modest_text_utils_get_email_address (from);
1763 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr(),
1768 /* Create reply mail */
1769 switch (rf_helper->action) {
1770 /* Use the msg_header to ensure that we have all the
1771 information. The summary can lack some data */
1772 TnyHeader *msg_header;
1774 msg_header = tny_msg_get_header (msg);
1776 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1777 (use_signature) ? signature : NULL,
1778 rf_helper->reply_forward_type,
1779 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1780 g_object_unref (msg_header);
1782 case ACTION_REPLY_TO_ALL:
1783 msg_header = tny_msg_get_header (msg);
1785 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1786 (use_signature) ? signature : NULL,
1787 rf_helper->reply_forward_type,
1788 MODEST_TNY_MSG_REPLY_MODE_ALL);
1789 edit_type = MODEST_EDIT_TYPE_REPLY;
1790 g_object_unref (msg_header);
1792 case ACTION_FORWARD:
1794 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1795 rf_helper->reply_forward_type);
1796 edit_type = MODEST_EDIT_TYPE_FORWARD;
1799 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1801 g_return_if_reached ();
1809 g_warning ("%s: failed to create message\n", __FUNCTION__);
1813 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1814 rf_helper->account_name,
1815 TNY_ACCOUNT_TYPE_STORE);
1817 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1821 /* Create and register the windows */
1822 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, rf_helper->mailbox, FALSE);
1823 mgr = modest_runtime_get_window_mgr ();
1824 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1826 /* Note that register_window could have deleted the account */
1827 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1828 gdouble parent_zoom;
1830 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1831 modest_window_set_zoom (msg_win, parent_zoom);
1834 /* Show edit window */
1835 gtk_widget_show_all (GTK_WIDGET (msg_win));
1838 /* We always unregister the header because the message is
1839 forwarded or replied so the original one is no longer
1841 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1844 g_object_unref (G_OBJECT (new_msg));
1846 g_object_unref (G_OBJECT (account));
1847 free_reply_forward_helper (rf_helper);
1850 /* Checks a list of headers. If any of them are not currently
1851 * downloaded (CACHED) then returns TRUE else returns FALSE.
1854 header_list_count_uncached_msgs (TnyList *header_list)
1857 gint uncached_messages = 0;
1859 iter = tny_list_create_iterator (header_list);
1860 while (!tny_iterator_is_done (iter)) {
1863 header = TNY_HEADER (tny_iterator_get_current (iter));
1865 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1866 uncached_messages ++;
1867 g_object_unref (header);
1870 tny_iterator_next (iter);
1872 g_object_unref (iter);
1874 return uncached_messages;
1877 /* Returns FALSE if the user does not want to download the
1878 * messages. Returns TRUE if the user allowed the download.
1881 connect_to_get_msg (ModestWindow *win,
1882 gint num_of_uncached_msgs,
1883 TnyAccount *account)
1885 GtkResponseType response;
1887 /* Allways download if we are online. */
1888 if (tny_device_is_online (modest_runtime_get_device ()))
1891 /* If offline, then ask for user permission to download the messages */
1892 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1893 ngettext("mcen_nc_get_msg",
1895 num_of_uncached_msgs));
1897 if (response == GTK_RESPONSE_CANCEL)
1900 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1904 reply_forward_performer (gboolean canceled,
1906 GtkWindow *parent_window,
1907 TnyAccount *account,
1910 ReplyForwardHelper *rf_helper = NULL;
1911 ModestMailOperation *mail_op;
1913 rf_helper = (ReplyForwardHelper *) user_data;
1915 if (canceled || err) {
1916 free_reply_forward_helper (rf_helper);
1920 /* Retrieve the message */
1921 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1922 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1923 modest_ui_actions_disk_operations_error_handler,
1925 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1926 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1929 g_object_unref(mail_op);
1933 * Common code for the reply and forward actions
1936 reply_forward (ReplyForwardAction action, ModestWindow *win)
1938 ReplyForwardHelper *rf_helper = NULL;
1939 guint reply_forward_type;
1941 g_return_if_fail (win && MODEST_IS_WINDOW(win));
1943 /* we check for low-mem; in that case, show a warning, and don't allow
1944 * reply/forward (because it could potentially require a lot of memory */
1945 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1949 /* we need an account when editing */
1950 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1951 if (!modest_ui_actions_run_account_setup_wizard (win))
1955 reply_forward_type =
1956 modest_conf_get_int (modest_runtime_get_conf (),
1957 (action == ACTION_FORWARD) ?
1958 MODEST_CONF_FORWARD_TYPE :
1959 MODEST_CONF_REPLY_TYPE,
1962 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1964 TnyHeader *header = NULL;
1965 /* Get header and message. Do not free them here, the
1966 reply_forward_cb must do it */
1967 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1968 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1970 if (msg && header) {
1972 rf_helper = create_reply_forward_helper (action, win,
1973 reply_forward_type, header);
1974 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1976 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1980 g_object_unref (msg);
1982 g_object_unref (header);
1984 TnyHeader *header = NULL;
1986 gboolean do_retrieve = TRUE;
1987 TnyList *header_list = NULL;
1989 header_list = get_selected_headers (win);
1992 /* Check that only one message is selected for replying */
1993 if (tny_list_get_length (header_list) != 1) {
1994 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1995 NULL, _("mcen_ib_select_one_message"));
1996 g_object_unref (header_list);
2000 /* Only reply/forward to one message */
2001 iter = tny_list_create_iterator (header_list);
2002 header = TNY_HEADER (tny_iterator_get_current (iter));
2003 g_object_unref (iter);
2005 /* Retrieve messages */
2006 do_retrieve = (action == ACTION_FORWARD) ||
2007 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
2010 TnyAccount *account = NULL;
2011 TnyFolder *folder = NULL;
2012 gdouble download = TRUE;
2013 guint uncached_msgs = 0;
2015 folder = tny_header_get_folder (header);
2017 goto do_retrieve_frees;
2018 account = tny_folder_get_account (folder);
2020 goto do_retrieve_frees;
2022 uncached_msgs = header_list_count_uncached_msgs (header_list);
2024 if (uncached_msgs > 0) {
2025 /* Allways download if we are online. */
2026 if (!tny_device_is_online (modest_runtime_get_device ())) {
2029 /* If ask for user permission to download the messages */
2030 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2031 ngettext("mcen_nc_get_msg",
2035 /* End if the user does not want to continue */
2036 if (response == GTK_RESPONSE_CANCEL)
2043 rf_helper = create_reply_forward_helper (action, win,
2044 reply_forward_type, header);
2045 if (uncached_msgs > 0) {
2046 modest_platform_connect_and_perform (GTK_WINDOW (win),
2048 reply_forward_performer,
2051 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
2052 account, rf_helper);
2057 g_object_unref (account);
2059 g_object_unref (folder);
2061 reply_forward_cb (NULL, header, FALSE, NULL, NULL, NULL);
2064 g_object_unref (header_list);
2065 g_object_unref (header);
2070 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
2072 g_return_if_fail (MODEST_IS_WINDOW(win));
2074 reply_forward (ACTION_REPLY, win);
2078 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
2080 g_return_if_fail (MODEST_IS_WINDOW(win));
2082 reply_forward (ACTION_FORWARD, win);
2086 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
2088 g_return_if_fail (MODEST_IS_WINDOW(win));
2090 reply_forward (ACTION_REPLY_TO_ALL, win);
2094 modest_ui_actions_on_next (GtkAction *action,
2095 ModestWindow *window)
2097 #ifndef MODEST_TOOLKIT_HILDON2
2098 if (MODEST_IS_MAIN_WINDOW (window)) {
2099 GtkWidget *header_view;
2101 header_view = modest_main_window_get_child_widget (
2102 MODEST_MAIN_WINDOW(window),
2103 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2107 modest_header_view_select_next (
2108 MODEST_HEADER_VIEW(header_view));
2110 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2111 modest_msg_view_window_select_next_message (
2112 MODEST_MSG_VIEW_WINDOW (window));
2115 g_return_if_reached ();
2120 modest_ui_actions_on_prev (GtkAction *action,
2121 ModestWindow *window)
2123 g_return_if_fail (MODEST_IS_WINDOW(window));
2125 #ifndef MODEST_TOOLKIT_HILDON2
2126 if (MODEST_IS_MAIN_WINDOW (window)) {
2127 GtkWidget *header_view;
2128 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2129 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2133 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
2135 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2136 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
2139 g_return_if_reached ();
2144 modest_ui_actions_on_sort (GtkAction *action,
2145 ModestWindow *window)
2147 GtkWidget *header_view = NULL;
2149 g_return_if_fail (MODEST_IS_WINDOW(window));
2151 #ifndef MODEST_TOOLKIT_HILDON2
2152 if (MODEST_IS_MAIN_WINDOW (window)) {
2153 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2154 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2156 if (MODEST_IS_HEADER_WINDOW (window)) {
2157 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2162 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
2167 /* Show sorting dialog */
2168 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
2172 sync_folder_cb (TnyFolder *folder,
2177 ModestHeaderView *header_view = (ModestHeaderView *) user_data;
2179 tny_folder_refresh_async (folder, NULL, NULL, NULL);
2180 /* ModestWindow *parent = (ModestWindow *) gtk_widget_get_ancestor ((GtkWidget *) user_data, GTK_TYPE_WINDOW); */
2182 /* We must clear first, because otherwise set_folder will ignore
2183 the change as the folders are the same */
2184 /* modest_header_view_clear (header_view); */
2185 /* modest_header_view_set_folder (header_view, folder, TRUE, parent, NULL, NULL); */
2187 g_object_unref (header_view);
2191 idle_refresh_folder (gpointer source)
2193 ModestHeaderView *header_view = NULL;
2195 /* If the window still exists */
2196 if (!GTK_IS_WIDGET (source) ||
2197 !GTK_WIDGET_VISIBLE (source))
2200 /* Refresh the current view */
2201 #ifdef MODEST_TOOLKIT_HILDON2
2202 if (MODEST_IS_HEADER_WINDOW (source))
2203 header_view = modest_header_window_get_header_view ((ModestHeaderWindow *) source);
2205 if (MODEST_IS_MAIN_WINDOW (source))
2206 header_view = modest_main_window_get_child_widget ((ModestMainWindow *) source,
2207 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2210 TnyFolder *folder = modest_header_view_get_folder (header_view);
2212 /* Sync the folder status */
2213 tny_folder_sync_async (folder, TRUE, sync_folder_cb, NULL, g_object_ref (header_view));
2214 g_object_unref (folder);
2222 update_account_cb (ModestMailOperation *self,
2223 TnyList *new_headers,
2227 gboolean show_visual_notifications;
2229 source = modest_mail_operation_get_source (self);
2230 show_visual_notifications = (source) ? FALSE : TRUE;
2232 /* Notify new messages have been downloaded. If the
2233 send&receive was invoked by the user then do not show any
2234 visual notification, only play a sound and activate the LED
2235 (for the Maemo version) */
2236 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0) {
2238 /* We only notify about really new messages (not seen) we get */
2239 TnyList *actually_new_list;
2240 TnyIterator *iterator;
2241 actually_new_list = TNY_LIST (tny_simple_list_new ());
2242 for (iterator = tny_list_create_iterator (new_headers);
2243 !tny_iterator_is_done (iterator);
2244 tny_iterator_next (iterator)) {
2246 TnyHeaderFlags flags;
2247 header = TNY_HEADER (tny_iterator_get_current (iterator));
2248 flags = tny_header_get_flags (header);
2250 if (!(flags & TNY_HEADER_FLAG_SEEN)) {
2251 /* Messages are ordered from most
2252 recent to oldest. But we want to
2253 show notifications starting from
2254 the oldest message. That's why we
2256 tny_list_prepend (actually_new_list, G_OBJECT (header));
2258 g_object_unref (header);
2260 g_object_unref (iterator);
2262 if (tny_list_get_length (actually_new_list) > 0) {
2263 GList *new_headers_list = NULL;
2265 new_headers_list = modest_utils_create_notification_list_from_header_list (actually_new_list);
2267 /* Send notifications */
2268 if (new_headers_list) {
2269 modest_platform_on_new_headers_received (new_headers_list,
2270 show_visual_notifications);
2272 modest_utils_free_notification_list (new_headers_list);
2275 g_object_unref (actually_new_list);
2279 /* Refresh the current folder in an idle. We do this
2280 in order to avoid refresh cancelations if the
2281 currently viewed folder is the inbox */
2282 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
2283 idle_refresh_folder,
2284 g_object_ref (source),
2286 g_object_unref (source);
2291 TnyAccount *account;
2293 gchar *account_name;
2294 gboolean poke_status;
2295 gboolean interactive;
2296 ModestMailOperation *mail_op;
2300 do_send_receive_performer (gboolean canceled,
2302 GtkWindow *parent_window,
2303 TnyAccount *account,
2306 SendReceiveInfo *info;
2308 info = (SendReceiveInfo *) user_data;
2310 if (err || canceled) {
2311 /* In disk full conditions we could get this error here */
2312 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
2313 (GtkWidget *) parent_window, err,
2316 if (info->mail_op) {
2317 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2323 #ifndef MODEST_TOOLKIT_HILDON2
2324 /* Set send/receive operation in progress */
2325 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2326 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2329 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2330 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2331 G_CALLBACK (on_send_receive_finished),
2335 /* Send & receive. */
2336 modest_mail_operation_update_account (info->mail_op, info->account_name,
2337 info->poke_status, info->interactive,
2338 update_account_cb, info->win);
2343 g_object_unref (G_OBJECT (info->mail_op));
2344 if (info->account_name)
2345 g_free (info->account_name);
2347 g_object_unref (info->win);
2349 g_object_unref (info->account);
2350 g_slice_free (SendReceiveInfo, info);
2354 * This function performs the send & receive required actions. The
2355 * window is used to create the mail operation. Typically it should
2356 * always be the main window, but we pass it as argument in order to
2360 modest_ui_actions_do_send_receive (const gchar *account_name,
2361 gboolean force_connection,
2362 gboolean poke_status,
2363 gboolean interactive,
2366 gchar *acc_name = NULL;
2367 SendReceiveInfo *info;
2368 ModestTnyAccountStore *acc_store;
2369 TnyAccount *account;
2371 /* If no account name was provided then get the current account, and if
2372 there is no current account then pick the default one: */
2373 if (!account_name) {
2375 acc_name = g_strdup (modest_window_get_active_account (win));
2377 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2379 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2383 acc_name = g_strdup (account_name);
2386 acc_store = modest_runtime_get_account_store ();
2387 account = modest_tny_account_store_get_server_account (acc_store, acc_name, TNY_ACCOUNT_TYPE_STORE);
2391 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2395 /* Do not automatically refresh accounts that are flagged as
2396 NO_AUTO_UPDATE. This could be useful for accounts that
2397 handle their own update times */
2399 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
2400 if (proto != MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
2401 const gchar *tag = MODEST_PROTOCOL_REGISTRY_NO_AUTO_UPDATE_PROTOCOLS;
2402 ModestProtocolRegistry *registry = modest_runtime_get_protocol_registry ();
2404 if (modest_protocol_registry_protocol_type_has_tag (registry, proto, tag)) {
2405 g_debug ("%s no auto update allowed for account %s", __FUNCTION__, account_name);
2406 g_object_unref (account);
2413 /* Create the info for the connect and perform */
2414 info = g_slice_new (SendReceiveInfo);
2415 info->account_name = acc_name;
2416 info->win = (win) ? g_object_ref (win) : NULL;
2417 info->poke_status = poke_status;
2418 info->interactive = interactive;
2419 info->account = account;
2420 /* We need to create the operation here, because otherwise it
2421 could happen that the queue emits the queue-empty signal
2422 while we're trying to connect the account */
2423 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2424 modest_ui_actions_disk_operations_error_handler,
2426 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2428 /* Invoke the connect and perform */
2429 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2430 force_connection, info->account,
2431 do_send_receive_performer, info);
2436 modest_ui_actions_do_cancel_send (const gchar *account_name,
2439 TnyTransportAccount *transport_account;
2440 TnySendQueue *send_queue = NULL;
2441 GError *error = NULL;
2443 /* Get transport account */
2445 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2446 (modest_runtime_get_account_store(),
2448 TNY_ACCOUNT_TYPE_TRANSPORT));
2449 if (!transport_account) {
2450 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2455 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2456 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2457 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2458 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2459 "modest: could not find send queue for account\n");
2461 /* Cancel the current send */
2462 tny_account_cancel (TNY_ACCOUNT (transport_account));
2464 /* Suspend all pending messages */
2465 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2469 if (transport_account != NULL)
2470 g_object_unref (G_OBJECT (transport_account));
2474 modest_ui_actions_cancel_send_all (ModestWindow *win)
2476 GSList *account_names, *iter;
2478 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2481 iter = account_names;
2483 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2484 iter = g_slist_next (iter);
2487 modest_account_mgr_free_account_names (account_names);
2488 account_names = NULL;
2492 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2495 /* Check if accounts exist */
2496 gboolean accounts_exist =
2497 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2499 /* If not, allow the user to create an account before trying to send/receive. */
2500 if (!accounts_exist)
2501 modest_ui_actions_on_accounts (NULL, win);
2503 /* Cancel all sending operaitons */
2504 modest_ui_actions_cancel_send_all (win);
2508 * Refreshes all accounts. This function will be used by automatic
2512 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2513 gboolean force_connection,
2514 gboolean poke_status,
2515 gboolean interactive)
2517 GSList *account_names, *iter;
2519 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2522 iter = account_names;
2524 modest_ui_actions_do_send_receive ((const char*) iter->data,
2526 poke_status, interactive, win);
2527 iter = g_slist_next (iter);
2530 modest_account_mgr_free_account_names (account_names);
2531 account_names = NULL;
2535 * Handler of the click on Send&Receive button in the main toolbar
2538 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2540 /* Check if accounts exist */
2541 gboolean accounts_exist;
2544 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2546 /* If not, allow the user to create an account before trying to send/receive. */
2547 if (!accounts_exist)
2548 modest_ui_actions_on_accounts (NULL, win);
2550 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2551 #ifndef MODEST_TOOLKIT_HILDON2
2552 if (MODEST_IS_MAIN_WINDOW (win)) {
2553 GtkWidget *folder_view;
2554 TnyFolderStore *folder_store;
2557 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2558 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2562 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2565 g_object_unref (folder_store);
2566 /* Refresh the active account. Force the connection if needed
2567 and poke the status of all folders */
2568 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2570 if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2571 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2574 const gchar *active_account;
2575 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2577 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2582 #ifndef MODEST_TOOLKIT_HILDON2
2584 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2587 GtkWidget *header_view;
2589 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2591 header_view = modest_main_window_get_child_widget (main_window,
2592 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2596 conf = modest_runtime_get_conf ();
2598 /* what is saved/restored is depending on the style; thus; we save with
2599 * old style, then update the style, and restore for this new style
2601 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2603 if (modest_header_view_get_style
2604 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2605 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2606 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2608 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2609 MODEST_HEADER_VIEW_STYLE_DETAILS);
2611 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2612 MODEST_CONF_HEADER_VIEW_KEY);
2616 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2618 ModestMainWindow *main_window)
2620 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2621 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2623 /* in the case the folder is empty, show the empty folder message and focus
2625 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2626 if (modest_header_view_is_empty (header_view)) {
2627 TnyFolder *folder = modest_header_view_get_folder (header_view);
2628 GtkWidget *folder_view =
2629 modest_main_window_get_child_widget (main_window,
2630 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2631 if (folder != NULL) {
2632 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2633 g_object_unref (folder);
2635 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2639 /* If no header has been selected then exit */
2644 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2645 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2647 /* Update toolbar dimming state */
2648 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2649 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2654 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2657 ModestWindow *window)
2659 GtkTreeRowReference *rowref;
2661 g_return_if_fail (MODEST_IS_WINDOW(window));
2662 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2663 g_return_if_fail (TNY_IS_HEADER (header));
2665 if (modest_header_view_count_selected_headers (header_view) > 1) {
2666 /* Don't allow activation if there are more than one message selected */
2667 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2671 /* we check for low-mem; in that case, show a warning, and don't allow
2672 * activating headers
2674 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2677 #ifndef MODEST_TOOLKIT_HILDON2
2678 GtkWidget *open_widget;
2679 if (MODEST_IS_MAIN_WINDOW (window)) {
2680 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2681 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2682 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2687 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2688 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2689 gtk_tree_row_reference_free (rowref);
2692 #ifndef MODEST_TOOLKIT_HILDON2
2694 set_active_account_from_tny_account (TnyAccount *account,
2695 ModestWindow *window)
2697 const gchar *server_acc_name = tny_account_get_id (account);
2699 /* We need the TnyAccount provided by the
2700 account store because that is the one that
2701 knows the name of the Modest account */
2702 TnyAccount *modest_server_account =
2703 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2704 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2706 if (!modest_server_account) {
2707 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2711 /* Update active account, but only if it's not a pseudo-account */
2712 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2713 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2714 const gchar *modest_acc_name =
2715 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2716 if (modest_acc_name)
2717 modest_window_set_active_account (window, modest_acc_name);
2720 g_object_unref (modest_server_account);
2724 folder_refreshed_cb (ModestMailOperation *mail_op,
2728 ModestMainWindow *win = NULL;
2729 GtkWidget *folder_view, *header_view;
2730 const GError *error;
2732 g_return_if_fail (TNY_IS_FOLDER (folder));
2734 win = MODEST_MAIN_WINDOW (user_data);
2736 /* Check if the operation failed due to memory low conditions */
2737 error = modest_mail_operation_get_error (mail_op);
2738 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2739 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2740 modest_platform_run_information_dialog (GTK_WINDOW (win),
2741 _KR("memr_ib_operation_disabled"),
2747 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2749 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2752 TnyFolderStore *current_folder;
2754 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2755 if (current_folder) {
2756 gboolean different = ((TnyFolderStore *) folder != current_folder);
2757 g_object_unref (current_folder);
2763 /* Check if folder is empty and set headers view contents style */
2764 if ((tny_folder_get_all_count (folder) == 0) ||
2765 modest_header_view_is_empty (MODEST_HEADER_VIEW (header_view)))
2766 modest_main_window_set_contents_style (win,
2767 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2771 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2772 TnyFolderStore *folder_store,
2774 ModestMainWindow *main_window)
2776 GtkWidget *header_view;
2778 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2780 header_view = modest_main_window_get_child_widget(main_window,
2781 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2786 if (TNY_IS_ACCOUNT (folder_store)) {
2788 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2790 /* Show account details */
2791 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2794 if (TNY_IS_FOLDER (folder_store) && selected) {
2795 TnyAccount *account;
2797 /* Update the active account */
2798 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2800 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2801 g_object_unref (account);
2805 /* Set the header style by default, it could
2806 be changed later by the refresh callback to
2808 modest_main_window_set_contents_style (main_window,
2809 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2811 /* Set folder on header view. This function
2812 will call tny_folder_refresh_async so we
2813 pass a callback that will be called when
2814 finished. We use that callback to set the
2815 empty view if there are no messages */
2816 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2817 TNY_FOLDER (folder_store),
2819 MODEST_WINDOW (main_window),
2820 folder_refreshed_cb,
2823 /* Restore configuration. We need to do this
2824 *after* the set_folder because the widget
2825 memory asks the header view about its
2827 modest_widget_memory_restore (modest_runtime_get_conf (),
2828 G_OBJECT(header_view),
2829 MODEST_CONF_HEADER_VIEW_KEY);
2831 /* No need to save the header view
2832 configuration for Maemo because it only
2833 saves the sorting stuff and that it's
2834 already being done by the sort
2835 dialog. Remove it when the GNOME version
2836 has the same behaviour */
2837 #ifdef MODEST_TOOLKIT_GTK
2838 if (modest_main_window_get_contents_style (main_window) ==
2839 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2840 modest_widget_memory_save (modest_runtime_get_conf (),
2841 G_OBJECT (header_view),
2842 MODEST_CONF_HEADER_VIEW_KEY);
2844 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2848 /* Update dimming state */
2849 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2850 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2855 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2862 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2864 online = tny_device_is_online (modest_runtime_get_device());
2867 /* already online -- the item is simply not there... */
2868 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2870 GTK_MESSAGE_WARNING,
2872 _("The %s you selected cannot be found"),
2874 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2875 gtk_dialog_run (GTK_DIALOG(dialog));
2877 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2880 _("mcen_bd_dialog_cancel"),
2881 GTK_RESPONSE_REJECT,
2882 _("mcen_bd_dialog_ok"),
2883 GTK_RESPONSE_ACCEPT,
2885 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2886 "Do you want to get online?"), item);
2887 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2888 gtk_label_new (txt), FALSE, FALSE, 0);
2889 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2892 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2893 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2894 /* TODO: Comment about why is this commented out: */
2895 /* modest_platform_connect_and_wait (); */
2898 gtk_widget_destroy (dialog);
2902 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2905 /* g_debug ("%s %s", __FUNCTION__, link); */
2910 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2913 modest_platform_activate_uri (link);
2917 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2920 modest_platform_show_uri_popup (link);
2924 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2927 /* we check for low-mem; in that case, show a warning, and don't allow
2928 * viewing attachments
2930 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2933 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2937 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2938 const gchar *address,
2941 /* g_debug ("%s %s", __FUNCTION__, address); */
2945 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2946 TnyMsg *saved_draft,
2949 ModestMsgEditWindow *edit_window;
2951 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2952 #ifndef MODEST_TOOLKIT_HILDON2
2953 ModestMainWindow *win;
2955 /* FIXME. Make the header view sensitive again. This is a
2956 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2958 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2959 modest_runtime_get_window_mgr(), FALSE));
2961 GtkWidget *hdrview = modest_main_window_get_child_widget(
2962 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2963 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2967 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2969 /* Set draft is there was no error */
2970 if (!modest_mail_operation_get_error (mail_op))
2971 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2973 g_object_unref(edit_window);
2977 enough_space_for_message (ModestMsgEditWindow *edit_window,
2980 guint64 available_disk, expected_size;
2985 available_disk = modest_utils_get_available_space (NULL);
2986 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2987 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2992 /* Double check: disk full condition or message too big */
2993 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
2994 expected_size > available_disk) {
2995 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
2996 modest_platform_information_banner (NULL, NULL, msg);
3003 * djcb: if we're in low-memory state, we only allow for
3004 * saving messages smaller than
3005 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
3006 * should still allow for sending anything critical...
3008 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
3009 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
3013 * djcb: we also make sure that the attachments are smaller than the max size
3014 * this is for the case where we'd try to forward a message with attachments
3015 * bigger than our max allowed size, or sending an message from drafts which
3016 * somehow got past our checks when attaching.
3018 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
3019 modest_platform_run_information_dialog (
3020 GTK_WINDOW(edit_window),
3021 _("mail_ib_error_attachment_size"),
3030 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3032 TnyTransportAccount *transport_account;
3033 ModestMailOperation *mail_operation;
3035 gchar *account_name;
3036 ModestAccountMgr *account_mgr;
3037 gboolean had_error = FALSE;
3039 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
3041 data = modest_msg_edit_window_get_msg_data (edit_window);
3044 if (!enough_space_for_message (edit_window, data)) {
3045 modest_msg_edit_window_free_msg_data (edit_window, data);
3049 account_name = g_strdup (data->account_name);
3050 account_mgr = modest_runtime_get_account_mgr();
3052 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3054 account_name = modest_account_mgr_get_default_account (account_mgr);
3055 if (!account_name) {
3056 g_printerr ("modest: no account found\n");
3057 modest_msg_edit_window_free_msg_data (edit_window, data);
3061 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
3062 account_name = g_strdup (data->account_name);
3066 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3067 (modest_runtime_get_account_store (),
3069 TNY_ACCOUNT_TYPE_TRANSPORT));
3070 if (!transport_account) {
3071 g_printerr ("modest: no transport account found for '%s'\n", account_name);
3072 g_free (account_name);
3073 modest_msg_edit_window_free_msg_data (edit_window, data);
3077 /* Create the mail operation */
3078 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
3080 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3082 modest_mail_operation_save_to_drafts (mail_operation,
3094 data->priority_flags,
3097 on_save_to_drafts_cb,
3098 g_object_ref(edit_window));
3100 #ifdef MODEST_TOOLKIT_HILDON2
3101 /* In hildon2 we always show the information banner on saving to drafts.
3102 * It will be a system information banner in this case.
3104 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3105 modest_platform_information_banner (NULL, NULL, text);
3108 ModestMainWindow *win = NULL;
3110 /* Use the main window as the parent of the banner, if the
3111 main window does not exist it won't be shown, if the parent
3112 window exists then it's properly shown. We don't use the
3113 editor window because it could be closed (save to drafts
3114 could happen after closing the window */
3115 win = (ModestMainWindow *)
3116 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
3118 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3119 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
3123 modest_msg_edit_window_set_modified (edit_window, FALSE);
3126 g_free (account_name);
3127 g_object_unref (G_OBJECT (transport_account));
3128 g_object_unref (G_OBJECT (mail_operation));
3130 modest_msg_edit_window_free_msg_data (edit_window, data);
3132 #ifndef MODEST_TOOLKIT_HILDON2
3134 * If the drafts folder is selected then make the header view
3135 * insensitive while the message is being saved to drafts
3136 * (it'll be sensitive again in on_save_to_drafts_cb()). This
3137 * is not very clean but it avoids letting the drafts folder
3138 * in an inconsistent state: the user could edit the message
3139 * being saved and undesirable things would happen.
3140 * In the average case the user won't notice anything at
3141 * all. In the worst case (the user is editing a really big
3142 * file from Drafts) the header view will be insensitive
3143 * during the saving process (10 or 20 seconds, depending on
3144 * the message). Anyway this is just a quick workaround: once
3145 * we find a better solution it should be removed
3146 * See NB#65125 (commend #18) for details.
3148 if (!had_error && win != NULL) {
3149 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
3150 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
3152 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
3154 if (modest_tny_folder_is_local_folder(folder)) {
3155 TnyFolderType folder_type;
3156 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
3157 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
3158 GtkWidget *hdrview = modest_main_window_get_child_widget(
3159 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3160 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
3164 if (folder != NULL) g_object_unref(folder);
3172 /* For instance, when clicking the Send toolbar button when editing a message: */
3174 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3176 TnyTransportAccount *transport_account = NULL;
3177 gboolean had_error = FALSE;
3179 ModestAccountMgr *account_mgr;
3180 gchar *account_name;
3181 ModestMailOperation *mail_operation;
3184 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
3186 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
3189 data = modest_msg_edit_window_get_msg_data (edit_window);
3191 recipients = g_strconcat (data->to?data->to:"",
3192 data->cc?data->cc:"",
3193 data->bcc?data->bcc:"",
3195 if (recipients == NULL || recipients[0] == '\0') {
3196 /* Empty subject -> no send */
3197 g_free (recipients);
3198 modest_msg_edit_window_free_msg_data (edit_window, data);
3201 g_free (recipients);
3204 if (!enough_space_for_message (edit_window, data)) {
3205 modest_msg_edit_window_free_msg_data (edit_window, data);
3209 account_mgr = modest_runtime_get_account_mgr();
3210 account_name = g_strdup (data->account_name);
3212 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3215 account_name = modest_account_mgr_get_default_account (account_mgr);
3217 if (!account_name) {
3218 modest_msg_edit_window_free_msg_data (edit_window, data);
3219 /* Run account setup wizard */
3220 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
3225 /* Get the currently-active transport account for this modest account: */
3226 if (account_name && strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
3228 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3229 (modest_runtime_get_account_store (),
3230 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
3233 if (!transport_account) {
3234 modest_msg_edit_window_free_msg_data (edit_window, data);
3235 /* Run account setup wizard */
3236 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
3241 /* Create the mail operation */
3242 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
3243 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3245 modest_mail_operation_send_new_mail (mail_operation,
3259 data->priority_flags);
3261 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3262 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
3264 if (modest_mail_operation_get_error (mail_operation) != NULL) {
3265 const GError *error = modest_mail_operation_get_error (mail_operation);
3266 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3267 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3268 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3269 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3275 g_free (account_name);
3276 g_object_unref (G_OBJECT (transport_account));
3277 g_object_unref (G_OBJECT (mail_operation));
3279 modest_msg_edit_window_free_msg_data (edit_window, data);
3282 modest_msg_edit_window_set_sent (edit_window, TRUE);
3284 /* Save settings and close the window: */
3285 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3292 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3293 ModestMsgEditWindow *window)
3295 ModestMsgEditFormatState *format_state = NULL;
3297 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3298 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3300 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3303 format_state = modest_msg_edit_window_get_format_state (window);
3304 g_return_if_fail (format_state != NULL);
3306 format_state->bold = gtk_toggle_action_get_active (action);
3307 modest_msg_edit_window_set_format_state (window, format_state);
3308 g_free (format_state);
3313 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3314 ModestMsgEditWindow *window)
3316 ModestMsgEditFormatState *format_state = NULL;
3318 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3319 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3321 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3324 format_state = modest_msg_edit_window_get_format_state (window);
3325 g_return_if_fail (format_state != NULL);
3327 format_state->italics = gtk_toggle_action_get_active (action);
3328 modest_msg_edit_window_set_format_state (window, format_state);
3329 g_free (format_state);
3334 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3335 ModestMsgEditWindow *window)
3337 ModestMsgEditFormatState *format_state = NULL;
3339 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3340 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3342 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3345 format_state = modest_msg_edit_window_get_format_state (window);
3346 g_return_if_fail (format_state != NULL);
3348 format_state->bullet = gtk_toggle_action_get_active (action);
3349 modest_msg_edit_window_set_format_state (window, format_state);
3350 g_free (format_state);
3355 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3356 GtkRadioAction *selected,
3357 ModestMsgEditWindow *window)
3359 ModestMsgEditFormatState *format_state = NULL;
3360 GtkJustification value;
3362 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3364 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3367 value = gtk_radio_action_get_current_value (selected);
3369 format_state = modest_msg_edit_window_get_format_state (window);
3370 g_return_if_fail (format_state != NULL);
3372 format_state->justification = value;
3373 modest_msg_edit_window_set_format_state (window, format_state);
3374 g_free (format_state);
3378 modest_ui_actions_on_select_editor_color (GtkAction *action,
3379 ModestMsgEditWindow *window)
3381 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3382 g_return_if_fail (GTK_IS_ACTION (action));
3384 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3387 modest_msg_edit_window_select_color (window);
3391 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3392 ModestMsgEditWindow *window)
3394 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3395 g_return_if_fail (GTK_IS_ACTION (action));
3397 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3400 modest_msg_edit_window_select_background_color (window);
3404 modest_ui_actions_on_insert_image (GObject *object,
3405 ModestMsgEditWindow *window)
3407 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3410 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3413 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3416 modest_msg_edit_window_insert_image (window);
3420 modest_ui_actions_on_attach_file (GtkAction *action,
3421 ModestMsgEditWindow *window)
3423 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3424 g_return_if_fail (GTK_IS_ACTION (action));
3426 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3429 modest_msg_edit_window_offer_attach_file (window);
3433 modest_ui_actions_on_remove_attachments (GtkAction *action,
3434 ModestMsgEditWindow *window)
3436 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3438 modest_msg_edit_window_remove_attachments (window, NULL);
3442 do_create_folder_cb (ModestMailOperation *mail_op,
3443 TnyFolderStore *parent_folder,
3444 TnyFolder *new_folder,
3447 gchar *suggested_name = (gchar *) user_data;
3448 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3449 const GError *error;
3451 error = modest_mail_operation_get_error (mail_op);
3453 gboolean disk_full = FALSE;
3454 TnyAccount *account;
3455 /* Show an error. If there was some problem writing to
3456 disk, show it, otherwise show the generic folder
3457 create error. We do it here and not in an error
3458 handler because the call to do_create_folder will
3459 stop the main loop in a gtk_dialog_run and then,
3460 the message won't be shown until that dialog is
3462 account = modest_mail_operation_get_account (mail_op);
3465 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3466 (GtkWidget *) source_win,
3469 _("mail_in_ui_folder_create_error_memory"));
3470 g_object_unref (account);
3473 /* Show an error and try again if there is no
3474 full memory condition */
3475 modest_platform_information_banner ((GtkWidget *) source_win, NULL,
3476 _("mail_in_ui_folder_create_error"));
3477 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3481 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3482 * FIXME: any other? */
3483 GtkWidget *folder_view;
3485 #ifndef MODEST_TOOLKIT_HILDON2
3486 if (MODEST_IS_MAIN_WINDOW(source_win))
3488 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3489 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3492 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3493 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3495 /* Select the newly created folder. It could happen
3496 that the widget is no longer there (i.e. the window
3497 has been destroyed, so we need to check this */
3499 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3501 g_object_unref (new_folder);
3503 /* Free. Note that the first time it'll be NULL so noop */
3504 g_free (suggested_name);
3505 g_object_unref (source_win);
3510 TnyFolderStore *parent;
3511 } CreateFolderConnect;
3514 do_create_folder_performer (gboolean canceled,
3516 GtkWindow *parent_window,
3517 TnyAccount *account,
3520 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3521 ModestMailOperation *mail_op;
3523 if (canceled || err) {
3524 /* In disk full conditions we could get this error here */
3525 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3526 (GtkWidget *) parent_window, err,
3527 NULL, _("mail_in_ui_folder_create_error_memory"));
3529 /* This happens if we have selected the outbox folder
3531 if (err && err->code == TNY_SERVICE_ERROR_UNKNOWN &&
3532 TNY_IS_MERGE_FOLDER (helper->parent)) {
3533 /* Show an error and retry */
3534 modest_platform_information_banner ((GtkWidget *) parent_window,
3536 _("mail_in_ui_folder_create_error"));
3538 do_create_folder (parent_window, helper->parent, helper->folder_name);
3544 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3545 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3547 modest_mail_operation_create_folder (mail_op,
3549 (const gchar *) helper->folder_name,
3550 do_create_folder_cb,
3551 g_strdup (helper->folder_name));
3552 g_object_unref (mail_op);
3556 g_object_unref (helper->parent);
3557 if (helper->folder_name)
3558 g_free (helper->folder_name);
3559 g_slice_free (CreateFolderConnect, helper);
3564 do_create_folder (GtkWindow *parent_window,
3565 TnyFolderStore *suggested_parent,
3566 const gchar *suggested_name)
3569 gchar *folder_name = NULL;
3570 TnyFolderStore *parent_folder = NULL;
3572 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3574 (gchar *) suggested_name,
3578 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3579 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3580 helper->folder_name = g_strdup (folder_name);
3581 helper->parent = g_object_ref (parent_folder);
3583 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3586 do_create_folder_performer,
3591 g_free (folder_name);
3593 g_object_unref (parent_folder);
3597 modest_ui_actions_create_folder(GtkWidget *parent_window,
3598 GtkWidget *folder_view,
3599 TnyFolderStore *parent_folder)
3601 if (!parent_folder) {
3602 #ifdef MODEST_TOOLKIT_HILDON2
3603 ModestTnyAccountStore *acc_store;
3605 acc_store = modest_runtime_get_account_store ();
3607 parent_folder = (TnyFolderStore *)
3608 modest_tny_account_store_get_local_folders_account (acc_store);
3610 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3614 if (parent_folder) {
3615 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3616 g_object_unref (parent_folder);
3621 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3624 g_return_if_fail (MODEST_IS_WINDOW(window));
3626 #ifndef MODEST_TOOLKIT_HILDON2
3627 if (MODEST_IS_MAIN_WINDOW (window)) {
3628 GtkWidget *folder_view;
3630 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3631 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3635 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3637 if (MODEST_IS_FOLDER_WINDOW (window)) {
3638 GtkWidget *folder_view;
3640 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3641 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3644 g_assert_not_reached ();
3649 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3652 const GError *error = NULL;
3653 gchar *message = NULL;
3655 TnyAccount *account = modest_mail_operation_get_account (mail_op);
3657 /* Get error message */
3658 error = modest_mail_operation_get_error (mail_op);
3660 g_return_if_reached ();
3662 mem_full = modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
3663 (GError *) error, account);
3665 message = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3666 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3667 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3668 message = _CS("ckdg_ib_folder_already_exists");
3669 } else if (error->domain == TNY_ERROR_DOMAIN &&
3670 error->code == TNY_SERVICE_ERROR_STATE) {
3671 /* This means that the folder is already in use (a
3672 message is opened for example */
3673 message = _("emev_ni_internal_error");
3675 message = _CS("ckdg_ib_unable_to_rename");
3678 /* We don't set a parent for the dialog because the dialog
3679 will be destroyed so the banner won't appear */
3680 modest_platform_information_banner (NULL, NULL, message);
3683 g_object_unref (account);
3689 TnyFolderStore *folder;
3694 on_rename_folder_cb (ModestMailOperation *mail_op,
3695 TnyFolder *new_folder,
3698 ModestFolderView *folder_view;
3700 /* If the window was closed when renaming a folder, or if
3701 * it's not a main window this will happen */
3702 if (!MODEST_IS_FOLDER_VIEW (user_data))
3705 folder_view = MODEST_FOLDER_VIEW (user_data);
3706 /* Note that if the rename fails new_folder will be NULL */
3708 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3709 #ifndef MODEST_TOOLKIT_HILDON2
3711 modest_folder_view_select_first_inbox_or_local (folder_view);
3714 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3718 on_rename_folder_performer (gboolean canceled,
3720 GtkWindow *parent_window,
3721 TnyAccount *account,
3724 ModestMailOperation *mail_op = NULL;
3725 GtkTreeSelection *sel = NULL;
3726 GtkWidget *folder_view = NULL;
3727 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3729 if (canceled || err) {
3730 /* In disk full conditions we could get this error here */
3731 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3732 (GtkWidget *) parent_window, err,
3737 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3738 modest_ui_actions_rename_folder_error_handler,
3739 parent_window, NULL);
3741 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3743 #ifndef MODEST_TOOLKIT_HILDON2
3744 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3746 folder_view = modest_main_window_get_child_widget (
3747 MODEST_MAIN_WINDOW (parent_window),
3748 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3751 if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3752 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3753 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3757 /* Clear the folders view */
3758 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3759 gtk_tree_selection_unselect_all (sel);
3761 /* Actually rename the folder */
3762 modest_mail_operation_rename_folder (mail_op,
3763 TNY_FOLDER (data->folder),
3764 (const gchar *) (data->new_name),
3765 on_rename_folder_cb,
3767 g_object_unref (mail_op);
3770 g_object_unref (data->folder);
3771 g_free (data->new_name);
3776 modest_ui_actions_on_rename_folder (GtkAction *action,
3777 ModestWindow *window)
3779 modest_ui_actions_on_edit_mode_rename_folder (window);
3783 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3785 TnyFolderStore *folder;
3786 GtkWidget *folder_view;
3787 gboolean do_rename = TRUE;
3789 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3791 #ifndef MODEST_TOOLKIT_HILDON2
3792 if (MODEST_IS_MAIN_WINDOW (window)) {
3793 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3794 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3798 if (MODEST_IS_FOLDER_WINDOW (window)) {
3799 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3805 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3810 if (TNY_IS_FOLDER (folder)) {
3811 gchar *folder_name = NULL;
3813 const gchar *current_name;
3814 TnyFolderStore *parent;
3816 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3817 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3818 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
3819 parent, current_name,
3821 g_object_unref (parent);
3823 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3826 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3827 rename_folder_data->folder = g_object_ref (folder);
3828 rename_folder_data->new_name = folder_name;
3829 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
3830 folder, on_rename_folder_performer, rename_folder_data);
3833 g_object_unref (folder);
3838 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3841 GObject *win = modest_mail_operation_get_source (mail_op);
3843 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3844 _("mail_in_ui_folder_delete_error"),
3846 g_object_unref (win);
3850 TnyFolderStore *folder;
3851 gboolean move_to_trash;
3855 on_delete_folder_cb (gboolean canceled,
3857 GtkWindow *parent_window,
3858 TnyAccount *account,
3861 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3862 GtkWidget *folder_view;
3863 ModestMailOperation *mail_op;
3864 GtkTreeSelection *sel;
3866 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
3867 /* Note that the connection process can fail due to
3868 memory low conditions as it can not successfully
3869 store the summary */
3870 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3871 (GtkWidget*) parent_window, err,
3873 g_debug ("Error connecting when trying to delete a folder");
3874 g_object_unref (G_OBJECT (info->folder));
3879 #ifndef MODEST_TOOLKIT_HILDON2
3880 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
3881 folder_view = modest_main_window_get_child_widget (
3882 MODEST_MAIN_WINDOW (parent_window),
3883 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3885 if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3886 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
3889 g_object_unref (G_OBJECT (info->folder));
3894 /* Unselect the folder before deleting it to free the headers */
3895 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3896 gtk_tree_selection_unselect_all (sel);
3898 /* Create the mail operation */
3900 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3901 modest_ui_actions_delete_folder_error_handler,
3904 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3906 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3908 #ifndef MODEST_TOOLKIT_HILDON2
3909 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3912 g_object_unref (mail_op);
3913 g_object_unref (info->folder);
3918 delete_folder (ModestWindow *window, gboolean move_to_trash)
3920 TnyFolderStore *folder;
3921 GtkWidget *folder_view;
3925 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3927 #ifndef MODEST_TOOLKIT_HILDON2
3928 if (MODEST_IS_MAIN_WINDOW (window)) {
3930 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3931 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3933 if (MODEST_IS_FOLDER_WINDOW (window)) {
3934 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3942 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3947 /* Show an error if it's an account */
3948 if (!TNY_IS_FOLDER (folder)) {
3949 modest_platform_run_information_dialog (GTK_WINDOW (window),
3950 _("mail_in_ui_folder_delete_error"),
3952 g_object_unref (G_OBJECT (folder));
3957 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3958 tny_folder_get_name (TNY_FOLDER (folder)));
3959 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
3960 (const gchar *) message);
3963 if (response == GTK_RESPONSE_OK) {
3964 TnyAccount *account = NULL;
3965 DeleteFolderInfo *info = NULL;
3966 info = g_new0(DeleteFolderInfo, 1);
3967 info->folder = g_object_ref (folder);
3968 info->move_to_trash = move_to_trash;
3970 account = tny_folder_get_account (TNY_FOLDER (folder));
3971 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
3973 TNY_FOLDER_STORE (account),
3974 on_delete_folder_cb, info);
3975 g_object_unref (account);
3976 g_object_unref (folder);
3984 modest_ui_actions_on_delete_folder (GtkAction *action,
3985 ModestWindow *window)
3987 modest_ui_actions_on_edit_mode_delete_folder (window);
3991 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
3993 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
3995 return delete_folder (window, FALSE);
3998 #ifndef MODEST_TOOLKIT_HILDON2
4000 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
4002 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4004 delete_folder (MODEST_WINDOW (main_window), TRUE);
4008 typedef struct _PasswordDialogFields {
4009 GtkWidget *username;
4010 GtkWidget *password;
4012 } PasswordDialogFields;
4015 password_dialog_check_field (GtkEditable *editable,
4016 PasswordDialogFields *fields)
4019 gboolean any_value_empty = FALSE;
4021 #ifdef MODEST_TOOLKIT_HILDON2
4022 value = hildon_entry_get_text (HILDON_ENTRY (fields->username));
4024 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
4026 if ((value == NULL) || value[0] == '\0') {
4027 any_value_empty = TRUE;
4029 #ifdef MODEST_TOOLKIT_HILDON2
4030 value = hildon_entry_get_text (HILDON_ENTRY (fields->password));
4032 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
4034 if ((value == NULL) || value[0] == '\0') {
4035 any_value_empty = TRUE;
4037 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
4041 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
4042 const gchar* server_account_name,
4047 ModestMainWindow *main_window)
4049 g_return_if_fail(server_account_name);
4050 gboolean completed = FALSE;
4051 PasswordDialogFields *fields = NULL;
4053 /* Initalize output parameters: */
4060 #ifndef MODEST_TOOLKIT_GTK
4061 /* Maemo uses a different (awkward) button order,
4062 * It should probably just use gtk_alternative_dialog_button_order ().
4064 #ifdef MODEST_TOOLKIT_HILDON2
4066 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4069 _HL("wdgt_bd_done"),
4070 GTK_RESPONSE_ACCEPT,
4072 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
4073 HILDON_MARGIN_DOUBLE);
4076 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4079 _("mcen_bd_dialog_ok"),
4080 GTK_RESPONSE_ACCEPT,
4081 _("mcen_bd_dialog_cancel"),
4082 GTK_RESPONSE_REJECT,
4084 #endif /* MODEST_TOOLKIT_HILDON2 */
4087 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4091 GTK_RESPONSE_REJECT,
4093 GTK_RESPONSE_ACCEPT,
4095 #endif /* MODEST_TOOLKIT_GTK */
4097 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
4099 gchar *server_name = modest_account_mgr_get_server_account_hostname (
4100 modest_runtime_get_account_mgr(), server_account_name);
4101 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
4102 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
4105 gtk_widget_destroy (dialog);
4109 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
4110 GtkWidget *label = gtk_label_new (txt);
4111 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
4113 g_free (server_name);
4114 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
4119 gchar *initial_username = modest_account_mgr_get_server_account_username (
4120 modest_runtime_get_account_mgr(), server_account_name);
4122 #ifdef MODEST_TOOLKIT_HILDON2
4123 GtkWidget *entry_username = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4124 if (initial_username)
4125 hildon_entry_set_text (HILDON_ENTRY (entry_username), initial_username);
4127 GtkWidget *entry_username = gtk_entry_new ();
4128 if (initial_username)
4129 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
4131 /* Dim this if a connection has ever succeeded with this username,
4132 * as per the UI spec: */
4133 /* const gboolean username_known = */
4134 /* modest_account_mgr_get_server_account_username_has_succeeded( */
4135 /* modest_runtime_get_account_mgr(), server_account_name); */
4136 /* gtk_widget_set_sensitive (entry_username, !username_known); */
4138 /* We drop the username sensitive code and disallow changing it here
4139 * as tinymail does not support really changing the username in the callback
4141 gtk_widget_set_sensitive (entry_username, FALSE);
4143 #ifndef MODEST_TOOLKIT_GTK
4144 /* Auto-capitalization is the default, so let's turn it off: */
4145 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
4147 /* Create a size group to be used by all captions.
4148 * Note that HildonCaption does not create a default size group if we do not specify one.
4149 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
4150 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
4152 #ifdef MODEST_TOOLKIT_HILDON2
4153 GtkWidget *caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4154 _("mail_fi_username"), FALSE,
4157 GtkWidget *caption = hildon_caption_new (sizegroup,
4158 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
4160 gtk_widget_show (entry_username);
4161 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4162 FALSE, FALSE, MODEST_MARGIN_HALF);
4163 gtk_widget_show (caption);
4165 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
4167 #endif /* !MODEST_TOOLKIT_GTK */
4170 #ifdef MODEST_TOOLKIT_HILDON2
4171 GtkWidget *entry_password = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4173 GtkWidget *entry_password = gtk_entry_new ();
4175 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
4176 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
4178 #ifndef MODEST_TOOLKIT_GTK
4179 /* Auto-capitalization is the default, so let's turn it off: */
4180 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
4181 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
4183 #ifdef MODEST_TOOLKIT_HILDON2
4184 caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4185 _("mail_fi_password"), FALSE,
4188 caption = hildon_caption_new (sizegroup,
4189 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
4191 gtk_widget_show (entry_password);
4192 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4193 FALSE, FALSE, MODEST_MARGIN_HALF);
4194 gtk_widget_show (caption);
4195 g_object_unref (sizegroup);
4197 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
4199 #endif /* !MODEST_TOOLKIT_GTK */
4201 if (initial_username != NULL)
4202 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
4204 /* This is not in the Maemo UI spec:
4205 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
4206 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
4210 fields = g_slice_new0 (PasswordDialogFields);
4211 fields->username = entry_username;
4212 fields->password = entry_password;
4213 fields->dialog = dialog;
4215 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
4216 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
4217 password_dialog_check_field (NULL, fields);
4219 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4221 while (!completed) {
4223 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
4225 #ifdef MODEST_TOOLKIT_HILDON2
4226 *username = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_username)));
4228 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
4231 /* Note that an empty field becomes the "" string */
4232 if (*username && strlen (*username) > 0) {
4233 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
4234 server_account_name,
4238 const gboolean username_was_changed =
4239 (strcmp (*username, initial_username) != 0);
4240 if (username_was_changed) {
4241 g_warning ("%s: tinymail does not yet support changing the "
4242 "username in the get_password() callback.\n", __FUNCTION__);
4248 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
4249 _("mcen_ib_username_pw_incorrect"));
4255 #ifdef MODEST_TOOLKIT_HILDON2
4256 *password = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_password)));
4258 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
4261 /* We do not save the password in the configuration,
4262 * because this function is only called for passwords that should
4263 * not be remembered:
4264 modest_server_account_set_password (
4265 modest_runtime_get_account_mgr(), server_account_name,
4272 #ifndef MODEST_TOOLKIT_HILDON2
4273 /* Set parent to NULL or the banner will disappear with its parent dialog */
4274 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
4286 /* This is not in the Maemo UI spec:
4287 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
4293 g_free (initial_username);
4294 gtk_widget_destroy (dialog);
4295 g_slice_free (PasswordDialogFields, fields);
4297 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
4301 modest_ui_actions_on_cut (GtkAction *action,
4302 ModestWindow *window)
4304 GtkWidget *focused_widget;
4305 GtkClipboard *clipboard;
4307 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4308 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4309 if (GTK_IS_EDITABLE (focused_widget)) {
4310 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
4311 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4312 gtk_clipboard_store (clipboard);
4313 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4314 GtkTextBuffer *buffer;
4316 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4317 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4318 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
4319 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4320 gtk_clipboard_store (clipboard);
4322 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4323 TnyList *header_list = modest_header_view_get_selected_headers (
4324 MODEST_HEADER_VIEW (focused_widget));
4325 gboolean continue_download = FALSE;
4326 gint num_of_unc_msgs;
4328 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4330 if (num_of_unc_msgs) {
4331 TnyAccount *account = get_account_from_header_list (header_list);
4333 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4334 g_object_unref (account);
4338 if (num_of_unc_msgs == 0 || continue_download) {
4339 /* modest_platform_information_banner (
4340 NULL, NULL, _CS("mcen_ib_getting_items"));*/
4341 modest_header_view_cut_selection (
4342 MODEST_HEADER_VIEW (focused_widget));
4345 g_object_unref (header_list);
4346 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4347 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4352 modest_ui_actions_on_copy (GtkAction *action,
4353 ModestWindow *window)
4355 GtkClipboard *clipboard;
4356 GtkWidget *focused_widget;
4357 gboolean copied = TRUE;
4359 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4360 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4362 if (GTK_IS_LABEL (focused_widget)) {
4364 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4365 gtk_clipboard_set_text (clipboard, selection, -1);
4367 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4368 gtk_clipboard_store (clipboard);
4369 } else if (GTK_IS_EDITABLE (focused_widget)) {
4370 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4371 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4372 gtk_clipboard_store (clipboard);
4373 } else if (GTK_IS_HTML (focused_widget)) {
4376 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4377 if ((sel == NULL) || (sel[0] == '\0')) {
4380 gtk_html_copy (GTK_HTML (focused_widget));
4381 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4382 gtk_clipboard_store (clipboard);
4384 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4385 GtkTextBuffer *buffer;
4386 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4387 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4388 gtk_text_buffer_copy_clipboard (buffer, clipboard);
4389 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4390 gtk_clipboard_store (clipboard);
4392 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4393 TnyList *header_list = modest_header_view_get_selected_headers (
4394 MODEST_HEADER_VIEW (focused_widget));
4395 gboolean continue_download = FALSE;
4396 gint num_of_unc_msgs;
4398 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4400 if (num_of_unc_msgs) {
4401 TnyAccount *account = get_account_from_header_list (header_list);
4403 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4404 g_object_unref (account);
4408 if (num_of_unc_msgs == 0 || continue_download) {
4409 modest_platform_information_banner (
4410 NULL, NULL, _CS("mcen_ib_getting_items"));
4411 modest_header_view_copy_selection (
4412 MODEST_HEADER_VIEW (focused_widget));
4416 g_object_unref (header_list);
4418 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4419 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4422 /* Show information banner if there was a copy to clipboard */
4424 modest_platform_information_banner (
4425 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4429 modest_ui_actions_on_undo (GtkAction *action,
4430 ModestWindow *window)
4432 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4433 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4434 #ifndef MODEST_TOOLKIT_HILDON2
4435 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4436 ModestEmailClipboard *clipboard = NULL;
4437 /* Clear clipboard source */
4438 clipboard = modest_runtime_get_email_clipboard ();
4439 modest_email_clipboard_clear (clipboard);
4442 g_return_if_reached ();
4447 modest_ui_actions_on_redo (GtkAction *action,
4448 ModestWindow *window)
4450 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4451 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4454 g_return_if_reached ();
4460 destroy_information_note (ModestMailOperation *mail_op,
4463 /* destroy information note */
4464 gtk_widget_destroy (GTK_WIDGET(user_data));
4468 destroy_folder_information_note (ModestMailOperation *mail_op,
4469 TnyFolder *new_folder,
4472 /* destroy information note */
4473 gtk_widget_destroy (GTK_WIDGET(user_data));
4478 paste_as_attachment_free (gpointer data)
4480 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4482 if (helper->banner) {
4483 gtk_widget_destroy (helper->banner);
4484 g_object_unref (helper->banner);
4490 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4495 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4496 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4501 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4506 modest_ui_actions_on_paste (GtkAction *action,
4507 ModestWindow *window)
4509 GtkWidget *focused_widget = NULL;
4510 GtkWidget *inf_note = NULL;
4511 ModestMailOperation *mail_op = NULL;
4513 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4514 if (GTK_IS_EDITABLE (focused_widget)) {
4515 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4516 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4517 ModestEmailClipboard *e_clipboard = NULL;
4518 e_clipboard = modest_runtime_get_email_clipboard ();
4519 if (modest_email_clipboard_cleared (e_clipboard)) {
4520 GtkTextBuffer *buffer;
4521 GtkClipboard *clipboard;
4523 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4524 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4525 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4526 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4527 ModestMailOperation *mail_op;
4528 TnyFolder *src_folder = NULL;
4529 TnyList *data = NULL;
4531 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4532 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4533 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4534 _CS("ckct_nw_pasting"));
4535 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4536 mail_op = modest_mail_operation_new (G_OBJECT (window));
4537 if (helper->banner != NULL) {
4538 g_object_ref (G_OBJECT (helper->banner));
4539 gtk_widget_show (GTK_WIDGET (helper->banner));
4543 modest_mail_operation_get_msgs_full (mail_op,
4545 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4547 paste_as_attachment_free);
4551 g_object_unref (data);
4553 g_object_unref (src_folder);
4556 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4557 ModestEmailClipboard *clipboard = NULL;
4558 TnyFolder *src_folder = NULL;
4559 TnyFolderStore *folder_store = NULL;
4560 TnyList *data = NULL;
4561 gboolean delete = FALSE;
4563 /* Check clipboard source */
4564 clipboard = modest_runtime_get_email_clipboard ();
4565 if (modest_email_clipboard_cleared (clipboard))
4568 /* Get elements to paste */
4569 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4571 /* Create a new mail operation */
4572 mail_op = modest_mail_operation_new (G_OBJECT(window));
4574 /* Get destination folder */
4575 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4577 /* transfer messages */
4581 /* Ask for user confirmation */
4583 modest_ui_actions_msgs_move_to_confirmation (window,
4584 TNY_FOLDER (folder_store),
4588 if (response == GTK_RESPONSE_OK) {
4589 /* Launch notification */
4590 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4591 _CS("ckct_nw_pasting"));
4592 if (inf_note != NULL) {
4593 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4594 gtk_widget_show (GTK_WIDGET(inf_note));
4597 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4598 modest_mail_operation_xfer_msgs (mail_op,
4600 TNY_FOLDER (folder_store),
4602 destroy_information_note,
4605 g_object_unref (mail_op);
4608 } else if (src_folder != NULL) {
4609 /* Launch notification */
4610 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4611 _CS("ckct_nw_pasting"));
4612 if (inf_note != NULL) {
4613 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4614 gtk_widget_show (GTK_WIDGET(inf_note));
4617 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4618 modest_mail_operation_xfer_folder (mail_op,
4622 destroy_folder_information_note,
4628 g_object_unref (data);
4629 if (src_folder != NULL)
4630 g_object_unref (src_folder);
4631 if (folder_store != NULL)
4632 g_object_unref (folder_store);
4638 modest_ui_actions_on_select_all (GtkAction *action,
4639 ModestWindow *window)
4641 GtkWidget *focused_widget;
4643 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4644 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4645 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4646 } else if (GTK_IS_LABEL (focused_widget)) {
4647 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4648 } else if (GTK_IS_EDITABLE (focused_widget)) {
4649 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4650 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4651 GtkTextBuffer *buffer;
4652 GtkTextIter start, end;
4654 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4655 gtk_text_buffer_get_start_iter (buffer, &start);
4656 gtk_text_buffer_get_end_iter (buffer, &end);
4657 gtk_text_buffer_select_range (buffer, &start, &end);
4658 } else if (GTK_IS_HTML (focused_widget)) {
4659 gtk_html_select_all (GTK_HTML (focused_widget));
4660 #ifndef MODEST_TOOLKIT_HILDON2
4661 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4662 GtkWidget *header_view = focused_widget;
4663 GtkTreeSelection *selection = NULL;
4665 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4666 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4667 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4670 /* Disable window dimming management */
4671 modest_window_disable_dimming (MODEST_WINDOW(window));
4673 /* Select all messages */
4674 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4675 gtk_tree_selection_select_all (selection);
4677 /* Set focuse on header view */
4678 gtk_widget_grab_focus (header_view);
4680 /* Enable window dimming management */
4681 modest_window_enable_dimming (MODEST_WINDOW(window));
4682 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4683 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4690 modest_ui_actions_on_mark_as_read (GtkAction *action,
4691 ModestWindow *window)
4693 g_return_if_fail (MODEST_IS_WINDOW(window));
4695 /* Mark each header as read */
4696 do_headers_action (window, headers_action_mark_as_read, NULL);
4700 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4701 ModestWindow *window)
4703 g_return_if_fail (MODEST_IS_WINDOW(window));
4705 /* Mark each header as read */
4706 do_headers_action (window, headers_action_mark_as_unread, NULL);
4710 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4711 GtkRadioAction *selected,
4712 ModestWindow *window)
4716 value = gtk_radio_action_get_current_value (selected);
4717 if (MODEST_IS_WINDOW (window)) {
4718 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4723 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4724 GtkRadioAction *selected,
4725 ModestWindow *window)
4727 TnyHeaderFlags flags;
4728 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4730 flags = gtk_radio_action_get_current_value (selected);
4731 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4735 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4736 GtkRadioAction *selected,
4737 ModestWindow *window)
4741 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4743 file_format = gtk_radio_action_get_current_value (selected);
4744 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4749 modest_ui_actions_on_zoom_plus (GtkAction *action,
4750 ModestWindow *window)
4752 g_return_if_fail (MODEST_IS_WINDOW (window));
4754 modest_window_zoom_plus (MODEST_WINDOW (window));
4758 modest_ui_actions_on_zoom_minus (GtkAction *action,
4759 ModestWindow *window)
4761 g_return_if_fail (MODEST_IS_WINDOW (window));
4763 modest_window_zoom_minus (MODEST_WINDOW (window));
4767 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4768 ModestWindow *window)
4770 ModestWindowMgr *mgr;
4771 gboolean fullscreen, active;
4772 g_return_if_fail (MODEST_IS_WINDOW (window));
4774 mgr = modest_runtime_get_window_mgr ();
4776 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4777 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4779 if (active != fullscreen) {
4780 modest_window_mgr_set_fullscreen_mode (mgr, active);
4781 #ifndef MODEST_TOOLKIT_HILDON2
4782 gtk_window_present (GTK_WINDOW (window));
4788 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4789 ModestWindow *window)
4791 ModestWindowMgr *mgr;
4792 gboolean fullscreen;
4794 g_return_if_fail (MODEST_IS_WINDOW (window));
4796 mgr = modest_runtime_get_window_mgr ();
4797 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4798 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4800 #ifndef MODEST_TOOLKIT_HILDON2
4801 gtk_window_present (GTK_WINDOW (window));
4806 * Used by modest_ui_actions_on_details to call do_headers_action
4809 headers_action_show_details (TnyHeader *header,
4810 ModestWindow *window,
4814 gboolean async_retrieval;
4817 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4818 async_retrieval = TRUE;
4819 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
4821 async_retrieval = FALSE;
4823 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header, async_retrieval, msg);
4825 g_object_unref (msg);
4829 * Show the header details in a ModestDetailsDialog widget
4832 modest_ui_actions_on_details (GtkAction *action,
4835 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4839 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4843 header = tny_msg_get_header (msg);
4845 headers_action_show_details (header, win, NULL);
4846 g_object_unref (header);
4848 g_object_unref (msg);
4849 #ifndef MODEST_TOOLKIT_HILDON2
4850 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4851 GtkWidget *folder_view, *header_view;
4853 /* Check which widget has the focus */
4854 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4855 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4856 if (gtk_widget_is_focus (folder_view)) {
4857 TnyFolderStore *folder_store
4858 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4859 if (!folder_store) {
4860 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4863 /* Show only when it's a folder */
4864 /* This function should not be called for account items,
4865 * because we dim the menu item for them. */
4866 if (TNY_IS_FOLDER (folder_store)) {
4867 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4868 TNY_FOLDER (folder_store));
4871 g_object_unref (folder_store);
4874 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4875 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4876 /* Show details of each header */
4877 do_headers_action (win, headers_action_show_details, header_view);
4880 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4882 GtkWidget *header_view;
4884 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4885 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4887 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4889 g_object_unref (folder);
4896 modest_ui_actions_on_limit_error (GtkAction *action,
4899 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
4901 modest_platform_information_banner ((GtkWidget *) win, NULL, _CS("ckdg_ib_maximum_characters_reached"));
4906 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4907 ModestMsgEditWindow *window)
4909 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4911 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4915 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4916 ModestMsgEditWindow *window)
4918 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4920 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4923 #ifndef MODEST_TOOLKIT_HILDON2
4925 modest_ui_actions_toggle_folders_view (GtkAction *action,
4926 ModestMainWindow *main_window)
4928 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4930 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4931 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4933 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4938 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4939 ModestWindow *window)
4941 gboolean active, fullscreen = FALSE;
4942 ModestWindowMgr *mgr;
4944 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4946 /* Check if we want to toggle the toolbar view in fullscreen
4948 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4949 "ViewShowToolbarFullScreen")) {
4953 /* Toggle toolbar */
4954 mgr = modest_runtime_get_window_mgr ();
4955 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4959 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4960 ModestMsgEditWindow *window)
4962 modest_msg_edit_window_select_font (window);
4967 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4968 const gchar *display_name,
4971 /* don't update the display name if it was already set;
4972 * updating the display name apparently is expensive */
4973 const gchar* old_name = gtk_window_get_title (window);
4975 if (display_name == NULL)
4978 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4979 return; /* don't do anything */
4981 /* This is usually used to change the title of the main window, which
4982 * is the one that holds the folder view. Note that this change can
4983 * happen even when the widget doesn't have the focus. */
4984 gtk_window_set_title (window, display_name);
4989 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4991 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4992 modest_msg_edit_window_select_contacts (window);
4996 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4998 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4999 modest_msg_edit_window_check_names (window, FALSE);
5002 #ifndef MODEST_TOOLKIT_HILDON2
5004 * This function is used to track changes in the selection of the
5005 * folder view that is inside the "move to" dialog to enable/disable
5006 * the OK button because we do not want the user to select a disallowed
5007 * destination for a folder.
5008 * The user also not desired to be able to use NEW button on items where
5009 * folder creation is not possibel.
5012 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
5013 TnyFolderStore *folder_store,
5017 GtkWidget *dialog = NULL;
5018 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
5019 gboolean moving_folder = FALSE;
5020 gboolean is_local_account = TRUE;
5021 GtkWidget *folder_view = NULL;
5022 ModestTnyFolderRules rules;
5024 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
5029 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
5033 /* check if folder_store is an remote account */
5034 if (TNY_IS_ACCOUNT (folder_store)) {
5035 TnyAccount *local_account = NULL;
5036 TnyAccount *mmc_account = NULL;
5037 ModestTnyAccountStore *account_store = NULL;
5039 account_store = modest_runtime_get_account_store ();
5040 local_account = modest_tny_account_store_get_local_folders_account (account_store);
5041 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
5043 if ((gpointer) local_account != (gpointer) folder_store &&
5044 (gpointer) mmc_account != (gpointer) folder_store) {
5045 ModestProtocolType proto;
5046 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
5047 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
5048 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
5050 is_local_account = FALSE;
5051 /* New button should be dimmed on remote
5053 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5055 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
5057 g_object_unref (local_account);
5059 /* It could not exist */
5061 g_object_unref (mmc_account);
5064 /* Check the target folder rules */
5065 if (TNY_IS_FOLDER (folder_store)) {
5066 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
5067 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
5068 ok_sensitive = FALSE;
5069 new_sensitive = FALSE;
5074 /* Check if we're moving a folder */
5075 if (MODEST_IS_MAIN_WINDOW (user_data)) {
5076 /* Get the widgets */
5077 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
5078 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5079 if (gtk_widget_is_focus (folder_view))
5080 moving_folder = TRUE;
5083 if (moving_folder) {
5084 TnyFolderStore *moved_folder = NULL, *parent = NULL;
5086 /* Get the folder to move */
5087 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5089 /* Check that we're not moving to the same folder */
5090 if (TNY_IS_FOLDER (moved_folder)) {
5091 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
5092 if (parent == folder_store)
5093 ok_sensitive = FALSE;
5094 g_object_unref (parent);
5097 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
5098 /* Do not allow to move to an account unless it's the
5099 local folders account */
5100 if (!is_local_account)
5101 ok_sensitive = FALSE;
5104 if (ok_sensitive && (moved_folder == folder_store)) {
5105 /* Do not allow to move to itself */
5106 ok_sensitive = FALSE;
5108 g_object_unref (moved_folder);
5110 TnyFolder *src_folder = NULL;
5112 /* Moving a message */
5113 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
5115 TnyHeader *header = NULL;
5116 header = modest_msg_view_window_get_header
5117 (MODEST_MSG_VIEW_WINDOW (user_data));
5118 if (!TNY_IS_HEADER(header))
5119 g_warning ("%s: could not get source header", __FUNCTION__);
5121 src_folder = tny_header_get_folder (header);
5124 g_object_unref (header);
5127 TNY_FOLDER (modest_folder_view_get_selected
5128 (MODEST_FOLDER_VIEW (folder_view)));
5131 if (TNY_IS_FOLDER(src_folder)) {
5132 /* Do not allow to move the msg to the same folder */
5133 /* Do not allow to move the msg to an account */
5134 if ((gpointer) src_folder == (gpointer) folder_store ||
5135 TNY_IS_ACCOUNT (folder_store))
5136 ok_sensitive = FALSE;
5137 g_object_unref (src_folder);
5139 g_warning ("%s: could not get source folder", __FUNCTION__);
5143 /* Set sensitivity of the OK and NEW button */
5144 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
5145 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
5150 on_move_to_dialog_response (GtkDialog *dialog,
5154 GtkWidget *parent_win;
5155 MoveToInfo *helper = NULL;
5156 ModestFolderView *folder_view;
5157 gboolean unset_edit_mode = FALSE;
5159 helper = (MoveToInfo *) user_data;
5161 parent_win = (GtkWidget *) helper->win;
5162 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
5163 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
5165 TnyFolderStore *dst_folder;
5166 TnyFolderStore *selected;
5168 case MODEST_GTK_RESPONSE_NEW_FOLDER:
5169 selected = modest_folder_view_get_selected (folder_view);
5170 modest_ui_actions_create_folder (GTK_WIDGET (dialog), GTK_WIDGET (folder_view), selected);
5171 g_object_unref (selected);
5173 case GTK_RESPONSE_NONE:
5174 case GTK_RESPONSE_CANCEL:
5175 case GTK_RESPONSE_DELETE_EVENT:
5177 case GTK_RESPONSE_OK:
5178 dst_folder = modest_folder_view_get_selected (folder_view);
5180 #ifndef MODEST_TOOLKIT_HILDON2
5181 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
5182 /* Clean list to move used for filtering */
5183 modest_folder_view_set_list_to_move (folder_view, NULL);
5185 modest_ui_actions_on_main_window_move_to (NULL,
5186 GTK_WIDGET (folder_view),
5188 MODEST_MAIN_WINDOW (parent_win));
5190 if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
5191 /* Clean list to move used for filtering */
5192 modest_folder_view_set_list_to_move (folder_view, NULL);
5194 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
5197 GTK_WINDOW (parent_win));
5200 /* if the user selected a root folder
5201 (account) then do not perform any action */
5202 if (TNY_IS_ACCOUNT (dst_folder)) {
5203 g_signal_stop_emission_by_name (dialog, "response");
5207 /* Clean list to move used for filtering */
5208 modest_folder_view_set_list_to_move (folder_view, NULL);
5210 /* Moving from headers window in edit mode */
5211 modest_ui_actions_on_window_move_to (NULL, helper->list,
5213 MODEST_WINDOW (parent_win));
5217 g_object_unref (dst_folder);
5219 unset_edit_mode = TRUE;
5222 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
5225 /* Free the helper and exit */
5227 g_object_unref (helper->list);
5228 if (unset_edit_mode) {
5229 #ifdef MODEST_TOOLKIT_HILDON2
5230 modest_hildon2_window_unset_edit_mode (MODEST_HILDON2_WINDOW (helper->win));
5233 g_slice_free (MoveToInfo, helper);
5234 gtk_widget_destroy (GTK_WIDGET (dialog));
5238 create_move_to_dialog (GtkWindow *win,
5239 GtkWidget *folder_view,
5240 TnyList *list_to_move)
5242 GtkWidget *dialog, *tree_view = NULL;
5244 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
5246 #ifndef MODEST_TOOLKIT_HILDON2
5247 /* Track changes in the selection to
5248 * disable the OK button whenever "Move to" is not possible
5249 * disbale NEW button whenever New is not possible */
5250 g_signal_connect (tree_view,
5251 "folder_selection_changed",
5252 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
5256 /* It could happen that we're trying to move a message from a
5257 window (msg window for example) after the main window was
5258 closed, so we can not just get the model of the folder
5260 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
5261 const gchar *visible_id = NULL;
5263 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5264 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5265 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
5266 MODEST_FOLDER_VIEW(tree_view));
5269 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
5271 /* Show the same account than the one that is shown in the main window */
5272 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
5275 const gchar *active_account_name = NULL;
5276 ModestAccountMgr *mgr = NULL;
5277 ModestAccountSettings *settings = NULL;
5278 ModestServerAccountSettings *store_settings = NULL;
5280 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5281 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5282 /* modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view), */
5283 /* TNY_ACCOUNT_STORE (modest_runtime_get_account_store ())); */
5285 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
5286 mgr = modest_runtime_get_account_mgr ();
5287 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
5290 const gchar *store_account_name;
5291 store_settings = modest_account_settings_get_store_settings (settings);
5292 store_account_name = modest_server_account_settings_get_account_name (store_settings);
5294 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
5295 store_account_name);
5296 g_object_unref (store_settings);
5297 g_object_unref (settings);
5301 /* we keep a pointer to the embedded folder view, so we can
5302 * retrieve it with get_folder_view_from_move_to_dialog (see
5303 * above) later (needed for focus handling)
5305 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
5307 /* Hide special folders */
5308 #ifndef MODEST_TOOLKIT_HILDON2
5309 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
5312 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
5313 #ifndef MODEST_TOOLKIT_HILDON2
5314 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5317 gtk_widget_show (GTK_WIDGET (tree_view));
5323 * Shows a confirmation dialog to the user when we're moving messages
5324 * from a remote server to the local storage. Returns the dialog
5325 * response. If it's other kind of movement then it always returns
5328 * This one is used by the next functions:
5329 * modest_ui_actions_on_paste - commented out
5330 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
5333 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
5334 TnyFolder *dest_folder,
5338 gint response = GTK_RESPONSE_OK;
5339 TnyAccount *account = NULL;
5340 TnyFolder *src_folder = NULL;
5341 TnyIterator *iter = NULL;
5342 TnyHeader *header = NULL;
5344 /* return with OK if the destination is a remote folder */
5345 if (modest_tny_folder_is_remote_folder (dest_folder))
5346 return GTK_RESPONSE_OK;
5348 /* Get source folder */
5349 iter = tny_list_create_iterator (headers);
5350 header = TNY_HEADER (tny_iterator_get_current (iter));
5352 src_folder = tny_header_get_folder (header);
5353 g_object_unref (header);
5355 g_object_unref (iter);
5357 /* if no src_folder, message may be an attahcment */
5358 if (src_folder == NULL)
5359 return GTK_RESPONSE_CANCEL;
5361 /* If the source is a local or MMC folder */
5362 if (!modest_tny_folder_is_remote_folder (src_folder)) {
5363 g_object_unref (src_folder);
5364 return GTK_RESPONSE_OK;
5367 /* Get the account */
5368 account = tny_folder_get_account (src_folder);
5370 /* now if offline we ask the user */
5371 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
5372 response = GTK_RESPONSE_OK;
5374 response = GTK_RESPONSE_CANCEL;
5377 g_object_unref (src_folder);
5378 g_object_unref (account);
5384 move_to_helper_destroyer (gpointer user_data)
5386 MoveToHelper *helper = (MoveToHelper *) user_data;
5388 /* Close the "Pasting" information banner */
5389 if (helper->banner) {
5390 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5391 g_object_unref (helper->banner);
5393 if (gtk_tree_row_reference_valid (helper->reference)) {
5394 gtk_tree_row_reference_free (helper->reference);
5395 helper->reference = NULL;
5401 move_to_cb (ModestMailOperation *mail_op,
5404 MoveToHelper *helper = (MoveToHelper *) user_data;
5405 GObject *object = modest_mail_operation_get_source (mail_op);
5407 /* Note that the operation could have failed, in that case do
5409 if (modest_mail_operation_get_status (mail_op) !=
5410 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5413 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5414 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5416 if (!modest_msg_view_window_select_next_message (self) &&
5417 !modest_msg_view_window_select_previous_message (self)) {
5418 /* No more messages to view, so close this window */
5419 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5421 #ifndef MODEST_TOOLKIT_HILDON2
5422 } else if (MODEST_IS_MAIN_WINDOW (object) &&
5423 gtk_tree_row_reference_valid (helper->reference)) {
5424 GtkWidget *header_view;
5426 GtkTreeSelection *sel;
5428 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5429 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5430 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5431 path = gtk_tree_row_reference_get_path (helper->reference);
5432 /* We need to unselect the previous one
5433 because we could be copying instead of
5435 gtk_tree_selection_unselect_all (sel);
5436 gtk_tree_selection_select_path (sel, path);
5437 gtk_tree_path_free (path);
5440 g_object_unref (object);
5443 /* Destroy the helper */
5444 move_to_helper_destroyer (helper);
5448 folder_move_to_cb (ModestMailOperation *mail_op,
5449 TnyFolder *new_folder,
5454 object = modest_mail_operation_get_source (mail_op);
5455 #ifndef MODEST_TOOLKIT_HILDON2
5456 if (MODEST_IS_MAIN_WINDOW (object)) {
5457 GtkWidget *folder_view;
5458 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5459 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5460 g_object_ref (folder_view);
5461 g_object_unref (object);
5462 move_to_cb (mail_op, user_data);
5463 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5464 g_object_unref (folder_view);
5469 move_to_cb (mail_op, user_data);
5474 msgs_move_to_cb (ModestMailOperation *mail_op,
5477 move_to_cb (mail_op, user_data);
5481 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5484 GObject *win = NULL;
5485 const GError *error;
5486 TnyAccount *account = NULL;
5488 #ifndef MODEST_TOOLKIT_HILDON2
5489 ModestWindow *main_window = NULL;
5491 /* Disable next automatic folder selection */
5492 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5493 FALSE); /* don't create */
5495 /* Show notification dialog only if the main window exists */
5497 GtkWidget *folder_view = NULL;
5499 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5500 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5501 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5503 if (user_data && TNY_IS_FOLDER (user_data)) {
5504 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5505 TNY_FOLDER (user_data), FALSE);
5509 win = modest_mail_operation_get_source (mail_op);
5510 error = modest_mail_operation_get_error (mail_op);
5512 if (TNY_IS_FOLDER (user_data))
5513 account = modest_tny_folder_get_account (TNY_FOLDER (user_data));
5514 else if (TNY_IS_ACCOUNT (user_data))
5515 account = g_object_ref (user_data);
5517 /* If it's not a disk full error then show a generic error */
5518 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5519 (GtkWidget *) win, (GError *) error,
5521 modest_platform_run_information_dialog ((GtkWindow *) win,
5522 _("mail_in_ui_folder_move_target_error"),
5525 g_object_unref (account);
5527 g_object_unref (win);
5530 #ifndef MODEST_TOOLKIT_HILDON2
5532 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5541 gint pending_purges = 0;
5542 gboolean some_purged = FALSE;
5543 ModestWindow *win = MODEST_WINDOW (user_data);
5544 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5546 /* If there was any error */
5547 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5548 modest_window_mgr_unregister_header (mgr, header);
5552 /* Once the message has been retrieved for purging, we check if
5553 * it's all ok for purging */
5555 parts = tny_simple_list_new ();
5556 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5557 iter = tny_list_create_iterator (parts);
5559 while (!tny_iterator_is_done (iter)) {
5561 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5562 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5563 if (tny_mime_part_is_purged (part))
5570 g_object_unref (part);
5572 tny_iterator_next (iter);
5574 g_object_unref (iter);
5577 if (pending_purges>0) {
5579 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5581 if (response == GTK_RESPONSE_OK) {
5584 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5585 iter = tny_list_create_iterator (parts);
5586 while (!tny_iterator_is_done (iter)) {
5589 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5590 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5591 tny_mime_part_set_purged (part);
5594 g_object_unref (part);
5596 tny_iterator_next (iter);
5598 g_object_unref (iter);
5600 tny_msg_rewrite_cache (msg);
5602 gtk_widget_destroy (info);
5606 modest_window_mgr_unregister_header (mgr, header);
5608 g_object_unref (parts);
5612 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5613 ModestMainWindow *win)
5615 GtkWidget *header_view;
5616 TnyList *header_list;
5618 TnyHeaderFlags flags;
5619 ModestWindow *msg_view_window = NULL;
5622 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5624 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5625 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5627 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5629 g_warning ("%s: no header selected", __FUNCTION__);
5633 if (tny_list_get_length (header_list) == 1) {
5634 TnyIterator *iter = tny_list_create_iterator (header_list);
5635 header = TNY_HEADER (tny_iterator_get_current (iter));
5636 g_object_unref (iter);
5640 if (!header || !TNY_IS_HEADER(header)) {
5641 g_warning ("%s: header is not valid", __FUNCTION__);
5645 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5646 header, &msg_view_window);
5647 flags = tny_header_get_flags (header);
5648 if (!(flags & TNY_HEADER_FLAG_CACHED))
5651 if (msg_view_window != NULL)
5652 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5654 /* do nothing; uid was registered before, so window is probably on it's way */
5655 g_debug ("header %p has already been registered", header);
5658 ModestMailOperation *mail_op = NULL;
5659 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5660 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5661 modest_ui_actions_disk_operations_error_handler,
5663 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5664 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5666 g_object_unref (mail_op);
5669 g_object_unref (header);
5671 g_object_unref (header_list);
5676 * Checks if we need a connection to do the transfer and if the user
5677 * wants to connect to complete it
5680 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5681 TnyFolderStore *src_folder,
5683 TnyFolder *dst_folder,
5684 gboolean delete_originals,
5685 gboolean *need_connection,
5688 TnyAccount *src_account;
5689 gint uncached_msgs = 0;
5691 /* We don't need any further check if
5693 * 1- the source folder is local OR
5694 * 2- the device is already online
5696 if (!modest_tny_folder_store_is_remote (src_folder) ||
5697 tny_device_is_online (modest_runtime_get_device())) {
5698 *need_connection = FALSE;
5703 /* We must ask for a connection when
5705 * - the message(s) is not already cached OR
5706 * - the message(s) is cached but the leave_on_server setting
5707 * is FALSE (because we need to sync the source folder to
5708 * delete the message from the server (for IMAP we could do it
5709 * offline, it'll take place the next time we get a
5712 uncached_msgs = header_list_count_uncached_msgs (headers);
5713 src_account = get_account_from_folder_store (src_folder);
5714 if (uncached_msgs > 0) {
5718 *need_connection = TRUE;
5719 num_headers = tny_list_get_length (headers);
5720 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5722 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5723 GTK_RESPONSE_CANCEL) {
5729 /* The transfer is possible and the user wants to */
5732 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5733 const gchar *account_name;
5734 gboolean leave_on_server;
5736 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5737 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5740 if (leave_on_server == TRUE) {
5741 *need_connection = FALSE;
5743 *need_connection = TRUE;
5746 *need_connection = FALSE;
5751 g_object_unref (src_account);
5755 xfer_messages_error_handler (ModestMailOperation *mail_op,
5759 const GError *error;
5760 TnyAccount *account;
5762 win = modest_mail_operation_get_source (mail_op);
5763 error = modest_mail_operation_get_error (mail_op);
5765 /* We cannot get the account from the mail op as that is the
5766 source account and for checking memory full conditions we
5767 need the destination one */
5768 account = TNY_ACCOUNT (user_data);
5771 !modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5772 (GtkWidget *) win, (GError*) error,
5773 account, _KR("cerm_memory_card_full"))) {
5774 modest_platform_run_information_dialog ((GtkWindow *) win,
5775 _("mail_in_ui_folder_move_target_error"),
5779 g_object_unref (win);
5783 TnyFolderStore *dst_folder;
5788 * Utility function that transfer messages from both the main window
5789 * and the msg view window when using the "Move to" dialog
5792 xfer_messages_performer (gboolean canceled,
5794 GtkWindow *parent_window,
5795 TnyAccount *account,
5798 ModestWindow *win = MODEST_WINDOW (parent_window);
5799 TnyAccount *dst_account = NULL;
5800 gboolean dst_forbids_message_add = FALSE;
5801 XferMsgsHelper *helper;
5802 MoveToHelper *movehelper;
5803 ModestMailOperation *mail_op;
5805 helper = (XferMsgsHelper *) user_data;
5807 if (canceled || err) {
5808 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5809 (GtkWidget *) parent_window, err,
5811 /* Show the proper error message */
5812 modest_ui_actions_on_account_connection_error (parent_window, account);
5817 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5819 /* tinymail will return NULL for local folders it seems */
5820 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5821 modest_tny_account_get_protocol_type (dst_account),
5822 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
5824 if (dst_forbids_message_add) {
5825 modest_platform_information_banner (GTK_WIDGET (win),
5827 ngettext("mail_in_ui_folder_move_target_error",
5828 "mail_in_ui_folder_move_targets_error",
5829 tny_list_get_length (helper->headers)));
5833 movehelper = g_new0 (MoveToHelper, 1);
5835 #ifndef MODEST_TOOLKIT_HILDON2
5836 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5837 _CS("ckct_nw_pasting"));
5838 if (movehelper->banner != NULL) {
5839 g_object_ref (movehelper->banner);
5840 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5843 if (MODEST_IS_MAIN_WINDOW (win)) {
5844 GtkWidget *header_view =
5845 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5846 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5847 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5851 /* Perform the mail operation */
5852 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5853 xfer_messages_error_handler,
5854 g_object_ref (dst_account),
5856 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5859 modest_mail_operation_xfer_msgs (mail_op,
5861 TNY_FOLDER (helper->dst_folder),
5866 g_object_unref (G_OBJECT (mail_op));
5869 g_object_unref (dst_account);
5870 g_object_unref (helper->dst_folder);
5871 g_object_unref (helper->headers);
5872 g_slice_free (XferMsgsHelper, helper);
5876 TnyFolder *src_folder;
5877 TnyFolderStore *dst_folder;
5878 gboolean delete_original;
5879 GtkWidget *folder_view;
5883 on_move_folder_cb (gboolean canceled,
5885 GtkWindow *parent_window,
5886 TnyAccount *account,
5889 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5890 GtkTreeSelection *sel;
5891 ModestMailOperation *mail_op = NULL;
5893 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
5894 /* Note that the connection process can fail due to
5895 memory low conditions as it can not successfully
5896 store the summary */
5897 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5898 (GtkWidget*) parent_window, err,
5900 g_debug ("Error connecting when trying to move a folder");
5902 g_object_unref (G_OBJECT (info->src_folder));
5903 g_object_unref (G_OBJECT (info->dst_folder));
5908 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5909 #ifndef MODEST_TOOLKIT_HILDON2
5910 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5911 _CS("ckct_nw_pasting"));
5912 if (helper->banner != NULL) {
5913 g_object_ref (helper->banner);
5914 gtk_widget_show (GTK_WIDGET(helper->banner));
5917 /* Clean folder on header view before moving it */
5918 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5919 gtk_tree_selection_unselect_all (sel);
5921 /* Let gtk events run. We need that the folder
5922 view frees its reference to the source
5923 folder *before* issuing the mail operation
5924 so we need the signal handler of selection
5925 changed to happen before the mail
5927 while (gtk_events_pending ())
5928 gtk_main_iteration (); */
5931 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5932 modest_ui_actions_move_folder_error_handler,
5933 g_object_ref (info->dst_folder), g_object_unref);
5934 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5937 #ifndef MODEST_TOOLKIT_HILDON2
5938 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
5939 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5940 TNY_FOLDER (info->dst_folder), TRUE);
5943 modest_mail_operation_xfer_folder (mail_op,
5944 TNY_FOLDER (info->src_folder),
5946 info->delete_original,
5949 g_object_unref (G_OBJECT (info->src_folder));
5951 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5954 /* Unref mail operation */
5955 g_object_unref (G_OBJECT (mail_op));
5956 g_object_unref (G_OBJECT (info->dst_folder));
5961 get_account_from_folder_store (TnyFolderStore *folder_store)
5963 if (TNY_IS_ACCOUNT (folder_store))
5964 return g_object_ref (folder_store);
5966 return tny_folder_get_account (TNY_FOLDER (folder_store));
5969 #ifndef MODEST_TOOLKIT_HILDON2
5971 * UI handler for the "Move to" action when invoked from the
5975 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5976 GtkWidget *folder_view,
5977 TnyFolderStore *dst_folder,
5978 ModestMainWindow *win)
5980 ModestHeaderView *header_view = NULL;
5981 TnyFolderStore *src_folder = NULL;
5983 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5985 /* Get the source folder */
5986 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5988 /* Get header view */
5989 header_view = (ModestHeaderView *)
5990 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5992 /* Get folder or messages to transfer */
5993 if (gtk_widget_is_focus (folder_view)) {
5994 gboolean do_xfer = TRUE;
5996 /* Allow only to transfer folders to the local root folder */
5997 if (TNY_IS_ACCOUNT (dst_folder) &&
5998 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5999 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
6001 } else if (!TNY_IS_FOLDER (src_folder)) {
6002 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
6007 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
6008 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6010 info->src_folder = g_object_ref (src_folder);
6011 info->dst_folder = g_object_ref (dst_folder);
6012 info->delete_original = TRUE;
6013 info->folder_view = folder_view;
6015 connect_info->callback = on_move_folder_cb;
6016 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6017 connect_info->data = info;
6019 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6020 TNY_FOLDER_STORE (src_folder),
6023 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
6026 headers = modest_header_view_get_selected_headers(header_view);
6028 /* Transfer the messages */
6029 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
6030 headers, TNY_FOLDER (dst_folder));
6032 g_object_unref (headers);
6036 g_object_unref (src_folder);
6040 #ifdef MODEST_TOOLKIT_HILDON2
6042 * UI handler for the "Move to" action when invoked from the
6043 * ModestFolderWindow
6046 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
6047 TnyFolderStore *dst_folder,
6051 TnyFolderStore *src_folder = NULL;
6052 TnyIterator *iterator;
6054 if (tny_list_get_length (selection) != 1)
6057 iterator = tny_list_create_iterator (selection);
6058 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
6059 g_object_unref (iterator);
6062 gboolean do_xfer = TRUE;
6064 /* Allow only to transfer folders to the local root folder */
6065 if (TNY_IS_ACCOUNT (dst_folder) &&
6066 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
6067 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
6070 modest_platform_run_information_dialog (win,
6071 _("mail_in_ui_folder_move_target_error"),
6073 } else if (!TNY_IS_FOLDER (src_folder)) {
6074 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
6079 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
6080 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6082 info->src_folder = g_object_ref (src_folder);
6083 info->dst_folder = g_object_ref (dst_folder);
6084 info->delete_original = TRUE;
6085 info->folder_view = folder_view;
6087 connect_info->callback = on_move_folder_cb;
6088 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6089 connect_info->data = info;
6091 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6092 TNY_FOLDER_STORE (src_folder),
6097 g_object_unref (src_folder);
6103 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
6104 TnyFolder *src_folder,
6106 TnyFolder *dst_folder)
6108 gboolean need_connection = TRUE;
6109 gboolean do_xfer = TRUE;
6110 XferMsgsHelper *helper;
6112 g_return_if_fail (TNY_IS_FOLDER (src_folder));
6113 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6114 g_return_if_fail (TNY_IS_LIST (headers));
6116 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
6117 headers, TNY_FOLDER (dst_folder),
6118 TRUE, &need_connection,
6121 /* If we don't want to transfer just return */
6125 /* Create the helper */
6126 helper = g_slice_new (XferMsgsHelper);
6127 helper->dst_folder = g_object_ref (dst_folder);
6128 helper->headers = g_object_ref (headers);
6130 if (need_connection) {
6131 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6132 connect_info->callback = xfer_messages_performer;
6133 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
6134 connect_info->data = helper;
6136 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6137 TNY_FOLDER_STORE (src_folder),
6140 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
6141 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
6142 src_account, helper);
6143 g_object_unref (src_account);
6148 * UI handler for the "Move to" action when invoked from the
6149 * ModestMsgViewWindow
6152 modest_ui_actions_on_window_move_to (GtkAction *action,
6154 TnyFolderStore *dst_folder,
6157 TnyFolder *src_folder = NULL;
6159 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6162 TnyHeader *header = NULL;
6165 iter = tny_list_create_iterator (headers);
6166 header = (TnyHeader *) tny_iterator_get_current (iter);
6167 src_folder = tny_header_get_folder (header);
6169 /* Transfer the messages */
6170 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
6172 TNY_FOLDER (dst_folder));
6175 g_object_unref (header);
6176 g_object_unref (iter);
6177 g_object_unref (src_folder);
6182 modest_ui_actions_on_move_to (GtkAction *action,
6185 modest_ui_actions_on_edit_mode_move_to (win);
6189 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
6191 GtkWidget *dialog = NULL;
6192 MoveToInfo *helper = NULL;
6193 TnyList *list_to_move;
6195 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
6197 #ifndef MODEST_TOOLKIT_HILDON2
6198 /* Get the main window if exists */
6199 ModestMainWindow *main_window;
6200 if (MODEST_IS_MAIN_WINDOW (win))
6201 main_window = MODEST_MAIN_WINDOW (win);
6204 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
6205 FALSE)); /* don't create */
6208 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
6213 if (tny_list_get_length (list_to_move) < 1) {
6214 g_object_unref (list_to_move);
6218 /* Create and run the dialog */
6219 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
6220 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
6221 GTK_WINDOW (dialog),
6225 helper = g_slice_new0 (MoveToInfo);
6226 helper->list = list_to_move;
6229 /* Listen to response signal */
6230 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
6232 /* Show the dialog */
6233 gtk_widget_show (dialog);
6239 * Calls #HeadersFunc for each header already selected in the main
6240 * window or the message currently being shown in the msg view window
6243 do_headers_action (ModestWindow *win,
6247 TnyList *headers_list = NULL;
6248 TnyIterator *iter = NULL;
6249 TnyHeader *header = NULL;
6250 TnyFolder *folder = NULL;
6253 headers_list = get_selected_headers (win);
6257 /* Get the folder */
6258 iter = tny_list_create_iterator (headers_list);
6259 header = TNY_HEADER (tny_iterator_get_current (iter));
6261 folder = tny_header_get_folder (header);
6262 g_object_unref (header);
6265 /* Call the function for each header */
6266 while (!tny_iterator_is_done (iter)) {
6267 header = TNY_HEADER (tny_iterator_get_current (iter));
6268 func (header, win, user_data);
6269 g_object_unref (header);
6270 tny_iterator_next (iter);
6273 /* Trick: do a poke status in order to speed up the signaling
6276 tny_folder_poke_status (folder);
6277 g_object_unref (folder);
6281 g_object_unref (iter);
6282 g_object_unref (headers_list);
6286 modest_ui_actions_view_attachment (GtkAction *action,
6287 ModestWindow *window)
6289 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6290 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
6292 /* not supported window for this action */
6293 g_return_if_reached ();
6298 modest_ui_actions_save_attachments (GtkAction *action,
6299 ModestWindow *window)
6301 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6303 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
6306 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
6308 /* not supported window for this action */
6309 g_return_if_reached ();
6314 modest_ui_actions_remove_attachments (GtkAction *action,
6315 ModestWindow *window)
6317 #ifndef MODEST_TOOLKIT_HILDON2
6318 if (MODEST_IS_MAIN_WINDOW (window)) {
6319 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
6320 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6322 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6324 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
6326 /* not supported window for this action */
6327 g_return_if_reached ();
6332 modest_ui_actions_on_settings (GtkAction *action,
6337 dialog = modest_platform_get_global_settings_dialog ();
6338 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
6339 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
6340 gtk_widget_show_all (dialog);
6342 gtk_dialog_run (GTK_DIALOG (dialog));
6344 gtk_widget_destroy (dialog);
6348 modest_ui_actions_on_help (GtkAction *action,
6351 /* Help app is not available at all in fremantle */
6352 #ifndef MODEST_TOOLKIT_HILDON2
6353 const gchar *help_id;
6355 g_return_if_fail (win && GTK_IS_WINDOW(win));
6357 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
6360 modest_platform_show_help (GTK_WINDOW (win), help_id);
6365 modest_ui_actions_on_csm_help (GtkAction *action,
6368 /* Help app is not available at all in fremantle */
6369 #ifndef MODEST_TOOLKIT_HILDON2
6371 const gchar* help_id = NULL;
6372 GtkWidget *folder_view;
6373 TnyFolderStore *folder_store;
6375 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
6377 /* Get selected folder */
6378 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
6379 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6380 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6382 /* Switch help_id */
6383 if (folder_store && TNY_IS_FOLDER (folder_store))
6384 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
6387 g_object_unref (folder_store);
6390 modest_platform_show_help (GTK_WINDOW (win), help_id);
6392 modest_ui_actions_on_help (action, win);
6397 retrieve_contents_cb (ModestMailOperation *mail_op,
6404 /* We only need this callback to show an error in case of
6405 memory low condition */
6406 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
6407 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
6412 retrieve_msg_contents_performer (gboolean canceled,
6414 GtkWindow *parent_window,
6415 TnyAccount *account,
6418 ModestMailOperation *mail_op;
6419 TnyList *headers = TNY_LIST (user_data);
6421 if (err || canceled) {
6422 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6423 (GtkWidget *) parent_window, err,
6428 /* Create mail operation */
6429 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
6430 modest_ui_actions_disk_operations_error_handler,
6432 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
6433 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
6436 g_object_unref (mail_op);
6438 g_object_unref (headers);
6439 g_object_unref (account);
6443 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
6444 ModestWindow *window)
6446 TnyList *headers = NULL;
6447 TnyAccount *account = NULL;
6448 TnyIterator *iter = NULL;
6449 TnyHeader *header = NULL;
6450 TnyFolder *folder = NULL;
6453 headers = get_selected_headers (window);
6457 /* Pick the account */
6458 iter = tny_list_create_iterator (headers);
6459 header = TNY_HEADER (tny_iterator_get_current (iter));
6460 folder = tny_header_get_folder (header);
6461 account = tny_folder_get_account (folder);
6462 g_object_unref (folder);
6463 g_object_unref (header);
6464 g_object_unref (iter);
6466 /* Connect and perform the message retrieval */
6467 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6468 g_object_ref (account),
6469 retrieve_msg_contents_performer,
6470 g_object_ref (headers));
6473 g_object_unref (account);
6474 g_object_unref (headers);
6478 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6480 g_return_if_fail (MODEST_IS_WINDOW (window));
6483 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6487 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6489 g_return_if_fail (MODEST_IS_WINDOW (window));
6492 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6496 modest_ui_actions_on_email_menu_activated (GtkAction *action,
6497 ModestWindow *window)
6499 g_return_if_fail (MODEST_IS_WINDOW (window));
6502 modest_ui_actions_check_menu_dimming_rules (window);
6506 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
6507 ModestWindow *window)
6509 g_return_if_fail (MODEST_IS_WINDOW (window));
6512 modest_ui_actions_check_menu_dimming_rules (window);
6516 modest_ui_actions_on_view_menu_activated (GtkAction *action,
6517 ModestWindow *window)
6519 g_return_if_fail (MODEST_IS_WINDOW (window));
6522 modest_ui_actions_check_menu_dimming_rules (window);
6526 modest_ui_actions_on_format_menu_activated (GtkAction *action,
6527 ModestWindow *window)
6529 g_return_if_fail (MODEST_IS_WINDOW (window));
6532 modest_ui_actions_check_menu_dimming_rules (window);
6536 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
6537 ModestWindow *window)
6539 g_return_if_fail (MODEST_IS_WINDOW (window));
6542 modest_ui_actions_check_menu_dimming_rules (window);
6546 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
6547 ModestWindow *window)
6549 g_return_if_fail (MODEST_IS_WINDOW (window));
6552 modest_ui_actions_check_menu_dimming_rules (window);
6556 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
6557 ModestWindow *window)
6559 g_return_if_fail (MODEST_IS_WINDOW (window));
6562 modest_ui_actions_check_menu_dimming_rules (window);
6566 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
6567 ModestWindow *window)
6569 g_return_if_fail (MODEST_IS_WINDOW (window));
6572 modest_ui_actions_check_menu_dimming_rules (window);
6576 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
6577 ModestWindow *window)
6579 g_return_if_fail (MODEST_IS_WINDOW (window));
6582 modest_ui_actions_check_menu_dimming_rules (window);
6586 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6588 g_return_if_fail (MODEST_IS_WINDOW (window));
6590 /* we check for low-mem; in that case, show a warning, and don't allow
6593 if (modest_platform_check_memory_low (window, TRUE))
6596 modest_platform_show_search_messages (GTK_WINDOW (window));
6600 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6602 g_return_if_fail (MODEST_IS_WINDOW (win));
6605 /* we check for low-mem; in that case, show a warning, and don't allow
6606 * for the addressbook
6608 if (modest_platform_check_memory_low (win, TRUE))
6612 modest_platform_show_addressbook (GTK_WINDOW (win));
6617 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6618 ModestWindow *window)
6621 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6623 if (GTK_IS_TOGGLE_ACTION (action))
6624 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6628 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window),
6632 #ifndef MODEST_TOOLKIT_HILDON2
6634 on_send_receive_finished (ModestMailOperation *mail_op,
6637 GtkWidget *header_view, *folder_view;
6638 TnyFolderStore *folder_store;
6639 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6641 /* Set send/receive operation finished */
6642 modest_main_window_notify_send_receive_completed (main_win);
6644 /* Don't refresh the current folder if there were any errors */
6645 if (modest_mail_operation_get_status (mail_op) !=
6646 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6649 /* Refresh the current folder if we're viewing a window. We do
6650 this because the user won't be able to see the new mails in
6651 the selected folder after a Send&Receive because it only
6652 performs a poke_status, i.e, only the number of read/unread
6653 messages is updated, but the new headers are not
6655 folder_view = modest_main_window_get_child_widget (main_win,
6656 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6660 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6662 /* Do not need to refresh INBOX again because the
6663 update_account does it always automatically */
6664 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6665 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6666 ModestMailOperation *refresh_op;
6668 header_view = modest_main_window_get_child_widget (main_win,
6669 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6671 /* We do not need to set the contents style
6672 because it hasn't changed. We also do not
6673 need to save the widget status. Just force
6675 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6676 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6677 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6678 folder_refreshed_cb, main_win);
6679 g_object_unref (refresh_op);
6683 g_object_unref (folder_store);
6688 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6694 const gchar* server_name = NULL;
6695 TnyTransportAccount *transport;
6696 gchar *message = NULL;
6697 ModestProtocol *protocol;
6699 /* Don't show anything if the user cancelled something or the
6700 * send receive request is not interactive. Authentication
6701 * errors are managed by the account store so no need to show
6702 * a dialog here again */
6703 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6704 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6705 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6709 /* Get the server name. Note that we could be using a
6710 connection specific transport account */
6711 transport = (TnyTransportAccount *)
6712 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
6714 ModestTnyAccountStore *acc_store;
6715 const gchar *acc_name;
6716 TnyTransportAccount *conn_specific;
6718 acc_store = modest_runtime_get_account_store();
6719 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
6720 conn_specific = (TnyTransportAccount *)
6721 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
6722 if (conn_specific) {
6723 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
6724 g_object_unref (conn_specific);
6726 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
6728 g_object_unref (transport);
6732 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
6733 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
6734 tny_account_get_proto (TNY_ACCOUNT (transport)));
6736 g_warning ("%s: Account with no proto", __FUNCTION__);
6740 /* Show the appropriate message text for the GError: */
6741 switch (err->code) {
6742 case TNY_SERVICE_ERROR_CONNECT:
6743 message = modest_protocol_get_translation (protocol,
6744 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
6747 case TNY_SERVICE_ERROR_SEND:
6748 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6750 case TNY_SERVICE_ERROR_UNAVAILABLE:
6751 message = modest_protocol_get_translation (protocol,
6752 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
6756 g_warning ("%s: unexpected ERROR %d",
6757 __FUNCTION__, err->code);
6758 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6762 modest_platform_run_information_dialog (NULL, message, FALSE);
6767 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6772 ModestWindow *top_window = NULL;
6773 ModestWindowMgr *mgr = NULL;
6774 GtkWidget *header_view = NULL;
6775 TnyFolder *selected_folder = NULL;
6776 TnyFolderType folder_type;
6778 mgr = modest_runtime_get_window_mgr ();
6779 top_window = modest_window_mgr_get_current_top (mgr);
6784 #ifndef MODEST_TOOLKIT_HILDON2
6785 if (MODEST_IS_MAIN_WINDOW (top_window)) {
6786 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (top_window),
6787 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6790 if (MODEST_IS_HEADER_WINDOW (top_window)) {
6791 header_view = (GtkWidget *)
6792 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
6796 /* Get selected folder */
6798 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
6799 if (!selected_folder)
6802 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6803 #if GTK_CHECK_VERSION(2, 8, 0)
6804 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
6805 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6806 GtkTreeViewColumn *tree_column;
6808 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6809 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6811 gtk_tree_view_column_queue_resize (tree_column);
6813 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
6814 gtk_widget_queue_draw (header_view);
6817 #ifndef MODEST_TOOLKIT_HILDON2
6818 /* Rerun dimming rules, because the message could become deletable for example */
6819 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6820 MODEST_DIMMING_RULES_TOOLBAR);
6821 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6822 MODEST_DIMMING_RULES_MENU);
6826 g_object_unref (selected_folder);
6830 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6831 TnyAccount *account)
6833 ModestProtocolType protocol_type;
6834 ModestProtocol *protocol;
6835 gchar *error_note = NULL;
6837 protocol_type = modest_tny_account_get_protocol_type (account);
6838 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6841 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6842 if (error_note == NULL) {
6843 g_warning ("%s: This should not be reached", __FUNCTION__);
6845 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6846 g_free (error_note);
6851 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6855 TnyFolderStore *folder = NULL;
6856 TnyAccount *account = NULL;
6857 ModestProtocolType proto;
6858 ModestProtocol *protocol;
6859 TnyHeader *header = NULL;
6861 #ifndef MODEST_TOOLKIT_HILDON2
6862 if (MODEST_IS_MAIN_WINDOW (win)) {
6863 GtkWidget *header_view;
6864 TnyList* headers = NULL;
6866 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6867 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6868 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6869 if (!headers || tny_list_get_length (headers) == 0) {
6871 g_object_unref (headers);
6874 iter = tny_list_create_iterator (headers);
6875 header = TNY_HEADER (tny_iterator_get_current (iter));
6876 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6877 g_object_unref (iter);
6878 g_object_unref (headers);
6880 if (MODEST_IS_HEADER_WINDOW (win)) {
6881 GtkWidget *header_view;
6882 TnyList* headers = NULL;
6884 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
6885 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6886 if (!headers || tny_list_get_length (headers) == 0) {
6888 g_object_unref (headers);
6891 iter = tny_list_create_iterator (headers);
6892 header = TNY_HEADER (tny_iterator_get_current (iter));
6894 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6896 g_warning ("List should contain headers");
6898 g_object_unref (iter);
6899 g_object_unref (headers);
6901 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6902 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6904 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6907 if (!header || !folder)
6910 /* Get the account type */
6911 account = tny_folder_get_account (TNY_FOLDER (folder));
6912 proto = modest_tny_account_get_protocol_type (account);
6913 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6916 subject = tny_header_dup_subject (header);
6917 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6921 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6927 g_object_unref (account);
6929 g_object_unref (folder);
6931 g_object_unref (header);
6937 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6938 const gchar *account_name,
6939 const gchar *account_title)
6941 ModestAccountMgr *account_mgr;
6944 ModestProtocol *protocol;
6945 gboolean removed = FALSE;
6947 g_return_val_if_fail (account_name, FALSE);
6948 g_return_val_if_fail (account_title, FALSE);
6950 account_mgr = modest_runtime_get_account_mgr();
6952 /* The warning text depends on the account type: */
6953 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6954 modest_account_mgr_get_store_protocol (account_mgr,
6956 txt = modest_protocol_get_translation (protocol,
6957 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6960 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6962 response = modest_platform_run_confirmation_dialog (parent_window, txt);
6966 if (response == GTK_RESPONSE_OK) {
6967 /* Remove account. If it succeeds then it also removes
6968 the account from the ModestAccountView: */
6969 gboolean is_default = FALSE;
6970 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6971 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6973 g_free (default_account_name);
6975 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6977 /* Close all email notifications, we cannot
6978 distinguish if the notification belongs to
6979 this account or not, so for safety reasons
6980 we remove them all */
6981 modest_platform_remove_new_mail_notifications (FALSE);
6983 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
6990 on_fetch_images_performer (gboolean canceled,
6992 GtkWindow *parent_window,
6993 TnyAccount *account,
6996 if (err || canceled) {
6997 /* Show an unable to retrieve images ??? */
7001 /* Note that the user could have closed the window while connecting */
7002 if (GTK_WIDGET_VISIBLE (parent_window))
7003 modest_msg_view_window_fetch_images ((ModestMsgViewWindow *) parent_window);
7004 g_object_unref ((GObject *) user_data);
7008 modest_ui_actions_on_fetch_images (GtkAction *action,
7009 ModestWindow *window)
7011 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
7013 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
7015 on_fetch_images_performer,
7016 g_object_ref (window));
7020 modest_ui_actions_on_reload_message (const gchar *msg_id)
7022 ModestWindow *window = NULL;
7024 g_return_if_fail (msg_id && msg_id[0] != '\0');
7025 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
7031 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
7034 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));
7037 /** Check whether any connections are active, and cancel them if
7039 * Returns TRUE is there was no problem,
7040 * or if an operation was cancelled so we can continue.
7041 * Returns FALSE if the user chose to cancel his request instead.
7045 modest_ui_actions_check_for_active_account (ModestWindow *self,
7046 const gchar* account_name)
7048 ModestTnySendQueue *send_queue;
7049 ModestTnyAccountStore *acc_store;
7050 ModestMailOperationQueue* queue;
7051 TnyConnectionStatus store_conn_status;
7052 TnyAccount *store_account = NULL, *transport_account = NULL;
7053 gboolean retval = TRUE, sending = FALSE;
7055 acc_store = modest_runtime_get_account_store ();
7056 queue = modest_runtime_get_mail_operation_queue ();
7059 modest_tny_account_store_get_server_account (acc_store,
7061 TNY_ACCOUNT_TYPE_STORE);
7063 /* This could happen if the account was deleted before the
7064 call to this function */
7069 modest_tny_account_store_get_server_account (acc_store,
7071 TNY_ACCOUNT_TYPE_TRANSPORT);
7073 /* This could happen if the account was deleted before the
7074 call to this function */
7075 if (!transport_account) {
7076 g_object_unref (store_account);
7080 /* If the transport account was not used yet, then the send
7081 queue could not exist (it's created on demand) */
7082 send_queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (transport_account), FALSE);
7083 if (TNY_IS_SEND_QUEUE (send_queue))
7084 sending = modest_tny_send_queue_sending_in_progress (send_queue);
7086 store_conn_status = tny_account_get_connection_status (store_account);
7087 if (store_conn_status == TNY_CONNECTION_STATUS_CONNECTED || sending) {
7090 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (self),
7091 _("emev_nc_disconnect_account"));
7092 if (response == GTK_RESPONSE_OK) {
7101 /* FIXME: We should only cancel those of this account */
7102 modest_mail_operation_queue_cancel_all (queue);
7104 /* Also disconnect the account */
7105 if ((tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED) &&
7106 (tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)) {
7107 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
7111 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (transport_account),
7117 g_object_unref (store_account);
7118 g_object_unref (transport_account);