1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #endif /*HAVE_CONFIG_H*/
34 #include <glib/gi18n.h>
35 #include <glib/gprintf.h>
37 #include <modest-runtime.h>
38 #include <modest-defs.h>
39 #include <modest-tny-folder.h>
40 #include <modest-tny-msg.h>
41 #include <modest-tny-account.h>
42 #include <modest-address-book.h>
43 #include "modest-error.h"
44 #include "modest-ui-actions.h"
45 #include "modest-tny-platform-factory.h"
46 #include "modest-platform.h"
47 #include "modest-debug.h"
48 #include <tny-mime-part.h>
49 #include <tny-error.h>
50 #include <tny-camel-folder.h>
51 #include <tny-camel-imap-folder.h>
52 #include <tny-camel-pop-folder.h>
53 #ifdef MODEST_TOOLKIT_HILDON2
54 #include <modest-accounts-window.h>
55 #include <hildon/hildon-pannable-area.h>
56 #include <hildon/hildon-gtk.h>
57 #include <modest-header-window.h>
58 #include <modest-folder-window.h>
59 #include <modest-maemo-utils.h>
61 #include "modest-utils.h"
62 #include "widgets/modest-connection-specific-smtp-window.h"
63 #include "widgets/modest-ui-constants.h"
64 #include <widgets/modest-main-window.h>
65 #include <widgets/modest-msg-view-window.h>
66 #include <widgets/modest-account-view-window.h>
67 #include <widgets/modest-details-dialog.h>
68 #include <widgets/modest-attachments-view.h>
69 #include "widgets/modest-folder-view.h"
70 #include "widgets/modest-global-settings-dialog.h"
71 #include "modest-account-mgr-helpers.h"
72 #include "modest-mail-operation.h"
73 #include "modest-text-utils.h"
74 #include <modest-widget-memory.h>
75 #include <tny-error.h>
76 #include <tny-simple-list.h>
77 #include <tny-msg-view.h>
78 #include <tny-device.h>
79 #include <tny-merge-folder.h>
81 #include <gtkhtml/gtkhtml.h>
83 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
85 typedef struct _GetMsgAsyncHelper {
87 ModestMailOperation *mail_op;
94 typedef enum _ReplyForwardAction {
100 typedef struct _ReplyForwardHelper {
101 guint reply_forward_type;
102 ReplyForwardAction action;
105 GtkWidget *parent_window;
107 } ReplyForwardHelper;
109 typedef struct _MoveToHelper {
110 GtkTreeRowReference *reference;
114 typedef struct _PasteAsAttachmentHelper {
115 ModestMsgEditWindow *window;
117 } PasteAsAttachmentHelper;
125 * The do_headers_action uses this kind of functions to perform some
126 * action to each member of a list of headers
128 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
130 static void do_headers_action (ModestWindow *win,
134 static void open_msg_cb (ModestMailOperation *mail_op,
141 static void reply_forward_cb (ModestMailOperation *mail_op,
148 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
150 #ifndef MODEST_TOOLKIT_HILDON2
151 static void folder_refreshed_cb (ModestMailOperation *mail_op,
155 static void on_send_receive_finished (ModestMailOperation *mail_op,
159 static gint header_list_count_uncached_msgs (TnyList *header_list);
161 static gboolean connect_to_get_msg (ModestWindow *win,
162 gint num_of_uncached_msgs,
163 TnyAccount *account);
165 static gboolean remote_folder_has_leave_on_server (TnyFolderStore *folder);
167 static void do_create_folder (GtkWindow *window,
168 TnyFolderStore *parent_folder,
169 const gchar *suggested_name);
171 static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store);
173 #ifndef MODEST_TOOLKIT_HILDON2
174 static void modest_ui_actions_on_main_window_move_to (GtkAction *action,
175 GtkWidget *folder_view,
176 TnyFolderStore *dst_folder,
177 ModestMainWindow *win);
180 static void modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
181 TnyFolderStore *dst_folder,
186 static void modest_ui_actions_on_window_move_to (GtkAction *action,
187 TnyList *list_to_move,
188 TnyFolderStore *dst_folder,
192 * This function checks whether a TnyFolderStore is a pop account
195 remote_folder_has_leave_on_server (TnyFolderStore *folder)
200 g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
202 account = get_account_from_folder_store (folder);
203 result = (modest_protocol_registry_protocol_type_has_leave_on_server (modest_runtime_get_protocol_registry (),
204 modest_tny_account_get_protocol_type (account)));
205 g_object_unref (account);
210 /* FIXME: this should be merged with the similar code in modest-account-view-window */
211 /* Show the account creation wizard dialog.
212 * returns: TRUE if an account was created. FALSE if the user cancelled.
215 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
217 gboolean result = FALSE;
219 gint dialog_response;
221 /* there is no such wizard yet */
222 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
223 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (wizard), (GtkWindow *) win);
225 #ifndef MODEST_TOOLKIT_HILDON2
226 /* always present a main window in the background
227 * we do it here, so we cannot end up with two wizards (as this
228 * function might be called in modest_window_mgr_get_main_window as well */
230 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
231 TRUE); /* create if not existent */
235 ModestWindowMgr *mgr;
237 mgr = modest_runtime_get_window_mgr ();
239 window_list = modest_window_mgr_get_window_list (mgr);
240 if (window_list == NULL) {
241 win = MODEST_WINDOW (modest_accounts_window_new ());
242 if (modest_window_mgr_register_window (mgr, win, NULL)) {
243 gtk_widget_show_all (GTK_WIDGET (win));
245 gtk_widget_destroy (GTK_WIDGET (win));
250 g_list_free (window_list);
256 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
258 /* make sure the mainwindow is visible. We need to present the
259 wizard again to give it the focus back. show_all are needed
260 in order to get the widgets properly drawn (MainWindow main
261 paned won't be in its right position and the dialog will be
263 #ifndef MODEST_TOOLKIT_HILDON2
264 gtk_widget_show_all (GTK_WIDGET (win));
265 gtk_widget_show_all (GTK_WIDGET (wizard));
266 gtk_window_present (GTK_WINDOW (win));
267 gtk_window_present (GTK_WINDOW (wizard));
270 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
271 gtk_widget_destroy (GTK_WIDGET (wizard));
272 if (gtk_events_pending ())
273 gtk_main_iteration ();
275 if (dialog_response == GTK_RESPONSE_CANCEL) {
278 /* Check whether an account was created: */
279 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
286 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
289 const gchar *authors[] = {
290 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
293 about = gtk_about_dialog_new ();
294 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
295 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
296 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
297 _("Copyright (c) 2006, Nokia Corporation\n"
298 "All rights reserved."));
299 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
300 _("a modest e-mail client\n\n"
301 "design and implementation: Dirk-Jan C. Binnema\n"
302 "contributions from the fine people at KC and Ig\n"
303 "uses the tinymail email framework written by Philip van Hoof"));
304 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
305 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
306 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
307 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
309 gtk_dialog_run (GTK_DIALOG (about));
310 gtk_widget_destroy(about);
314 * Gets the list of currently selected messages. If the win is the
315 * main window, then it returns a newly allocated list of the headers
316 * selected in the header view. If win is the msg view window, then
317 * the value returned is a list with just a single header.
319 * The caller of this funcion must free the list.
322 get_selected_headers (ModestWindow *win)
324 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
325 /* for MsgViewWindows, we simply return a list with one element */
327 TnyList *list = NULL;
329 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
330 if (header != NULL) {
331 list = tny_simple_list_new ();
332 tny_list_prepend (list, G_OBJECT(header));
333 g_object_unref (G_OBJECT(header));
337 #ifndef MODEST_TOOLKIT_HILDON2
338 } else if (MODEST_IS_MAIN_WINDOW(win)) {
339 GtkWidget *header_view;
341 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
342 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
343 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
345 } else if (MODEST_IS_HEADER_WINDOW (win)) {
346 GtkWidget *header_view;
348 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
349 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
356 #ifndef MODEST_TOOLKIT_HILDON2
357 static GtkTreeRowReference *
358 get_next_after_selected_headers (ModestHeaderView *header_view)
360 GtkTreeSelection *sel;
361 GList *selected_rows, *node;
363 GtkTreeRowReference *result;
366 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
367 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
368 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
370 if (selected_rows == NULL)
373 node = g_list_last (selected_rows);
374 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
375 gtk_tree_path_next (path);
377 result = gtk_tree_row_reference_new (model, path);
379 gtk_tree_path_free (path);
380 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
381 g_list_free (selected_rows);
388 headers_action_mark_as_read (TnyHeader *header,
392 TnyHeaderFlags flags;
394 g_return_if_fail (TNY_IS_HEADER(header));
396 flags = tny_header_get_flags (header);
397 if (flags & TNY_HEADER_FLAG_SEEN) return;
398 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
402 headers_action_mark_as_unread (TnyHeader *header,
406 TnyHeaderFlags flags;
408 g_return_if_fail (TNY_IS_HEADER(header));
410 flags = tny_header_get_flags (header);
411 if (flags & TNY_HEADER_FLAG_SEEN) {
412 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
416 /** After deleing a message that is currently visible in a window,
417 * show the next message from the list, or close the window if there are no more messages.
420 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
422 /* Close msg view window or select next */
423 if (!modest_msg_view_window_select_next_message (win) &&
424 !modest_msg_view_window_select_previous_message (win)) {
426 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
432 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
434 modest_ui_actions_on_edit_mode_delete_message (win);
438 modest_ui_actions_on_edit_mode_delete_message (ModestWindow *win)
440 TnyList *header_list = NULL;
441 TnyIterator *iter = NULL;
442 TnyHeader *header = NULL;
443 gchar *message = NULL;
446 ModestWindowMgr *mgr;
447 gboolean retval = TRUE;
449 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
451 #ifndef MODEST_TOOLKIT_HILDON2
452 /* Check first if the header view has the focus */
453 if (MODEST_IS_MAIN_WINDOW (win)) {
454 GtkWidget *header_view = NULL;
457 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
458 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
459 if (!gtk_widget_is_focus (header_view))
463 /* Get the headers, either from the header view (if win is the main window),
464 * or from the message view window: */
465 header_list = get_selected_headers (win);
466 if (!header_list) return FALSE;
468 /* Check if any of the headers are already opened, or in the process of being opened */
469 #ifndef MODEST_TOOLKIT_HILDON2
470 if (MODEST_IS_MAIN_WINDOW (win)) {
471 gint opened_headers = 0;
473 iter = tny_list_create_iterator (header_list);
474 mgr = modest_runtime_get_window_mgr ();
475 while (!tny_iterator_is_done (iter)) {
476 header = TNY_HEADER (tny_iterator_get_current (iter));
478 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
480 g_object_unref (header);
482 tny_iterator_next (iter);
484 g_object_unref (iter);
486 if (opened_headers > 0) {
489 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
492 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg, FALSE);
495 g_object_unref (header_list);
502 if (tny_list_get_length(header_list) == 1) {
503 iter = tny_list_create_iterator (header_list);
504 header = TNY_HEADER (tny_iterator_get_current (iter));
507 subject = tny_header_dup_subject (header);
509 subject = g_strdup (_("mail_va_no_subject"));
510 desc = g_strdup_printf ("%s", subject);
512 g_object_unref (header);
515 g_object_unref (iter);
517 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
518 tny_list_get_length(header_list)), desc);
520 /* Confirmation dialog */
521 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
524 if (response == GTK_RESPONSE_OK) {
525 GtkTreeSelection *sel = NULL;
526 GList *sel_list = NULL;
527 ModestMailOperation *mail_op = NULL;
529 /* Find last selected row */
530 #ifndef MODEST_TOOLKIT_HILDON2
531 if (MODEST_IS_MAIN_WINDOW (win)) {
533 ModestWindowMgr *mgr = NULL;
534 GtkTreeModel *model = NULL;
535 GtkTreeRowReference *next_row_reference = NULL, *prev_row_reference = NULL;
536 GtkTreePath *next_path = NULL, *prev_path = NULL;
538 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
539 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
540 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
541 for (tmp=sel_list; tmp; tmp=tmp->next) {
542 if (tmp->next == NULL) {
543 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
544 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
546 gtk_tree_path_prev (prev_path);
547 gtk_tree_path_next (next_path);
549 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
550 next_row_reference = gtk_tree_row_reference_new (model, next_path);
556 /* Disable window dimming management */
557 modest_window_disable_dimming (win);
559 /* Remove each header. If it's a view window header_view == NULL */
560 mail_op = modest_mail_operation_new ((GObject *) win);
561 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
563 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
564 g_object_unref (mail_op);
566 /* Enable window dimming management */
568 gtk_tree_selection_unselect_all (sel);
570 modest_window_enable_dimming (win);
572 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
573 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
575 /* Get main window */
576 mgr = modest_runtime_get_window_mgr ();
577 #ifndef MODEST_TOOLKIT_HILDON2
578 } else if (MODEST_IS_MAIN_WINDOW (win)) {
579 /* Select next or previous row */
580 if (gtk_tree_row_reference_valid (next_row_reference)) {
581 gtk_tree_selection_select_path (sel, next_path);
583 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
584 gtk_tree_selection_select_path (sel, prev_path);
588 if (gtk_tree_row_reference_valid (next_row_reference))
589 gtk_tree_row_reference_free (next_row_reference);
590 if (next_path != NULL)
591 gtk_tree_path_free (next_path);
592 if (gtk_tree_row_reference_valid (prev_row_reference))
593 gtk_tree_row_reference_free (prev_row_reference);
594 if (prev_path != NULL)
595 gtk_tree_path_free (prev_path);
599 /* Update toolbar dimming state */
600 modest_ui_actions_check_menu_dimming_rules (win);
601 modest_ui_actions_check_toolbar_dimming_rules (win);
604 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
605 g_list_free (sel_list);
614 g_object_unref (header_list);
622 /* delete either message or folder, based on where we are */
624 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
626 g_return_if_fail (MODEST_IS_WINDOW(win));
628 /* Check first if the header view has the focus */
629 #ifndef MODEST_TOOLKIT_HILDON2
630 if (MODEST_IS_MAIN_WINDOW (win)) {
632 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
633 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
634 if (gtk_widget_is_focus (w)) {
635 modest_ui_actions_on_delete_folder (action, MODEST_WINDOW(win));
640 modest_ui_actions_on_delete_message (action, win);
644 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
646 ModestWindowMgr *mgr = NULL;
648 #ifdef MODEST_PLATFORM_MAEMO
649 modest_window_mgr_save_state_for_all_windows (modest_runtime_get_window_mgr ());
650 #endif /* MODEST_PLATFORM_MAEMO */
652 g_debug ("closing down, clearing %d item(s) from operation queue",
653 modest_mail_operation_queue_num_elements
654 (modest_runtime_get_mail_operation_queue()));
656 /* cancel all outstanding operations */
657 modest_mail_operation_queue_cancel_all
658 (modest_runtime_get_mail_operation_queue());
660 g_debug ("queue has been cleared");
663 /* Check if there are opened editing windows */
664 mgr = modest_runtime_get_window_mgr ();
665 modest_window_mgr_close_all_windows (mgr);
667 /* note: when modest-tny-account-store is finalized,
668 it will automatically set all network connections
671 /* gtk_main_quit (); */
675 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
679 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
681 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
682 /* gtk_widget_destroy (GTK_WIDGET (win)); */
683 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
684 /* gboolean ret_value; */
685 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
686 /* } else if (MODEST_IS_WINDOW (win)) { */
687 /* gtk_widget_destroy (GTK_WIDGET (win)); */
689 /* g_return_if_reached (); */
694 modest_ui_actions_add_to_contacts (GtkAction *action, ModestWindow *win)
696 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
698 modest_msg_view_window_add_to_contacts (MODEST_MSG_VIEW_WINDOW (win));
702 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
704 GtkClipboard *clipboard = NULL;
705 gchar *selection = NULL;
707 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
708 selection = gtk_clipboard_wait_for_text (clipboard);
711 modest_address_book_add_address (selection, (GtkWindow *) win);
717 modest_ui_actions_on_new_account (GtkAction *action,
718 ModestWindow *window)
720 if (!modest_ui_actions_run_account_setup_wizard (window)) {
721 g_debug ("%s: wizard was already running", __FUNCTION__);
726 modest_ui_actions_on_accounts (GtkAction *action,
729 /* This is currently only implemented for Maemo */
730 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
731 if (!modest_ui_actions_run_account_setup_wizard (win))
732 g_debug ("%s: wizard was already running", __FUNCTION__);
736 /* Show the list of accounts */
737 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
739 /* The accounts dialog must be modal */
740 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
741 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
746 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
748 /* This is currently only implemented for Maemo,
749 * because it requires an API (libconic) to detect different connection
752 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
754 /* Create the window if necessary: */
755 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
756 modest_connection_specific_smtp_window_fill_with_connections (
757 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
758 modest_runtime_get_account_mgr());
760 /* Show the window: */
761 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
762 GTK_WINDOW (specific_window), (GtkWindow *) win);
763 gtk_widget_show (specific_window);
764 #endif /* !MODEST_TOOLKIT_GTK */
768 count_part_size (const gchar *part)
770 GnomeVFSURI *vfs_uri;
771 gchar *escaped_filename;
773 GnomeVFSFileInfo *info;
776 /* Estimation of attachment size if we cannot get it from file info */
779 vfs_uri = gnome_vfs_uri_new (part);
781 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
782 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
783 g_free (escaped_filename);
784 gnome_vfs_uri_unref (vfs_uri);
786 info = gnome_vfs_file_info_new ();
788 if (gnome_vfs_get_file_info (part,
790 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
792 if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) {
797 gnome_vfs_file_info_unref (info);
803 count_parts_size (GSList *parts)
808 for (node = parts; node != NULL; node = g_slist_next (node)) {
809 result += count_part_size ((const gchar *) node->data);
816 modest_ui_actions_compose_msg(ModestWindow *win,
819 const gchar *bcc_str,
820 const gchar *subject_str,
821 const gchar *body_str,
823 gboolean set_as_modified)
825 gchar *account_name = NULL;
826 const gchar *mailbox;
828 TnyAccount *account = NULL;
829 TnyFolder *folder = NULL;
830 gchar *from_str = NULL, *signature = NULL, *body = NULL;
831 gchar *recipient = NULL;
832 gboolean use_signature = FALSE;
833 ModestWindow *msg_win = NULL;
834 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
835 ModestTnyAccountStore *store = modest_runtime_get_account_store();
836 GnomeVFSFileSize total_size, allowed_size;
837 guint64 available_disk, expected_size, parts_size;
840 /* we check for low-mem */
841 if (modest_platform_check_memory_low (win, TRUE))
844 available_disk = modest_utils_get_available_space (NULL);
845 parts_count = g_slist_length (attachments);
846 parts_size = count_parts_size (attachments);
847 expected_size = modest_tny_msg_estimate_size (body, NULL, parts_count, parts_size);
849 /* Double check: disk full condition or message too big */
850 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
851 expected_size > available_disk) {
852 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
853 modest_platform_system_banner (NULL, NULL, msg);
859 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
860 modest_platform_run_information_dialog (
862 _("mail_ib_error_attachment_size"),
868 #ifdef MODEST_TOOLKIT_HILDON2
870 account_name = g_strdup (modest_window_get_active_account(win));
873 account_name = modest_account_mgr_get_default_account(mgr);
876 g_printerr ("modest: no account found\n");
881 mailbox = modest_window_get_active_mailbox (win);
884 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
886 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
889 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
891 g_printerr ("modest: failed to find Drafts folder\n");
894 from_str = modest_account_mgr_get_from_string (mgr, account_name, mailbox);
896 g_printerr ("modest: failed get from string for '%s'\n", account_name);
900 recipient = modest_text_utils_get_email_address (from_str);
901 signature = modest_account_mgr_get_signature_from_recipient (mgr, recipient, &use_signature);
903 if (body_str != NULL) {
904 body = use_signature ? g_strconcat(body_str, "\n",
905 MODEST_TEXT_UTILS_SIGNATURE_MARKER,
906 "\n", signature, NULL) : g_strdup(body_str);
908 body = use_signature ? g_strconcat("\n", MODEST_TEXT_UTILS_SIGNATURE_MARKER,
909 "\n", signature, NULL) : g_strdup("");
912 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, NULL, NULL, body, NULL, NULL, NULL);
914 g_printerr ("modest: failed to create new msg\n");
918 /* Create and register edit window */
919 /* This is destroyed by TODO. */
921 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
922 msg_win = modest_msg_edit_window_new (msg, account_name, mailbox, FALSE);
924 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, win)) {
925 gtk_widget_destroy (GTK_WIDGET (msg_win));
928 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
929 gtk_widget_show_all (GTK_WIDGET (msg_win));
931 while (attachments) {
932 GnomeVFSFileSize att_size;
934 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
935 attachments->data, allowed_size);
936 total_size += att_size;
938 if (att_size > allowed_size) {
939 g_debug ("%s: total size: %u",
940 __FUNCTION__, (unsigned int)total_size);
943 allowed_size -= att_size;
945 attachments = g_slist_next(attachments);
952 g_free (account_name);
954 g_object_unref (G_OBJECT(account));
956 g_object_unref (G_OBJECT(folder));
958 g_object_unref (G_OBJECT(msg));
962 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
964 /* if there are no accounts yet, just show the wizard */
965 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
966 if (!modest_ui_actions_run_account_setup_wizard (win))
969 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
974 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
978 ModestMailOperationStatus status;
980 /* If there is no message or the operation was not successful */
981 status = modest_mail_operation_get_status (mail_op);
982 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
985 /* If it's a memory low issue, then show a banner */
986 error = modest_mail_operation_get_error (mail_op);
987 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
988 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
989 GObject *source = modest_mail_operation_get_source (mail_op);
990 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
991 _KR("memr_ib_operation_disabled"),
993 g_object_unref (source);
996 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
997 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
998 gchar *subject, *msg, *format = NULL;
1001 subject = (header) ? tny_header_dup_subject (header) : NULL;
1003 subject = g_strdup (_("mail_va_no_subject"));
1005 account = modest_mail_operation_get_account (mail_op);
1007 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
1008 ModestProtocol *protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), proto);
1011 if (tny_account_get_connection_status (account) ==
1012 TNY_CONNECTION_STATUS_CONNECTED) {
1013 format = modest_protocol_get_translation (protocol,
1014 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE,
1017 format = g_strdup_printf (_("mail_ib_backend_server_invalid"),
1018 tny_account_get_hostname (account));
1021 g_object_unref (account);
1025 format = g_strdup (_("emev_ni_ui_imap_message_not_available_in_server"));
1027 msg = g_strdup_printf (format, subject);
1028 modest_platform_run_information_dialog (NULL, msg, FALSE);
1034 /* Remove the header from the preregistered uids */
1035 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1048 } OpenMsgBannerInfo;
1051 GtkTreeModel *model;
1053 ModestWindow *caller_window;
1054 OpenMsgBannerInfo *banner_info;
1055 GtkTreeRowReference *rowref;
1059 open_msg_banner_idle (gpointer userdata)
1061 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
1063 gdk_threads_enter ();
1064 banner_info->idle_handler = 0;
1065 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
1066 if (banner_info->banner)
1067 g_object_ref (banner_info->banner);
1069 gdk_threads_leave ();
1075 get_header_view_from_window (ModestWindow *window)
1077 GtkWidget *header_view;
1079 #ifndef MODEST_TOOLKIT_HILDON2
1080 if (MODEST_IS_MAIN_WINDOW (window)) {
1081 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
1082 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1084 if (MODEST_IS_HEADER_WINDOW (window)){
1085 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
1095 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
1098 gchar *account = NULL;
1099 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
1104 folder = tny_header_get_folder (header);
1105 /* Gets folder type (OUTBOX headers will be opened in edit window */
1106 if (modest_tny_folder_is_local_folder (folder)) {
1107 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1108 if (folder_type == TNY_FOLDER_TYPE_INVALID)
1109 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1112 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
1113 TnyTransportAccount *traccount = NULL;
1114 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
1115 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
1117 ModestTnySendQueue *send_queue = NULL;
1118 ModestTnySendQueueStatus status;
1120 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
1121 TNY_ACCOUNT(traccount)));
1122 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
1123 if (TNY_IS_SEND_QUEUE (send_queue)) {
1124 msg_id = modest_tny_send_queue_get_msg_id (header);
1125 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
1127 /* Only open messages in outbox with the editor if they are in Failed state */
1128 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
1131 #ifdef MODEST_TOOLKIT_HILDON2
1133 /* In Fremantle we can not
1134 open any message from
1135 outbox which is not in
1141 g_object_unref(traccount);
1143 g_warning("Cannot get transport account for message in outbox!!");
1145 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
1146 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
1150 TnyAccount *acc = tny_folder_get_account (folder);
1153 g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (acc));
1154 g_object_unref (acc);
1158 g_object_unref (folder);
1164 open_msg_cb (ModestMailOperation *mail_op,
1171 ModestWindowMgr *mgr = NULL;
1172 ModestWindow *parent_win = NULL;
1173 ModestWindow *win = NULL;
1174 gchar *account = NULL;
1175 gboolean open_in_editor = FALSE;
1177 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1179 /* Do nothing if there was any problem with the mail
1180 operation. The error will be shown by the error_handler of
1181 the mail operation */
1182 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1185 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1187 /* Mark header as read */
1188 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1190 account = get_info_from_header (header, &open_in_editor, &can_open);
1194 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1196 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1198 if (open_in_editor) {
1199 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1200 gchar *from_header = NULL, *acc_name;
1201 gchar *mailbox = NULL;
1203 from_header = tny_header_dup_from (header);
1205 /* we cannot edit without a valid account... */
1206 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1207 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1208 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1210 g_free (from_header);
1215 acc_name = modest_utils_get_account_name_from_recipient (from_header, &mailbox);
1216 g_free (from_header);
1222 win = modest_msg_edit_window_new (msg, account, mailbox, TRUE);
1226 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1227 const gchar *mailbox = NULL;
1229 if (parent_win && MODEST_IS_WINDOW (parent_win))
1230 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_win));
1232 if (helper->rowref && helper->model) {
1233 win = modest_msg_view_window_new_with_header_model (msg, account, mailbox, (const gchar*) uid,
1234 helper->model, helper->rowref);
1236 win = modest_msg_view_window_new_for_attachment (msg, account, mailbox, (const gchar*) uid);
1241 /* Register and show new window */
1243 mgr = modest_runtime_get_window_mgr ();
1244 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1245 gtk_widget_destroy (GTK_WIDGET (win));
1248 gtk_widget_show_all (GTK_WIDGET(win));
1251 #ifndef MODEST_TOOLKIT_HILDON2
1252 /* Update toolbar dimming state */
1253 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1254 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1261 g_object_unref (parent_win);
1265 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1268 const GError *error;
1269 GObject *win = NULL;
1270 ModestMailOperationStatus status;
1272 win = modest_mail_operation_get_source (mail_op);
1273 error = modest_mail_operation_get_error (mail_op);
1274 status = modest_mail_operation_get_status (mail_op);
1276 /* If the mail op has been cancelled then it's not an error:
1277 don't show any message */
1278 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1279 TnyAccount *account = modest_mail_operation_get_account (mail_op);
1280 if (modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
1281 (GError *) error, account)) {
1282 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
1283 modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
1285 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1286 modest_platform_information_banner ((GtkWidget *) win,
1287 NULL, _("emev_ui_imap_inbox_select_error"));
1288 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1289 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1290 modest_platform_information_banner ((GtkWidget *) win,
1291 NULL, _CS ("sfil_ni_unable_to_open_file_not_found"));
1292 } else if (user_data) {
1293 modest_platform_information_banner ((GtkWidget *) win,
1297 g_object_unref (account);
1301 g_object_unref (win);
1305 * Returns the account a list of headers belongs to. It returns a
1306 * *new* reference so don't forget to unref it
1309 get_account_from_header_list (TnyList *headers)
1311 TnyAccount *account = NULL;
1313 if (tny_list_get_length (headers) > 0) {
1314 TnyIterator *iter = tny_list_create_iterator (headers);
1315 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1316 TnyFolder *folder = tny_header_get_folder (header);
1319 g_object_unref (header);
1321 while (!tny_iterator_is_done (iter)) {
1322 header = TNY_HEADER (tny_iterator_get_current (iter));
1323 folder = tny_header_get_folder (header);
1326 g_object_unref (header);
1328 tny_iterator_next (iter);
1333 account = tny_folder_get_account (folder);
1334 g_object_unref (folder);
1338 g_object_unref (header);
1340 g_object_unref (iter);
1346 get_account_from_header (TnyHeader *header)
1348 TnyAccount *account = NULL;
1351 folder = tny_header_get_folder (header);
1354 account = tny_folder_get_account (folder);
1355 g_object_unref (folder);
1361 caller_win_destroyed (OpenMsgHelper *helper, GObject *object)
1363 if (helper->caller_window)
1364 helper->caller_window = NULL;
1368 open_msg_helper_destroyer (gpointer user_data)
1370 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1372 if (helper->caller_window) {
1373 g_object_weak_unref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1374 helper->caller_window = NULL;
1377 if (helper->banner_info) {
1378 g_free (helper->banner_info->message);
1379 if (helper->banner_info->idle_handler > 0) {
1380 g_source_remove (helper->banner_info->idle_handler);
1381 helper->banner_info->idle_handler = 0;
1383 if (helper->banner_info->banner != NULL) {
1384 gtk_widget_destroy (helper->banner_info->banner);
1385 g_object_unref (helper->banner_info->banner);
1386 helper->banner_info->banner = NULL;
1388 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1389 helper->banner_info = NULL;
1391 g_object_unref (helper->model);
1392 g_object_unref (helper->header);
1393 gtk_tree_row_reference_free (helper->rowref);
1394 g_slice_free (OpenMsgHelper, helper);
1398 open_msg_performer(gboolean canceled,
1400 GtkWindow *parent_window,
1401 TnyAccount *account,
1404 ModestMailOperation *mail_op = NULL;
1405 gchar *error_msg = NULL;
1406 ModestProtocolType proto;
1407 TnyConnectionStatus status;
1408 OpenMsgHelper *helper = NULL;
1409 ModestProtocol *protocol;
1410 ModestProtocolRegistry *protocol_registry;
1413 helper = (OpenMsgHelper *) user_data;
1415 status = tny_account_get_connection_status (account);
1416 if (err || canceled || helper->caller_window == NULL) {
1417 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1418 /* Free the helper */
1419 open_msg_helper_destroyer (helper);
1421 /* In disk full conditions we could get this error here */
1422 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
1423 (GtkWidget *) parent_window, err,
1429 /* Get the error message depending on the protocol */
1430 proto = modest_tny_account_get_protocol_type (account);
1431 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1432 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1435 protocol_registry = modest_runtime_get_protocol_registry ();
1436 subject = tny_header_dup_subject (helper->header);
1438 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1439 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1443 if (error_msg == NULL) {
1444 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1447 #ifndef MODEST_TOOLKIT_HILDON2
1448 gboolean show_open_draft = FALSE;
1449 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1451 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1453 TnyFolderType folder_type;
1455 folder = tny_header_get_folder (helper->header);
1456 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1457 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1458 g_object_unref (folder);
1462 #ifdef MODEST_TOOLKIT_HILDON2
1465 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1468 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1469 g_free (account_name);
1470 open_msg_helper_destroyer (helper);
1475 ModestWindow *window;
1476 GtkWidget *header_view;
1479 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1480 uid = modest_tny_folder_get_header_unique_id (helper->header);
1482 const gchar *mailbox = NULL;
1483 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_window));
1484 window = modest_msg_view_window_new_from_header_view
1485 (MODEST_HEADER_VIEW (header_view), account_name, mailbox, uid, helper->rowref);
1486 if (window != NULL) {
1487 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1489 gtk_widget_destroy (GTK_WIDGET (window));
1491 gtk_widget_show_all (GTK_WIDGET(window));
1495 g_free (account_name);
1497 open_msg_helper_destroyer (helper);
1500 g_free (account_name);
1502 /* Create the mail operation */
1504 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1505 modest_ui_actions_disk_operations_error_handler,
1506 g_strdup (error_msg), g_free);
1507 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1511 #ifndef MODEST_TOOLKIT_HILDON2
1512 if (show_open_draft) {
1513 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1514 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1515 helper->banner_info->banner = NULL;
1516 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1517 helper->banner_info);
1523 headers = TNY_LIST (tny_simple_list_new ());
1524 tny_list_prepend (headers, G_OBJECT (helper->header));
1525 modest_mail_operation_get_msgs_full (mail_op,
1529 open_msg_helper_destroyer);
1530 g_object_unref (headers);
1537 g_object_unref (mail_op);
1538 g_object_unref (account);
1542 * This function is used by both modest_ui_actions_on_open and
1543 * modest_ui_actions_on_header_activated. This way we always do the
1544 * same when trying to open messages.
1547 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1549 ModestWindowMgr *mgr = NULL;
1550 TnyAccount *account;
1551 gboolean cached = FALSE;
1553 GtkWidget *header_view = NULL;
1554 OpenMsgHelper *helper;
1555 ModestWindow *window;
1557 g_return_if_fail (header != NULL && rowref != NULL && gtk_tree_row_reference_valid (rowref));
1559 mgr = modest_runtime_get_window_mgr ();
1562 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1563 if (header_view == NULL)
1566 /* Get the account */
1567 account = get_account_from_header (header);
1572 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1574 /* Do not open again the message and present the
1575 window to the user */
1578 #ifndef MODEST_TOOLKIT_HILDON2
1579 gtk_window_present (GTK_WINDOW (window));
1582 /* the header has been registered already, we don't do
1583 * anything but wait for the window to come up*/
1584 g_debug ("header %p already registered, waiting for window", header);
1589 /* Open each message */
1590 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1592 /* Allways download if we are online. */
1593 if (!tny_device_is_online (modest_runtime_get_device ())) {
1596 /* If ask for user permission to download the messages */
1597 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1598 _("mcen_nc_get_msg"));
1600 /* End if the user does not want to continue */
1601 if (response == GTK_RESPONSE_CANCEL) {
1607 /* We register the window for opening */
1608 modest_window_mgr_register_header (mgr, header, NULL);
1610 /* Create the helper. We need to get a reference to the model
1611 here because it could change while the message is readed
1612 (the user could switch between folders) */
1613 helper = g_slice_new (OpenMsgHelper);
1614 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1615 helper->caller_window = win;
1616 g_object_weak_ref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1617 helper->header = g_object_ref (header);
1618 helper->rowref = gtk_tree_row_reference_copy (rowref);
1619 helper->banner_info = NULL;
1621 /* Connect to the account and perform */
1623 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1624 open_msg_performer, helper);
1626 /* Call directly the performer, do not need to connect */
1627 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1628 g_object_ref (account), helper);
1633 g_object_unref (account);
1637 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1644 /* we check for low-mem; in that case, show a warning, and don't allow
1647 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1651 headers = get_selected_headers (win);
1655 headers_count = tny_list_get_length (headers);
1656 if (headers_count != 1) {
1657 if (headers_count > 1) {
1658 /* Don't allow activation if there are more than one message selected */
1659 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1662 g_object_unref (headers);
1666 iter = tny_list_create_iterator (headers);
1667 header = TNY_HEADER (tny_iterator_get_current (iter));
1668 g_object_unref (iter);
1672 open_msg_from_header (header, NULL, win);
1673 g_object_unref (header);
1676 g_object_unref(headers);
1680 rf_helper_window_closed (gpointer data,
1683 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1685 helper->parent_window = NULL;
1688 static ReplyForwardHelper*
1689 create_reply_forward_helper (ReplyForwardAction action,
1691 guint reply_forward_type,
1694 ReplyForwardHelper *rf_helper = NULL;
1695 const gchar *active_acc = modest_window_get_active_account (win);
1696 const gchar *active_mailbox = modest_window_get_active_mailbox (win);
1698 rf_helper = g_slice_new0 (ReplyForwardHelper);
1699 rf_helper->reply_forward_type = reply_forward_type;
1700 rf_helper->action = action;
1701 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1702 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1703 rf_helper->account_name = (active_acc) ?
1704 g_strdup (active_acc) :
1705 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1706 rf_helper->mailbox = g_strdup (active_mailbox);
1708 /* Note that window could be destroyed just AFTER calling
1709 register_window so we must ensure that this pointer does
1710 not hold invalid references */
1711 if (rf_helper->parent_window)
1712 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1713 rf_helper_window_closed, rf_helper);
1719 free_reply_forward_helper (gpointer data)
1721 ReplyForwardHelper *helper;
1723 helper = (ReplyForwardHelper *) data;
1724 g_free (helper->account_name);
1725 g_free (helper->mailbox);
1727 g_object_unref (helper->header);
1728 if (helper->parent_window)
1729 g_object_weak_unref (G_OBJECT (helper->parent_window),
1730 rf_helper_window_closed, helper);
1731 g_slice_free (ReplyForwardHelper, helper);
1735 reply_forward_cb (ModestMailOperation *mail_op,
1742 TnyMsg *new_msg = NULL;
1743 ReplyForwardHelper *rf_helper;
1744 ModestWindow *msg_win = NULL;
1745 ModestEditType edit_type;
1747 TnyAccount *account = NULL;
1748 ModestWindowMgr *mgr = NULL;
1749 gchar *signature = NULL;
1750 gboolean use_signature;
1753 /* If there was any error. The mail operation could be NULL,
1754 this means that we already have the message downloaded and
1755 that we didn't do a mail operation to retrieve it */
1756 rf_helper = (ReplyForwardHelper *) user_data;
1757 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1760 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1761 rf_helper->account_name, rf_helper->mailbox);
1762 recipient = modest_text_utils_get_email_address (from);
1763 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr(),
1768 /* Create reply mail */
1769 switch (rf_helper->action) {
1770 /* Use the msg_header to ensure that we have all the
1771 information. The summary can lack some data */
1772 TnyHeader *msg_header;
1774 msg_header = tny_msg_get_header (msg);
1776 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1777 (use_signature) ? signature : NULL,
1778 rf_helper->reply_forward_type,
1779 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1780 g_object_unref (msg_header);
1782 case ACTION_REPLY_TO_ALL:
1783 msg_header = tny_msg_get_header (msg);
1785 modest_tny_msg_create_reply_msg (msg, msg_header, from,
1786 (use_signature) ? signature : NULL,
1787 rf_helper->reply_forward_type,
1788 MODEST_TNY_MSG_REPLY_MODE_ALL);
1789 edit_type = MODEST_EDIT_TYPE_REPLY;
1790 g_object_unref (msg_header);
1792 case ACTION_FORWARD:
1794 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1795 rf_helper->reply_forward_type);
1796 edit_type = MODEST_EDIT_TYPE_FORWARD;
1799 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1801 g_return_if_reached ();
1809 g_warning ("%s: failed to create message\n", __FUNCTION__);
1813 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1814 rf_helper->account_name,
1815 TNY_ACCOUNT_TYPE_STORE);
1817 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1821 /* Create and register the windows */
1822 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, rf_helper->mailbox, FALSE);
1823 mgr = modest_runtime_get_window_mgr ();
1824 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1826 /* Note that register_window could have deleted the account */
1827 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1828 gdouble parent_zoom;
1830 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1831 modest_window_set_zoom (msg_win, parent_zoom);
1834 /* Show edit window */
1835 gtk_widget_show_all (GTK_WIDGET (msg_win));
1838 /* We always unregister the header because the message is
1839 forwarded or replied so the original one is no longer
1841 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1844 g_object_unref (G_OBJECT (new_msg));
1846 g_object_unref (G_OBJECT (account));
1847 free_reply_forward_helper (rf_helper);
1850 /* Checks a list of headers. If any of them are not currently
1851 * downloaded (CACHED) then returns TRUE else returns FALSE.
1854 header_list_count_uncached_msgs (TnyList *header_list)
1857 gint uncached_messages = 0;
1859 iter = tny_list_create_iterator (header_list);
1860 while (!tny_iterator_is_done (iter)) {
1863 header = TNY_HEADER (tny_iterator_get_current (iter));
1865 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1866 uncached_messages ++;
1867 g_object_unref (header);
1870 tny_iterator_next (iter);
1872 g_object_unref (iter);
1874 return uncached_messages;
1877 /* Returns FALSE if the user does not want to download the
1878 * messages. Returns TRUE if the user allowed the download.
1881 connect_to_get_msg (ModestWindow *win,
1882 gint num_of_uncached_msgs,
1883 TnyAccount *account)
1885 GtkResponseType response;
1887 /* Allways download if we are online. */
1888 if (tny_device_is_online (modest_runtime_get_device ()))
1891 /* If offline, then ask for user permission to download the messages */
1892 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1893 ngettext("mcen_nc_get_msg",
1895 num_of_uncached_msgs));
1897 if (response == GTK_RESPONSE_CANCEL)
1900 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1904 reply_forward_performer (gboolean canceled,
1906 GtkWindow *parent_window,
1907 TnyAccount *account,
1910 ReplyForwardHelper *rf_helper = NULL;
1911 ModestMailOperation *mail_op;
1913 rf_helper = (ReplyForwardHelper *) user_data;
1915 if (canceled || err) {
1916 free_reply_forward_helper (rf_helper);
1920 /* Retrieve the message */
1921 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1922 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1923 modest_ui_actions_disk_operations_error_handler,
1925 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1926 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1929 g_object_unref(mail_op);
1933 * Common code for the reply and forward actions
1936 reply_forward (ReplyForwardAction action, ModestWindow *win)
1938 ReplyForwardHelper *rf_helper = NULL;
1939 guint reply_forward_type;
1941 g_return_if_fail (win && MODEST_IS_WINDOW(win));
1943 /* we check for low-mem; in that case, show a warning, and don't allow
1944 * reply/forward (because it could potentially require a lot of memory */
1945 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1949 /* we need an account when editing */
1950 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1951 if (!modest_ui_actions_run_account_setup_wizard (win))
1955 reply_forward_type =
1956 modest_conf_get_int (modest_runtime_get_conf (),
1957 (action == ACTION_FORWARD) ?
1958 MODEST_CONF_FORWARD_TYPE :
1959 MODEST_CONF_REPLY_TYPE,
1962 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1964 TnyHeader *header = NULL;
1965 /* Get header and message. Do not free them here, the
1966 reply_forward_cb must do it */
1967 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1968 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1970 if (msg && header) {
1972 rf_helper = create_reply_forward_helper (action, win,
1973 reply_forward_type, header);
1974 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1976 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1980 g_object_unref (msg);
1982 g_object_unref (header);
1984 TnyHeader *header = NULL;
1986 gboolean do_retrieve = TRUE;
1987 TnyList *header_list = NULL;
1989 header_list = get_selected_headers (win);
1992 /* Check that only one message is selected for replying */
1993 if (tny_list_get_length (header_list) != 1) {
1994 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1995 NULL, _("mcen_ib_select_one_message"));
1996 g_object_unref (header_list);
2000 /* Only reply/forward to one message */
2001 iter = tny_list_create_iterator (header_list);
2002 header = TNY_HEADER (tny_iterator_get_current (iter));
2003 g_object_unref (iter);
2005 /* Retrieve messages */
2006 do_retrieve = (action == ACTION_FORWARD) ||
2007 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
2010 TnyAccount *account = NULL;
2011 TnyFolder *folder = NULL;
2012 gdouble download = TRUE;
2013 guint uncached_msgs = 0;
2015 folder = tny_header_get_folder (header);
2017 goto do_retrieve_frees;
2018 account = tny_folder_get_account (folder);
2020 goto do_retrieve_frees;
2022 uncached_msgs = header_list_count_uncached_msgs (header_list);
2024 if (uncached_msgs > 0) {
2025 /* Allways download if we are online. */
2026 if (!tny_device_is_online (modest_runtime_get_device ())) {
2029 /* If ask for user permission to download the messages */
2030 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2031 ngettext("mcen_nc_get_msg",
2035 /* End if the user does not want to continue */
2036 if (response == GTK_RESPONSE_CANCEL)
2043 rf_helper = create_reply_forward_helper (action, win,
2044 reply_forward_type, header);
2045 if (uncached_msgs > 0) {
2046 modest_platform_connect_and_perform (GTK_WINDOW (win),
2048 reply_forward_performer,
2051 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
2052 account, rf_helper);
2057 g_object_unref (account);
2059 g_object_unref (folder);
2061 reply_forward_cb (NULL, header, FALSE, NULL, NULL, NULL);
2064 g_object_unref (header_list);
2065 g_object_unref (header);
2070 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
2072 g_return_if_fail (MODEST_IS_WINDOW(win));
2074 reply_forward (ACTION_REPLY, win);
2078 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
2080 g_return_if_fail (MODEST_IS_WINDOW(win));
2082 reply_forward (ACTION_FORWARD, win);
2086 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
2088 g_return_if_fail (MODEST_IS_WINDOW(win));
2090 reply_forward (ACTION_REPLY_TO_ALL, win);
2094 modest_ui_actions_on_next (GtkAction *action,
2095 ModestWindow *window)
2097 #ifndef MODEST_TOOLKIT_HILDON2
2098 if (MODEST_IS_MAIN_WINDOW (window)) {
2099 GtkWidget *header_view;
2101 header_view = modest_main_window_get_child_widget (
2102 MODEST_MAIN_WINDOW(window),
2103 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2107 modest_header_view_select_next (
2108 MODEST_HEADER_VIEW(header_view));
2110 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2111 modest_msg_view_window_select_next_message (
2112 MODEST_MSG_VIEW_WINDOW (window));
2115 g_return_if_reached ();
2120 modest_ui_actions_on_prev (GtkAction *action,
2121 ModestWindow *window)
2123 g_return_if_fail (MODEST_IS_WINDOW(window));
2125 #ifndef MODEST_TOOLKIT_HILDON2
2126 if (MODEST_IS_MAIN_WINDOW (window)) {
2127 GtkWidget *header_view;
2128 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2129 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2133 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
2135 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2136 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
2139 g_return_if_reached ();
2144 modest_ui_actions_on_sort (GtkAction *action,
2145 ModestWindow *window)
2147 GtkWidget *header_view = NULL;
2149 g_return_if_fail (MODEST_IS_WINDOW(window));
2151 #ifndef MODEST_TOOLKIT_HILDON2
2152 if (MODEST_IS_MAIN_WINDOW (window)) {
2153 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2154 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2156 if (MODEST_IS_HEADER_WINDOW (window)) {
2157 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2162 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
2167 /* Show sorting dialog */
2168 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
2172 sync_folder_cb (ModestMailOperation *mail_op,
2176 ModestHeaderView *header_view = (ModestHeaderView *) user_data;
2178 if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
2179 ModestWindow *parent = (ModestWindow *) modest_mail_operation_get_source (mail_op);
2181 /* We must clear first, because otherwise set_folder will ignore */
2182 /* the change as the folders are the same */
2183 modest_header_view_clear (header_view);
2184 modest_header_view_set_folder (header_view, folder, TRUE, parent, NULL, NULL);
2186 g_object_unref (parent);
2189 g_object_unref (header_view);
2193 idle_refresh_folder (gpointer source)
2195 ModestHeaderView *header_view = NULL;
2197 /* If the window still exists */
2198 if (!GTK_IS_WIDGET (source) ||
2199 !GTK_WIDGET_VISIBLE (source))
2202 /* Refresh the current view */
2203 #ifdef MODEST_TOOLKIT_HILDON2
2204 if (MODEST_IS_HEADER_WINDOW (source))
2205 header_view = modest_header_window_get_header_view ((ModestHeaderWindow *) source);
2207 if (MODEST_IS_MAIN_WINDOW (source))
2208 header_view = modest_main_window_get_child_widget ((ModestMainWindow *) source,
2209 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2212 TnyFolder *folder = modest_header_view_get_folder (header_view);
2214 /* Sync the folder status */
2215 ModestMailOperation *mail_op = modest_mail_operation_new (source);
2216 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2217 modest_mail_operation_sync_folder (mail_op, folder, FALSE, sync_folder_cb, g_object_ref (header_view));
2218 g_object_unref (folder);
2219 g_object_unref (mail_op);
2227 update_account_cb (ModestMailOperation *self,
2228 TnyList *new_headers,
2232 gboolean show_visual_notifications;
2234 source = modest_mail_operation_get_source (self);
2235 show_visual_notifications = (source) ? FALSE : TRUE;
2237 /* Notify new messages have been downloaded. If the
2238 send&receive was invoked by the user then do not show any
2239 visual notification, only play a sound and activate the LED
2240 (for the Maemo version) */
2241 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0) {
2243 /* We only notify about really new messages (not seen) we get */
2244 TnyList *actually_new_list;
2245 TnyIterator *iterator;
2246 actually_new_list = TNY_LIST (tny_simple_list_new ());
2247 for (iterator = tny_list_create_iterator (new_headers);
2248 !tny_iterator_is_done (iterator);
2249 tny_iterator_next (iterator)) {
2251 TnyHeaderFlags flags;
2252 header = TNY_HEADER (tny_iterator_get_current (iterator));
2253 flags = tny_header_get_flags (header);
2255 if (!(flags & TNY_HEADER_FLAG_SEEN)) {
2256 /* Messages are ordered from most
2257 recent to oldest. But we want to
2258 show notifications starting from
2259 the oldest message. That's why we
2261 tny_list_prepend (actually_new_list, G_OBJECT (header));
2263 g_object_unref (header);
2265 g_object_unref (iterator);
2267 if (tny_list_get_length (actually_new_list) > 0) {
2268 GList *new_headers_list = NULL;
2270 new_headers_list = modest_utils_create_notification_list_from_header_list (actually_new_list);
2272 /* Send notifications */
2273 if (new_headers_list) {
2274 modest_platform_on_new_headers_received (new_headers_list,
2275 show_visual_notifications);
2277 modest_utils_free_notification_list (new_headers_list);
2280 g_object_unref (actually_new_list);
2284 /* Refresh the current folder in an idle. We do this
2285 in order to avoid refresh cancelations if the
2286 currently viewed folder is the inbox */
2287 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
2288 idle_refresh_folder,
2289 g_object_ref (source),
2291 g_object_unref (source);
2296 TnyAccount *account;
2298 gchar *account_name;
2299 gboolean poke_status;
2300 gboolean interactive;
2301 ModestMailOperation *mail_op;
2305 do_send_receive_performer (gboolean canceled,
2307 GtkWindow *parent_window,
2308 TnyAccount *account,
2311 SendReceiveInfo *info;
2313 info = (SendReceiveInfo *) user_data;
2315 if (err || canceled) {
2316 /* In disk full conditions we could get this error here */
2317 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
2318 (GtkWidget *) parent_window, err,
2321 if (info->mail_op) {
2322 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2328 #ifndef MODEST_TOOLKIT_HILDON2
2329 /* Set send/receive operation in progress */
2330 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2331 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2334 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2335 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2336 G_CALLBACK (on_send_receive_finished),
2340 /* Send & receive. */
2341 modest_mail_operation_update_account (info->mail_op, info->account_name,
2342 info->poke_status, info->interactive,
2343 update_account_cb, info->win);
2348 g_object_unref (G_OBJECT (info->mail_op));
2349 if (info->account_name)
2350 g_free (info->account_name);
2352 g_object_unref (info->win);
2354 g_object_unref (info->account);
2355 g_slice_free (SendReceiveInfo, info);
2359 * This function performs the send & receive required actions. The
2360 * window is used to create the mail operation. Typically it should
2361 * always be the main window, but we pass it as argument in order to
2365 modest_ui_actions_do_send_receive (const gchar *account_name,
2366 gboolean force_connection,
2367 gboolean poke_status,
2368 gboolean interactive,
2371 gchar *acc_name = NULL;
2372 SendReceiveInfo *info;
2373 ModestTnyAccountStore *acc_store;
2374 TnyAccount *account;
2376 /* If no account name was provided then get the current account, and if
2377 there is no current account then pick the default one: */
2378 if (!account_name) {
2380 acc_name = g_strdup (modest_window_get_active_account (win));
2382 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2384 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2388 acc_name = g_strdup (account_name);
2391 acc_store = modest_runtime_get_account_store ();
2392 account = modest_tny_account_store_get_server_account (acc_store, acc_name, TNY_ACCOUNT_TYPE_STORE);
2396 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2400 /* Do not automatically refresh accounts that are flagged as
2401 NO_AUTO_UPDATE. This could be useful for accounts that
2402 handle their own update times */
2404 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
2405 if (proto != MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
2406 const gchar *tag = MODEST_PROTOCOL_REGISTRY_NO_AUTO_UPDATE_PROTOCOLS;
2407 ModestProtocolRegistry *registry = modest_runtime_get_protocol_registry ();
2409 if (modest_protocol_registry_protocol_type_has_tag (registry, proto, tag)) {
2410 g_debug ("%s no auto update allowed for account %s", __FUNCTION__, account_name);
2411 g_object_unref (account);
2418 /* Create the info for the connect and perform */
2419 info = g_slice_new (SendReceiveInfo);
2420 info->account_name = acc_name;
2421 info->win = (win) ? g_object_ref (win) : NULL;
2422 info->poke_status = poke_status;
2423 info->interactive = interactive;
2424 info->account = account;
2425 /* We need to create the operation here, because otherwise it
2426 could happen that the queue emits the queue-empty signal
2427 while we're trying to connect the account */
2428 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2429 modest_ui_actions_disk_operations_error_handler,
2431 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2433 /* Invoke the connect and perform */
2434 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2435 force_connection, info->account,
2436 do_send_receive_performer, info);
2441 modest_ui_actions_do_cancel_send (const gchar *account_name,
2444 TnyTransportAccount *transport_account;
2445 TnySendQueue *send_queue = NULL;
2446 GError *error = NULL;
2448 /* Get transport account */
2450 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2451 (modest_runtime_get_account_store(),
2453 TNY_ACCOUNT_TYPE_TRANSPORT));
2454 if (!transport_account) {
2455 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2460 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2461 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2462 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2463 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2464 "modest: could not find send queue for account\n");
2466 /* Cancel the current send */
2467 tny_account_cancel (TNY_ACCOUNT (transport_account));
2469 /* Suspend all pending messages */
2470 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2474 if (transport_account != NULL)
2475 g_object_unref (G_OBJECT (transport_account));
2479 modest_ui_actions_cancel_send_all (ModestWindow *win)
2481 GSList *account_names, *iter;
2483 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2486 iter = account_names;
2488 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2489 iter = g_slist_next (iter);
2492 modest_account_mgr_free_account_names (account_names);
2493 account_names = NULL;
2497 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2500 /* Check if accounts exist */
2501 gboolean accounts_exist =
2502 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2504 /* If not, allow the user to create an account before trying to send/receive. */
2505 if (!accounts_exist)
2506 modest_ui_actions_on_accounts (NULL, win);
2508 /* Cancel all sending operaitons */
2509 modest_ui_actions_cancel_send_all (win);
2513 * Refreshes all accounts. This function will be used by automatic
2517 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2518 gboolean force_connection,
2519 gboolean poke_status,
2520 gboolean interactive)
2522 GSList *account_names, *iter;
2524 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2527 iter = account_names;
2529 modest_ui_actions_do_send_receive ((const char*) iter->data,
2531 poke_status, interactive, win);
2532 iter = g_slist_next (iter);
2535 modest_account_mgr_free_account_names (account_names);
2536 account_names = NULL;
2540 * Handler of the click on Send&Receive button in the main toolbar
2543 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2545 /* Check if accounts exist */
2546 gboolean accounts_exist;
2549 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2551 /* If not, allow the user to create an account before trying to send/receive. */
2552 if (!accounts_exist)
2553 modest_ui_actions_on_accounts (NULL, win);
2555 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2556 #ifndef MODEST_TOOLKIT_HILDON2
2557 if (MODEST_IS_MAIN_WINDOW (win)) {
2558 GtkWidget *folder_view;
2559 TnyFolderStore *folder_store;
2562 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2563 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2567 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2570 g_object_unref (folder_store);
2571 /* Refresh the active account. Force the connection if needed
2572 and poke the status of all folders */
2573 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2575 if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2576 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2579 const gchar *active_account;
2580 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2582 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2587 #ifndef MODEST_TOOLKIT_HILDON2
2589 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2592 GtkWidget *header_view;
2594 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2596 header_view = modest_main_window_get_child_widget (main_window,
2597 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2601 conf = modest_runtime_get_conf ();
2603 /* what is saved/restored is depending on the style; thus; we save with
2604 * old style, then update the style, and restore for this new style
2606 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2608 if (modest_header_view_get_style
2609 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2610 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2611 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2613 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2614 MODEST_HEADER_VIEW_STYLE_DETAILS);
2616 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2617 MODEST_CONF_HEADER_VIEW_KEY);
2621 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2623 ModestMainWindow *main_window)
2625 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2626 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2628 /* in the case the folder is empty, show the empty folder message and focus
2630 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2631 if (modest_header_view_is_empty (header_view)) {
2632 TnyFolder *folder = modest_header_view_get_folder (header_view);
2633 GtkWidget *folder_view =
2634 modest_main_window_get_child_widget (main_window,
2635 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2636 if (folder != NULL) {
2637 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2638 g_object_unref (folder);
2640 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2644 /* If no header has been selected then exit */
2649 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2650 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2652 /* Update toolbar dimming state */
2653 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2654 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2659 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2662 ModestWindow *window)
2664 GtkTreeRowReference *rowref;
2666 g_return_if_fail (MODEST_IS_WINDOW(window));
2667 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2668 g_return_if_fail (TNY_IS_HEADER (header));
2670 if (modest_header_view_count_selected_headers (header_view) > 1) {
2671 /* Don't allow activation if there are more than one message selected */
2672 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2676 /* we check for low-mem; in that case, show a warning, and don't allow
2677 * activating headers
2679 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2682 #ifndef MODEST_TOOLKIT_HILDON2
2683 GtkWidget *open_widget;
2684 if (MODEST_IS_MAIN_WINDOW (window)) {
2685 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2686 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2687 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2692 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2693 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2694 gtk_tree_row_reference_free (rowref);
2697 #ifndef MODEST_TOOLKIT_HILDON2
2699 set_active_account_from_tny_account (TnyAccount *account,
2700 ModestWindow *window)
2702 const gchar *server_acc_name = tny_account_get_id (account);
2704 /* We need the TnyAccount provided by the
2705 account store because that is the one that
2706 knows the name of the Modest account */
2707 TnyAccount *modest_server_account =
2708 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2709 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2711 if (!modest_server_account) {
2712 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2716 /* Update active account, but only if it's not a pseudo-account */
2717 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2718 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2719 const gchar *modest_acc_name =
2720 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2721 if (modest_acc_name)
2722 modest_window_set_active_account (window, modest_acc_name);
2725 g_object_unref (modest_server_account);
2729 folder_refreshed_cb (ModestMailOperation *mail_op,
2733 ModestMainWindow *win = NULL;
2734 GtkWidget *folder_view, *header_view;
2735 const GError *error;
2737 g_return_if_fail (TNY_IS_FOLDER (folder));
2739 win = MODEST_MAIN_WINDOW (user_data);
2741 /* Check if the operation failed due to memory low conditions */
2742 error = modest_mail_operation_get_error (mail_op);
2743 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2744 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2745 modest_platform_run_information_dialog (GTK_WINDOW (win),
2746 _KR("memr_ib_operation_disabled"),
2752 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2754 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2757 TnyFolderStore *current_folder;
2759 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2760 if (current_folder) {
2761 gboolean different = ((TnyFolderStore *) folder != current_folder);
2762 g_object_unref (current_folder);
2768 /* Check if folder is empty and set headers view contents style */
2769 if ((tny_folder_get_all_count (folder) == 0) ||
2770 modest_header_view_is_empty (MODEST_HEADER_VIEW (header_view)))
2771 modest_main_window_set_contents_style (win,
2772 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2776 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2777 TnyFolderStore *folder_store,
2779 ModestMainWindow *main_window)
2781 GtkWidget *header_view;
2783 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2785 header_view = modest_main_window_get_child_widget(main_window,
2786 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2791 if (TNY_IS_ACCOUNT (folder_store)) {
2793 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2795 /* Show account details */
2796 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2799 if (TNY_IS_FOLDER (folder_store) && selected) {
2800 TnyAccount *account;
2802 /* Update the active account */
2803 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2805 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2806 g_object_unref (account);
2810 /* Set the header style by default, it could
2811 be changed later by the refresh callback to
2813 modest_main_window_set_contents_style (main_window,
2814 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2816 /* Set folder on header view. This function
2817 will call tny_folder_refresh_async so we
2818 pass a callback that will be called when
2819 finished. We use that callback to set the
2820 empty view if there are no messages */
2821 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2822 TNY_FOLDER (folder_store),
2824 MODEST_WINDOW (main_window),
2825 folder_refreshed_cb,
2828 /* Restore configuration. We need to do this
2829 *after* the set_folder because the widget
2830 memory asks the header view about its
2832 modest_widget_memory_restore (modest_runtime_get_conf (),
2833 G_OBJECT(header_view),
2834 MODEST_CONF_HEADER_VIEW_KEY);
2836 /* No need to save the header view
2837 configuration for Maemo because it only
2838 saves the sorting stuff and that it's
2839 already being done by the sort
2840 dialog. Remove it when the GNOME version
2841 has the same behaviour */
2842 #ifdef MODEST_TOOLKIT_GTK
2843 if (modest_main_window_get_contents_style (main_window) ==
2844 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2845 modest_widget_memory_save (modest_runtime_get_conf (),
2846 G_OBJECT (header_view),
2847 MODEST_CONF_HEADER_VIEW_KEY);
2849 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2853 /* Update dimming state */
2854 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2855 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2860 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2867 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2869 online = tny_device_is_online (modest_runtime_get_device());
2872 /* already online -- the item is simply not there... */
2873 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2875 GTK_MESSAGE_WARNING,
2877 _("The %s you selected cannot be found"),
2879 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2880 gtk_dialog_run (GTK_DIALOG(dialog));
2882 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2885 _("mcen_bd_dialog_cancel"),
2886 GTK_RESPONSE_REJECT,
2887 _("mcen_bd_dialog_ok"),
2888 GTK_RESPONSE_ACCEPT,
2890 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2891 "Do you want to get online?"), item);
2892 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2893 gtk_label_new (txt), FALSE, FALSE, 0);
2894 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2897 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2898 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2899 /* TODO: Comment about why is this commented out: */
2900 /* modest_platform_connect_and_wait (); */
2903 gtk_widget_destroy (dialog);
2907 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2910 /* g_debug ("%s %s", __FUNCTION__, link); */
2915 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2918 modest_platform_activate_uri (link);
2922 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2925 modest_platform_show_uri_popup (link);
2929 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2932 /* we check for low-mem; in that case, show a warning, and don't allow
2933 * viewing attachments
2935 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2938 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2942 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2943 const gchar *address,
2946 /* g_debug ("%s %s", __FUNCTION__, address); */
2950 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2951 TnyMsg *saved_draft,
2954 ModestMsgEditWindow *edit_window;
2956 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2957 #ifndef MODEST_TOOLKIT_HILDON2
2958 ModestMainWindow *win;
2960 /* FIXME. Make the header view sensitive again. This is a
2961 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2963 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2964 modest_runtime_get_window_mgr(), FALSE));
2966 GtkWidget *hdrview = modest_main_window_get_child_widget(
2967 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2968 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2972 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2974 /* Set draft is there was no error */
2975 if (!modest_mail_operation_get_error (mail_op))
2976 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2978 g_object_unref(edit_window);
2982 enough_space_for_message (ModestMsgEditWindow *edit_window,
2985 guint64 available_disk, expected_size;
2990 available_disk = modest_utils_get_available_space (NULL);
2991 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2992 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2997 /* Double check: disk full condition or message too big */
2998 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
2999 expected_size > available_disk) {
3000 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3001 modest_platform_information_banner (NULL, NULL, msg);
3008 * djcb: if we're in low-memory state, we only allow for
3009 * saving messages smaller than
3010 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
3011 * should still allow for sending anything critical...
3013 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
3014 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
3018 * djcb: we also make sure that the attachments are smaller than the max size
3019 * this is for the case where we'd try to forward a message with attachments
3020 * bigger than our max allowed size, or sending an message from drafts which
3021 * somehow got past our checks when attaching.
3023 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
3024 modest_platform_run_information_dialog (
3025 GTK_WINDOW(edit_window),
3026 _("mail_ib_error_attachment_size"),
3035 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3037 TnyTransportAccount *transport_account;
3038 ModestMailOperation *mail_operation;
3040 gchar *account_name;
3041 ModestAccountMgr *account_mgr;
3042 gboolean had_error = FALSE;
3044 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
3046 data = modest_msg_edit_window_get_msg_data (edit_window);
3049 if (!enough_space_for_message (edit_window, data)) {
3050 modest_msg_edit_window_free_msg_data (edit_window, data);
3054 account_name = g_strdup (data->account_name);
3055 account_mgr = modest_runtime_get_account_mgr();
3057 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3059 account_name = modest_account_mgr_get_default_account (account_mgr);
3060 if (!account_name) {
3061 g_printerr ("modest: no account found\n");
3062 modest_msg_edit_window_free_msg_data (edit_window, data);
3066 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
3067 account_name = g_strdup (data->account_name);
3071 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3072 (modest_runtime_get_account_store (),
3074 TNY_ACCOUNT_TYPE_TRANSPORT));
3075 if (!transport_account) {
3076 g_printerr ("modest: no transport account found for '%s'\n", account_name);
3077 g_free (account_name);
3078 modest_msg_edit_window_free_msg_data (edit_window, data);
3082 /* Create the mail operation */
3083 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
3085 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3087 modest_mail_operation_save_to_drafts (mail_operation,
3099 data->priority_flags,
3102 on_save_to_drafts_cb,
3103 g_object_ref(edit_window));
3105 #ifdef MODEST_TOOLKIT_HILDON2
3106 /* In hildon2 we always show the information banner on saving to drafts.
3107 * It will be a system information banner in this case.
3109 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3110 modest_platform_information_banner (NULL, NULL, text);
3113 ModestMainWindow *win = NULL;
3115 /* Use the main window as the parent of the banner, if the
3116 main window does not exist it won't be shown, if the parent
3117 window exists then it's properly shown. We don't use the
3118 editor window because it could be closed (save to drafts
3119 could happen after closing the window */
3120 win = (ModestMainWindow *)
3121 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
3123 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3124 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
3128 modest_msg_edit_window_set_modified (edit_window, FALSE);
3131 g_free (account_name);
3132 g_object_unref (G_OBJECT (transport_account));
3133 g_object_unref (G_OBJECT (mail_operation));
3135 modest_msg_edit_window_free_msg_data (edit_window, data);
3137 #ifndef MODEST_TOOLKIT_HILDON2
3139 * If the drafts folder is selected then make the header view
3140 * insensitive while the message is being saved to drafts
3141 * (it'll be sensitive again in on_save_to_drafts_cb()). This
3142 * is not very clean but it avoids letting the drafts folder
3143 * in an inconsistent state: the user could edit the message
3144 * being saved and undesirable things would happen.
3145 * In the average case the user won't notice anything at
3146 * all. In the worst case (the user is editing a really big
3147 * file from Drafts) the header view will be insensitive
3148 * during the saving process (10 or 20 seconds, depending on
3149 * the message). Anyway this is just a quick workaround: once
3150 * we find a better solution it should be removed
3151 * See NB#65125 (commend #18) for details.
3153 if (!had_error && win != NULL) {
3154 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
3155 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
3157 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
3159 if (modest_tny_folder_is_local_folder(folder)) {
3160 TnyFolderType folder_type;
3161 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
3162 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
3163 GtkWidget *hdrview = modest_main_window_get_child_widget(
3164 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3165 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
3169 if (folder != NULL) g_object_unref(folder);
3177 /* For instance, when clicking the Send toolbar button when editing a message: */
3179 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3181 TnyTransportAccount *transport_account = NULL;
3182 gboolean had_error = FALSE;
3184 ModestAccountMgr *account_mgr;
3185 gchar *account_name;
3186 ModestMailOperation *mail_operation;
3189 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
3191 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
3194 data = modest_msg_edit_window_get_msg_data (edit_window);
3196 recipients = g_strconcat (data->to?data->to:"",
3197 data->cc?data->cc:"",
3198 data->bcc?data->bcc:"",
3200 if (recipients == NULL || recipients[0] == '\0') {
3201 /* Empty subject -> no send */
3202 g_free (recipients);
3203 modest_msg_edit_window_free_msg_data (edit_window, data);
3206 g_free (recipients);
3209 if (!enough_space_for_message (edit_window, data)) {
3210 modest_msg_edit_window_free_msg_data (edit_window, data);
3214 account_mgr = modest_runtime_get_account_mgr();
3215 account_name = g_strdup (data->account_name);
3217 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3220 account_name = modest_account_mgr_get_default_account (account_mgr);
3222 if (!account_name) {
3223 modest_msg_edit_window_free_msg_data (edit_window, data);
3224 /* Run account setup wizard */
3225 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
3230 /* Get the currently-active transport account for this modest account: */
3231 if (account_name && strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
3233 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3234 (modest_runtime_get_account_store (),
3235 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
3238 if (!transport_account) {
3239 modest_msg_edit_window_free_msg_data (edit_window, data);
3240 /* Run account setup wizard */
3241 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
3246 /* Create the mail operation */
3247 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
3248 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3250 modest_mail_operation_send_new_mail (mail_operation,
3264 data->priority_flags);
3266 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3267 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
3269 if (modest_mail_operation_get_error (mail_operation) != NULL) {
3270 const GError *error = modest_mail_operation_get_error (mail_operation);
3271 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3272 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3273 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3274 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3280 g_free (account_name);
3281 g_object_unref (G_OBJECT (transport_account));
3282 g_object_unref (G_OBJECT (mail_operation));
3284 modest_msg_edit_window_free_msg_data (edit_window, data);
3287 modest_msg_edit_window_set_sent (edit_window, TRUE);
3289 /* Save settings and close the window: */
3290 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3297 modest_ui_actions_on_toggle_bold (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->bold = 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_italics (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->italics = 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_toggle_bullets (GtkToggleAction *action,
3340 ModestMsgEditWindow *window)
3342 ModestMsgEditFormatState *format_state = NULL;
3344 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3345 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3347 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3350 format_state = modest_msg_edit_window_get_format_state (window);
3351 g_return_if_fail (format_state != NULL);
3353 format_state->bullet = gtk_toggle_action_get_active (action);
3354 modest_msg_edit_window_set_format_state (window, format_state);
3355 g_free (format_state);
3360 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3361 GtkRadioAction *selected,
3362 ModestMsgEditWindow *window)
3364 ModestMsgEditFormatState *format_state = NULL;
3365 GtkJustification value;
3367 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3369 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3372 value = gtk_radio_action_get_current_value (selected);
3374 format_state = modest_msg_edit_window_get_format_state (window);
3375 g_return_if_fail (format_state != NULL);
3377 format_state->justification = value;
3378 modest_msg_edit_window_set_format_state (window, format_state);
3379 g_free (format_state);
3383 modest_ui_actions_on_select_editor_color (GtkAction *action,
3384 ModestMsgEditWindow *window)
3386 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3387 g_return_if_fail (GTK_IS_ACTION (action));
3389 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3392 modest_msg_edit_window_select_color (window);
3396 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3397 ModestMsgEditWindow *window)
3399 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3400 g_return_if_fail (GTK_IS_ACTION (action));
3402 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3405 modest_msg_edit_window_select_background_color (window);
3409 modest_ui_actions_on_insert_image (GObject *object,
3410 ModestMsgEditWindow *window)
3412 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3415 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3418 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3421 modest_msg_edit_window_insert_image (window);
3425 modest_ui_actions_on_attach_file (GtkAction *action,
3426 ModestMsgEditWindow *window)
3428 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3429 g_return_if_fail (GTK_IS_ACTION (action));
3431 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3434 modest_msg_edit_window_offer_attach_file (window);
3438 modest_ui_actions_on_remove_attachments (GtkAction *action,
3439 ModestMsgEditWindow *window)
3441 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3443 modest_msg_edit_window_remove_attachments (window, NULL);
3447 do_create_folder_cb (ModestMailOperation *mail_op,
3448 TnyFolderStore *parent_folder,
3449 TnyFolder *new_folder,
3452 gchar *suggested_name = (gchar *) user_data;
3453 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3454 const GError *error;
3456 error = modest_mail_operation_get_error (mail_op);
3458 gboolean disk_full = FALSE;
3459 TnyAccount *account;
3460 /* Show an error. If there was some problem writing to
3461 disk, show it, otherwise show the generic folder
3462 create error. We do it here and not in an error
3463 handler because the call to do_create_folder will
3464 stop the main loop in a gtk_dialog_run and then,
3465 the message won't be shown until that dialog is
3467 account = modest_mail_operation_get_account (mail_op);
3470 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3471 (GtkWidget *) source_win,
3474 _("mail_in_ui_folder_create_error_memory"));
3475 g_object_unref (account);
3478 /* Show an error and try again if there is no
3479 full memory condition */
3480 modest_platform_information_banner ((GtkWidget *) source_win, NULL,
3481 _("mail_in_ui_folder_create_error"));
3482 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3486 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3487 * FIXME: any other? */
3488 GtkWidget *folder_view;
3490 #ifndef MODEST_TOOLKIT_HILDON2
3491 if (MODEST_IS_MAIN_WINDOW(source_win))
3493 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3494 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3497 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3498 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3500 /* Select the newly created folder. It could happen
3501 that the widget is no longer there (i.e. the window
3502 has been destroyed, so we need to check this */
3504 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3506 g_object_unref (new_folder);
3508 /* Free. Note that the first time it'll be NULL so noop */
3509 g_free (suggested_name);
3510 g_object_unref (source_win);
3515 TnyFolderStore *parent;
3516 } CreateFolderConnect;
3519 do_create_folder_performer (gboolean canceled,
3521 GtkWindow *parent_window,
3522 TnyAccount *account,
3525 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3526 ModestMailOperation *mail_op;
3528 if (canceled || err) {
3529 /* In disk full conditions we could get this error here */
3530 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3531 (GtkWidget *) parent_window, err,
3532 NULL, _("mail_in_ui_folder_create_error_memory"));
3534 /* This happens if we have selected the outbox folder
3536 if (err && err->code == TNY_SERVICE_ERROR_UNKNOWN &&
3537 TNY_IS_MERGE_FOLDER (helper->parent)) {
3538 /* Show an error and retry */
3539 modest_platform_information_banner ((GtkWidget *) parent_window,
3541 _("mail_in_ui_folder_create_error"));
3543 do_create_folder (parent_window, helper->parent, helper->folder_name);
3549 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3550 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3552 modest_mail_operation_create_folder (mail_op,
3554 (const gchar *) helper->folder_name,
3555 do_create_folder_cb,
3556 g_strdup (helper->folder_name));
3557 g_object_unref (mail_op);
3561 g_object_unref (helper->parent);
3562 if (helper->folder_name)
3563 g_free (helper->folder_name);
3564 g_slice_free (CreateFolderConnect, helper);
3569 do_create_folder (GtkWindow *parent_window,
3570 TnyFolderStore *suggested_parent,
3571 const gchar *suggested_name)
3574 gchar *folder_name = NULL;
3575 TnyFolderStore *parent_folder = NULL;
3577 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3579 (gchar *) suggested_name,
3583 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3584 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3585 helper->folder_name = g_strdup (folder_name);
3586 helper->parent = g_object_ref (parent_folder);
3588 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3591 do_create_folder_performer,
3596 g_free (folder_name);
3598 g_object_unref (parent_folder);
3602 modest_ui_actions_create_folder(GtkWidget *parent_window,
3603 GtkWidget *folder_view,
3604 TnyFolderStore *parent_folder)
3606 if (!parent_folder) {
3607 #ifdef MODEST_TOOLKIT_HILDON2
3608 ModestTnyAccountStore *acc_store;
3610 acc_store = modest_runtime_get_account_store ();
3612 parent_folder = (TnyFolderStore *)
3613 modest_tny_account_store_get_local_folders_account (acc_store);
3615 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3619 if (parent_folder) {
3620 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3621 g_object_unref (parent_folder);
3626 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3629 g_return_if_fail (MODEST_IS_WINDOW(window));
3631 #ifndef MODEST_TOOLKIT_HILDON2
3632 if (MODEST_IS_MAIN_WINDOW (window)) {
3633 GtkWidget *folder_view;
3635 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3636 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3640 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3642 if (MODEST_IS_FOLDER_WINDOW (window)) {
3643 GtkWidget *folder_view;
3645 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3646 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3649 g_assert_not_reached ();
3654 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3657 const GError *error = NULL;
3658 gchar *message = NULL;
3660 TnyAccount *account = modest_mail_operation_get_account (mail_op);
3662 /* Get error message */
3663 error = modest_mail_operation_get_error (mail_op);
3665 g_return_if_reached ();
3667 mem_full = modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
3668 (GError *) error, account);
3670 message = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3671 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3672 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3673 message = _CS("ckdg_ib_folder_already_exists");
3674 } else if (error->domain == TNY_ERROR_DOMAIN &&
3675 error->code == TNY_SERVICE_ERROR_STATE) {
3676 /* This means that the folder is already in use (a
3677 message is opened for example */
3678 message = _("emev_ni_internal_error");
3680 message = _CS("ckdg_ib_unable_to_rename");
3683 /* We don't set a parent for the dialog because the dialog
3684 will be destroyed so the banner won't appear */
3685 modest_platform_information_banner (NULL, NULL, message);
3688 g_object_unref (account);
3694 TnyFolderStore *folder;
3699 on_rename_folder_cb (ModestMailOperation *mail_op,
3700 TnyFolder *new_folder,
3703 ModestFolderView *folder_view;
3705 /* If the window was closed when renaming a folder, or if
3706 * it's not a main window this will happen */
3707 if (!MODEST_IS_FOLDER_VIEW (user_data))
3710 folder_view = MODEST_FOLDER_VIEW (user_data);
3711 /* Note that if the rename fails new_folder will be NULL */
3713 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3714 #ifndef MODEST_TOOLKIT_HILDON2
3716 modest_folder_view_select_first_inbox_or_local (folder_view);
3719 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3723 on_rename_folder_performer (gboolean canceled,
3725 GtkWindow *parent_window,
3726 TnyAccount *account,
3729 ModestMailOperation *mail_op = NULL;
3730 GtkTreeSelection *sel = NULL;
3731 GtkWidget *folder_view = NULL;
3732 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3734 if (canceled || err) {
3735 /* In disk full conditions we could get this error here */
3736 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3737 (GtkWidget *) parent_window, err,
3742 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3743 modest_ui_actions_rename_folder_error_handler,
3744 parent_window, NULL);
3746 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3748 #ifndef MODEST_TOOLKIT_HILDON2
3749 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3751 folder_view = modest_main_window_get_child_widget (
3752 MODEST_MAIN_WINDOW (parent_window),
3753 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3756 if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3757 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3758 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3762 /* Clear the folders view */
3763 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3764 gtk_tree_selection_unselect_all (sel);
3766 /* Actually rename the folder */
3767 modest_mail_operation_rename_folder (mail_op,
3768 TNY_FOLDER (data->folder),
3769 (const gchar *) (data->new_name),
3770 on_rename_folder_cb,
3772 g_object_unref (mail_op);
3775 g_object_unref (data->folder);
3776 g_free (data->new_name);
3781 modest_ui_actions_on_rename_folder (GtkAction *action,
3782 ModestWindow *window)
3784 modest_ui_actions_on_edit_mode_rename_folder (window);
3788 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3790 TnyFolderStore *folder;
3791 GtkWidget *folder_view;
3792 gboolean do_rename = TRUE;
3794 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3796 #ifndef MODEST_TOOLKIT_HILDON2
3797 if (MODEST_IS_MAIN_WINDOW (window)) {
3798 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3799 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3803 if (MODEST_IS_FOLDER_WINDOW (window)) {
3804 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3810 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3815 if (TNY_IS_FOLDER (folder)) {
3816 gchar *folder_name = NULL;
3818 const gchar *current_name;
3819 TnyFolderStore *parent;
3821 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3822 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3823 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
3824 parent, current_name,
3826 g_object_unref (parent);
3828 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3831 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3832 rename_folder_data->folder = g_object_ref (folder);
3833 rename_folder_data->new_name = folder_name;
3834 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
3835 folder, on_rename_folder_performer, rename_folder_data);
3838 g_object_unref (folder);
3843 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3846 GObject *win = modest_mail_operation_get_source (mail_op);
3848 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3849 _("mail_in_ui_folder_delete_error"),
3851 g_object_unref (win);
3855 TnyFolderStore *folder;
3856 gboolean move_to_trash;
3860 on_delete_folder_cb (gboolean canceled,
3862 GtkWindow *parent_window,
3863 TnyAccount *account,
3866 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3867 GtkWidget *folder_view;
3868 ModestMailOperation *mail_op;
3869 GtkTreeSelection *sel;
3871 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
3872 /* Note that the connection process can fail due to
3873 memory low conditions as it can not successfully
3874 store the summary */
3875 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3876 (GtkWidget*) parent_window, err,
3878 g_debug ("Error connecting when trying to delete a folder");
3879 g_object_unref (G_OBJECT (info->folder));
3884 #ifndef MODEST_TOOLKIT_HILDON2
3885 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
3886 folder_view = modest_main_window_get_child_widget (
3887 MODEST_MAIN_WINDOW (parent_window),
3888 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3890 if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3891 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
3894 g_object_unref (G_OBJECT (info->folder));
3899 /* Unselect the folder before deleting it to free the headers */
3900 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3901 gtk_tree_selection_unselect_all (sel);
3903 /* Create the mail operation */
3905 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3906 modest_ui_actions_delete_folder_error_handler,
3909 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3911 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3913 #ifndef MODEST_TOOLKIT_HILDON2
3914 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3917 g_object_unref (mail_op);
3918 g_object_unref (info->folder);
3923 delete_folder (ModestWindow *window, gboolean move_to_trash)
3925 TnyFolderStore *folder;
3926 GtkWidget *folder_view;
3930 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3932 #ifndef MODEST_TOOLKIT_HILDON2
3933 if (MODEST_IS_MAIN_WINDOW (window)) {
3935 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3936 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3938 if (MODEST_IS_FOLDER_WINDOW (window)) {
3939 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3947 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3952 /* Show an error if it's an account */
3953 if (!TNY_IS_FOLDER (folder)) {
3954 modest_platform_run_information_dialog (GTK_WINDOW (window),
3955 _("mail_in_ui_folder_delete_error"),
3957 g_object_unref (G_OBJECT (folder));
3962 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3963 tny_folder_get_name (TNY_FOLDER (folder)));
3964 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
3965 (const gchar *) message);
3968 if (response == GTK_RESPONSE_OK) {
3969 TnyAccount *account = NULL;
3970 DeleteFolderInfo *info = NULL;
3971 info = g_new0(DeleteFolderInfo, 1);
3972 info->folder = g_object_ref (folder);
3973 info->move_to_trash = move_to_trash;
3975 account = tny_folder_get_account (TNY_FOLDER (folder));
3976 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
3978 TNY_FOLDER_STORE (account),
3979 on_delete_folder_cb, info);
3980 g_object_unref (account);
3981 g_object_unref (folder);
3989 modest_ui_actions_on_delete_folder (GtkAction *action,
3990 ModestWindow *window)
3992 modest_ui_actions_on_edit_mode_delete_folder (window);
3996 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
3998 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
4000 return delete_folder (window, FALSE);
4003 #ifndef MODEST_TOOLKIT_HILDON2
4005 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
4007 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4009 delete_folder (MODEST_WINDOW (main_window), TRUE);
4013 typedef struct _PasswordDialogFields {
4014 GtkWidget *username;
4015 GtkWidget *password;
4017 } PasswordDialogFields;
4020 password_dialog_check_field (GtkEditable *editable,
4021 PasswordDialogFields *fields)
4024 gboolean any_value_empty = FALSE;
4026 #ifdef MODEST_TOOLKIT_HILDON2
4027 value = hildon_entry_get_text (HILDON_ENTRY (fields->username));
4029 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
4031 if ((value == NULL) || value[0] == '\0') {
4032 any_value_empty = TRUE;
4034 #ifdef MODEST_TOOLKIT_HILDON2
4035 value = hildon_entry_get_text (HILDON_ENTRY (fields->password));
4037 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
4039 if ((value == NULL) || value[0] == '\0') {
4040 any_value_empty = TRUE;
4042 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
4046 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
4047 const gchar* server_account_name,
4052 ModestMainWindow *main_window)
4054 g_return_if_fail(server_account_name);
4055 gboolean completed = FALSE;
4056 PasswordDialogFields *fields = NULL;
4058 /* Initalize output parameters: */
4065 #ifndef MODEST_TOOLKIT_GTK
4066 /* Maemo uses a different (awkward) button order,
4067 * It should probably just use gtk_alternative_dialog_button_order ().
4069 #ifdef MODEST_TOOLKIT_HILDON2
4071 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4074 _HL("wdgt_bd_done"),
4075 GTK_RESPONSE_ACCEPT,
4077 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
4078 HILDON_MARGIN_DOUBLE);
4081 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4084 _("mcen_bd_dialog_ok"),
4085 GTK_RESPONSE_ACCEPT,
4086 _("mcen_bd_dialog_cancel"),
4087 GTK_RESPONSE_REJECT,
4089 #endif /* MODEST_TOOLKIT_HILDON2 */
4092 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4096 GTK_RESPONSE_REJECT,
4098 GTK_RESPONSE_ACCEPT,
4100 #endif /* MODEST_TOOLKIT_GTK */
4102 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
4104 gchar *server_name = modest_account_mgr_get_server_account_hostname (
4105 modest_runtime_get_account_mgr(), server_account_name);
4106 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
4107 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
4110 gtk_widget_destroy (dialog);
4114 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
4115 GtkWidget *label = gtk_label_new (txt);
4116 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
4118 g_free (server_name);
4119 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
4124 gchar *initial_username = modest_account_mgr_get_server_account_username (
4125 modest_runtime_get_account_mgr(), server_account_name);
4127 #ifdef MODEST_TOOLKIT_HILDON2
4128 GtkWidget *entry_username = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4129 if (initial_username)
4130 hildon_entry_set_text (HILDON_ENTRY (entry_username), initial_username);
4132 GtkWidget *entry_username = gtk_entry_new ();
4133 if (initial_username)
4134 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
4136 /* Dim this if a connection has ever succeeded with this username,
4137 * as per the UI spec: */
4138 /* const gboolean username_known = */
4139 /* modest_account_mgr_get_server_account_username_has_succeeded( */
4140 /* modest_runtime_get_account_mgr(), server_account_name); */
4141 /* gtk_widget_set_sensitive (entry_username, !username_known); */
4143 /* We drop the username sensitive code and disallow changing it here
4144 * as tinymail does not support really changing the username in the callback
4146 gtk_widget_set_sensitive (entry_username, FALSE);
4148 #ifndef MODEST_TOOLKIT_GTK
4149 /* Auto-capitalization is the default, so let's turn it off: */
4150 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
4152 /* Create a size group to be used by all captions.
4153 * Note that HildonCaption does not create a default size group if we do not specify one.
4154 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
4155 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
4157 #ifdef MODEST_TOOLKIT_HILDON2
4158 GtkWidget *caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4159 _("mail_fi_username"), FALSE,
4162 GtkWidget *caption = hildon_caption_new (sizegroup,
4163 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
4165 gtk_widget_show (entry_username);
4166 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4167 FALSE, FALSE, MODEST_MARGIN_HALF);
4168 gtk_widget_show (caption);
4170 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
4172 #endif /* !MODEST_TOOLKIT_GTK */
4175 #ifdef MODEST_TOOLKIT_HILDON2
4176 GtkWidget *entry_password = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4178 GtkWidget *entry_password = gtk_entry_new ();
4180 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
4181 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
4183 #ifndef MODEST_TOOLKIT_GTK
4184 /* Auto-capitalization is the default, so let's turn it off: */
4185 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
4186 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
4188 #ifdef MODEST_TOOLKIT_HILDON2
4189 caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4190 _("mail_fi_password"), FALSE,
4193 caption = hildon_caption_new (sizegroup,
4194 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
4196 gtk_widget_show (entry_password);
4197 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4198 FALSE, FALSE, MODEST_MARGIN_HALF);
4199 gtk_widget_show (caption);
4200 g_object_unref (sizegroup);
4202 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
4204 #endif /* !MODEST_TOOLKIT_GTK */
4206 if (initial_username != NULL)
4207 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
4209 /* This is not in the Maemo UI spec:
4210 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
4211 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
4215 fields = g_slice_new0 (PasswordDialogFields);
4216 fields->username = entry_username;
4217 fields->password = entry_password;
4218 fields->dialog = dialog;
4220 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
4221 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
4222 password_dialog_check_field (NULL, fields);
4224 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4226 while (!completed) {
4228 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
4230 #ifdef MODEST_TOOLKIT_HILDON2
4231 *username = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_username)));
4233 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
4236 /* Note that an empty field becomes the "" string */
4237 if (*username && strlen (*username) > 0) {
4238 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
4239 server_account_name,
4243 const gboolean username_was_changed =
4244 (strcmp (*username, initial_username) != 0);
4245 if (username_was_changed) {
4246 g_warning ("%s: tinymail does not yet support changing the "
4247 "username in the get_password() callback.\n", __FUNCTION__);
4253 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
4254 _("mcen_ib_username_pw_incorrect"));
4260 #ifdef MODEST_TOOLKIT_HILDON2
4261 *password = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_password)));
4263 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
4266 /* We do not save the password in the configuration,
4267 * because this function is only called for passwords that should
4268 * not be remembered:
4269 modest_server_account_set_password (
4270 modest_runtime_get_account_mgr(), server_account_name,
4277 #ifndef MODEST_TOOLKIT_HILDON2
4278 /* Set parent to NULL or the banner will disappear with its parent dialog */
4279 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
4291 /* This is not in the Maemo UI spec:
4292 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
4298 g_free (initial_username);
4299 gtk_widget_destroy (dialog);
4300 g_slice_free (PasswordDialogFields, fields);
4302 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
4306 modest_ui_actions_on_cut (GtkAction *action,
4307 ModestWindow *window)
4309 GtkWidget *focused_widget;
4310 GtkClipboard *clipboard;
4312 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4313 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4314 if (GTK_IS_EDITABLE (focused_widget)) {
4315 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
4316 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4317 gtk_clipboard_store (clipboard);
4318 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4319 GtkTextBuffer *buffer;
4321 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4322 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4323 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
4324 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4325 gtk_clipboard_store (clipboard);
4327 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4328 TnyList *header_list = modest_header_view_get_selected_headers (
4329 MODEST_HEADER_VIEW (focused_widget));
4330 gboolean continue_download = FALSE;
4331 gint num_of_unc_msgs;
4333 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4335 if (num_of_unc_msgs) {
4336 TnyAccount *account = get_account_from_header_list (header_list);
4338 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4339 g_object_unref (account);
4343 if (num_of_unc_msgs == 0 || continue_download) {
4344 /* modest_platform_information_banner (
4345 NULL, NULL, _CS("mcen_ib_getting_items"));*/
4346 modest_header_view_cut_selection (
4347 MODEST_HEADER_VIEW (focused_widget));
4350 g_object_unref (header_list);
4351 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4352 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4357 modest_ui_actions_on_copy (GtkAction *action,
4358 ModestWindow *window)
4360 GtkClipboard *clipboard;
4361 GtkWidget *focused_widget;
4362 gboolean copied = TRUE;
4364 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4365 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4367 if (GTK_IS_LABEL (focused_widget)) {
4369 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4370 gtk_clipboard_set_text (clipboard, selection, -1);
4372 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4373 gtk_clipboard_store (clipboard);
4374 } else if (GTK_IS_EDITABLE (focused_widget)) {
4375 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4376 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4377 gtk_clipboard_store (clipboard);
4378 } else if (GTK_IS_HTML (focused_widget)) {
4381 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4382 if ((sel == NULL) || (sel[0] == '\0')) {
4385 gtk_html_copy (GTK_HTML (focused_widget));
4386 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4387 gtk_clipboard_store (clipboard);
4389 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4390 GtkTextBuffer *buffer;
4391 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4392 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4393 gtk_text_buffer_copy_clipboard (buffer, clipboard);
4394 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4395 gtk_clipboard_store (clipboard);
4397 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4398 TnyList *header_list = modest_header_view_get_selected_headers (
4399 MODEST_HEADER_VIEW (focused_widget));
4400 gboolean continue_download = FALSE;
4401 gint num_of_unc_msgs;
4403 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4405 if (num_of_unc_msgs) {
4406 TnyAccount *account = get_account_from_header_list (header_list);
4408 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4409 g_object_unref (account);
4413 if (num_of_unc_msgs == 0 || continue_download) {
4414 modest_platform_information_banner (
4415 NULL, NULL, _CS("mcen_ib_getting_items"));
4416 modest_header_view_copy_selection (
4417 MODEST_HEADER_VIEW (focused_widget));
4421 g_object_unref (header_list);
4423 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4424 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4427 /* Show information banner if there was a copy to clipboard */
4429 modest_platform_information_banner (
4430 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4434 modest_ui_actions_on_undo (GtkAction *action,
4435 ModestWindow *window)
4437 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4438 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4439 #ifndef MODEST_TOOLKIT_HILDON2
4440 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4441 ModestEmailClipboard *clipboard = NULL;
4442 /* Clear clipboard source */
4443 clipboard = modest_runtime_get_email_clipboard ();
4444 modest_email_clipboard_clear (clipboard);
4447 g_return_if_reached ();
4452 modest_ui_actions_on_redo (GtkAction *action,
4453 ModestWindow *window)
4455 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4456 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4459 g_return_if_reached ();
4465 destroy_information_note (ModestMailOperation *mail_op,
4468 /* destroy information note */
4469 gtk_widget_destroy (GTK_WIDGET(user_data));
4473 destroy_folder_information_note (ModestMailOperation *mail_op,
4474 TnyFolder *new_folder,
4477 /* destroy information note */
4478 gtk_widget_destroy (GTK_WIDGET(user_data));
4483 paste_as_attachment_free (gpointer data)
4485 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4487 if (helper->banner) {
4488 gtk_widget_destroy (helper->banner);
4489 g_object_unref (helper->banner);
4495 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4500 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4501 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4506 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4511 modest_ui_actions_on_paste (GtkAction *action,
4512 ModestWindow *window)
4514 GtkWidget *focused_widget = NULL;
4515 GtkWidget *inf_note = NULL;
4516 ModestMailOperation *mail_op = NULL;
4518 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4519 if (GTK_IS_EDITABLE (focused_widget)) {
4520 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4521 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4522 ModestEmailClipboard *e_clipboard = NULL;
4523 e_clipboard = modest_runtime_get_email_clipboard ();
4524 if (modest_email_clipboard_cleared (e_clipboard)) {
4525 GtkTextBuffer *buffer;
4526 GtkClipboard *clipboard;
4528 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4529 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4530 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4531 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4532 ModestMailOperation *mail_op;
4533 TnyFolder *src_folder = NULL;
4534 TnyList *data = NULL;
4536 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4537 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4538 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4539 _CS("ckct_nw_pasting"));
4540 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4541 mail_op = modest_mail_operation_new (G_OBJECT (window));
4542 if (helper->banner != NULL) {
4543 g_object_ref (G_OBJECT (helper->banner));
4544 gtk_widget_show (GTK_WIDGET (helper->banner));
4548 modest_mail_operation_get_msgs_full (mail_op,
4550 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4552 paste_as_attachment_free);
4556 g_object_unref (data);
4558 g_object_unref (src_folder);
4561 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4562 ModestEmailClipboard *clipboard = NULL;
4563 TnyFolder *src_folder = NULL;
4564 TnyFolderStore *folder_store = NULL;
4565 TnyList *data = NULL;
4566 gboolean delete = FALSE;
4568 /* Check clipboard source */
4569 clipboard = modest_runtime_get_email_clipboard ();
4570 if (modest_email_clipboard_cleared (clipboard))
4573 /* Get elements to paste */
4574 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4576 /* Create a new mail operation */
4577 mail_op = modest_mail_operation_new (G_OBJECT(window));
4579 /* Get destination folder */
4580 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4582 /* transfer messages */
4586 /* Ask for user confirmation */
4588 modest_ui_actions_msgs_move_to_confirmation (window,
4589 TNY_FOLDER (folder_store),
4593 if (response == GTK_RESPONSE_OK) {
4594 /* Launch notification */
4595 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4596 _CS("ckct_nw_pasting"));
4597 if (inf_note != NULL) {
4598 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4599 gtk_widget_show (GTK_WIDGET(inf_note));
4602 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4603 modest_mail_operation_xfer_msgs (mail_op,
4605 TNY_FOLDER (folder_store),
4607 destroy_information_note,
4610 g_object_unref (mail_op);
4613 } else if (src_folder != NULL) {
4614 /* Launch notification */
4615 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4616 _CS("ckct_nw_pasting"));
4617 if (inf_note != NULL) {
4618 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4619 gtk_widget_show (GTK_WIDGET(inf_note));
4622 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4623 modest_mail_operation_xfer_folder (mail_op,
4627 destroy_folder_information_note,
4633 g_object_unref (data);
4634 if (src_folder != NULL)
4635 g_object_unref (src_folder);
4636 if (folder_store != NULL)
4637 g_object_unref (folder_store);
4643 modest_ui_actions_on_select_all (GtkAction *action,
4644 ModestWindow *window)
4646 GtkWidget *focused_widget;
4648 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4649 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4650 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4651 } else if (GTK_IS_LABEL (focused_widget)) {
4652 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4653 } else if (GTK_IS_EDITABLE (focused_widget)) {
4654 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4655 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4656 GtkTextBuffer *buffer;
4657 GtkTextIter start, end;
4659 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4660 gtk_text_buffer_get_start_iter (buffer, &start);
4661 gtk_text_buffer_get_end_iter (buffer, &end);
4662 gtk_text_buffer_select_range (buffer, &start, &end);
4663 } else if (GTK_IS_HTML (focused_widget)) {
4664 gtk_html_select_all (GTK_HTML (focused_widget));
4665 #ifndef MODEST_TOOLKIT_HILDON2
4666 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4667 GtkWidget *header_view = focused_widget;
4668 GtkTreeSelection *selection = NULL;
4670 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4671 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4672 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4675 /* Disable window dimming management */
4676 modest_window_disable_dimming (MODEST_WINDOW(window));
4678 /* Select all messages */
4679 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4680 gtk_tree_selection_select_all (selection);
4682 /* Set focuse on header view */
4683 gtk_widget_grab_focus (header_view);
4685 /* Enable window dimming management */
4686 modest_window_enable_dimming (MODEST_WINDOW(window));
4687 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4688 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4695 modest_ui_actions_on_mark_as_read (GtkAction *action,
4696 ModestWindow *window)
4698 g_return_if_fail (MODEST_IS_WINDOW(window));
4700 /* Mark each header as read */
4701 do_headers_action (window, headers_action_mark_as_read, NULL);
4705 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4706 ModestWindow *window)
4708 g_return_if_fail (MODEST_IS_WINDOW(window));
4710 /* Mark each header as read */
4711 do_headers_action (window, headers_action_mark_as_unread, NULL);
4715 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4716 GtkRadioAction *selected,
4717 ModestWindow *window)
4721 value = gtk_radio_action_get_current_value (selected);
4722 if (MODEST_IS_WINDOW (window)) {
4723 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4728 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4729 GtkRadioAction *selected,
4730 ModestWindow *window)
4732 TnyHeaderFlags flags;
4733 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4735 flags = gtk_radio_action_get_current_value (selected);
4736 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4740 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4741 GtkRadioAction *selected,
4742 ModestWindow *window)
4746 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4748 file_format = gtk_radio_action_get_current_value (selected);
4749 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4754 modest_ui_actions_on_zoom_plus (GtkAction *action,
4755 ModestWindow *window)
4757 g_return_if_fail (MODEST_IS_WINDOW (window));
4759 modest_window_zoom_plus (MODEST_WINDOW (window));
4763 modest_ui_actions_on_zoom_minus (GtkAction *action,
4764 ModestWindow *window)
4766 g_return_if_fail (MODEST_IS_WINDOW (window));
4768 modest_window_zoom_minus (MODEST_WINDOW (window));
4772 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4773 ModestWindow *window)
4775 ModestWindowMgr *mgr;
4776 gboolean fullscreen, active;
4777 g_return_if_fail (MODEST_IS_WINDOW (window));
4779 mgr = modest_runtime_get_window_mgr ();
4781 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4782 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4784 if (active != fullscreen) {
4785 modest_window_mgr_set_fullscreen_mode (mgr, active);
4786 #ifndef MODEST_TOOLKIT_HILDON2
4787 gtk_window_present (GTK_WINDOW (window));
4793 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4794 ModestWindow *window)
4796 ModestWindowMgr *mgr;
4797 gboolean fullscreen;
4799 g_return_if_fail (MODEST_IS_WINDOW (window));
4801 mgr = modest_runtime_get_window_mgr ();
4802 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4803 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4805 #ifndef MODEST_TOOLKIT_HILDON2
4806 gtk_window_present (GTK_WINDOW (window));
4811 * Used by modest_ui_actions_on_details to call do_headers_action
4814 headers_action_show_details (TnyHeader *header,
4815 ModestWindow *window,
4819 gboolean async_retrieval;
4822 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4823 async_retrieval = TRUE;
4824 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
4826 async_retrieval = FALSE;
4828 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header, async_retrieval, msg);
4830 g_object_unref (msg);
4834 * Show the header details in a ModestDetailsDialog widget
4837 modest_ui_actions_on_details (GtkAction *action,
4840 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4844 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4848 header = tny_msg_get_header (msg);
4850 headers_action_show_details (header, win, NULL);
4851 g_object_unref (header);
4853 g_object_unref (msg);
4854 #ifndef MODEST_TOOLKIT_HILDON2
4855 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4856 GtkWidget *folder_view, *header_view;
4858 /* Check which widget has the focus */
4859 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4860 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4861 if (gtk_widget_is_focus (folder_view)) {
4862 TnyFolderStore *folder_store
4863 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4864 if (!folder_store) {
4865 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4868 /* Show only when it's a folder */
4869 /* This function should not be called for account items,
4870 * because we dim the menu item for them. */
4871 if (TNY_IS_FOLDER (folder_store)) {
4872 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4873 TNY_FOLDER (folder_store));
4876 g_object_unref (folder_store);
4879 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4880 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4881 /* Show details of each header */
4882 do_headers_action (win, headers_action_show_details, header_view);
4885 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4887 GtkWidget *header_view;
4889 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4890 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4892 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4894 g_object_unref (folder);
4901 modest_ui_actions_on_limit_error (GtkAction *action,
4904 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
4906 modest_platform_information_banner ((GtkWidget *) win, NULL, _CS("ckdg_ib_maximum_characters_reached"));
4911 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4912 ModestMsgEditWindow *window)
4914 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4916 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4920 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4921 ModestMsgEditWindow *window)
4923 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4925 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4928 #ifndef MODEST_TOOLKIT_HILDON2
4930 modest_ui_actions_toggle_folders_view (GtkAction *action,
4931 ModestMainWindow *main_window)
4933 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4935 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4936 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4938 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4943 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4944 ModestWindow *window)
4946 gboolean active, fullscreen = FALSE;
4947 ModestWindowMgr *mgr;
4949 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4951 /* Check if we want to toggle the toolbar view in fullscreen
4953 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4954 "ViewShowToolbarFullScreen")) {
4958 /* Toggle toolbar */
4959 mgr = modest_runtime_get_window_mgr ();
4960 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4964 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4965 ModestMsgEditWindow *window)
4967 modest_msg_edit_window_select_font (window);
4972 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4973 const gchar *display_name,
4976 /* don't update the display name if it was already set;
4977 * updating the display name apparently is expensive */
4978 const gchar* old_name = gtk_window_get_title (window);
4980 if (display_name == NULL)
4983 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4984 return; /* don't do anything */
4986 /* This is usually used to change the title of the main window, which
4987 * is the one that holds the folder view. Note that this change can
4988 * happen even when the widget doesn't have the focus. */
4989 gtk_window_set_title (window, display_name);
4994 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4996 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4997 modest_msg_edit_window_select_contacts (window);
5001 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
5003 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5004 modest_msg_edit_window_check_names (window, FALSE);
5007 #ifndef MODEST_TOOLKIT_HILDON2
5009 * This function is used to track changes in the selection of the
5010 * folder view that is inside the "move to" dialog to enable/disable
5011 * the OK button because we do not want the user to select a disallowed
5012 * destination for a folder.
5013 * The user also not desired to be able to use NEW button on items where
5014 * folder creation is not possibel.
5017 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
5018 TnyFolderStore *folder_store,
5022 GtkWidget *dialog = NULL;
5023 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
5024 gboolean moving_folder = FALSE;
5025 gboolean is_local_account = TRUE;
5026 GtkWidget *folder_view = NULL;
5027 ModestTnyFolderRules rules;
5029 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
5034 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
5038 /* check if folder_store is an remote account */
5039 if (TNY_IS_ACCOUNT (folder_store)) {
5040 TnyAccount *local_account = NULL;
5041 TnyAccount *mmc_account = NULL;
5042 ModestTnyAccountStore *account_store = NULL;
5044 account_store = modest_runtime_get_account_store ();
5045 local_account = modest_tny_account_store_get_local_folders_account (account_store);
5046 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
5048 if ((gpointer) local_account != (gpointer) folder_store &&
5049 (gpointer) mmc_account != (gpointer) folder_store) {
5050 ModestProtocolType proto;
5051 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
5052 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
5053 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
5055 is_local_account = FALSE;
5056 /* New button should be dimmed on remote
5058 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5060 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
5062 g_object_unref (local_account);
5064 /* It could not exist */
5066 g_object_unref (mmc_account);
5069 /* Check the target folder rules */
5070 if (TNY_IS_FOLDER (folder_store)) {
5071 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
5072 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
5073 ok_sensitive = FALSE;
5074 new_sensitive = FALSE;
5079 /* Check if we're moving a folder */
5080 if (MODEST_IS_MAIN_WINDOW (user_data)) {
5081 /* Get the widgets */
5082 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
5083 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5084 if (gtk_widget_is_focus (folder_view))
5085 moving_folder = TRUE;
5088 if (moving_folder) {
5089 TnyFolderStore *moved_folder = NULL, *parent = NULL;
5091 /* Get the folder to move */
5092 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5094 /* Check that we're not moving to the same folder */
5095 if (TNY_IS_FOLDER (moved_folder)) {
5096 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
5097 if (parent == folder_store)
5098 ok_sensitive = FALSE;
5099 g_object_unref (parent);
5102 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
5103 /* Do not allow to move to an account unless it's the
5104 local folders account */
5105 if (!is_local_account)
5106 ok_sensitive = FALSE;
5109 if (ok_sensitive && (moved_folder == folder_store)) {
5110 /* Do not allow to move to itself */
5111 ok_sensitive = FALSE;
5113 g_object_unref (moved_folder);
5115 TnyFolder *src_folder = NULL;
5117 /* Moving a message */
5118 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
5120 TnyHeader *header = NULL;
5121 header = modest_msg_view_window_get_header
5122 (MODEST_MSG_VIEW_WINDOW (user_data));
5123 if (!TNY_IS_HEADER(header))
5124 g_warning ("%s: could not get source header", __FUNCTION__);
5126 src_folder = tny_header_get_folder (header);
5129 g_object_unref (header);
5132 TNY_FOLDER (modest_folder_view_get_selected
5133 (MODEST_FOLDER_VIEW (folder_view)));
5136 if (TNY_IS_FOLDER(src_folder)) {
5137 /* Do not allow to move the msg to the same folder */
5138 /* Do not allow to move the msg to an account */
5139 if ((gpointer) src_folder == (gpointer) folder_store ||
5140 TNY_IS_ACCOUNT (folder_store))
5141 ok_sensitive = FALSE;
5142 g_object_unref (src_folder);
5144 g_warning ("%s: could not get source folder", __FUNCTION__);
5148 /* Set sensitivity of the OK and NEW button */
5149 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
5150 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
5155 on_move_to_dialog_response (GtkDialog *dialog,
5159 GtkWidget *parent_win;
5160 MoveToInfo *helper = NULL;
5161 ModestFolderView *folder_view;
5162 gboolean unset_edit_mode = FALSE;
5164 helper = (MoveToInfo *) user_data;
5166 parent_win = (GtkWidget *) helper->win;
5167 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
5168 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
5170 TnyFolderStore *dst_folder;
5171 TnyFolderStore *selected;
5173 case MODEST_GTK_RESPONSE_NEW_FOLDER:
5174 selected = modest_folder_view_get_selected (folder_view);
5175 modest_ui_actions_create_folder (GTK_WIDGET (dialog), GTK_WIDGET (folder_view), selected);
5176 g_object_unref (selected);
5178 case GTK_RESPONSE_NONE:
5179 case GTK_RESPONSE_CANCEL:
5180 case GTK_RESPONSE_DELETE_EVENT:
5182 case GTK_RESPONSE_OK:
5183 dst_folder = modest_folder_view_get_selected (folder_view);
5185 #ifndef MODEST_TOOLKIT_HILDON2
5186 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
5187 /* Clean list to move used for filtering */
5188 modest_folder_view_set_list_to_move (folder_view, NULL);
5190 modest_ui_actions_on_main_window_move_to (NULL,
5191 GTK_WIDGET (folder_view),
5193 MODEST_MAIN_WINDOW (parent_win));
5195 if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
5196 /* Clean list to move used for filtering */
5197 modest_folder_view_set_list_to_move (folder_view, NULL);
5199 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
5202 GTK_WINDOW (parent_win));
5205 /* if the user selected a root folder
5206 (account) then do not perform any action */
5207 if (TNY_IS_ACCOUNT (dst_folder)) {
5208 g_signal_stop_emission_by_name (dialog, "response");
5212 /* Clean list to move used for filtering */
5213 modest_folder_view_set_list_to_move (folder_view, NULL);
5215 /* Moving from headers window in edit mode */
5216 modest_ui_actions_on_window_move_to (NULL, helper->list,
5218 MODEST_WINDOW (parent_win));
5222 g_object_unref (dst_folder);
5224 unset_edit_mode = TRUE;
5227 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
5230 /* Free the helper and exit */
5232 g_object_unref (helper->list);
5233 if (unset_edit_mode) {
5234 #ifdef MODEST_TOOLKIT_HILDON2
5235 modest_hildon2_window_unset_edit_mode (MODEST_HILDON2_WINDOW (helper->win));
5238 g_slice_free (MoveToInfo, helper);
5239 gtk_widget_destroy (GTK_WIDGET (dialog));
5243 create_move_to_dialog (GtkWindow *win,
5244 GtkWidget *folder_view,
5245 TnyList *list_to_move)
5247 GtkWidget *dialog, *tree_view = NULL;
5249 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
5251 #ifndef MODEST_TOOLKIT_HILDON2
5252 /* Track changes in the selection to
5253 * disable the OK button whenever "Move to" is not possible
5254 * disbale NEW button whenever New is not possible */
5255 g_signal_connect (tree_view,
5256 "folder_selection_changed",
5257 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
5261 /* It could happen that we're trying to move a message from a
5262 window (msg window for example) after the main window was
5263 closed, so we can not just get the model of the folder
5265 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
5266 const gchar *visible_id = NULL;
5268 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5269 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5270 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
5271 MODEST_FOLDER_VIEW(tree_view));
5274 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
5276 /* Show the same account than the one that is shown in the main window */
5277 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
5280 const gchar *active_account_name = NULL;
5281 ModestAccountMgr *mgr = NULL;
5282 ModestAccountSettings *settings = NULL;
5283 ModestServerAccountSettings *store_settings = NULL;
5285 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5286 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5287 /* modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view), */
5288 /* TNY_ACCOUNT_STORE (modest_runtime_get_account_store ())); */
5290 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
5291 mgr = modest_runtime_get_account_mgr ();
5292 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
5295 const gchar *store_account_name;
5296 store_settings = modest_account_settings_get_store_settings (settings);
5297 store_account_name = modest_server_account_settings_get_account_name (store_settings);
5299 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
5300 store_account_name);
5301 g_object_unref (store_settings);
5302 g_object_unref (settings);
5306 /* we keep a pointer to the embedded folder view, so we can
5307 * retrieve it with get_folder_view_from_move_to_dialog (see
5308 * above) later (needed for focus handling)
5310 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
5312 /* Hide special folders */
5313 #ifndef MODEST_TOOLKIT_HILDON2
5314 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
5317 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
5318 #ifndef MODEST_TOOLKIT_HILDON2
5319 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5322 gtk_widget_show (GTK_WIDGET (tree_view));
5328 * Shows a confirmation dialog to the user when we're moving messages
5329 * from a remote server to the local storage. Returns the dialog
5330 * response. If it's other kind of movement then it always returns
5333 * This one is used by the next functions:
5334 * modest_ui_actions_on_paste - commented out
5335 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
5338 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
5339 TnyFolder *dest_folder,
5343 gint response = GTK_RESPONSE_OK;
5344 TnyAccount *account = NULL;
5345 TnyFolder *src_folder = NULL;
5346 TnyIterator *iter = NULL;
5347 TnyHeader *header = NULL;
5349 /* return with OK if the destination is a remote folder */
5350 if (modest_tny_folder_is_remote_folder (dest_folder))
5351 return GTK_RESPONSE_OK;
5353 /* Get source folder */
5354 iter = tny_list_create_iterator (headers);
5355 header = TNY_HEADER (tny_iterator_get_current (iter));
5357 src_folder = tny_header_get_folder (header);
5358 g_object_unref (header);
5360 g_object_unref (iter);
5362 /* if no src_folder, message may be an attahcment */
5363 if (src_folder == NULL)
5364 return GTK_RESPONSE_CANCEL;
5366 /* If the source is a local or MMC folder */
5367 if (!modest_tny_folder_is_remote_folder (src_folder)) {
5368 g_object_unref (src_folder);
5369 return GTK_RESPONSE_OK;
5372 /* Get the account */
5373 account = tny_folder_get_account (src_folder);
5375 /* now if offline we ask the user */
5376 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
5377 response = GTK_RESPONSE_OK;
5379 response = GTK_RESPONSE_CANCEL;
5382 g_object_unref (src_folder);
5383 g_object_unref (account);
5389 move_to_helper_destroyer (gpointer user_data)
5391 MoveToHelper *helper = (MoveToHelper *) user_data;
5393 /* Close the "Pasting" information banner */
5394 if (helper->banner) {
5395 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5396 g_object_unref (helper->banner);
5398 if (gtk_tree_row_reference_valid (helper->reference)) {
5399 gtk_tree_row_reference_free (helper->reference);
5400 helper->reference = NULL;
5406 move_to_cb (ModestMailOperation *mail_op,
5409 MoveToHelper *helper = (MoveToHelper *) user_data;
5410 GObject *object = modest_mail_operation_get_source (mail_op);
5412 /* Note that the operation could have failed, in that case do
5414 if (modest_mail_operation_get_status (mail_op) !=
5415 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5418 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5419 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5421 if (!modest_msg_view_window_select_next_message (self) &&
5422 !modest_msg_view_window_select_previous_message (self)) {
5423 /* No more messages to view, so close this window */
5424 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5426 #ifndef MODEST_TOOLKIT_HILDON2
5427 } else if (MODEST_IS_MAIN_WINDOW (object) &&
5428 gtk_tree_row_reference_valid (helper->reference)) {
5429 GtkWidget *header_view;
5431 GtkTreeSelection *sel;
5433 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5434 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5435 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5436 path = gtk_tree_row_reference_get_path (helper->reference);
5437 /* We need to unselect the previous one
5438 because we could be copying instead of
5440 gtk_tree_selection_unselect_all (sel);
5441 gtk_tree_selection_select_path (sel, path);
5442 gtk_tree_path_free (path);
5445 g_object_unref (object);
5448 /* Destroy the helper */
5449 move_to_helper_destroyer (helper);
5453 folder_move_to_cb (ModestMailOperation *mail_op,
5454 TnyFolder *new_folder,
5459 object = modest_mail_operation_get_source (mail_op);
5460 #ifndef MODEST_TOOLKIT_HILDON2
5461 if (MODEST_IS_MAIN_WINDOW (object)) {
5462 GtkWidget *folder_view;
5463 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5464 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5465 g_object_ref (folder_view);
5466 g_object_unref (object);
5467 move_to_cb (mail_op, user_data);
5468 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5469 g_object_unref (folder_view);
5474 move_to_cb (mail_op, user_data);
5479 msgs_move_to_cb (ModestMailOperation *mail_op,
5482 move_to_cb (mail_op, user_data);
5486 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5489 GObject *win = NULL;
5490 const GError *error;
5491 TnyAccount *account = NULL;
5493 #ifndef MODEST_TOOLKIT_HILDON2
5494 ModestWindow *main_window = NULL;
5496 /* Disable next automatic folder selection */
5497 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5498 FALSE); /* don't create */
5500 /* Show notification dialog only if the main window exists */
5502 GtkWidget *folder_view = NULL;
5504 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5505 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5506 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5508 if (user_data && TNY_IS_FOLDER (user_data)) {
5509 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5510 TNY_FOLDER (user_data), FALSE);
5514 win = modest_mail_operation_get_source (mail_op);
5515 error = modest_mail_operation_get_error (mail_op);
5517 if (TNY_IS_FOLDER (user_data))
5518 account = modest_tny_folder_get_account (TNY_FOLDER (user_data));
5519 else if (TNY_IS_ACCOUNT (user_data))
5520 account = g_object_ref (user_data);
5522 /* If it's not a disk full error then show a generic error */
5523 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5524 (GtkWidget *) win, (GError *) error,
5526 modest_platform_run_information_dialog ((GtkWindow *) win,
5527 _("mail_in_ui_folder_move_target_error"),
5530 g_object_unref (account);
5532 g_object_unref (win);
5535 #ifndef MODEST_TOOLKIT_HILDON2
5537 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5546 gint pending_purges = 0;
5547 gboolean some_purged = FALSE;
5548 ModestWindow *win = MODEST_WINDOW (user_data);
5549 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5551 /* If there was any error */
5552 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5553 modest_window_mgr_unregister_header (mgr, header);
5557 /* Once the message has been retrieved for purging, we check if
5558 * it's all ok for purging */
5560 parts = tny_simple_list_new ();
5561 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5562 iter = tny_list_create_iterator (parts);
5564 while (!tny_iterator_is_done (iter)) {
5566 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5567 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5568 if (tny_mime_part_is_purged (part))
5575 g_object_unref (part);
5577 tny_iterator_next (iter);
5579 g_object_unref (iter);
5582 if (pending_purges>0) {
5584 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5586 if (response == GTK_RESPONSE_OK) {
5589 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5590 iter = tny_list_create_iterator (parts);
5591 while (!tny_iterator_is_done (iter)) {
5594 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5595 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5596 tny_mime_part_set_purged (part);
5599 g_object_unref (part);
5601 tny_iterator_next (iter);
5603 g_object_unref (iter);
5605 tny_msg_rewrite_cache (msg);
5607 gtk_widget_destroy (info);
5611 modest_window_mgr_unregister_header (mgr, header);
5613 g_object_unref (parts);
5617 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5618 ModestMainWindow *win)
5620 GtkWidget *header_view;
5621 TnyList *header_list;
5623 TnyHeaderFlags flags;
5624 ModestWindow *msg_view_window = NULL;
5627 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5629 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5630 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5632 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5634 g_warning ("%s: no header selected", __FUNCTION__);
5638 if (tny_list_get_length (header_list) == 1) {
5639 TnyIterator *iter = tny_list_create_iterator (header_list);
5640 header = TNY_HEADER (tny_iterator_get_current (iter));
5641 g_object_unref (iter);
5645 if (!header || !TNY_IS_HEADER(header)) {
5646 g_warning ("%s: header is not valid", __FUNCTION__);
5650 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5651 header, &msg_view_window);
5652 flags = tny_header_get_flags (header);
5653 if (!(flags & TNY_HEADER_FLAG_CACHED))
5656 if (msg_view_window != NULL)
5657 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5659 /* do nothing; uid was registered before, so window is probably on it's way */
5660 g_debug ("header %p has already been registered", header);
5663 ModestMailOperation *mail_op = NULL;
5664 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5665 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5666 modest_ui_actions_disk_operations_error_handler,
5668 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5669 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5671 g_object_unref (mail_op);
5674 g_object_unref (header);
5676 g_object_unref (header_list);
5681 * Checks if we need a connection to do the transfer and if the user
5682 * wants to connect to complete it
5685 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5686 TnyFolderStore *src_folder,
5688 TnyFolder *dst_folder,
5689 gboolean delete_originals,
5690 gboolean *need_connection,
5693 TnyAccount *src_account;
5694 gint uncached_msgs = 0;
5696 /* We don't need any further check if
5698 * 1- the source folder is local OR
5699 * 2- the device is already online
5701 if (!modest_tny_folder_store_is_remote (src_folder) ||
5702 tny_device_is_online (modest_runtime_get_device())) {
5703 *need_connection = FALSE;
5708 /* We must ask for a connection when
5710 * - the message(s) is not already cached OR
5711 * - the message(s) is cached but the leave_on_server setting
5712 * is FALSE (because we need to sync the source folder to
5713 * delete the message from the server (for IMAP we could do it
5714 * offline, it'll take place the next time we get a
5717 uncached_msgs = header_list_count_uncached_msgs (headers);
5718 src_account = get_account_from_folder_store (src_folder);
5719 if (uncached_msgs > 0) {
5723 *need_connection = TRUE;
5724 num_headers = tny_list_get_length (headers);
5725 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5727 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5728 GTK_RESPONSE_CANCEL) {
5734 /* The transfer is possible and the user wants to */
5737 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5738 const gchar *account_name;
5739 gboolean leave_on_server;
5741 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5742 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5745 if (leave_on_server == TRUE) {
5746 *need_connection = FALSE;
5748 *need_connection = TRUE;
5751 *need_connection = FALSE;
5756 g_object_unref (src_account);
5760 xfer_messages_error_handler (ModestMailOperation *mail_op,
5764 const GError *error;
5765 TnyAccount *account;
5767 win = modest_mail_operation_get_source (mail_op);
5768 error = modest_mail_operation_get_error (mail_op);
5770 /* We cannot get the account from the mail op as that is the
5771 source account and for checking memory full conditions we
5772 need the destination one */
5773 account = TNY_ACCOUNT (user_data);
5776 !modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5777 (GtkWidget *) win, (GError*) error,
5778 account, _KR("cerm_memory_card_full"))) {
5779 modest_platform_run_information_dialog ((GtkWindow *) win,
5780 _("mail_in_ui_folder_move_target_error"),
5784 g_object_unref (win);
5788 TnyFolderStore *dst_folder;
5793 * Utility function that transfer messages from both the main window
5794 * and the msg view window when using the "Move to" dialog
5797 xfer_messages_performer (gboolean canceled,
5799 GtkWindow *parent_window,
5800 TnyAccount *account,
5803 ModestWindow *win = MODEST_WINDOW (parent_window);
5804 TnyAccount *dst_account = NULL;
5805 gboolean dst_forbids_message_add = FALSE;
5806 XferMsgsHelper *helper;
5807 MoveToHelper *movehelper;
5808 ModestMailOperation *mail_op;
5810 helper = (XferMsgsHelper *) user_data;
5812 if (canceled || err) {
5813 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5814 (GtkWidget *) parent_window, err,
5816 /* Show the proper error message */
5817 modest_ui_actions_on_account_connection_error (parent_window, account);
5822 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5824 /* tinymail will return NULL for local folders it seems */
5825 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5826 modest_tny_account_get_protocol_type (dst_account),
5827 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
5829 if (dst_forbids_message_add) {
5830 modest_platform_information_banner (GTK_WIDGET (win),
5832 ngettext("mail_in_ui_folder_move_target_error",
5833 "mail_in_ui_folder_move_targets_error",
5834 tny_list_get_length (helper->headers)));
5838 movehelper = g_new0 (MoveToHelper, 1);
5840 #ifndef MODEST_TOOLKIT_HILDON2
5841 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5842 _CS("ckct_nw_pasting"));
5843 if (movehelper->banner != NULL) {
5844 g_object_ref (movehelper->banner);
5845 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5848 if (MODEST_IS_MAIN_WINDOW (win)) {
5849 GtkWidget *header_view =
5850 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5851 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5852 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5856 /* Perform the mail operation */
5857 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5858 xfer_messages_error_handler,
5859 g_object_ref (dst_account),
5861 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5864 modest_mail_operation_xfer_msgs (mail_op,
5866 TNY_FOLDER (helper->dst_folder),
5871 g_object_unref (G_OBJECT (mail_op));
5874 g_object_unref (dst_account);
5875 g_object_unref (helper->dst_folder);
5876 g_object_unref (helper->headers);
5877 g_slice_free (XferMsgsHelper, helper);
5881 TnyFolder *src_folder;
5882 TnyFolderStore *dst_folder;
5883 gboolean delete_original;
5884 GtkWidget *folder_view;
5888 on_move_folder_cb (gboolean canceled,
5890 GtkWindow *parent_window,
5891 TnyAccount *account,
5894 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5895 GtkTreeSelection *sel;
5896 ModestMailOperation *mail_op = NULL;
5898 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
5899 /* Note that the connection process can fail due to
5900 memory low conditions as it can not successfully
5901 store the summary */
5902 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5903 (GtkWidget*) parent_window, err,
5905 g_debug ("Error connecting when trying to move a folder");
5907 g_object_unref (G_OBJECT (info->src_folder));
5908 g_object_unref (G_OBJECT (info->dst_folder));
5913 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5914 #ifndef MODEST_TOOLKIT_HILDON2
5915 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5916 _CS("ckct_nw_pasting"));
5917 if (helper->banner != NULL) {
5918 g_object_ref (helper->banner);
5919 gtk_widget_show (GTK_WIDGET(helper->banner));
5922 /* Clean folder on header view before moving it */
5923 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5924 gtk_tree_selection_unselect_all (sel);
5926 /* Let gtk events run. We need that the folder
5927 view frees its reference to the source
5928 folder *before* issuing the mail operation
5929 so we need the signal handler of selection
5930 changed to happen before the mail
5932 while (gtk_events_pending ())
5933 gtk_main_iteration (); */
5936 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5937 modest_ui_actions_move_folder_error_handler,
5938 g_object_ref (info->dst_folder), g_object_unref);
5939 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5942 #ifndef MODEST_TOOLKIT_HILDON2
5943 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
5944 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5945 TNY_FOLDER (info->dst_folder), TRUE);
5948 modest_mail_operation_xfer_folder (mail_op,
5949 TNY_FOLDER (info->src_folder),
5951 info->delete_original,
5954 g_object_unref (G_OBJECT (info->src_folder));
5956 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5959 /* Unref mail operation */
5960 g_object_unref (G_OBJECT (mail_op));
5961 g_object_unref (G_OBJECT (info->dst_folder));
5966 get_account_from_folder_store (TnyFolderStore *folder_store)
5968 if (TNY_IS_ACCOUNT (folder_store))
5969 return g_object_ref (folder_store);
5971 return tny_folder_get_account (TNY_FOLDER (folder_store));
5974 #ifndef MODEST_TOOLKIT_HILDON2
5976 * UI handler for the "Move to" action when invoked from the
5980 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5981 GtkWidget *folder_view,
5982 TnyFolderStore *dst_folder,
5983 ModestMainWindow *win)
5985 ModestHeaderView *header_view = NULL;
5986 TnyFolderStore *src_folder = NULL;
5988 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5990 /* Get the source folder */
5991 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5993 /* Get header view */
5994 header_view = (ModestHeaderView *)
5995 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5997 /* Get folder or messages to transfer */
5998 if (gtk_widget_is_focus (folder_view)) {
5999 gboolean do_xfer = TRUE;
6001 /* Allow only to transfer folders to the local root folder */
6002 if (TNY_IS_ACCOUNT (dst_folder) &&
6003 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
6004 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
6006 } else if (!TNY_IS_FOLDER (src_folder)) {
6007 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
6012 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
6013 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6015 info->src_folder = g_object_ref (src_folder);
6016 info->dst_folder = g_object_ref (dst_folder);
6017 info->delete_original = TRUE;
6018 info->folder_view = folder_view;
6020 connect_info->callback = on_move_folder_cb;
6021 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6022 connect_info->data = info;
6024 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6025 TNY_FOLDER_STORE (src_folder),
6028 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
6031 headers = modest_header_view_get_selected_headers(header_view);
6033 /* Transfer the messages */
6034 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
6035 headers, TNY_FOLDER (dst_folder));
6037 g_object_unref (headers);
6041 g_object_unref (src_folder);
6045 #ifdef MODEST_TOOLKIT_HILDON2
6047 * UI handler for the "Move to" action when invoked from the
6048 * ModestFolderWindow
6051 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
6052 TnyFolderStore *dst_folder,
6056 TnyFolderStore *src_folder = NULL;
6057 TnyIterator *iterator;
6059 if (tny_list_get_length (selection) != 1)
6062 iterator = tny_list_create_iterator (selection);
6063 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
6064 g_object_unref (iterator);
6067 gboolean do_xfer = TRUE;
6069 /* Allow only to transfer folders to the local root folder */
6070 if (TNY_IS_ACCOUNT (dst_folder) &&
6071 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
6072 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
6075 modest_platform_run_information_dialog (win,
6076 _("mail_in_ui_folder_move_target_error"),
6078 } else if (!TNY_IS_FOLDER (src_folder)) {
6079 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
6084 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
6085 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6087 info->src_folder = g_object_ref (src_folder);
6088 info->dst_folder = g_object_ref (dst_folder);
6089 info->delete_original = TRUE;
6090 info->folder_view = folder_view;
6092 connect_info->callback = on_move_folder_cb;
6093 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6094 connect_info->data = info;
6096 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6097 TNY_FOLDER_STORE (src_folder),
6102 g_object_unref (src_folder);
6108 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
6109 TnyFolder *src_folder,
6111 TnyFolder *dst_folder)
6113 gboolean need_connection = TRUE;
6114 gboolean do_xfer = TRUE;
6115 XferMsgsHelper *helper;
6117 g_return_if_fail (TNY_IS_FOLDER (src_folder));
6118 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6119 g_return_if_fail (TNY_IS_LIST (headers));
6121 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
6122 headers, TNY_FOLDER (dst_folder),
6123 TRUE, &need_connection,
6126 /* If we don't want to transfer just return */
6130 /* Create the helper */
6131 helper = g_slice_new (XferMsgsHelper);
6132 helper->dst_folder = g_object_ref (dst_folder);
6133 helper->headers = g_object_ref (headers);
6135 if (need_connection) {
6136 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6137 connect_info->callback = xfer_messages_performer;
6138 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
6139 connect_info->data = helper;
6141 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6142 TNY_FOLDER_STORE (src_folder),
6145 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
6146 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
6147 src_account, helper);
6148 g_object_unref (src_account);
6153 * UI handler for the "Move to" action when invoked from the
6154 * ModestMsgViewWindow
6157 modest_ui_actions_on_window_move_to (GtkAction *action,
6159 TnyFolderStore *dst_folder,
6162 TnyFolder *src_folder = NULL;
6164 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6167 TnyHeader *header = NULL;
6170 iter = tny_list_create_iterator (headers);
6171 header = (TnyHeader *) tny_iterator_get_current (iter);
6172 src_folder = tny_header_get_folder (header);
6174 /* Transfer the messages */
6175 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
6177 TNY_FOLDER (dst_folder));
6180 g_object_unref (header);
6181 g_object_unref (iter);
6182 g_object_unref (src_folder);
6187 modest_ui_actions_on_move_to (GtkAction *action,
6190 modest_ui_actions_on_edit_mode_move_to (win);
6194 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
6196 GtkWidget *dialog = NULL;
6197 MoveToInfo *helper = NULL;
6198 TnyList *list_to_move;
6200 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
6202 #ifndef MODEST_TOOLKIT_HILDON2
6203 /* Get the main window if exists */
6204 ModestMainWindow *main_window;
6205 if (MODEST_IS_MAIN_WINDOW (win))
6206 main_window = MODEST_MAIN_WINDOW (win);
6209 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
6210 FALSE)); /* don't create */
6213 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
6218 if (tny_list_get_length (list_to_move) < 1) {
6219 g_object_unref (list_to_move);
6223 /* Create and run the dialog */
6224 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
6225 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
6226 GTK_WINDOW (dialog),
6230 helper = g_slice_new0 (MoveToInfo);
6231 helper->list = list_to_move;
6234 /* Listen to response signal */
6235 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
6237 /* Show the dialog */
6238 gtk_widget_show (dialog);
6244 * Calls #HeadersFunc for each header already selected in the main
6245 * window or the message currently being shown in the msg view window
6248 do_headers_action (ModestWindow *win,
6252 TnyList *headers_list = NULL;
6253 TnyIterator *iter = NULL;
6254 TnyHeader *header = NULL;
6255 TnyFolder *folder = NULL;
6258 headers_list = get_selected_headers (win);
6262 /* Get the folder */
6263 iter = tny_list_create_iterator (headers_list);
6264 header = TNY_HEADER (tny_iterator_get_current (iter));
6266 folder = tny_header_get_folder (header);
6267 g_object_unref (header);
6270 /* Call the function for each header */
6271 while (!tny_iterator_is_done (iter)) {
6272 header = TNY_HEADER (tny_iterator_get_current (iter));
6273 func (header, win, user_data);
6274 g_object_unref (header);
6275 tny_iterator_next (iter);
6278 /* Trick: do a poke status in order to speed up the signaling
6281 tny_folder_poke_status (folder);
6282 g_object_unref (folder);
6286 g_object_unref (iter);
6287 g_object_unref (headers_list);
6291 modest_ui_actions_view_attachment (GtkAction *action,
6292 ModestWindow *window)
6294 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6295 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
6297 /* not supported window for this action */
6298 g_return_if_reached ();
6303 modest_ui_actions_save_attachments (GtkAction *action,
6304 ModestWindow *window)
6306 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6308 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
6311 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
6313 /* not supported window for this action */
6314 g_return_if_reached ();
6319 modest_ui_actions_remove_attachments (GtkAction *action,
6320 ModestWindow *window)
6322 #ifndef MODEST_TOOLKIT_HILDON2
6323 if (MODEST_IS_MAIN_WINDOW (window)) {
6324 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
6325 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6327 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6329 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
6331 /* not supported window for this action */
6332 g_return_if_reached ();
6337 modest_ui_actions_on_settings (GtkAction *action,
6342 dialog = modest_platform_get_global_settings_dialog ();
6343 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
6344 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
6345 gtk_widget_show_all (dialog);
6347 gtk_dialog_run (GTK_DIALOG (dialog));
6349 gtk_widget_destroy (dialog);
6353 modest_ui_actions_on_help (GtkAction *action,
6356 /* Help app is not available at all in fremantle */
6357 #ifndef MODEST_TOOLKIT_HILDON2
6358 const gchar *help_id;
6360 g_return_if_fail (win && GTK_IS_WINDOW(win));
6362 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
6365 modest_platform_show_help (GTK_WINDOW (win), help_id);
6370 modest_ui_actions_on_csm_help (GtkAction *action,
6373 /* Help app is not available at all in fremantle */
6374 #ifndef MODEST_TOOLKIT_HILDON2
6376 const gchar* help_id = NULL;
6377 GtkWidget *folder_view;
6378 TnyFolderStore *folder_store;
6380 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
6382 /* Get selected folder */
6383 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
6384 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6385 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6387 /* Switch help_id */
6388 if (folder_store && TNY_IS_FOLDER (folder_store))
6389 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
6392 g_object_unref (folder_store);
6395 modest_platform_show_help (GTK_WINDOW (win), help_id);
6397 modest_ui_actions_on_help (action, win);
6402 retrieve_contents_cb (ModestMailOperation *mail_op,
6409 /* We only need this callback to show an error in case of
6410 memory low condition */
6411 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
6412 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
6417 retrieve_msg_contents_performer (gboolean canceled,
6419 GtkWindow *parent_window,
6420 TnyAccount *account,
6423 ModestMailOperation *mail_op;
6424 TnyList *headers = TNY_LIST (user_data);
6426 if (err || canceled) {
6427 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6428 (GtkWidget *) parent_window, err,
6433 /* Create mail operation */
6434 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
6435 modest_ui_actions_disk_operations_error_handler,
6437 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
6438 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
6441 g_object_unref (mail_op);
6443 g_object_unref (headers);
6444 g_object_unref (account);
6448 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
6449 ModestWindow *window)
6451 TnyList *headers = NULL;
6452 TnyAccount *account = NULL;
6453 TnyIterator *iter = NULL;
6454 TnyHeader *header = NULL;
6455 TnyFolder *folder = NULL;
6458 headers = get_selected_headers (window);
6462 /* Pick the account */
6463 iter = tny_list_create_iterator (headers);
6464 header = TNY_HEADER (tny_iterator_get_current (iter));
6465 folder = tny_header_get_folder (header);
6466 account = tny_folder_get_account (folder);
6467 g_object_unref (folder);
6468 g_object_unref (header);
6469 g_object_unref (iter);
6471 /* Connect and perform the message retrieval */
6472 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6473 g_object_ref (account),
6474 retrieve_msg_contents_performer,
6475 g_object_ref (headers));
6478 g_object_unref (account);
6479 g_object_unref (headers);
6483 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6485 g_return_if_fail (MODEST_IS_WINDOW (window));
6488 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6492 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6494 g_return_if_fail (MODEST_IS_WINDOW (window));
6497 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6501 modest_ui_actions_on_email_menu_activated (GtkAction *action,
6502 ModestWindow *window)
6504 g_return_if_fail (MODEST_IS_WINDOW (window));
6507 modest_ui_actions_check_menu_dimming_rules (window);
6511 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
6512 ModestWindow *window)
6514 g_return_if_fail (MODEST_IS_WINDOW (window));
6517 modest_ui_actions_check_menu_dimming_rules (window);
6521 modest_ui_actions_on_view_menu_activated (GtkAction *action,
6522 ModestWindow *window)
6524 g_return_if_fail (MODEST_IS_WINDOW (window));
6527 modest_ui_actions_check_menu_dimming_rules (window);
6531 modest_ui_actions_on_format_menu_activated (GtkAction *action,
6532 ModestWindow *window)
6534 g_return_if_fail (MODEST_IS_WINDOW (window));
6537 modest_ui_actions_check_menu_dimming_rules (window);
6541 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
6542 ModestWindow *window)
6544 g_return_if_fail (MODEST_IS_WINDOW (window));
6547 modest_ui_actions_check_menu_dimming_rules (window);
6551 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
6552 ModestWindow *window)
6554 g_return_if_fail (MODEST_IS_WINDOW (window));
6557 modest_ui_actions_check_menu_dimming_rules (window);
6561 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
6562 ModestWindow *window)
6564 g_return_if_fail (MODEST_IS_WINDOW (window));
6567 modest_ui_actions_check_menu_dimming_rules (window);
6571 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
6572 ModestWindow *window)
6574 g_return_if_fail (MODEST_IS_WINDOW (window));
6577 modest_ui_actions_check_menu_dimming_rules (window);
6581 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
6582 ModestWindow *window)
6584 g_return_if_fail (MODEST_IS_WINDOW (window));
6587 modest_ui_actions_check_menu_dimming_rules (window);
6591 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6593 g_return_if_fail (MODEST_IS_WINDOW (window));
6595 /* we check for low-mem; in that case, show a warning, and don't allow
6598 if (modest_platform_check_memory_low (window, TRUE))
6601 modest_platform_show_search_messages (GTK_WINDOW (window));
6605 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6607 g_return_if_fail (MODEST_IS_WINDOW (win));
6610 /* we check for low-mem; in that case, show a warning, and don't allow
6611 * for the addressbook
6613 if (modest_platform_check_memory_low (win, TRUE))
6617 modest_platform_show_addressbook (GTK_WINDOW (win));
6622 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6623 ModestWindow *window)
6626 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6628 if (GTK_IS_TOGGLE_ACTION (action))
6629 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6633 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window),
6637 #ifndef MODEST_TOOLKIT_HILDON2
6639 on_send_receive_finished (ModestMailOperation *mail_op,
6642 GtkWidget *header_view, *folder_view;
6643 TnyFolderStore *folder_store;
6644 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6646 /* Set send/receive operation finished */
6647 modest_main_window_notify_send_receive_completed (main_win);
6649 /* Don't refresh the current folder if there were any errors */
6650 if (modest_mail_operation_get_status (mail_op) !=
6651 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6654 /* Refresh the current folder if we're viewing a window. We do
6655 this because the user won't be able to see the new mails in
6656 the selected folder after a Send&Receive because it only
6657 performs a poke_status, i.e, only the number of read/unread
6658 messages is updated, but the new headers are not
6660 folder_view = modest_main_window_get_child_widget (main_win,
6661 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6665 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6667 /* Do not need to refresh INBOX again because the
6668 update_account does it always automatically */
6669 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6670 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6671 ModestMailOperation *refresh_op;
6673 header_view = modest_main_window_get_child_widget (main_win,
6674 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6676 /* We do not need to set the contents style
6677 because it hasn't changed. We also do not
6678 need to save the widget status. Just force
6680 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6681 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6682 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6683 folder_refreshed_cb, main_win);
6684 g_object_unref (refresh_op);
6688 g_object_unref (folder_store);
6693 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6699 const gchar* server_name = NULL;
6700 TnyTransportAccount *transport;
6701 gchar *message = NULL;
6702 ModestProtocol *protocol;
6704 /* Don't show anything if the user cancelled something or the
6705 * send receive request is not interactive. Authentication
6706 * errors are managed by the account store so no need to show
6707 * a dialog here again */
6708 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6709 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6710 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6714 /* Get the server name. Note that we could be using a
6715 connection specific transport account */
6716 transport = (TnyTransportAccount *)
6717 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
6719 ModestTnyAccountStore *acc_store;
6720 const gchar *acc_name;
6721 TnyTransportAccount *conn_specific;
6723 acc_store = modest_runtime_get_account_store();
6724 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
6725 conn_specific = (TnyTransportAccount *)
6726 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
6727 if (conn_specific) {
6728 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
6729 g_object_unref (conn_specific);
6731 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
6733 g_object_unref (transport);
6737 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
6738 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
6739 tny_account_get_proto (TNY_ACCOUNT (transport)));
6741 g_warning ("%s: Account with no proto", __FUNCTION__);
6745 /* Show the appropriate message text for the GError: */
6746 switch (err->code) {
6747 case TNY_SERVICE_ERROR_CONNECT:
6748 message = modest_protocol_get_translation (protocol,
6749 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
6752 case TNY_SERVICE_ERROR_SEND:
6753 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6755 case TNY_SERVICE_ERROR_UNAVAILABLE:
6756 message = modest_protocol_get_translation (protocol,
6757 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
6761 g_warning ("%s: unexpected ERROR %d",
6762 __FUNCTION__, err->code);
6763 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6767 modest_platform_run_information_dialog (NULL, message, FALSE);
6772 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6777 ModestWindow *top_window = NULL;
6778 ModestWindowMgr *mgr = NULL;
6779 GtkWidget *header_view = NULL;
6780 TnyFolder *selected_folder = NULL;
6781 TnyFolderType folder_type;
6783 mgr = modest_runtime_get_window_mgr ();
6784 top_window = modest_window_mgr_get_current_top (mgr);
6789 #ifndef MODEST_TOOLKIT_HILDON2
6790 if (MODEST_IS_MAIN_WINDOW (top_window)) {
6791 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (top_window),
6792 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6795 if (MODEST_IS_HEADER_WINDOW (top_window)) {
6796 header_view = (GtkWidget *)
6797 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
6801 /* Get selected folder */
6803 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
6804 if (!selected_folder)
6807 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6808 #if GTK_CHECK_VERSION(2, 8, 0)
6809 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
6810 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6811 GtkTreeViewColumn *tree_column;
6813 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6814 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6816 gtk_tree_view_column_queue_resize (tree_column);
6818 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
6819 gtk_widget_queue_draw (header_view);
6822 #ifndef MODEST_TOOLKIT_HILDON2
6823 /* Rerun dimming rules, because the message could become deletable for example */
6824 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6825 MODEST_DIMMING_RULES_TOOLBAR);
6826 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6827 MODEST_DIMMING_RULES_MENU);
6831 g_object_unref (selected_folder);
6835 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6836 TnyAccount *account)
6838 ModestProtocolType protocol_type;
6839 ModestProtocol *protocol;
6840 gchar *error_note = NULL;
6842 protocol_type = modest_tny_account_get_protocol_type (account);
6843 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6846 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6847 if (error_note == NULL) {
6848 g_warning ("%s: This should not be reached", __FUNCTION__);
6850 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6851 g_free (error_note);
6856 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6860 TnyFolderStore *folder = NULL;
6861 TnyAccount *account = NULL;
6862 ModestProtocolType proto;
6863 ModestProtocol *protocol;
6864 TnyHeader *header = NULL;
6866 #ifndef MODEST_TOOLKIT_HILDON2
6867 if (MODEST_IS_MAIN_WINDOW (win)) {
6868 GtkWidget *header_view;
6869 TnyList* headers = NULL;
6871 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6872 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6873 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6874 if (!headers || tny_list_get_length (headers) == 0) {
6876 g_object_unref (headers);
6879 iter = tny_list_create_iterator (headers);
6880 header = TNY_HEADER (tny_iterator_get_current (iter));
6881 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6882 g_object_unref (iter);
6883 g_object_unref (headers);
6885 if (MODEST_IS_HEADER_WINDOW (win)) {
6886 GtkWidget *header_view;
6887 TnyList* headers = NULL;
6889 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
6890 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6891 if (!headers || tny_list_get_length (headers) == 0) {
6893 g_object_unref (headers);
6896 iter = tny_list_create_iterator (headers);
6897 header = TNY_HEADER (tny_iterator_get_current (iter));
6899 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6901 g_warning ("List should contain headers");
6903 g_object_unref (iter);
6904 g_object_unref (headers);
6906 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6907 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6909 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6912 if (!header || !folder)
6915 /* Get the account type */
6916 account = tny_folder_get_account (TNY_FOLDER (folder));
6917 proto = modest_tny_account_get_protocol_type (account);
6918 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6921 subject = tny_header_dup_subject (header);
6922 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6926 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6932 g_object_unref (account);
6934 g_object_unref (folder);
6936 g_object_unref (header);
6942 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6943 const gchar *account_name,
6944 const gchar *account_title)
6946 ModestAccountMgr *account_mgr;
6949 ModestProtocol *protocol;
6950 gboolean removed = FALSE;
6952 g_return_val_if_fail (account_name, FALSE);
6953 g_return_val_if_fail (account_title, FALSE);
6955 account_mgr = modest_runtime_get_account_mgr();
6957 /* The warning text depends on the account type: */
6958 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6959 modest_account_mgr_get_store_protocol (account_mgr,
6961 txt = modest_protocol_get_translation (protocol,
6962 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6965 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6967 response = modest_platform_run_confirmation_dialog (parent_window, txt);
6971 if (response == GTK_RESPONSE_OK) {
6972 /* Remove account. If it succeeds then it also removes
6973 the account from the ModestAccountView: */
6974 gboolean is_default = FALSE;
6975 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6976 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6978 g_free (default_account_name);
6980 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6982 /* Close all email notifications, we cannot
6983 distinguish if the notification belongs to
6984 this account or not, so for safety reasons
6985 we remove them all */
6986 modest_platform_remove_new_mail_notifications (FALSE);
6988 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
6995 on_fetch_images_performer (gboolean canceled,
6997 GtkWindow *parent_window,
6998 TnyAccount *account,
7001 if (err || canceled) {
7002 /* Show an unable to retrieve images ??? */
7006 /* Note that the user could have closed the window while connecting */
7007 if (GTK_WIDGET_VISIBLE (parent_window))
7008 modest_msg_view_window_fetch_images ((ModestMsgViewWindow *) parent_window);
7009 g_object_unref ((GObject *) user_data);
7013 modest_ui_actions_on_fetch_images (GtkAction *action,
7014 ModestWindow *window)
7016 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
7018 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
7020 on_fetch_images_performer,
7021 g_object_ref (window));
7025 modest_ui_actions_on_reload_message (const gchar *msg_id)
7027 ModestWindow *window = NULL;
7029 g_return_if_fail (msg_id && msg_id[0] != '\0');
7030 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
7036 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
7039 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));
7042 /** Check whether any connections are active, and cancel them if
7044 * Returns TRUE is there was no problem,
7045 * or if an operation was cancelled so we can continue.
7046 * Returns FALSE if the user chose to cancel his request instead.
7050 modest_ui_actions_check_for_active_account (ModestWindow *self,
7051 const gchar* account_name)
7053 ModestTnySendQueue *send_queue;
7054 ModestTnyAccountStore *acc_store;
7055 ModestMailOperationQueue* queue;
7056 TnyConnectionStatus store_conn_status;
7057 TnyAccount *store_account = NULL, *transport_account = NULL;
7058 gboolean retval = TRUE, sending = FALSE;
7060 acc_store = modest_runtime_get_account_store ();
7061 queue = modest_runtime_get_mail_operation_queue ();
7064 modest_tny_account_store_get_server_account (acc_store,
7066 TNY_ACCOUNT_TYPE_STORE);
7068 /* This could happen if the account was deleted before the
7069 call to this function */
7074 modest_tny_account_store_get_server_account (acc_store,
7076 TNY_ACCOUNT_TYPE_TRANSPORT);
7078 /* This could happen if the account was deleted before the
7079 call to this function */
7080 if (!transport_account) {
7081 g_object_unref (store_account);
7085 /* If the transport account was not used yet, then the send
7086 queue could not exist (it's created on demand) */
7087 send_queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (transport_account), FALSE);
7088 if (TNY_IS_SEND_QUEUE (send_queue))
7089 sending = modest_tny_send_queue_sending_in_progress (send_queue);
7091 store_conn_status = tny_account_get_connection_status (store_account);
7092 if (store_conn_status == TNY_CONNECTION_STATUS_CONNECTED || sending) {
7095 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (self),
7096 _("emev_nc_disconnect_account"));
7097 if (response == GTK_RESPONSE_OK) {
7106 /* FIXME: We should only cancel those of this account */
7107 modest_mail_operation_queue_cancel_all (queue);
7109 /* Also disconnect the account */
7110 if ((tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED) &&
7111 (tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)) {
7112 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
7116 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (transport_account),
7122 g_object_unref (store_account);
7123 g_object_unref (transport_account);