1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #endif /*HAVE_CONFIG_H*/
34 #include <glib/gi18n.h>
35 #include <glib/gprintf.h>
37 #include <modest-runtime.h>
38 #include <modest-defs.h>
39 #include <modest-tny-folder.h>
40 #include <modest-tny-msg.h>
41 #include <modest-tny-account.h>
42 #include <modest-address-book.h>
43 #include "modest-error.h"
44 #include "modest-ui-actions.h"
45 #include "modest-tny-platform-factory.h"
46 #include "modest-platform.h"
47 #include "modest-debug.h"
48 #include <tny-mime-part.h>
49 #include <tny-error.h>
50 #include <tny-camel-folder.h>
51 #include <tny-camel-imap-folder.h>
52 #include <tny-camel-pop-folder.h>
53 #ifdef MODEST_TOOLKIT_HILDON2
54 #include <modest-accounts-window.h>
55 #include <hildon/hildon-pannable-area.h>
56 #include <hildon/hildon-gtk.h>
57 #include <modest-header-window.h>
58 #include <modest-folder-window.h>
59 #include <modest-maemo-utils.h>
62 #include <modest-utils.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 idle_refresh_folder (gpointer source)
2174 ModestHeaderView *header_view = NULL;
2176 /* If the window still exists */
2177 if (!GTK_IS_WIDGET (source) ||
2178 !GTK_WIDGET_VISIBLE (source))
2181 /* Refresh the current view */
2182 #ifdef MODEST_TOOLKIT_HILDON2
2183 if (MODEST_IS_HEADER_WINDOW (source))
2184 header_view = modest_header_window_get_header_view ((ModestHeaderWindow *) source);
2186 if (MODEST_IS_MAIN_WINDOW (source))
2187 header_view = modest_main_window_get_child_widget ((ModestMainWindow *) source,
2188 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2191 TnyFolder *folder = modest_header_view_get_folder (header_view);
2193 /* We must clear first, because otherwise set_folder will ignore
2194 the change as the folders are the same */
2195 modest_header_view_clear (header_view);
2196 modest_header_view_set_folder (header_view, folder, TRUE,
2197 (ModestWindow *) source, NULL, NULL);
2198 g_object_unref (folder);
2206 update_account_cb (ModestMailOperation *self,
2207 TnyList *new_headers,
2211 gboolean show_visual_notifications;
2213 source = modest_mail_operation_get_source (self);
2214 show_visual_notifications = (source) ? FALSE : TRUE;
2216 /* Notify new messages have been downloaded. If the
2217 send&receive was invoked by the user then do not show any
2218 visual notification, only play a sound and activate the LED
2219 (for the Maemo version) */
2220 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0) {
2222 /* We only notify about really new messages (not seen) we get */
2223 TnyList *actually_new_list;
2224 TnyIterator *iterator;
2225 actually_new_list = TNY_LIST (tny_simple_list_new ());
2226 for (iterator = tny_list_create_iterator (new_headers);
2227 !tny_iterator_is_done (iterator);
2228 tny_iterator_next (iterator)) {
2230 TnyHeaderFlags flags;
2231 header = TNY_HEADER (tny_iterator_get_current (iterator));
2232 flags = tny_header_get_flags (header);
2234 if (!(flags & TNY_HEADER_FLAG_SEEN)) {
2235 /* Messages are ordered from most
2236 recent to oldest. But we want to
2237 show notifications starting from
2238 the oldest message. That's why we
2240 tny_list_prepend (actually_new_list, G_OBJECT (header));
2242 g_object_unref (header);
2244 g_object_unref (iterator);
2246 if (tny_list_get_length (actually_new_list) > 0) {
2247 GList *new_headers_list = NULL;
2249 new_headers_list = modest_utils_create_notification_list_from_header_list (actually_new_list);
2251 /* Send notifications */
2252 if (new_headers_list) {
2253 modest_platform_on_new_headers_received (new_headers_list,
2254 show_visual_notifications);
2256 modest_utils_free_notification_list (new_headers_list);
2259 g_object_unref (actually_new_list);
2263 /* Refresh the current folder in an idle. We do this
2264 in order to avoid refresh cancelations if the
2265 currently viewed folder is the inbox */
2266 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
2267 idle_refresh_folder,
2268 g_object_ref (source),
2270 g_object_unref (source);
2275 TnyAccount *account;
2277 gchar *account_name;
2278 gboolean poke_status;
2279 gboolean interactive;
2280 ModestMailOperation *mail_op;
2284 do_send_receive_performer (gboolean canceled,
2286 GtkWindow *parent_window,
2287 TnyAccount *account,
2290 SendReceiveInfo *info;
2292 info = (SendReceiveInfo *) user_data;
2294 if (err || canceled) {
2295 /* In disk full conditions we could get this error here */
2296 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
2297 (GtkWidget *) parent_window, err,
2300 if (info->mail_op) {
2301 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2307 #ifndef MODEST_TOOLKIT_HILDON2
2308 /* Set send/receive operation in progress */
2309 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2310 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2313 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2314 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2315 G_CALLBACK (on_send_receive_finished),
2319 /* Send & receive. */
2320 modest_mail_operation_update_account (info->mail_op, info->account_name,
2321 info->poke_status, info->interactive,
2322 update_account_cb, info->win);
2327 g_object_unref (G_OBJECT (info->mail_op));
2328 if (info->account_name)
2329 g_free (info->account_name);
2331 g_object_unref (info->win);
2333 g_object_unref (info->account);
2334 g_slice_free (SendReceiveInfo, info);
2338 * This function performs the send & receive required actions. The
2339 * window is used to create the mail operation. Typically it should
2340 * always be the main window, but we pass it as argument in order to
2344 modest_ui_actions_do_send_receive (const gchar *account_name,
2345 gboolean force_connection,
2346 gboolean poke_status,
2347 gboolean interactive,
2350 gchar *acc_name = NULL;
2351 SendReceiveInfo *info;
2352 ModestTnyAccountStore *acc_store;
2353 TnyAccount *account;
2355 /* If no account name was provided then get the current account, and if
2356 there is no current account then pick the default one: */
2357 if (!account_name) {
2359 acc_name = g_strdup (modest_window_get_active_account (win));
2361 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2363 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2367 acc_name = g_strdup (account_name);
2370 acc_store = modest_runtime_get_account_store ();
2371 account = modest_tny_account_store_get_server_account (acc_store, acc_name, TNY_ACCOUNT_TYPE_STORE);
2375 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2379 /* Do not automatically refresh accounts that are flagged as
2380 NO_AUTO_UPDATE. This could be useful for accounts that
2381 handle their own update times */
2383 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
2384 if (proto != MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
2385 const gchar *tag = MODEST_PROTOCOL_REGISTRY_NO_AUTO_UPDATE_PROTOCOLS;
2386 ModestProtocolRegistry *registry = modest_runtime_get_protocol_registry ();
2388 if (modest_protocol_registry_protocol_type_has_tag (registry, proto, tag)) {
2389 g_debug ("%s no auto update allowed for account %s", __FUNCTION__, account_name);
2390 g_object_unref (account);
2397 /* Create the info for the connect and perform */
2398 info = g_slice_new (SendReceiveInfo);
2399 info->account_name = acc_name;
2400 info->win = (win) ? g_object_ref (win) : NULL;
2401 info->poke_status = poke_status;
2402 info->interactive = interactive;
2403 info->account = account;
2404 /* We need to create the operation here, because otherwise it
2405 could happen that the queue emits the queue-empty signal
2406 while we're trying to connect the account */
2407 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2408 modest_ui_actions_disk_operations_error_handler,
2410 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2412 /* Invoke the connect and perform */
2413 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2414 force_connection, info->account,
2415 do_send_receive_performer, info);
2420 modest_ui_actions_do_cancel_send (const gchar *account_name,
2423 TnyTransportAccount *transport_account;
2424 TnySendQueue *send_queue = NULL;
2425 GError *error = NULL;
2427 /* Get transport account */
2429 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2430 (modest_runtime_get_account_store(),
2432 TNY_ACCOUNT_TYPE_TRANSPORT));
2433 if (!transport_account) {
2434 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2439 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2440 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2441 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2442 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2443 "modest: could not find send queue for account\n");
2445 /* Cancel the current send */
2446 tny_account_cancel (TNY_ACCOUNT (transport_account));
2448 /* Suspend all pending messages */
2449 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2453 if (transport_account != NULL)
2454 g_object_unref (G_OBJECT (transport_account));
2458 modest_ui_actions_cancel_send_all (ModestWindow *win)
2460 GSList *account_names, *iter;
2462 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2465 iter = account_names;
2467 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2468 iter = g_slist_next (iter);
2471 modest_account_mgr_free_account_names (account_names);
2472 account_names = NULL;
2476 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2479 /* Check if accounts exist */
2480 gboolean accounts_exist =
2481 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2483 /* If not, allow the user to create an account before trying to send/receive. */
2484 if (!accounts_exist)
2485 modest_ui_actions_on_accounts (NULL, win);
2487 /* Cancel all sending operaitons */
2488 modest_ui_actions_cancel_send_all (win);
2492 * Refreshes all accounts. This function will be used by automatic
2496 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2497 gboolean force_connection,
2498 gboolean poke_status,
2499 gboolean interactive)
2501 GSList *account_names, *iter;
2503 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2506 iter = account_names;
2508 modest_ui_actions_do_send_receive ((const char*) iter->data,
2510 poke_status, interactive, win);
2511 iter = g_slist_next (iter);
2514 modest_account_mgr_free_account_names (account_names);
2515 account_names = NULL;
2519 * Handler of the click on Send&Receive button in the main toolbar
2522 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2524 /* Check if accounts exist */
2525 gboolean accounts_exist;
2528 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2530 /* If not, allow the user to create an account before trying to send/receive. */
2531 if (!accounts_exist)
2532 modest_ui_actions_on_accounts (NULL, win);
2534 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2535 #ifndef MODEST_TOOLKIT_HILDON2
2536 if (MODEST_IS_MAIN_WINDOW (win)) {
2537 GtkWidget *folder_view;
2538 TnyFolderStore *folder_store;
2541 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2542 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2546 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2549 g_object_unref (folder_store);
2550 /* Refresh the active account. Force the connection if needed
2551 and poke the status of all folders */
2552 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2554 if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2555 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2558 const gchar *active_account;
2559 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2561 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2566 #ifndef MODEST_TOOLKIT_HILDON2
2568 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2571 GtkWidget *header_view;
2573 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2575 header_view = modest_main_window_get_child_widget (main_window,
2576 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2580 conf = modest_runtime_get_conf ();
2582 /* what is saved/restored is depending on the style; thus; we save with
2583 * old style, then update the style, and restore for this new style
2585 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2587 if (modest_header_view_get_style
2588 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2589 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2590 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2592 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2593 MODEST_HEADER_VIEW_STYLE_DETAILS);
2595 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2596 MODEST_CONF_HEADER_VIEW_KEY);
2600 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2602 ModestMainWindow *main_window)
2604 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2605 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2607 /* in the case the folder is empty, show the empty folder message and focus
2609 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2610 if (modest_header_view_is_empty (header_view)) {
2611 TnyFolder *folder = modest_header_view_get_folder (header_view);
2612 GtkWidget *folder_view =
2613 modest_main_window_get_child_widget (main_window,
2614 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2615 if (folder != NULL) {
2616 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2617 g_object_unref (folder);
2619 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2623 /* If no header has been selected then exit */
2628 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2629 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2631 /* Update toolbar dimming state */
2632 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2633 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2638 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2641 ModestWindow *window)
2643 GtkTreeRowReference *rowref;
2645 g_return_if_fail (MODEST_IS_WINDOW(window));
2646 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2647 g_return_if_fail (TNY_IS_HEADER (header));
2649 if (modest_header_view_count_selected_headers (header_view) > 1) {
2650 /* Don't allow activation if there are more than one message selected */
2651 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2655 /* we check for low-mem; in that case, show a warning, and don't allow
2656 * activating headers
2658 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2661 #ifndef MODEST_TOOLKIT_HILDON2
2662 GtkWidget *open_widget;
2663 if (MODEST_IS_MAIN_WINDOW (window)) {
2664 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2665 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2666 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2671 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2672 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2673 gtk_tree_row_reference_free (rowref);
2676 #ifndef MODEST_TOOLKIT_HILDON2
2678 set_active_account_from_tny_account (TnyAccount *account,
2679 ModestWindow *window)
2681 const gchar *server_acc_name = tny_account_get_id (account);
2683 /* We need the TnyAccount provided by the
2684 account store because that is the one that
2685 knows the name of the Modest account */
2686 TnyAccount *modest_server_account =
2687 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2688 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2690 if (!modest_server_account) {
2691 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2695 /* Update active account, but only if it's not a pseudo-account */
2696 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2697 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2698 const gchar *modest_acc_name =
2699 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2700 if (modest_acc_name)
2701 modest_window_set_active_account (window, modest_acc_name);
2704 g_object_unref (modest_server_account);
2708 folder_refreshed_cb (ModestMailOperation *mail_op,
2712 ModestMainWindow *win = NULL;
2713 GtkWidget *folder_view, *header_view;
2714 const GError *error;
2716 g_return_if_fail (TNY_IS_FOLDER (folder));
2718 win = MODEST_MAIN_WINDOW (user_data);
2720 /* Check if the operation failed due to memory low conditions */
2721 error = modest_mail_operation_get_error (mail_op);
2722 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2723 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2724 modest_platform_run_information_dialog (GTK_WINDOW (win),
2725 _KR("memr_ib_operation_disabled"),
2731 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2733 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2736 TnyFolderStore *current_folder;
2738 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2739 if (current_folder) {
2740 gboolean different = ((TnyFolderStore *) folder != current_folder);
2741 g_object_unref (current_folder);
2747 /* Check if folder is empty and set headers view contents style */
2748 if ((tny_folder_get_all_count (folder) == 0) ||
2749 modest_header_view_is_empty (MODEST_HEADER_VIEW (header_view)))
2750 modest_main_window_set_contents_style (win,
2751 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2755 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2756 TnyFolderStore *folder_store,
2758 ModestMainWindow *main_window)
2760 GtkWidget *header_view;
2762 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2764 header_view = modest_main_window_get_child_widget(main_window,
2765 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2770 if (TNY_IS_ACCOUNT (folder_store)) {
2772 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2774 /* Show account details */
2775 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2778 if (TNY_IS_FOLDER (folder_store) && selected) {
2779 TnyAccount *account;
2781 /* Update the active account */
2782 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2784 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2785 g_object_unref (account);
2789 /* Set the header style by default, it could
2790 be changed later by the refresh callback to
2792 modest_main_window_set_contents_style (main_window,
2793 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2795 /* Set folder on header view. This function
2796 will call tny_folder_refresh_async so we
2797 pass a callback that will be called when
2798 finished. We use that callback to set the
2799 empty view if there are no messages */
2800 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2801 TNY_FOLDER (folder_store),
2803 MODEST_WINDOW (main_window),
2804 folder_refreshed_cb,
2807 /* Restore configuration. We need to do this
2808 *after* the set_folder because the widget
2809 memory asks the header view about its
2811 modest_widget_memory_restore (modest_runtime_get_conf (),
2812 G_OBJECT(header_view),
2813 MODEST_CONF_HEADER_VIEW_KEY);
2815 /* No need to save the header view
2816 configuration for Maemo because it only
2817 saves the sorting stuff and that it's
2818 already being done by the sort
2819 dialog. Remove it when the GNOME version
2820 has the same behaviour */
2821 #ifdef MODEST_TOOLKIT_GTK
2822 if (modest_main_window_get_contents_style (main_window) ==
2823 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2824 modest_widget_memory_save (modest_runtime_get_conf (),
2825 G_OBJECT (header_view),
2826 MODEST_CONF_HEADER_VIEW_KEY);
2828 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2832 /* Update dimming state */
2833 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2834 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2839 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2846 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2848 online = tny_device_is_online (modest_runtime_get_device());
2851 /* already online -- the item is simply not there... */
2852 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2854 GTK_MESSAGE_WARNING,
2856 _("The %s you selected cannot be found"),
2858 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2859 gtk_dialog_run (GTK_DIALOG(dialog));
2861 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2864 _("mcen_bd_dialog_cancel"),
2865 GTK_RESPONSE_REJECT,
2866 _("mcen_bd_dialog_ok"),
2867 GTK_RESPONSE_ACCEPT,
2869 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2870 "Do you want to get online?"), item);
2871 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2872 gtk_label_new (txt), FALSE, FALSE, 0);
2873 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2876 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2877 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2878 /* TODO: Comment about why is this commented out: */
2879 /* modest_platform_connect_and_wait (); */
2882 gtk_widget_destroy (dialog);
2886 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2889 /* g_debug ("%s %s", __FUNCTION__, link); */
2894 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2897 modest_platform_activate_uri (link);
2901 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2904 modest_platform_show_uri_popup (link);
2908 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2911 /* we check for low-mem; in that case, show a warning, and don't allow
2912 * viewing attachments
2914 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2917 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2921 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2922 const gchar *address,
2925 /* g_debug ("%s %s", __FUNCTION__, address); */
2929 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2930 TnyMsg *saved_draft,
2933 ModestMsgEditWindow *edit_window;
2935 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2936 #ifndef MODEST_TOOLKIT_HILDON2
2937 ModestMainWindow *win;
2939 /* FIXME. Make the header view sensitive again. This is a
2940 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2942 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2943 modest_runtime_get_window_mgr(), FALSE));
2945 GtkWidget *hdrview = modest_main_window_get_child_widget(
2946 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2947 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2951 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2953 /* Set draft is there was no error */
2954 if (!modest_mail_operation_get_error (mail_op))
2955 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2957 g_object_unref(edit_window);
2961 enough_space_for_message (ModestMsgEditWindow *edit_window,
2964 guint64 available_disk, expected_size;
2969 available_disk = modest_utils_get_available_space (NULL);
2970 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2971 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2976 /* Double check: disk full condition or message too big */
2977 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
2978 expected_size > available_disk) {
2979 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
2980 modest_platform_information_banner (NULL, NULL, msg);
2987 * djcb: if we're in low-memory state, we only allow for
2988 * saving messages smaller than
2989 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2990 * should still allow for sending anything critical...
2992 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2993 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2997 * djcb: we also make sure that the attachments are smaller than the max size
2998 * this is for the case where we'd try to forward a message with attachments
2999 * bigger than our max allowed size, or sending an message from drafts which
3000 * somehow got past our checks when attaching.
3002 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
3003 modest_platform_run_information_dialog (
3004 GTK_WINDOW(edit_window),
3005 _("mail_ib_error_attachment_size"),
3014 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3016 TnyTransportAccount *transport_account;
3017 ModestMailOperation *mail_operation;
3019 gchar *account_name;
3020 ModestAccountMgr *account_mgr;
3021 gboolean had_error = FALSE;
3023 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
3025 data = modest_msg_edit_window_get_msg_data (edit_window);
3028 if (!enough_space_for_message (edit_window, data)) {
3029 modest_msg_edit_window_free_msg_data (edit_window, data);
3033 account_name = g_strdup (data->account_name);
3034 account_mgr = modest_runtime_get_account_mgr();
3036 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3038 account_name = modest_account_mgr_get_default_account (account_mgr);
3039 if (!account_name) {
3040 g_printerr ("modest: no account found\n");
3041 modest_msg_edit_window_free_msg_data (edit_window, data);
3045 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
3046 account_name = g_strdup (data->account_name);
3050 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3051 (modest_runtime_get_account_store (),
3053 TNY_ACCOUNT_TYPE_TRANSPORT));
3054 if (!transport_account) {
3055 g_printerr ("modest: no transport account found for '%s'\n", account_name);
3056 g_free (account_name);
3057 modest_msg_edit_window_free_msg_data (edit_window, data);
3061 /* Create the mail operation */
3062 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
3064 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3066 modest_mail_operation_save_to_drafts (mail_operation,
3078 data->priority_flags,
3081 on_save_to_drafts_cb,
3082 g_object_ref(edit_window));
3084 #ifdef MODEST_TOOLKIT_HILDON2
3085 /* In hildon2 we always show the information banner on saving to drafts.
3086 * It will be a system information banner in this case.
3088 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3089 modest_platform_information_banner (NULL, NULL, text);
3092 ModestMainWindow *win = NULL;
3094 /* Use the main window as the parent of the banner, if the
3095 main window does not exist it won't be shown, if the parent
3096 window exists then it's properly shown. We don't use the
3097 editor window because it could be closed (save to drafts
3098 could happen after closing the window */
3099 win = (ModestMainWindow *)
3100 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
3102 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3103 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
3107 modest_msg_edit_window_set_modified (edit_window, FALSE);
3110 g_free (account_name);
3111 g_object_unref (G_OBJECT (transport_account));
3112 g_object_unref (G_OBJECT (mail_operation));
3114 modest_msg_edit_window_free_msg_data (edit_window, data);
3116 #ifndef MODEST_TOOLKIT_HILDON2
3118 * If the drafts folder is selected then make the header view
3119 * insensitive while the message is being saved to drafts
3120 * (it'll be sensitive again in on_save_to_drafts_cb()). This
3121 * is not very clean but it avoids letting the drafts folder
3122 * in an inconsistent state: the user could edit the message
3123 * being saved and undesirable things would happen.
3124 * In the average case the user won't notice anything at
3125 * all. In the worst case (the user is editing a really big
3126 * file from Drafts) the header view will be insensitive
3127 * during the saving process (10 or 20 seconds, depending on
3128 * the message). Anyway this is just a quick workaround: once
3129 * we find a better solution it should be removed
3130 * See NB#65125 (commend #18) for details.
3132 if (!had_error && win != NULL) {
3133 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
3134 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
3136 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
3138 if (modest_tny_folder_is_local_folder(folder)) {
3139 TnyFolderType folder_type;
3140 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
3141 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
3142 GtkWidget *hdrview = modest_main_window_get_child_widget(
3143 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3144 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
3148 if (folder != NULL) g_object_unref(folder);
3156 /* For instance, when clicking the Send toolbar button when editing a message: */
3158 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3160 TnyTransportAccount *transport_account = NULL;
3161 gboolean had_error = FALSE;
3163 ModestAccountMgr *account_mgr;
3164 gchar *account_name;
3165 ModestMailOperation *mail_operation;
3168 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
3170 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
3173 data = modest_msg_edit_window_get_msg_data (edit_window);
3175 recipients = g_strconcat (data->to?data->to:"",
3176 data->cc?data->cc:"",
3177 data->bcc?data->bcc:"",
3179 if (recipients == NULL || recipients[0] == '\0') {
3180 /* Empty subject -> no send */
3181 g_free (recipients);
3182 modest_msg_edit_window_free_msg_data (edit_window, data);
3185 g_free (recipients);
3188 if (!enough_space_for_message (edit_window, data)) {
3189 modest_msg_edit_window_free_msg_data (edit_window, data);
3193 account_mgr = modest_runtime_get_account_mgr();
3194 account_name = g_strdup (data->account_name);
3196 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3199 account_name = modest_account_mgr_get_default_account (account_mgr);
3201 if (!account_name) {
3202 modest_msg_edit_window_free_msg_data (edit_window, data);
3203 /* Run account setup wizard */
3204 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
3209 /* Get the currently-active transport account for this modest account: */
3210 if (account_name && strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
3212 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3213 (modest_runtime_get_account_store (),
3214 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
3217 if (!transport_account) {
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 /* Create the mail operation */
3226 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
3227 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3229 modest_mail_operation_send_new_mail (mail_operation,
3243 data->priority_flags);
3245 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3246 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
3248 if (modest_mail_operation_get_error (mail_operation) != NULL) {
3249 const GError *error = modest_mail_operation_get_error (mail_operation);
3250 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3251 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3252 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3253 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3259 g_free (account_name);
3260 g_object_unref (G_OBJECT (transport_account));
3261 g_object_unref (G_OBJECT (mail_operation));
3263 modest_msg_edit_window_free_msg_data (edit_window, data);
3266 modest_msg_edit_window_set_sent (edit_window, TRUE);
3268 /* Save settings and close the window: */
3269 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3276 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3277 ModestMsgEditWindow *window)
3279 ModestMsgEditFormatState *format_state = NULL;
3281 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3282 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3284 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3287 format_state = modest_msg_edit_window_get_format_state (window);
3288 g_return_if_fail (format_state != NULL);
3290 format_state->bold = gtk_toggle_action_get_active (action);
3291 modest_msg_edit_window_set_format_state (window, format_state);
3292 g_free (format_state);
3297 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3298 ModestMsgEditWindow *window)
3300 ModestMsgEditFormatState *format_state = NULL;
3302 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3303 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3305 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3308 format_state = modest_msg_edit_window_get_format_state (window);
3309 g_return_if_fail (format_state != NULL);
3311 format_state->italics = gtk_toggle_action_get_active (action);
3312 modest_msg_edit_window_set_format_state (window, format_state);
3313 g_free (format_state);
3318 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3319 ModestMsgEditWindow *window)
3321 ModestMsgEditFormatState *format_state = NULL;
3323 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3324 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3326 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3329 format_state = modest_msg_edit_window_get_format_state (window);
3330 g_return_if_fail (format_state != NULL);
3332 format_state->bullet = gtk_toggle_action_get_active (action);
3333 modest_msg_edit_window_set_format_state (window, format_state);
3334 g_free (format_state);
3339 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3340 GtkRadioAction *selected,
3341 ModestMsgEditWindow *window)
3343 ModestMsgEditFormatState *format_state = NULL;
3344 GtkJustification value;
3346 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3348 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3351 value = gtk_radio_action_get_current_value (selected);
3353 format_state = modest_msg_edit_window_get_format_state (window);
3354 g_return_if_fail (format_state != NULL);
3356 format_state->justification = value;
3357 modest_msg_edit_window_set_format_state (window, format_state);
3358 g_free (format_state);
3362 modest_ui_actions_on_select_editor_color (GtkAction *action,
3363 ModestMsgEditWindow *window)
3365 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3366 g_return_if_fail (GTK_IS_ACTION (action));
3368 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3371 modest_msg_edit_window_select_color (window);
3375 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3376 ModestMsgEditWindow *window)
3378 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3379 g_return_if_fail (GTK_IS_ACTION (action));
3381 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3384 modest_msg_edit_window_select_background_color (window);
3388 modest_ui_actions_on_insert_image (GObject *object,
3389 ModestMsgEditWindow *window)
3391 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3394 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3397 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3400 modest_msg_edit_window_insert_image (window);
3404 modest_ui_actions_on_attach_file (GtkAction *action,
3405 ModestMsgEditWindow *window)
3407 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3408 g_return_if_fail (GTK_IS_ACTION (action));
3410 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3413 modest_msg_edit_window_offer_attach_file (window);
3417 modest_ui_actions_on_remove_attachments (GtkAction *action,
3418 ModestMsgEditWindow *window)
3420 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3422 modest_msg_edit_window_remove_attachments (window, NULL);
3426 do_create_folder_cb (ModestMailOperation *mail_op,
3427 TnyFolderStore *parent_folder,
3428 TnyFolder *new_folder,
3431 gchar *suggested_name = (gchar *) user_data;
3432 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3433 const GError *error;
3435 error = modest_mail_operation_get_error (mail_op);
3437 gboolean disk_full = FALSE;
3438 TnyAccount *account;
3439 /* Show an error. If there was some problem writing to
3440 disk, show it, otherwise show the generic folder
3441 create error. We do it here and not in an error
3442 handler because the call to do_create_folder will
3443 stop the main loop in a gtk_dialog_run and then,
3444 the message won't be shown until that dialog is
3446 account = modest_mail_operation_get_account (mail_op);
3449 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3450 (GtkWidget *) source_win,
3453 _("mail_in_ui_folder_create_error_memory"));
3454 g_object_unref (account);
3457 /* Show an error and try again if there is no
3458 full memory condition */
3459 modest_platform_information_banner ((GtkWidget *) source_win, NULL,
3460 _("mail_in_ui_folder_create_error"));
3461 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3465 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3466 * FIXME: any other? */
3467 GtkWidget *folder_view;
3469 #ifndef MODEST_TOOLKIT_HILDON2
3470 if (MODEST_IS_MAIN_WINDOW(source_win))
3472 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3473 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3476 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3477 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3479 /* Select the newly created folder. It could happen
3480 that the widget is no longer there (i.e. the window
3481 has been destroyed, so we need to check this */
3483 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3485 g_object_unref (new_folder);
3487 /* Free. Note that the first time it'll be NULL so noop */
3488 g_free (suggested_name);
3489 g_object_unref (source_win);
3494 TnyFolderStore *parent;
3495 } CreateFolderConnect;
3498 do_create_folder_performer (gboolean canceled,
3500 GtkWindow *parent_window,
3501 TnyAccount *account,
3504 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3505 ModestMailOperation *mail_op;
3507 if (canceled || err) {
3508 /* In disk full conditions we could get this error here */
3509 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3510 (GtkWidget *) parent_window, err,
3511 NULL, _("mail_in_ui_folder_create_error_memory"));
3513 /* This happens if we have selected the outbox folder
3515 if (err && err->code == TNY_SERVICE_ERROR_UNKNOWN &&
3516 TNY_IS_MERGE_FOLDER (helper->parent)) {
3517 /* Show an error and retry */
3518 modest_platform_information_banner ((GtkWidget *) parent_window,
3520 _("mail_in_ui_folder_create_error"));
3522 do_create_folder (parent_window, helper->parent, helper->folder_name);
3528 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3529 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3531 modest_mail_operation_create_folder (mail_op,
3533 (const gchar *) helper->folder_name,
3534 do_create_folder_cb,
3535 g_strdup (helper->folder_name));
3536 g_object_unref (mail_op);
3540 g_object_unref (helper->parent);
3541 if (helper->folder_name)
3542 g_free (helper->folder_name);
3543 g_slice_free (CreateFolderConnect, helper);
3548 do_create_folder (GtkWindow *parent_window,
3549 TnyFolderStore *suggested_parent,
3550 const gchar *suggested_name)
3553 gchar *folder_name = NULL;
3554 TnyFolderStore *parent_folder = NULL;
3556 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3558 (gchar *) suggested_name,
3562 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3563 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3564 helper->folder_name = g_strdup (folder_name);
3565 helper->parent = g_object_ref (parent_folder);
3567 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3570 do_create_folder_performer,
3575 g_free (folder_name);
3577 g_object_unref (parent_folder);
3581 modest_ui_actions_create_folder(GtkWidget *parent_window,
3582 GtkWidget *folder_view,
3583 TnyFolderStore *parent_folder)
3585 if (!parent_folder) {
3586 #ifdef MODEST_TOOLKIT_HILDON2
3587 ModestTnyAccountStore *acc_store;
3589 acc_store = modest_runtime_get_account_store ();
3591 parent_folder = (TnyFolderStore *)
3592 modest_tny_account_store_get_local_folders_account (acc_store);
3594 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3598 if (parent_folder) {
3599 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3600 g_object_unref (parent_folder);
3605 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3608 g_return_if_fail (MODEST_IS_WINDOW(window));
3610 #ifndef MODEST_TOOLKIT_HILDON2
3611 if (MODEST_IS_MAIN_WINDOW (window)) {
3612 GtkWidget *folder_view;
3614 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3615 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3619 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3621 if (MODEST_IS_FOLDER_WINDOW (window)) {
3622 GtkWidget *folder_view;
3624 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3625 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3628 g_assert_not_reached ();
3633 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3636 const GError *error = NULL;
3637 gchar *message = NULL;
3639 TnyAccount *account = modest_mail_operation_get_account (mail_op);
3641 /* Get error message */
3642 error = modest_mail_operation_get_error (mail_op);
3644 g_return_if_reached ();
3646 mem_full = modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
3647 (GError *) error, account);
3649 message = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3650 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3651 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3652 message = _CS("ckdg_ib_folder_already_exists");
3653 } else if (error->domain == TNY_ERROR_DOMAIN &&
3654 error->code == TNY_SERVICE_ERROR_STATE) {
3655 /* This means that the folder is already in use (a
3656 message is opened for example */
3657 message = _("emev_ni_internal_error");
3659 message = _CS("ckdg_ib_unable_to_rename");
3662 /* We don't set a parent for the dialog because the dialog
3663 will be destroyed so the banner won't appear */
3664 modest_platform_information_banner (NULL, NULL, message);
3667 g_object_unref (account);
3673 TnyFolderStore *folder;
3678 on_rename_folder_cb (ModestMailOperation *mail_op,
3679 TnyFolder *new_folder,
3682 ModestFolderView *folder_view;
3684 /* If the window was closed when renaming a folder, or if
3685 * it's not a main window this will happen */
3686 if (!MODEST_IS_FOLDER_VIEW (user_data))
3689 folder_view = MODEST_FOLDER_VIEW (user_data);
3690 /* Note that if the rename fails new_folder will be NULL */
3692 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3693 #ifndef MODEST_TOOLKIT_HILDON2
3695 modest_folder_view_select_first_inbox_or_local (folder_view);
3698 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3702 on_rename_folder_performer (gboolean canceled,
3704 GtkWindow *parent_window,
3705 TnyAccount *account,
3708 ModestMailOperation *mail_op = NULL;
3709 GtkTreeSelection *sel = NULL;
3710 GtkWidget *folder_view = NULL;
3711 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3713 if (canceled || err) {
3714 /* In disk full conditions we could get this error here */
3715 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3716 (GtkWidget *) parent_window, err,
3721 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3722 modest_ui_actions_rename_folder_error_handler,
3723 parent_window, NULL);
3725 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3727 #ifndef MODEST_TOOLKIT_HILDON2
3728 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3730 folder_view = modest_main_window_get_child_widget (
3731 MODEST_MAIN_WINDOW (parent_window),
3732 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3735 if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3736 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3737 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3741 /* Clear the folders view */
3742 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3743 gtk_tree_selection_unselect_all (sel);
3745 /* Actually rename the folder */
3746 modest_mail_operation_rename_folder (mail_op,
3747 TNY_FOLDER (data->folder),
3748 (const gchar *) (data->new_name),
3749 on_rename_folder_cb,
3751 g_object_unref (mail_op);
3754 g_object_unref (data->folder);
3755 g_free (data->new_name);
3760 modest_ui_actions_on_rename_folder (GtkAction *action,
3761 ModestWindow *window)
3763 modest_ui_actions_on_edit_mode_rename_folder (window);
3767 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3769 TnyFolderStore *folder;
3770 GtkWidget *folder_view;
3771 gboolean do_rename = TRUE;
3773 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3775 #ifndef MODEST_TOOLKIT_HILDON2
3776 if (MODEST_IS_MAIN_WINDOW (window)) {
3777 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3778 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3782 if (MODEST_IS_FOLDER_WINDOW (window)) {
3783 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3789 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3794 if (TNY_IS_FOLDER (folder)) {
3795 gchar *folder_name = NULL;
3797 const gchar *current_name;
3798 TnyFolderStore *parent;
3800 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3801 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3802 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
3803 parent, current_name,
3805 g_object_unref (parent);
3807 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3810 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3811 rename_folder_data->folder = g_object_ref (folder);
3812 rename_folder_data->new_name = folder_name;
3813 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
3814 folder, on_rename_folder_performer, rename_folder_data);
3817 g_object_unref (folder);
3822 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3825 GObject *win = modest_mail_operation_get_source (mail_op);
3827 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3828 _("mail_in_ui_folder_delete_error"),
3830 g_object_unref (win);
3834 TnyFolderStore *folder;
3835 gboolean move_to_trash;
3839 on_delete_folder_cb (gboolean canceled,
3841 GtkWindow *parent_window,
3842 TnyAccount *account,
3845 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3846 GtkWidget *folder_view;
3847 ModestMailOperation *mail_op;
3848 GtkTreeSelection *sel;
3850 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
3851 /* Note that the connection process can fail due to
3852 memory low conditions as it can not successfully
3853 store the summary */
3854 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3855 (GtkWidget*) parent_window, err,
3857 g_debug ("Error connecting when trying to delete a folder");
3858 g_object_unref (G_OBJECT (info->folder));
3863 #ifndef MODEST_TOOLKIT_HILDON2
3864 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
3865 folder_view = modest_main_window_get_child_widget (
3866 MODEST_MAIN_WINDOW (parent_window),
3867 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3869 if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3870 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
3873 g_object_unref (G_OBJECT (info->folder));
3878 /* Unselect the folder before deleting it to free the headers */
3879 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3880 gtk_tree_selection_unselect_all (sel);
3882 /* Create the mail operation */
3884 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3885 modest_ui_actions_delete_folder_error_handler,
3888 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3890 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3892 #ifndef MODEST_TOOLKIT_HILDON2
3893 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3896 g_object_unref (mail_op);
3897 g_object_unref (info->folder);
3902 delete_folder (ModestWindow *window, gboolean move_to_trash)
3904 TnyFolderStore *folder;
3905 GtkWidget *folder_view;
3909 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3911 #ifndef MODEST_TOOLKIT_HILDON2
3912 if (MODEST_IS_MAIN_WINDOW (window)) {
3914 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3915 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3917 if (MODEST_IS_FOLDER_WINDOW (window)) {
3918 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3926 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3931 /* Show an error if it's an account */
3932 if (!TNY_IS_FOLDER (folder)) {
3933 modest_platform_run_information_dialog (GTK_WINDOW (window),
3934 _("mail_in_ui_folder_delete_error"),
3936 g_object_unref (G_OBJECT (folder));
3941 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3942 tny_folder_get_name (TNY_FOLDER (folder)));
3943 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
3944 (const gchar *) message);
3947 if (response == GTK_RESPONSE_OK) {
3948 TnyAccount *account = NULL;
3949 DeleteFolderInfo *info = NULL;
3950 info = g_new0(DeleteFolderInfo, 1);
3951 info->folder = g_object_ref (folder);
3952 info->move_to_trash = move_to_trash;
3954 account = tny_folder_get_account (TNY_FOLDER (folder));
3955 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
3957 TNY_FOLDER_STORE (account),
3958 on_delete_folder_cb, info);
3959 g_object_unref (account);
3960 g_object_unref (folder);
3968 modest_ui_actions_on_delete_folder (GtkAction *action,
3969 ModestWindow *window)
3971 modest_ui_actions_on_edit_mode_delete_folder (window);
3975 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
3977 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
3979 return delete_folder (window, FALSE);
3982 #ifndef MODEST_TOOLKIT_HILDON2
3984 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3986 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3988 delete_folder (MODEST_WINDOW (main_window), TRUE);
3992 typedef struct _PasswordDialogFields {
3993 GtkWidget *username;
3994 GtkWidget *password;
3996 } PasswordDialogFields;
3999 password_dialog_check_field (GtkEditable *editable,
4000 PasswordDialogFields *fields)
4003 gboolean any_value_empty = FALSE;
4005 #ifdef MODEST_TOOLKIT_HILDON2
4006 value = hildon_entry_get_text (HILDON_ENTRY (fields->username));
4008 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
4010 if ((value == NULL) || value[0] == '\0') {
4011 any_value_empty = TRUE;
4013 #ifdef MODEST_TOOLKIT_HILDON2
4014 value = hildon_entry_get_text (HILDON_ENTRY (fields->password));
4016 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
4018 if ((value == NULL) || value[0] == '\0') {
4019 any_value_empty = TRUE;
4021 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
4025 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
4026 const gchar* server_account_name,
4031 ModestMainWindow *main_window)
4033 g_return_if_fail(server_account_name);
4034 gboolean completed = FALSE;
4035 PasswordDialogFields *fields = NULL;
4037 /* Initalize output parameters: */
4044 #ifndef MODEST_TOOLKIT_GTK
4045 /* Maemo uses a different (awkward) button order,
4046 * It should probably just use gtk_alternative_dialog_button_order ().
4048 #ifdef MODEST_TOOLKIT_HILDON2
4050 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4053 _HL("wdgt_bd_done"),
4054 GTK_RESPONSE_ACCEPT,
4056 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
4057 HILDON_MARGIN_DOUBLE);
4060 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4063 _("mcen_bd_dialog_ok"),
4064 GTK_RESPONSE_ACCEPT,
4065 _("mcen_bd_dialog_cancel"),
4066 GTK_RESPONSE_REJECT,
4068 #endif /* MODEST_TOOLKIT_HILDON2 */
4071 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4075 GTK_RESPONSE_REJECT,
4077 GTK_RESPONSE_ACCEPT,
4079 #endif /* MODEST_TOOLKIT_GTK */
4081 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
4083 gchar *server_name = modest_account_mgr_get_server_account_hostname (
4084 modest_runtime_get_account_mgr(), server_account_name);
4085 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
4086 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
4089 gtk_widget_destroy (dialog);
4093 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
4094 GtkWidget *label = gtk_label_new (txt);
4095 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
4097 g_free (server_name);
4098 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
4103 gchar *initial_username = modest_account_mgr_get_server_account_username (
4104 modest_runtime_get_account_mgr(), server_account_name);
4106 #ifdef MODEST_TOOLKIT_HILDON2
4107 GtkWidget *entry_username = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4108 if (initial_username)
4109 hildon_entry_set_text (HILDON_ENTRY (entry_username), initial_username);
4111 GtkWidget *entry_username = gtk_entry_new ();
4112 if (initial_username)
4113 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
4115 /* Dim this if a connection has ever succeeded with this username,
4116 * as per the UI spec: */
4117 /* const gboolean username_known = */
4118 /* modest_account_mgr_get_server_account_username_has_succeeded( */
4119 /* modest_runtime_get_account_mgr(), server_account_name); */
4120 /* gtk_widget_set_sensitive (entry_username, !username_known); */
4122 /* We drop the username sensitive code and disallow changing it here
4123 * as tinymail does not support really changing the username in the callback
4125 gtk_widget_set_sensitive (entry_username, FALSE);
4127 #ifndef MODEST_TOOLKIT_GTK
4128 /* Auto-capitalization is the default, so let's turn it off: */
4129 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
4131 /* Create a size group to be used by all captions.
4132 * Note that HildonCaption does not create a default size group if we do not specify one.
4133 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
4134 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
4136 #ifdef MODEST_TOOLKIT_HILDON2
4137 GtkWidget *caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4138 _("mail_fi_username"), FALSE,
4141 GtkWidget *caption = hildon_caption_new (sizegroup,
4142 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
4144 gtk_widget_show (entry_username);
4145 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4146 FALSE, FALSE, MODEST_MARGIN_HALF);
4147 gtk_widget_show (caption);
4149 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
4151 #endif /* !MODEST_TOOLKIT_GTK */
4154 #ifdef MODEST_TOOLKIT_HILDON2
4155 GtkWidget *entry_password = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4157 GtkWidget *entry_password = gtk_entry_new ();
4159 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
4160 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
4162 #ifndef MODEST_TOOLKIT_GTK
4163 /* Auto-capitalization is the default, so let's turn it off: */
4164 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
4165 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
4167 #ifdef MODEST_TOOLKIT_HILDON2
4168 caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4169 _("mail_fi_password"), FALSE,
4172 caption = hildon_caption_new (sizegroup,
4173 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
4175 gtk_widget_show (entry_password);
4176 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4177 FALSE, FALSE, MODEST_MARGIN_HALF);
4178 gtk_widget_show (caption);
4179 g_object_unref (sizegroup);
4181 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
4183 #endif /* !MODEST_TOOLKIT_GTK */
4185 if (initial_username != NULL)
4186 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
4188 /* This is not in the Maemo UI spec:
4189 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
4190 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
4194 fields = g_slice_new0 (PasswordDialogFields);
4195 fields->username = entry_username;
4196 fields->password = entry_password;
4197 fields->dialog = dialog;
4199 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
4200 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
4201 password_dialog_check_field (NULL, fields);
4203 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4205 while (!completed) {
4207 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
4209 #ifdef MODEST_TOOLKIT_HILDON2
4210 *username = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_username)));
4212 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
4215 /* Note that an empty field becomes the "" string */
4216 if (*username && strlen (*username) > 0) {
4217 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
4218 server_account_name,
4222 const gboolean username_was_changed =
4223 (strcmp (*username, initial_username) != 0);
4224 if (username_was_changed) {
4225 g_warning ("%s: tinymail does not yet support changing the "
4226 "username in the get_password() callback.\n", __FUNCTION__);
4232 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
4233 _("mcen_ib_username_pw_incorrect"));
4239 #ifdef MODEST_TOOLKIT_HILDON2
4240 *password = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_password)));
4242 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
4245 /* We do not save the password in the configuration,
4246 * because this function is only called for passwords that should
4247 * not be remembered:
4248 modest_server_account_set_password (
4249 modest_runtime_get_account_mgr(), server_account_name,
4256 #ifndef MODEST_TOOLKIT_HILDON2
4257 /* Set parent to NULL or the banner will disappear with its parent dialog */
4258 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
4270 /* This is not in the Maemo UI spec:
4271 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
4277 g_free (initial_username);
4278 gtk_widget_destroy (dialog);
4279 g_slice_free (PasswordDialogFields, fields);
4281 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
4285 modest_ui_actions_on_cut (GtkAction *action,
4286 ModestWindow *window)
4288 GtkWidget *focused_widget;
4289 GtkClipboard *clipboard;
4291 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4292 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4293 if (GTK_IS_EDITABLE (focused_widget)) {
4294 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
4295 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4296 gtk_clipboard_store (clipboard);
4297 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4298 GtkTextBuffer *buffer;
4300 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4301 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4302 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
4303 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4304 gtk_clipboard_store (clipboard);
4306 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4307 TnyList *header_list = modest_header_view_get_selected_headers (
4308 MODEST_HEADER_VIEW (focused_widget));
4309 gboolean continue_download = FALSE;
4310 gint num_of_unc_msgs;
4312 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4314 if (num_of_unc_msgs) {
4315 TnyAccount *account = get_account_from_header_list (header_list);
4317 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4318 g_object_unref (account);
4322 if (num_of_unc_msgs == 0 || continue_download) {
4323 /* modest_platform_information_banner (
4324 NULL, NULL, _CS("mcen_ib_getting_items"));*/
4325 modest_header_view_cut_selection (
4326 MODEST_HEADER_VIEW (focused_widget));
4329 g_object_unref (header_list);
4330 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4331 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4336 modest_ui_actions_on_copy (GtkAction *action,
4337 ModestWindow *window)
4339 GtkClipboard *clipboard;
4340 GtkWidget *focused_widget;
4341 gboolean copied = TRUE;
4343 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4344 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4346 if (GTK_IS_LABEL (focused_widget)) {
4348 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4349 gtk_clipboard_set_text (clipboard, selection, -1);
4351 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4352 gtk_clipboard_store (clipboard);
4353 } else if (GTK_IS_EDITABLE (focused_widget)) {
4354 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4355 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4356 gtk_clipboard_store (clipboard);
4357 } else if (GTK_IS_HTML (focused_widget)) {
4360 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4361 if ((sel == NULL) || (sel[0] == '\0')) {
4364 gtk_html_copy (GTK_HTML (focused_widget));
4365 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4366 gtk_clipboard_store (clipboard);
4368 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4369 GtkTextBuffer *buffer;
4370 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4371 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4372 gtk_text_buffer_copy_clipboard (buffer, clipboard);
4373 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4374 gtk_clipboard_store (clipboard);
4376 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4377 TnyList *header_list = modest_header_view_get_selected_headers (
4378 MODEST_HEADER_VIEW (focused_widget));
4379 gboolean continue_download = FALSE;
4380 gint num_of_unc_msgs;
4382 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4384 if (num_of_unc_msgs) {
4385 TnyAccount *account = get_account_from_header_list (header_list);
4387 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4388 g_object_unref (account);
4392 if (num_of_unc_msgs == 0 || continue_download) {
4393 modest_platform_information_banner (
4394 NULL, NULL, _CS("mcen_ib_getting_items"));
4395 modest_header_view_copy_selection (
4396 MODEST_HEADER_VIEW (focused_widget));
4400 g_object_unref (header_list);
4402 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4403 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4406 /* Show information banner if there was a copy to clipboard */
4408 modest_platform_information_banner (
4409 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4413 modest_ui_actions_on_undo (GtkAction *action,
4414 ModestWindow *window)
4416 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4417 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4418 #ifndef MODEST_TOOLKIT_HILDON2
4419 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4420 ModestEmailClipboard *clipboard = NULL;
4421 /* Clear clipboard source */
4422 clipboard = modest_runtime_get_email_clipboard ();
4423 modest_email_clipboard_clear (clipboard);
4426 g_return_if_reached ();
4431 modest_ui_actions_on_redo (GtkAction *action,
4432 ModestWindow *window)
4434 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4435 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4438 g_return_if_reached ();
4444 destroy_information_note (ModestMailOperation *mail_op,
4447 /* destroy information note */
4448 gtk_widget_destroy (GTK_WIDGET(user_data));
4452 destroy_folder_information_note (ModestMailOperation *mail_op,
4453 TnyFolder *new_folder,
4456 /* destroy information note */
4457 gtk_widget_destroy (GTK_WIDGET(user_data));
4462 paste_as_attachment_free (gpointer data)
4464 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4466 if (helper->banner) {
4467 gtk_widget_destroy (helper->banner);
4468 g_object_unref (helper->banner);
4474 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4479 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4480 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4485 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4490 modest_ui_actions_on_paste (GtkAction *action,
4491 ModestWindow *window)
4493 GtkWidget *focused_widget = NULL;
4494 GtkWidget *inf_note = NULL;
4495 ModestMailOperation *mail_op = NULL;
4497 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4498 if (GTK_IS_EDITABLE (focused_widget)) {
4499 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4500 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4501 ModestEmailClipboard *e_clipboard = NULL;
4502 e_clipboard = modest_runtime_get_email_clipboard ();
4503 if (modest_email_clipboard_cleared (e_clipboard)) {
4504 GtkTextBuffer *buffer;
4505 GtkClipboard *clipboard;
4507 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4508 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4509 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4510 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4511 ModestMailOperation *mail_op;
4512 TnyFolder *src_folder = NULL;
4513 TnyList *data = NULL;
4515 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4516 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4517 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4518 _CS("ckct_nw_pasting"));
4519 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4520 mail_op = modest_mail_operation_new (G_OBJECT (window));
4521 if (helper->banner != NULL) {
4522 g_object_ref (G_OBJECT (helper->banner));
4523 gtk_widget_show (GTK_WIDGET (helper->banner));
4527 modest_mail_operation_get_msgs_full (mail_op,
4529 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4531 paste_as_attachment_free);
4535 g_object_unref (data);
4537 g_object_unref (src_folder);
4540 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4541 ModestEmailClipboard *clipboard = NULL;
4542 TnyFolder *src_folder = NULL;
4543 TnyFolderStore *folder_store = NULL;
4544 TnyList *data = NULL;
4545 gboolean delete = FALSE;
4547 /* Check clipboard source */
4548 clipboard = modest_runtime_get_email_clipboard ();
4549 if (modest_email_clipboard_cleared (clipboard))
4552 /* Get elements to paste */
4553 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4555 /* Create a new mail operation */
4556 mail_op = modest_mail_operation_new (G_OBJECT(window));
4558 /* Get destination folder */
4559 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4561 /* transfer messages */
4565 /* Ask for user confirmation */
4567 modest_ui_actions_msgs_move_to_confirmation (window,
4568 TNY_FOLDER (folder_store),
4572 if (response == GTK_RESPONSE_OK) {
4573 /* Launch notification */
4574 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4575 _CS("ckct_nw_pasting"));
4576 if (inf_note != NULL) {
4577 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4578 gtk_widget_show (GTK_WIDGET(inf_note));
4581 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4582 modest_mail_operation_xfer_msgs (mail_op,
4584 TNY_FOLDER (folder_store),
4586 destroy_information_note,
4589 g_object_unref (mail_op);
4592 } else if (src_folder != NULL) {
4593 /* Launch notification */
4594 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4595 _CS("ckct_nw_pasting"));
4596 if (inf_note != NULL) {
4597 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4598 gtk_widget_show (GTK_WIDGET(inf_note));
4601 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4602 modest_mail_operation_xfer_folder (mail_op,
4606 destroy_folder_information_note,
4612 g_object_unref (data);
4613 if (src_folder != NULL)
4614 g_object_unref (src_folder);
4615 if (folder_store != NULL)
4616 g_object_unref (folder_store);
4622 modest_ui_actions_on_select_all (GtkAction *action,
4623 ModestWindow *window)
4625 GtkWidget *focused_widget;
4627 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4628 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4629 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4630 } else if (GTK_IS_LABEL (focused_widget)) {
4631 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4632 } else if (GTK_IS_EDITABLE (focused_widget)) {
4633 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4634 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4635 GtkTextBuffer *buffer;
4636 GtkTextIter start, end;
4638 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4639 gtk_text_buffer_get_start_iter (buffer, &start);
4640 gtk_text_buffer_get_end_iter (buffer, &end);
4641 gtk_text_buffer_select_range (buffer, &start, &end);
4642 } else if (GTK_IS_HTML (focused_widget)) {
4643 gtk_html_select_all (GTK_HTML (focused_widget));
4644 #ifndef MODEST_TOOLKIT_HILDON2
4645 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4646 GtkWidget *header_view = focused_widget;
4647 GtkTreeSelection *selection = NULL;
4649 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4650 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4651 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4654 /* Disable window dimming management */
4655 modest_window_disable_dimming (MODEST_WINDOW(window));
4657 /* Select all messages */
4658 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4659 gtk_tree_selection_select_all (selection);
4661 /* Set focuse on header view */
4662 gtk_widget_grab_focus (header_view);
4664 /* Enable window dimming management */
4665 modest_window_enable_dimming (MODEST_WINDOW(window));
4666 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4667 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4674 modest_ui_actions_on_mark_as_read (GtkAction *action,
4675 ModestWindow *window)
4677 g_return_if_fail (MODEST_IS_WINDOW(window));
4679 /* Mark each header as read */
4680 do_headers_action (window, headers_action_mark_as_read, NULL);
4684 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4685 ModestWindow *window)
4687 g_return_if_fail (MODEST_IS_WINDOW(window));
4689 /* Mark each header as read */
4690 do_headers_action (window, headers_action_mark_as_unread, NULL);
4694 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4695 GtkRadioAction *selected,
4696 ModestWindow *window)
4700 value = gtk_radio_action_get_current_value (selected);
4701 if (MODEST_IS_WINDOW (window)) {
4702 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4707 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4708 GtkRadioAction *selected,
4709 ModestWindow *window)
4711 TnyHeaderFlags flags;
4712 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4714 flags = gtk_radio_action_get_current_value (selected);
4715 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4719 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4720 GtkRadioAction *selected,
4721 ModestWindow *window)
4725 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4727 file_format = gtk_radio_action_get_current_value (selected);
4728 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4733 modest_ui_actions_on_zoom_plus (GtkAction *action,
4734 ModestWindow *window)
4736 g_return_if_fail (MODEST_IS_WINDOW (window));
4738 modest_window_zoom_plus (MODEST_WINDOW (window));
4742 modest_ui_actions_on_zoom_minus (GtkAction *action,
4743 ModestWindow *window)
4745 g_return_if_fail (MODEST_IS_WINDOW (window));
4747 modest_window_zoom_minus (MODEST_WINDOW (window));
4751 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4752 ModestWindow *window)
4754 ModestWindowMgr *mgr;
4755 gboolean fullscreen, active;
4756 g_return_if_fail (MODEST_IS_WINDOW (window));
4758 mgr = modest_runtime_get_window_mgr ();
4760 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4761 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4763 if (active != fullscreen) {
4764 modest_window_mgr_set_fullscreen_mode (mgr, active);
4765 #ifndef MODEST_TOOLKIT_HILDON2
4766 gtk_window_present (GTK_WINDOW (window));
4772 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4773 ModestWindow *window)
4775 ModestWindowMgr *mgr;
4776 gboolean fullscreen;
4778 g_return_if_fail (MODEST_IS_WINDOW (window));
4780 mgr = modest_runtime_get_window_mgr ();
4781 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4782 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4784 #ifndef MODEST_TOOLKIT_HILDON2
4785 gtk_window_present (GTK_WINDOW (window));
4790 * Used by modest_ui_actions_on_details to call do_headers_action
4793 headers_action_show_details (TnyHeader *header,
4794 ModestWindow *window,
4798 gboolean async_retrieval;
4801 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4802 async_retrieval = TRUE;
4803 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
4805 async_retrieval = FALSE;
4807 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header, async_retrieval, msg);
4809 g_object_unref (msg);
4813 * Show the header details in a ModestDetailsDialog widget
4816 modest_ui_actions_on_details (GtkAction *action,
4819 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4823 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4827 header = tny_msg_get_header (msg);
4829 headers_action_show_details (header, win, NULL);
4830 g_object_unref (header);
4832 g_object_unref (msg);
4833 #ifndef MODEST_TOOLKIT_HILDON2
4834 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4835 GtkWidget *folder_view, *header_view;
4837 /* Check which widget has the focus */
4838 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4839 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4840 if (gtk_widget_is_focus (folder_view)) {
4841 TnyFolderStore *folder_store
4842 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4843 if (!folder_store) {
4844 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4847 /* Show only when it's a folder */
4848 /* This function should not be called for account items,
4849 * because we dim the menu item for them. */
4850 if (TNY_IS_FOLDER (folder_store)) {
4851 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4852 TNY_FOLDER (folder_store));
4855 g_object_unref (folder_store);
4858 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4859 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4860 /* Show details of each header */
4861 do_headers_action (win, headers_action_show_details, header_view);
4864 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4866 GtkWidget *header_view;
4868 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4869 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4871 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4873 g_object_unref (folder);
4880 modest_ui_actions_on_limit_error (GtkAction *action,
4883 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
4885 modest_platform_information_banner ((GtkWidget *) win, NULL, _CS("ckdg_ib_maximum_characters_reached"));
4890 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4891 ModestMsgEditWindow *window)
4893 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4895 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4899 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4900 ModestMsgEditWindow *window)
4902 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4904 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4907 #ifndef MODEST_TOOLKIT_HILDON2
4909 modest_ui_actions_toggle_folders_view (GtkAction *action,
4910 ModestMainWindow *main_window)
4912 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4914 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4915 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4917 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4922 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4923 ModestWindow *window)
4925 gboolean active, fullscreen = FALSE;
4926 ModestWindowMgr *mgr;
4928 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4930 /* Check if we want to toggle the toolbar view in fullscreen
4932 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4933 "ViewShowToolbarFullScreen")) {
4937 /* Toggle toolbar */
4938 mgr = modest_runtime_get_window_mgr ();
4939 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4943 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4944 ModestMsgEditWindow *window)
4946 modest_msg_edit_window_select_font (window);
4951 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4952 const gchar *display_name,
4955 /* don't update the display name if it was already set;
4956 * updating the display name apparently is expensive */
4957 const gchar* old_name = gtk_window_get_title (window);
4959 if (display_name == NULL)
4962 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4963 return; /* don't do anything */
4965 /* This is usually used to change the title of the main window, which
4966 * is the one that holds the folder view. Note that this change can
4967 * happen even when the widget doesn't have the focus. */
4968 gtk_window_set_title (window, display_name);
4973 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4975 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4976 modest_msg_edit_window_select_contacts (window);
4980 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4982 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4983 modest_msg_edit_window_check_names (window, FALSE);
4986 #ifndef MODEST_TOOLKIT_HILDON2
4988 * This function is used to track changes in the selection of the
4989 * folder view that is inside the "move to" dialog to enable/disable
4990 * the OK button because we do not want the user to select a disallowed
4991 * destination for a folder.
4992 * The user also not desired to be able to use NEW button on items where
4993 * folder creation is not possibel.
4996 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4997 TnyFolderStore *folder_store,
5001 GtkWidget *dialog = NULL;
5002 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
5003 gboolean moving_folder = FALSE;
5004 gboolean is_local_account = TRUE;
5005 GtkWidget *folder_view = NULL;
5006 ModestTnyFolderRules rules;
5008 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
5013 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
5017 /* check if folder_store is an remote account */
5018 if (TNY_IS_ACCOUNT (folder_store)) {
5019 TnyAccount *local_account = NULL;
5020 TnyAccount *mmc_account = NULL;
5021 ModestTnyAccountStore *account_store = NULL;
5023 account_store = modest_runtime_get_account_store ();
5024 local_account = modest_tny_account_store_get_local_folders_account (account_store);
5025 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
5027 if ((gpointer) local_account != (gpointer) folder_store &&
5028 (gpointer) mmc_account != (gpointer) folder_store) {
5029 ModestProtocolType proto;
5030 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
5031 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
5032 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
5034 is_local_account = FALSE;
5035 /* New button should be dimmed on remote
5037 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5039 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
5041 g_object_unref (local_account);
5043 /* It could not exist */
5045 g_object_unref (mmc_account);
5048 /* Check the target folder rules */
5049 if (TNY_IS_FOLDER (folder_store)) {
5050 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
5051 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
5052 ok_sensitive = FALSE;
5053 new_sensitive = FALSE;
5058 /* Check if we're moving a folder */
5059 if (MODEST_IS_MAIN_WINDOW (user_data)) {
5060 /* Get the widgets */
5061 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
5062 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5063 if (gtk_widget_is_focus (folder_view))
5064 moving_folder = TRUE;
5067 if (moving_folder) {
5068 TnyFolderStore *moved_folder = NULL, *parent = NULL;
5070 /* Get the folder to move */
5071 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5073 /* Check that we're not moving to the same folder */
5074 if (TNY_IS_FOLDER (moved_folder)) {
5075 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
5076 if (parent == folder_store)
5077 ok_sensitive = FALSE;
5078 g_object_unref (parent);
5081 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
5082 /* Do not allow to move to an account unless it's the
5083 local folders account */
5084 if (!is_local_account)
5085 ok_sensitive = FALSE;
5088 if (ok_sensitive && (moved_folder == folder_store)) {
5089 /* Do not allow to move to itself */
5090 ok_sensitive = FALSE;
5092 g_object_unref (moved_folder);
5094 TnyFolder *src_folder = NULL;
5096 /* Moving a message */
5097 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
5099 TnyHeader *header = NULL;
5100 header = modest_msg_view_window_get_header
5101 (MODEST_MSG_VIEW_WINDOW (user_data));
5102 if (!TNY_IS_HEADER(header))
5103 g_warning ("%s: could not get source header", __FUNCTION__);
5105 src_folder = tny_header_get_folder (header);
5108 g_object_unref (header);
5111 TNY_FOLDER (modest_folder_view_get_selected
5112 (MODEST_FOLDER_VIEW (folder_view)));
5115 if (TNY_IS_FOLDER(src_folder)) {
5116 /* Do not allow to move the msg to the same folder */
5117 /* Do not allow to move the msg to an account */
5118 if ((gpointer) src_folder == (gpointer) folder_store ||
5119 TNY_IS_ACCOUNT (folder_store))
5120 ok_sensitive = FALSE;
5121 g_object_unref (src_folder);
5123 g_warning ("%s: could not get source folder", __FUNCTION__);
5127 /* Set sensitivity of the OK and NEW button */
5128 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
5129 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
5134 on_move_to_dialog_response (GtkDialog *dialog,
5138 GtkWidget *parent_win;
5139 MoveToInfo *helper = NULL;
5140 ModestFolderView *folder_view;
5141 gboolean unset_edit_mode = FALSE;
5143 helper = (MoveToInfo *) user_data;
5145 parent_win = (GtkWidget *) helper->win;
5146 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
5147 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
5149 TnyFolderStore *dst_folder;
5150 TnyFolderStore *selected;
5152 case MODEST_GTK_RESPONSE_NEW_FOLDER:
5153 selected = modest_folder_view_get_selected (folder_view);
5154 modest_ui_actions_create_folder (GTK_WIDGET (dialog), GTK_WIDGET (folder_view), selected);
5155 g_object_unref (selected);
5157 case GTK_RESPONSE_NONE:
5158 case GTK_RESPONSE_CANCEL:
5159 case GTK_RESPONSE_DELETE_EVENT:
5161 case GTK_RESPONSE_OK:
5162 dst_folder = modest_folder_view_get_selected (folder_view);
5164 #ifndef MODEST_TOOLKIT_HILDON2
5165 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
5166 /* Clean list to move used for filtering */
5167 modest_folder_view_set_list_to_move (folder_view, NULL);
5169 modest_ui_actions_on_main_window_move_to (NULL,
5170 GTK_WIDGET (folder_view),
5172 MODEST_MAIN_WINDOW (parent_win));
5174 if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
5175 /* Clean list to move used for filtering */
5176 modest_folder_view_set_list_to_move (folder_view, NULL);
5178 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
5181 GTK_WINDOW (parent_win));
5184 /* if the user selected a root folder
5185 (account) then do not perform any action */
5186 if (TNY_IS_ACCOUNT (dst_folder)) {
5187 g_signal_stop_emission_by_name (dialog, "response");
5191 /* Clean list to move used for filtering */
5192 modest_folder_view_set_list_to_move (folder_view, NULL);
5194 /* Moving from headers window in edit mode */
5195 modest_ui_actions_on_window_move_to (NULL, helper->list,
5197 MODEST_WINDOW (parent_win));
5201 g_object_unref (dst_folder);
5203 unset_edit_mode = TRUE;
5206 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
5209 /* Free the helper and exit */
5211 g_object_unref (helper->list);
5212 if (unset_edit_mode) {
5213 #ifdef MODEST_TOOLKIT_HILDON2
5214 modest_hildon2_window_unset_edit_mode (MODEST_HILDON2_WINDOW (helper->win));
5217 g_slice_free (MoveToInfo, helper);
5218 gtk_widget_destroy (GTK_WIDGET (dialog));
5222 create_move_to_dialog (GtkWindow *win,
5223 GtkWidget *folder_view,
5224 TnyList *list_to_move)
5226 GtkWidget *dialog, *tree_view = NULL;
5228 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
5230 #ifndef MODEST_TOOLKIT_HILDON2
5231 /* Track changes in the selection to
5232 * disable the OK button whenever "Move to" is not possible
5233 * disbale NEW button whenever New is not possible */
5234 g_signal_connect (tree_view,
5235 "folder_selection_changed",
5236 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
5240 /* It could happen that we're trying to move a message from a
5241 window (msg window for example) after the main window was
5242 closed, so we can not just get the model of the folder
5244 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
5245 const gchar *visible_id = NULL;
5247 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5248 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5249 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
5250 MODEST_FOLDER_VIEW(tree_view));
5253 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
5255 /* Show the same account than the one that is shown in the main window */
5256 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
5259 const gchar *active_account_name = NULL;
5260 ModestAccountMgr *mgr = NULL;
5261 ModestAccountSettings *settings = NULL;
5262 ModestServerAccountSettings *store_settings = NULL;
5264 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5265 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5266 /* modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view), */
5267 /* TNY_ACCOUNT_STORE (modest_runtime_get_account_store ())); */
5269 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
5270 mgr = modest_runtime_get_account_mgr ();
5271 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
5274 const gchar *store_account_name;
5275 store_settings = modest_account_settings_get_store_settings (settings);
5276 store_account_name = modest_server_account_settings_get_account_name (store_settings);
5278 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
5279 store_account_name);
5280 g_object_unref (store_settings);
5281 g_object_unref (settings);
5285 /* we keep a pointer to the embedded folder view, so we can
5286 * retrieve it with get_folder_view_from_move_to_dialog (see
5287 * above) later (needed for focus handling)
5289 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
5291 /* Hide special folders */
5292 #ifndef MODEST_TOOLKIT_HILDON2
5293 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
5296 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
5297 #ifndef MODEST_TOOLKIT_HILDON2
5298 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5301 gtk_widget_show (GTK_WIDGET (tree_view));
5307 * Shows a confirmation dialog to the user when we're moving messages
5308 * from a remote server to the local storage. Returns the dialog
5309 * response. If it's other kind of movement then it always returns
5312 * This one is used by the next functions:
5313 * modest_ui_actions_on_paste - commented out
5314 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
5317 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
5318 TnyFolder *dest_folder,
5322 gint response = GTK_RESPONSE_OK;
5323 TnyAccount *account = NULL;
5324 TnyFolder *src_folder = NULL;
5325 TnyIterator *iter = NULL;
5326 TnyHeader *header = NULL;
5328 /* return with OK if the destination is a remote folder */
5329 if (modest_tny_folder_is_remote_folder (dest_folder))
5330 return GTK_RESPONSE_OK;
5332 /* Get source folder */
5333 iter = tny_list_create_iterator (headers);
5334 header = TNY_HEADER (tny_iterator_get_current (iter));
5336 src_folder = tny_header_get_folder (header);
5337 g_object_unref (header);
5339 g_object_unref (iter);
5341 /* if no src_folder, message may be an attahcment */
5342 if (src_folder == NULL)
5343 return GTK_RESPONSE_CANCEL;
5345 /* If the source is a local or MMC folder */
5346 if (!modest_tny_folder_is_remote_folder (src_folder)) {
5347 g_object_unref (src_folder);
5348 return GTK_RESPONSE_OK;
5351 /* Get the account */
5352 account = tny_folder_get_account (src_folder);
5354 /* now if offline we ask the user */
5355 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
5356 response = GTK_RESPONSE_OK;
5358 response = GTK_RESPONSE_CANCEL;
5361 g_object_unref (src_folder);
5362 g_object_unref (account);
5368 move_to_helper_destroyer (gpointer user_data)
5370 MoveToHelper *helper = (MoveToHelper *) user_data;
5372 /* Close the "Pasting" information banner */
5373 if (helper->banner) {
5374 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5375 g_object_unref (helper->banner);
5377 if (gtk_tree_row_reference_valid (helper->reference)) {
5378 gtk_tree_row_reference_free (helper->reference);
5379 helper->reference = NULL;
5385 move_to_cb (ModestMailOperation *mail_op,
5388 MoveToHelper *helper = (MoveToHelper *) user_data;
5389 GObject *object = modest_mail_operation_get_source (mail_op);
5391 /* Note that the operation could have failed, in that case do
5393 if (modest_mail_operation_get_status (mail_op) !=
5394 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5397 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5398 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5400 if (!modest_msg_view_window_select_next_message (self) &&
5401 !modest_msg_view_window_select_previous_message (self)) {
5402 /* No more messages to view, so close this window */
5403 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5405 #ifndef MODEST_TOOLKIT_HILDON2
5406 } else if (MODEST_IS_MAIN_WINDOW (object) &&
5407 gtk_tree_row_reference_valid (helper->reference)) {
5408 GtkWidget *header_view;
5410 GtkTreeSelection *sel;
5412 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5413 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5414 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5415 path = gtk_tree_row_reference_get_path (helper->reference);
5416 /* We need to unselect the previous one
5417 because we could be copying instead of
5419 gtk_tree_selection_unselect_all (sel);
5420 gtk_tree_selection_select_path (sel, path);
5421 gtk_tree_path_free (path);
5424 g_object_unref (object);
5427 /* Destroy the helper */
5428 move_to_helper_destroyer (helper);
5432 folder_move_to_cb (ModestMailOperation *mail_op,
5433 TnyFolder *new_folder,
5438 object = modest_mail_operation_get_source (mail_op);
5439 #ifndef MODEST_TOOLKIT_HILDON2
5440 if (MODEST_IS_MAIN_WINDOW (object)) {
5441 GtkWidget *folder_view;
5442 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5443 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5444 g_object_ref (folder_view);
5445 g_object_unref (object);
5446 move_to_cb (mail_op, user_data);
5447 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5448 g_object_unref (folder_view);
5453 move_to_cb (mail_op, user_data);
5458 msgs_move_to_cb (ModestMailOperation *mail_op,
5461 move_to_cb (mail_op, user_data);
5465 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5468 GObject *win = NULL;
5469 const GError *error;
5470 TnyAccount *account = NULL;
5472 #ifndef MODEST_TOOLKIT_HILDON2
5473 ModestWindow *main_window = NULL;
5475 /* Disable next automatic folder selection */
5476 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5477 FALSE); /* don't create */
5479 /* Show notification dialog only if the main window exists */
5481 GtkWidget *folder_view = NULL;
5483 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5484 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5485 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5487 if (user_data && TNY_IS_FOLDER (user_data)) {
5488 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5489 TNY_FOLDER (user_data), FALSE);
5493 win = modest_mail_operation_get_source (mail_op);
5494 error = modest_mail_operation_get_error (mail_op);
5496 if (TNY_IS_FOLDER (user_data))
5497 account = modest_tny_folder_get_account (TNY_FOLDER (user_data));
5498 else if (TNY_IS_ACCOUNT (user_data))
5499 account = g_object_ref (user_data);
5501 /* If it's not a disk full error then show a generic error */
5502 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5503 (GtkWidget *) win, (GError *) error,
5505 modest_platform_run_information_dialog ((GtkWindow *) win,
5506 _("mail_in_ui_folder_move_target_error"),
5509 g_object_unref (account);
5511 g_object_unref (win);
5514 #ifndef MODEST_TOOLKIT_HILDON2
5516 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5525 gint pending_purges = 0;
5526 gboolean some_purged = FALSE;
5527 ModestWindow *win = MODEST_WINDOW (user_data);
5528 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5530 /* If there was any error */
5531 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5532 modest_window_mgr_unregister_header (mgr, header);
5536 /* Once the message has been retrieved for purging, we check if
5537 * it's all ok for purging */
5539 parts = tny_simple_list_new ();
5540 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5541 iter = tny_list_create_iterator (parts);
5543 while (!tny_iterator_is_done (iter)) {
5545 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5546 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5547 if (tny_mime_part_is_purged (part))
5554 g_object_unref (part);
5556 tny_iterator_next (iter);
5558 g_object_unref (iter);
5561 if (pending_purges>0) {
5563 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5565 if (response == GTK_RESPONSE_OK) {
5568 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5569 iter = tny_list_create_iterator (parts);
5570 while (!tny_iterator_is_done (iter)) {
5573 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5574 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5575 tny_mime_part_set_purged (part);
5578 g_object_unref (part);
5580 tny_iterator_next (iter);
5582 g_object_unref (iter);
5584 tny_msg_rewrite_cache (msg);
5586 gtk_widget_destroy (info);
5590 modest_window_mgr_unregister_header (mgr, header);
5592 g_object_unref (parts);
5596 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5597 ModestMainWindow *win)
5599 GtkWidget *header_view;
5600 TnyList *header_list;
5602 TnyHeaderFlags flags;
5603 ModestWindow *msg_view_window = NULL;
5606 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5608 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5609 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5611 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5613 g_warning ("%s: no header selected", __FUNCTION__);
5617 if (tny_list_get_length (header_list) == 1) {
5618 TnyIterator *iter = tny_list_create_iterator (header_list);
5619 header = TNY_HEADER (tny_iterator_get_current (iter));
5620 g_object_unref (iter);
5624 if (!header || !TNY_IS_HEADER(header)) {
5625 g_warning ("%s: header is not valid", __FUNCTION__);
5629 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5630 header, &msg_view_window);
5631 flags = tny_header_get_flags (header);
5632 if (!(flags & TNY_HEADER_FLAG_CACHED))
5635 if (msg_view_window != NULL)
5636 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5638 /* do nothing; uid was registered before, so window is probably on it's way */
5639 g_debug ("header %p has already been registered", header);
5642 ModestMailOperation *mail_op = NULL;
5643 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5644 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5645 modest_ui_actions_disk_operations_error_handler,
5647 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5648 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5650 g_object_unref (mail_op);
5653 g_object_unref (header);
5655 g_object_unref (header_list);
5660 * Checks if we need a connection to do the transfer and if the user
5661 * wants to connect to complete it
5664 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5665 TnyFolderStore *src_folder,
5667 TnyFolder *dst_folder,
5668 gboolean delete_originals,
5669 gboolean *need_connection,
5672 TnyAccount *src_account;
5673 gint uncached_msgs = 0;
5675 /* We don't need any further check if
5677 * 1- the source folder is local OR
5678 * 2- the device is already online
5680 if (!modest_tny_folder_store_is_remote (src_folder) ||
5681 tny_device_is_online (modest_runtime_get_device())) {
5682 *need_connection = FALSE;
5687 /* We must ask for a connection when
5689 * - the message(s) is not already cached OR
5690 * - the message(s) is cached but the leave_on_server setting
5691 * is FALSE (because we need to sync the source folder to
5692 * delete the message from the server (for IMAP we could do it
5693 * offline, it'll take place the next time we get a
5696 uncached_msgs = header_list_count_uncached_msgs (headers);
5697 src_account = get_account_from_folder_store (src_folder);
5698 if (uncached_msgs > 0) {
5702 *need_connection = TRUE;
5703 num_headers = tny_list_get_length (headers);
5704 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5706 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5707 GTK_RESPONSE_CANCEL) {
5713 /* The transfer is possible and the user wants to */
5716 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5717 const gchar *account_name;
5718 gboolean leave_on_server;
5720 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5721 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5724 if (leave_on_server == TRUE) {
5725 *need_connection = FALSE;
5727 *need_connection = TRUE;
5730 *need_connection = FALSE;
5735 g_object_unref (src_account);
5739 xfer_messages_error_handler (ModestMailOperation *mail_op,
5743 const GError *error;
5744 TnyAccount *account;
5746 win = modest_mail_operation_get_source (mail_op);
5747 error = modest_mail_operation_get_error (mail_op);
5749 /* We cannot get the account from the mail op as that is the
5750 source account and for checking memory full conditions we
5751 need the destination one */
5752 account = TNY_ACCOUNT (user_data);
5755 !modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5756 (GtkWidget *) win, (GError*) error,
5757 account, _KR("cerm_memory_card_full"))) {
5758 modest_platform_run_information_dialog ((GtkWindow *) win,
5759 _("mail_in_ui_folder_move_target_error"),
5763 g_object_unref (win);
5767 TnyFolderStore *dst_folder;
5772 * Utility function that transfer messages from both the main window
5773 * and the msg view window when using the "Move to" dialog
5776 xfer_messages_performer (gboolean canceled,
5778 GtkWindow *parent_window,
5779 TnyAccount *account,
5782 ModestWindow *win = MODEST_WINDOW (parent_window);
5783 TnyAccount *dst_account = NULL;
5784 gboolean dst_forbids_message_add = FALSE;
5785 XferMsgsHelper *helper;
5786 MoveToHelper *movehelper;
5787 ModestMailOperation *mail_op;
5789 helper = (XferMsgsHelper *) user_data;
5791 if (canceled || err) {
5792 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5793 (GtkWidget *) parent_window, err,
5795 /* Show the proper error message */
5796 modest_ui_actions_on_account_connection_error (parent_window, account);
5801 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5803 /* tinymail will return NULL for local folders it seems */
5804 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5805 modest_tny_account_get_protocol_type (dst_account),
5806 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
5808 if (dst_forbids_message_add) {
5809 modest_platform_information_banner (GTK_WIDGET (win),
5811 ngettext("mail_in_ui_folder_move_target_error",
5812 "mail_in_ui_folder_move_targets_error",
5813 tny_list_get_length (helper->headers)));
5817 movehelper = g_new0 (MoveToHelper, 1);
5819 #ifndef MODEST_TOOLKIT_HILDON2
5820 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5821 _CS("ckct_nw_pasting"));
5822 if (movehelper->banner != NULL) {
5823 g_object_ref (movehelper->banner);
5824 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5827 if (MODEST_IS_MAIN_WINDOW (win)) {
5828 GtkWidget *header_view =
5829 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5830 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5831 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5835 /* Perform the mail operation */
5836 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5837 xfer_messages_error_handler,
5838 g_object_ref (dst_account),
5840 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5843 modest_mail_operation_xfer_msgs (mail_op,
5845 TNY_FOLDER (helper->dst_folder),
5850 g_object_unref (G_OBJECT (mail_op));
5853 g_object_unref (dst_account);
5854 g_object_unref (helper->dst_folder);
5855 g_object_unref (helper->headers);
5856 g_slice_free (XferMsgsHelper, helper);
5860 TnyFolder *src_folder;
5861 TnyFolderStore *dst_folder;
5862 gboolean delete_original;
5863 GtkWidget *folder_view;
5867 on_move_folder_cb (gboolean canceled,
5869 GtkWindow *parent_window,
5870 TnyAccount *account,
5873 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5874 GtkTreeSelection *sel;
5875 ModestMailOperation *mail_op = NULL;
5877 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
5878 /* Note that the connection process can fail due to
5879 memory low conditions as it can not successfully
5880 store the summary */
5881 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5882 (GtkWidget*) parent_window, err,
5884 g_debug ("Error connecting when trying to move a folder");
5886 g_object_unref (G_OBJECT (info->src_folder));
5887 g_object_unref (G_OBJECT (info->dst_folder));
5892 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5893 #ifndef MODEST_TOOLKIT_HILDON2
5894 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5895 _CS("ckct_nw_pasting"));
5896 if (helper->banner != NULL) {
5897 g_object_ref (helper->banner);
5898 gtk_widget_show (GTK_WIDGET(helper->banner));
5901 /* Clean folder on header view before moving it */
5902 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5903 gtk_tree_selection_unselect_all (sel);
5905 /* Let gtk events run. We need that the folder
5906 view frees its reference to the source
5907 folder *before* issuing the mail operation
5908 so we need the signal handler of selection
5909 changed to happen before the mail
5911 while (gtk_events_pending ())
5912 gtk_main_iteration (); */
5915 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5916 modest_ui_actions_move_folder_error_handler,
5917 g_object_ref (info->dst_folder), g_object_unref);
5918 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5921 #ifndef MODEST_TOOLKIT_HILDON2
5922 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
5923 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5924 TNY_FOLDER (info->dst_folder), TRUE);
5927 modest_mail_operation_xfer_folder (mail_op,
5928 TNY_FOLDER (info->src_folder),
5930 info->delete_original,
5933 g_object_unref (G_OBJECT (info->src_folder));
5935 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5938 /* Unref mail operation */
5939 g_object_unref (G_OBJECT (mail_op));
5940 g_object_unref (G_OBJECT (info->dst_folder));
5945 get_account_from_folder_store (TnyFolderStore *folder_store)
5947 if (TNY_IS_ACCOUNT (folder_store))
5948 return g_object_ref (folder_store);
5950 return tny_folder_get_account (TNY_FOLDER (folder_store));
5953 #ifndef MODEST_TOOLKIT_HILDON2
5955 * UI handler for the "Move to" action when invoked from the
5959 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5960 GtkWidget *folder_view,
5961 TnyFolderStore *dst_folder,
5962 ModestMainWindow *win)
5964 ModestHeaderView *header_view = NULL;
5965 TnyFolderStore *src_folder = NULL;
5967 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5969 /* Get the source folder */
5970 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5972 /* Get header view */
5973 header_view = (ModestHeaderView *)
5974 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5976 /* Get folder or messages to transfer */
5977 if (gtk_widget_is_focus (folder_view)) {
5978 gboolean do_xfer = TRUE;
5980 /* Allow only to transfer folders to the local root folder */
5981 if (TNY_IS_ACCOUNT (dst_folder) &&
5982 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5983 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5985 } else if (!TNY_IS_FOLDER (src_folder)) {
5986 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5991 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5992 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5994 info->src_folder = g_object_ref (src_folder);
5995 info->dst_folder = g_object_ref (dst_folder);
5996 info->delete_original = TRUE;
5997 info->folder_view = folder_view;
5999 connect_info->callback = on_move_folder_cb;
6000 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6001 connect_info->data = info;
6003 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6004 TNY_FOLDER_STORE (src_folder),
6007 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
6010 headers = modest_header_view_get_selected_headers(header_view);
6012 /* Transfer the messages */
6013 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
6014 headers, TNY_FOLDER (dst_folder));
6016 g_object_unref (headers);
6020 g_object_unref (src_folder);
6024 #ifdef MODEST_TOOLKIT_HILDON2
6026 * UI handler for the "Move to" action when invoked from the
6027 * ModestFolderWindow
6030 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
6031 TnyFolderStore *dst_folder,
6035 TnyFolderStore *src_folder = NULL;
6036 TnyIterator *iterator;
6038 if (tny_list_get_length (selection) != 1)
6041 iterator = tny_list_create_iterator (selection);
6042 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
6043 g_object_unref (iterator);
6046 gboolean do_xfer = TRUE;
6048 /* Allow only to transfer folders to the local root folder */
6049 if (TNY_IS_ACCOUNT (dst_folder) &&
6050 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
6051 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
6054 modest_platform_run_information_dialog (win,
6055 _("mail_in_ui_folder_move_target_error"),
6057 } else if (!TNY_IS_FOLDER (src_folder)) {
6058 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
6063 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
6064 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6066 info->src_folder = g_object_ref (src_folder);
6067 info->dst_folder = g_object_ref (dst_folder);
6068 info->delete_original = TRUE;
6069 info->folder_view = folder_view;
6071 connect_info->callback = on_move_folder_cb;
6072 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6073 connect_info->data = info;
6075 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6076 TNY_FOLDER_STORE (src_folder),
6081 g_object_unref (src_folder);
6087 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
6088 TnyFolder *src_folder,
6090 TnyFolder *dst_folder)
6092 gboolean need_connection = TRUE;
6093 gboolean do_xfer = TRUE;
6094 XferMsgsHelper *helper;
6096 g_return_if_fail (TNY_IS_FOLDER (src_folder));
6097 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6098 g_return_if_fail (TNY_IS_LIST (headers));
6100 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
6101 headers, TNY_FOLDER (dst_folder),
6102 TRUE, &need_connection,
6105 /* If we don't want to transfer just return */
6109 /* Create the helper */
6110 helper = g_slice_new (XferMsgsHelper);
6111 helper->dst_folder = g_object_ref (dst_folder);
6112 helper->headers = g_object_ref (headers);
6114 if (need_connection) {
6115 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6116 connect_info->callback = xfer_messages_performer;
6117 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
6118 connect_info->data = helper;
6120 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6121 TNY_FOLDER_STORE (src_folder),
6124 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
6125 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
6126 src_account, helper);
6127 g_object_unref (src_account);
6132 * UI handler for the "Move to" action when invoked from the
6133 * ModestMsgViewWindow
6136 modest_ui_actions_on_window_move_to (GtkAction *action,
6138 TnyFolderStore *dst_folder,
6141 TnyFolder *src_folder = NULL;
6143 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6146 TnyHeader *header = NULL;
6149 iter = tny_list_create_iterator (headers);
6150 header = (TnyHeader *) tny_iterator_get_current (iter);
6151 src_folder = tny_header_get_folder (header);
6153 /* Transfer the messages */
6154 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
6156 TNY_FOLDER (dst_folder));
6159 g_object_unref (header);
6160 g_object_unref (iter);
6161 g_object_unref (src_folder);
6166 modest_ui_actions_on_move_to (GtkAction *action,
6169 modest_ui_actions_on_edit_mode_move_to (win);
6173 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
6175 GtkWidget *dialog = NULL;
6176 MoveToInfo *helper = NULL;
6177 TnyList *list_to_move;
6179 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
6181 #ifndef MODEST_TOOLKIT_HILDON2
6182 /* Get the main window if exists */
6183 ModestMainWindow *main_window;
6184 if (MODEST_IS_MAIN_WINDOW (win))
6185 main_window = MODEST_MAIN_WINDOW (win);
6188 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
6189 FALSE)); /* don't create */
6192 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
6197 if (tny_list_get_length (list_to_move) < 1) {
6198 g_object_unref (list_to_move);
6202 /* Create and run the dialog */
6203 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
6204 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
6205 GTK_WINDOW (dialog),
6209 helper = g_slice_new0 (MoveToInfo);
6210 helper->list = list_to_move;
6213 /* Listen to response signal */
6214 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
6216 /* Show the dialog */
6217 gtk_widget_show (dialog);
6223 * Calls #HeadersFunc for each header already selected in the main
6224 * window or the message currently being shown in the msg view window
6227 do_headers_action (ModestWindow *win,
6231 TnyList *headers_list = NULL;
6232 TnyIterator *iter = NULL;
6233 TnyHeader *header = NULL;
6234 TnyFolder *folder = NULL;
6237 headers_list = get_selected_headers (win);
6241 /* Get the folder */
6242 iter = tny_list_create_iterator (headers_list);
6243 header = TNY_HEADER (tny_iterator_get_current (iter));
6245 folder = tny_header_get_folder (header);
6246 g_object_unref (header);
6249 /* Call the function for each header */
6250 while (!tny_iterator_is_done (iter)) {
6251 header = TNY_HEADER (tny_iterator_get_current (iter));
6252 func (header, win, user_data);
6253 g_object_unref (header);
6254 tny_iterator_next (iter);
6257 /* Trick: do a poke status in order to speed up the signaling
6260 tny_folder_poke_status (folder);
6261 g_object_unref (folder);
6265 g_object_unref (iter);
6266 g_object_unref (headers_list);
6270 modest_ui_actions_view_attachment (GtkAction *action,
6271 ModestWindow *window)
6273 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6274 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
6276 /* not supported window for this action */
6277 g_return_if_reached ();
6282 modest_ui_actions_save_attachments (GtkAction *action,
6283 ModestWindow *window)
6285 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6287 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
6290 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
6292 /* not supported window for this action */
6293 g_return_if_reached ();
6298 modest_ui_actions_remove_attachments (GtkAction *action,
6299 ModestWindow *window)
6301 #ifndef MODEST_TOOLKIT_HILDON2
6302 if (MODEST_IS_MAIN_WINDOW (window)) {
6303 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
6304 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6306 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6308 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
6310 /* not supported window for this action */
6311 g_return_if_reached ();
6316 modest_ui_actions_on_settings (GtkAction *action,
6321 dialog = modest_platform_get_global_settings_dialog ();
6322 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
6323 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
6324 gtk_widget_show_all (dialog);
6326 gtk_dialog_run (GTK_DIALOG (dialog));
6328 gtk_widget_destroy (dialog);
6332 modest_ui_actions_on_help (GtkAction *action,
6335 /* Help app is not available at all in fremantle */
6336 #ifndef MODEST_TOOLKIT_HILDON2
6337 const gchar *help_id;
6339 g_return_if_fail (win && GTK_IS_WINDOW(win));
6341 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
6344 modest_platform_show_help (GTK_WINDOW (win), help_id);
6349 modest_ui_actions_on_csm_help (GtkAction *action,
6352 /* Help app is not available at all in fremantle */
6353 #ifndef MODEST_TOOLKIT_HILDON2
6355 const gchar* help_id = NULL;
6356 GtkWidget *folder_view;
6357 TnyFolderStore *folder_store;
6359 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
6361 /* Get selected folder */
6362 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
6363 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6364 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6366 /* Switch help_id */
6367 if (folder_store && TNY_IS_FOLDER (folder_store))
6368 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
6371 g_object_unref (folder_store);
6374 modest_platform_show_help (GTK_WINDOW (win), help_id);
6376 modest_ui_actions_on_help (action, win);
6381 retrieve_contents_cb (ModestMailOperation *mail_op,
6388 /* We only need this callback to show an error in case of
6389 memory low condition */
6390 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
6391 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
6396 retrieve_msg_contents_performer (gboolean canceled,
6398 GtkWindow *parent_window,
6399 TnyAccount *account,
6402 ModestMailOperation *mail_op;
6403 TnyList *headers = TNY_LIST (user_data);
6405 if (err || canceled) {
6406 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6407 (GtkWidget *) parent_window, err,
6412 /* Create mail operation */
6413 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
6414 modest_ui_actions_disk_operations_error_handler,
6416 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
6417 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
6420 g_object_unref (mail_op);
6422 g_object_unref (headers);
6423 g_object_unref (account);
6427 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
6428 ModestWindow *window)
6430 TnyList *headers = NULL;
6431 TnyAccount *account = NULL;
6432 TnyIterator *iter = NULL;
6433 TnyHeader *header = NULL;
6434 TnyFolder *folder = NULL;
6437 headers = get_selected_headers (window);
6441 /* Pick the account */
6442 iter = tny_list_create_iterator (headers);
6443 header = TNY_HEADER (tny_iterator_get_current (iter));
6444 folder = tny_header_get_folder (header);
6445 account = tny_folder_get_account (folder);
6446 g_object_unref (folder);
6447 g_object_unref (header);
6448 g_object_unref (iter);
6450 /* Connect and perform the message retrieval */
6451 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6452 g_object_ref (account),
6453 retrieve_msg_contents_performer,
6454 g_object_ref (headers));
6457 g_object_unref (account);
6458 g_object_unref (headers);
6462 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6464 g_return_if_fail (MODEST_IS_WINDOW (window));
6467 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6471 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6473 g_return_if_fail (MODEST_IS_WINDOW (window));
6476 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6480 modest_ui_actions_on_email_menu_activated (GtkAction *action,
6481 ModestWindow *window)
6483 g_return_if_fail (MODEST_IS_WINDOW (window));
6486 modest_ui_actions_check_menu_dimming_rules (window);
6490 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
6491 ModestWindow *window)
6493 g_return_if_fail (MODEST_IS_WINDOW (window));
6496 modest_ui_actions_check_menu_dimming_rules (window);
6500 modest_ui_actions_on_view_menu_activated (GtkAction *action,
6501 ModestWindow *window)
6503 g_return_if_fail (MODEST_IS_WINDOW (window));
6506 modest_ui_actions_check_menu_dimming_rules (window);
6510 modest_ui_actions_on_format_menu_activated (GtkAction *action,
6511 ModestWindow *window)
6513 g_return_if_fail (MODEST_IS_WINDOW (window));
6516 modest_ui_actions_check_menu_dimming_rules (window);
6520 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
6521 ModestWindow *window)
6523 g_return_if_fail (MODEST_IS_WINDOW (window));
6526 modest_ui_actions_check_menu_dimming_rules (window);
6530 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
6531 ModestWindow *window)
6533 g_return_if_fail (MODEST_IS_WINDOW (window));
6536 modest_ui_actions_check_menu_dimming_rules (window);
6540 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
6541 ModestWindow *window)
6543 g_return_if_fail (MODEST_IS_WINDOW (window));
6546 modest_ui_actions_check_menu_dimming_rules (window);
6550 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
6551 ModestWindow *window)
6553 g_return_if_fail (MODEST_IS_WINDOW (window));
6556 modest_ui_actions_check_menu_dimming_rules (window);
6560 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
6561 ModestWindow *window)
6563 g_return_if_fail (MODEST_IS_WINDOW (window));
6566 modest_ui_actions_check_menu_dimming_rules (window);
6570 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6572 g_return_if_fail (MODEST_IS_WINDOW (window));
6574 /* we check for low-mem; in that case, show a warning, and don't allow
6577 if (modest_platform_check_memory_low (window, TRUE))
6580 modest_platform_show_search_messages (GTK_WINDOW (window));
6584 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6586 g_return_if_fail (MODEST_IS_WINDOW (win));
6589 /* we check for low-mem; in that case, show a warning, and don't allow
6590 * for the addressbook
6592 if (modest_platform_check_memory_low (win, TRUE))
6596 modest_platform_show_addressbook (GTK_WINDOW (win));
6601 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6602 ModestWindow *window)
6605 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6607 if (GTK_IS_TOGGLE_ACTION (action))
6608 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6612 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window),
6616 #ifndef MODEST_TOOLKIT_HILDON2
6618 on_send_receive_finished (ModestMailOperation *mail_op,
6621 GtkWidget *header_view, *folder_view;
6622 TnyFolderStore *folder_store;
6623 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6625 /* Set send/receive operation finished */
6626 modest_main_window_notify_send_receive_completed (main_win);
6628 /* Don't refresh the current folder if there were any errors */
6629 if (modest_mail_operation_get_status (mail_op) !=
6630 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6633 /* Refresh the current folder if we're viewing a window. We do
6634 this because the user won't be able to see the new mails in
6635 the selected folder after a Send&Receive because it only
6636 performs a poke_status, i.e, only the number of read/unread
6637 messages is updated, but the new headers are not
6639 folder_view = modest_main_window_get_child_widget (main_win,
6640 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6644 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6646 /* Do not need to refresh INBOX again because the
6647 update_account does it always automatically */
6648 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6649 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6650 ModestMailOperation *refresh_op;
6652 header_view = modest_main_window_get_child_widget (main_win,
6653 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6655 /* We do not need to set the contents style
6656 because it hasn't changed. We also do not
6657 need to save the widget status. Just force
6659 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6660 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6661 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6662 folder_refreshed_cb, main_win);
6663 g_object_unref (refresh_op);
6667 g_object_unref (folder_store);
6672 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6678 const gchar* server_name = NULL;
6679 TnyTransportAccount *transport;
6680 gchar *message = NULL;
6681 ModestProtocol *protocol;
6683 /* Don't show anything if the user cancelled something or the
6684 * send receive request is not interactive. Authentication
6685 * errors are managed by the account store so no need to show
6686 * a dialog here again */
6687 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6688 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6689 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6693 /* Get the server name. Note that we could be using a
6694 connection specific transport account */
6695 transport = (TnyTransportAccount *)
6696 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
6698 ModestTnyAccountStore *acc_store;
6699 const gchar *acc_name;
6700 TnyTransportAccount *conn_specific;
6702 acc_store = modest_runtime_get_account_store();
6703 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
6704 conn_specific = (TnyTransportAccount *)
6705 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
6706 if (conn_specific) {
6707 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
6708 g_object_unref (conn_specific);
6710 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
6712 g_object_unref (transport);
6716 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
6717 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
6718 tny_account_get_proto (TNY_ACCOUNT (transport)));
6720 g_warning ("%s: Account with no proto", __FUNCTION__);
6724 /* Show the appropriate message text for the GError: */
6725 switch (err->code) {
6726 case TNY_SERVICE_ERROR_CONNECT:
6727 message = modest_protocol_get_translation (protocol,
6728 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
6731 case TNY_SERVICE_ERROR_SEND:
6732 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6734 case TNY_SERVICE_ERROR_UNAVAILABLE:
6735 message = modest_protocol_get_translation (protocol,
6736 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
6740 g_warning ("%s: unexpected ERROR %d",
6741 __FUNCTION__, err->code);
6742 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6746 modest_platform_run_information_dialog (NULL, message, FALSE);
6751 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6756 ModestWindow *top_window = NULL;
6757 ModestWindowMgr *mgr = NULL;
6758 GtkWidget *header_view = NULL;
6759 TnyFolder *selected_folder = NULL;
6760 TnyFolderType folder_type;
6762 mgr = modest_runtime_get_window_mgr ();
6763 top_window = modest_window_mgr_get_current_top (mgr);
6768 #ifndef MODEST_TOOLKIT_HILDON2
6769 if (MODEST_IS_MAIN_WINDOW (top_window)) {
6770 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (top_window),
6771 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6774 if (MODEST_IS_HEADER_WINDOW (top_window)) {
6775 header_view = (GtkWidget *)
6776 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
6780 /* Get selected folder */
6782 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
6783 if (!selected_folder)
6786 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6787 #if GTK_CHECK_VERSION(2, 8, 0)
6788 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
6789 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6790 GtkTreeViewColumn *tree_column;
6792 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6793 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6795 gtk_tree_view_column_queue_resize (tree_column);
6797 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
6798 gtk_widget_queue_draw (header_view);
6801 #ifndef MODEST_TOOLKIT_HILDON2
6802 /* Rerun dimming rules, because the message could become deletable for example */
6803 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6804 MODEST_DIMMING_RULES_TOOLBAR);
6805 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6806 MODEST_DIMMING_RULES_MENU);
6810 g_object_unref (selected_folder);
6814 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6815 TnyAccount *account)
6817 ModestProtocolType protocol_type;
6818 ModestProtocol *protocol;
6819 gchar *error_note = NULL;
6821 protocol_type = modest_tny_account_get_protocol_type (account);
6822 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6825 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6826 if (error_note == NULL) {
6827 g_warning ("%s: This should not be reached", __FUNCTION__);
6829 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6830 g_free (error_note);
6835 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6839 TnyFolderStore *folder = NULL;
6840 TnyAccount *account = NULL;
6841 ModestProtocolType proto;
6842 ModestProtocol *protocol;
6843 TnyHeader *header = NULL;
6845 #ifndef MODEST_TOOLKIT_HILDON2
6846 if (MODEST_IS_MAIN_WINDOW (win)) {
6847 GtkWidget *header_view;
6848 TnyList* headers = NULL;
6850 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6851 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6852 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6853 if (!headers || tny_list_get_length (headers) == 0) {
6855 g_object_unref (headers);
6858 iter = tny_list_create_iterator (headers);
6859 header = TNY_HEADER (tny_iterator_get_current (iter));
6860 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6861 g_object_unref (iter);
6862 g_object_unref (headers);
6864 if (MODEST_IS_HEADER_WINDOW (win)) {
6865 GtkWidget *header_view;
6866 TnyList* headers = NULL;
6868 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
6869 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6870 if (!headers || tny_list_get_length (headers) == 0) {
6872 g_object_unref (headers);
6875 iter = tny_list_create_iterator (headers);
6876 header = TNY_HEADER (tny_iterator_get_current (iter));
6878 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6880 g_warning ("List should contain headers");
6882 g_object_unref (iter);
6883 g_object_unref (headers);
6885 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6886 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6888 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6891 if (!header || !folder)
6894 /* Get the account type */
6895 account = tny_folder_get_account (TNY_FOLDER (folder));
6896 proto = modest_tny_account_get_protocol_type (account);
6897 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6900 subject = tny_header_dup_subject (header);
6901 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6905 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6911 g_object_unref (account);
6913 g_object_unref (folder);
6915 g_object_unref (header);
6921 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6922 const gchar *account_name,
6923 const gchar *account_title)
6925 ModestAccountMgr *account_mgr;
6928 ModestProtocol *protocol;
6929 gboolean removed = FALSE;
6931 g_return_val_if_fail (account_name, FALSE);
6932 g_return_val_if_fail (account_title, FALSE);
6934 account_mgr = modest_runtime_get_account_mgr();
6936 /* The warning text depends on the account type: */
6937 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6938 modest_account_mgr_get_store_protocol (account_mgr,
6940 txt = modest_protocol_get_translation (protocol,
6941 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6944 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6946 response = modest_platform_run_confirmation_dialog (parent_window, txt);
6950 if (response == GTK_RESPONSE_OK) {
6951 /* Remove account. If it succeeds then it also removes
6952 the account from the ModestAccountView: */
6953 gboolean is_default = FALSE;
6954 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6955 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6957 g_free (default_account_name);
6959 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6961 /* Close all email notifications, we cannot
6962 distinguish if the notification belongs to
6963 this account or not, so for safety reasons
6964 we remove them all */
6965 modest_platform_remove_new_mail_notifications (FALSE);
6967 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
6974 on_fetch_images_performer (gboolean canceled,
6976 GtkWindow *parent_window,
6977 TnyAccount *account,
6980 if (err || canceled) {
6981 /* Show an unable to retrieve images ??? */
6985 /* Note that the user could have closed the window while connecting */
6986 if (GTK_WIDGET_VISIBLE (parent_window))
6987 modest_msg_view_window_fetch_images ((ModestMsgViewWindow *) parent_window);
6988 g_object_unref ((GObject *) user_data);
6992 modest_ui_actions_on_fetch_images (GtkAction *action,
6993 ModestWindow *window)
6995 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
6997 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6999 on_fetch_images_performer,
7000 g_object_ref (window));
7004 modest_ui_actions_on_reload_message (const gchar *msg_id)
7006 ModestWindow *window = NULL;
7008 g_return_if_fail (msg_id && msg_id[0] != '\0');
7009 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
7015 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
7018 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));
7021 /** Check whether any connections are active, and cancel them if
7023 * Returns TRUE is there was no problem,
7024 * or if an operation was cancelled so we can continue.
7025 * Returns FALSE if the user chose to cancel his request instead.
7029 modest_ui_actions_check_for_active_account (ModestWindow *self,
7030 const gchar* account_name)
7032 ModestTnySendQueue *send_queue;
7033 ModestTnyAccountStore *acc_store;
7034 ModestMailOperationQueue* queue;
7035 TnyConnectionStatus store_conn_status;
7036 TnyAccount *store_account = NULL, *transport_account = NULL;
7037 gboolean retval = TRUE, sending = FALSE;
7039 acc_store = modest_runtime_get_account_store ();
7040 queue = modest_runtime_get_mail_operation_queue ();
7043 modest_tny_account_store_get_server_account (acc_store,
7045 TNY_ACCOUNT_TYPE_STORE);
7047 /* This could happen if the account was deleted before the
7048 call to this function */
7053 modest_tny_account_store_get_server_account (acc_store,
7055 TNY_ACCOUNT_TYPE_TRANSPORT);
7057 /* This could happen if the account was deleted before the
7058 call to this function */
7059 if (!transport_account) {
7060 g_object_unref (store_account);
7064 /* If the transport account was not used yet, then the send
7065 queue could not exist (it's created on demand) */
7066 send_queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (transport_account), FALSE);
7067 if (TNY_IS_SEND_QUEUE (send_queue))
7068 sending = modest_tny_send_queue_sending_in_progress (send_queue);
7070 store_conn_status = tny_account_get_connection_status (store_account);
7071 if (store_conn_status == TNY_CONNECTION_STATUS_CONNECTED || sending) {
7074 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (self),
7075 _("emev_nc_disconnect_account"));
7076 if (response == GTK_RESPONSE_OK) {
7085 /* FIXME: We should only cancel those of this account */
7086 modest_mail_operation_queue_cancel_all (queue);
7088 /* Also disconnect the account */
7089 if ((tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED) &&
7090 (tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)) {
7091 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
7095 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (transport_account),
7101 g_object_unref (store_account);
7102 g_object_unref (transport_account);