1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #endif /*HAVE_CONFIG_H*/
34 #include <glib/gi18n.h>
35 #include <glib/gprintf.h>
37 #include <modest-runtime.h>
38 #include <modest-defs.h>
39 #include <modest-tny-folder.h>
40 #include <modest-tny-msg.h>
41 #include <modest-tny-account.h>
42 #include <modest-address-book.h>
43 #include "modest-error.h"
44 #include "modest-ui-actions.h"
45 #include "modest-tny-platform-factory.h"
46 #include "modest-platform.h"
47 #include "modest-debug.h"
48 #include <tny-mime-part.h>
49 #include <tny-error.h>
50 #include <tny-camel-folder.h>
51 #include <tny-camel-imap-folder.h>
52 #include <tny-camel-pop-folder.h>
53 #ifdef MODEST_TOOLKIT_HILDON2
54 #include <modest-accounts-window.h>
55 #include <hildon/hildon-pannable-area.h>
56 #include <hildon/hildon-gtk.h>
57 #include <modest-header-window.h>
58 #include <modest-folder-window.h>
59 #include <modest-maemo-utils.h>
62 #ifdef MODEST_PLATFORM_MAEMO
63 #include "maemo/modest-osso-state-saving.h"
64 #endif /* MODEST_PLATFORM_MAEMO */
65 #ifndef MODEST_TOOLKIT_GTK
66 #include "maemo/modest-hildon-includes.h"
67 #include "maemo/modest-connection-specific-smtp-window.h"
68 #endif /* !MODEST_TOOLKIT_GTK */
70 #include <modest-utils.h>
71 #include "widgets/modest-ui-constants.h"
72 #include <widgets/modest-main-window.h>
73 #include <widgets/modest-msg-view-window.h>
74 #include <widgets/modest-account-view-window.h>
75 #include <widgets/modest-details-dialog.h>
76 #include <widgets/modest-attachments-view.h>
77 #include "widgets/modest-folder-view.h"
78 #include "widgets/modest-global-settings-dialog.h"
79 #include "modest-account-mgr-helpers.h"
80 #include "modest-mail-operation.h"
81 #include "modest-text-utils.h"
82 #include <modest-widget-memory.h>
83 #include <tny-error.h>
84 #include <tny-simple-list.h>
85 #include <tny-msg-view.h>
86 #include <tny-device.h>
87 #include <tny-merge-folder.h>
88 #include <tny-camel-bs-msg.h>
89 #include <tny-camel-bs-mime-part.h>
92 #include <gtkhtml/gtkhtml.h>
94 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
96 typedef struct _GetMsgAsyncHelper {
98 ModestMailOperation *mail_op;
105 typedef enum _ReplyForwardAction {
109 } ReplyForwardAction;
111 typedef struct _ReplyForwardHelper {
112 guint reply_forward_type;
113 ReplyForwardAction action;
116 GtkWidget *parent_window;
118 TnyHeader *top_header;
121 } ReplyForwardHelper;
123 typedef struct _MoveToHelper {
124 GtkTreeRowReference *reference;
128 typedef struct _PasteAsAttachmentHelper {
129 ModestMsgEditWindow *window;
131 } PasteAsAttachmentHelper;
139 * The do_headers_action uses this kind of functions to perform some
140 * action to each member of a list of headers
142 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
144 static void do_headers_action (ModestWindow *win,
148 static void open_msg_cb (ModestMailOperation *mail_op,
155 static void reply_forward_cb (ModestMailOperation *mail_op,
162 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
164 static void folder_refreshed_cb (ModestMailOperation *mail_op,
168 static void on_send_receive_finished (ModestMailOperation *mail_op,
171 static gint header_list_count_uncached_msgs (TnyList *header_list);
173 static gboolean connect_to_get_msg (ModestWindow *win,
174 gint num_of_uncached_msgs,
175 TnyAccount *account);
177 static gboolean remote_folder_has_leave_on_server (TnyFolderStore *folder);
179 static void do_create_folder (GtkWindow *window,
180 TnyFolderStore *parent_folder,
181 const gchar *suggested_name);
183 static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store);
185 static void modest_ui_actions_on_main_window_move_to (GtkAction *action,
186 GtkWidget *folder_view,
187 TnyFolderStore *dst_folder,
188 ModestMainWindow *win);
189 #ifdef MODEST_TOOLKIT_HILDON2
190 static void modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
191 TnyFolderStore *dst_folder,
196 static void modest_ui_actions_on_window_move_to (GtkAction *action,
197 TnyList *list_to_move,
198 TnyFolderStore *dst_folder,
202 * This function checks whether a TnyFolderStore is a pop account
205 remote_folder_has_leave_on_server (TnyFolderStore *folder)
210 g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
212 account = get_account_from_folder_store (folder);
213 result = (modest_protocol_registry_protocol_type_has_leave_on_server (modest_runtime_get_protocol_registry (),
214 modest_tny_account_get_protocol_type (account)));
215 g_object_unref (account);
220 /* FIXME: this should be merged with the similar code in modest-account-view-window */
221 /* Show the account creation wizard dialog.
222 * returns: TRUE if an account was created. FALSE if the user cancelled.
225 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
227 gboolean result = FALSE;
229 gint dialog_response;
231 /* there is no such wizard yet */
232 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
233 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (wizard), (GtkWindow *) win);
235 #ifndef MODEST_TOOLKIT_HILDON2
236 /* always present a main window in the background
237 * we do it here, so we cannot end up with two wizards (as this
238 * function might be called in modest_window_mgr_get_main_window as well */
240 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
241 TRUE); /* create if not existent */
245 ModestWindowMgr *mgr;
247 mgr = modest_runtime_get_window_mgr ();
249 window_list = modest_window_mgr_get_window_list (mgr);
250 if (window_list == NULL) {
251 win = MODEST_WINDOW (modest_accounts_window_new ());
252 if (modest_window_mgr_register_window (mgr, win, NULL)) {
253 gtk_widget_show_all (GTK_WIDGET (win));
255 gtk_widget_destroy (GTK_WIDGET (win));
260 g_list_free (window_list);
266 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
268 /* make sure the mainwindow is visible. We need to present the
269 wizard again to give it the focus back. show_all are needed
270 in order to get the widgets properly drawn (MainWindow main
271 paned won't be in its right position and the dialog will be
273 #ifndef MODEST_TOOLKIT_HILDON2
274 gtk_widget_show_all (GTK_WIDGET (win));
275 gtk_widget_show_all (GTK_WIDGET (wizard));
276 gtk_window_present (GTK_WINDOW (win));
277 gtk_window_present (GTK_WINDOW (wizard));
280 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
281 gtk_widget_destroy (GTK_WIDGET (wizard));
282 if (gtk_events_pending ())
283 gtk_main_iteration ();
285 if (dialog_response == GTK_RESPONSE_CANCEL) {
288 /* Check whether an account was created: */
289 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
296 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
299 const gchar *authors[] = {
300 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
303 about = gtk_about_dialog_new ();
304 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
305 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
306 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
307 _("Copyright (c) 2006, Nokia Corporation\n"
308 "All rights reserved."));
309 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
310 _("a modest e-mail client\n\n"
311 "design and implementation: Dirk-Jan C. Binnema\n"
312 "contributions from the fine people at KC and Ig\n"
313 "uses the tinymail email framework written by Philip van Hoof"));
314 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
315 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
316 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
317 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
319 gtk_dialog_run (GTK_DIALOG (about));
320 gtk_widget_destroy(about);
324 * Gets the list of currently selected messages. If the win is the
325 * main window, then it returns a newly allocated list of the headers
326 * selected in the header view. If win is the msg view window, then
327 * the value returned is a list with just a single header.
329 * The caller of this funcion must free the list.
332 get_selected_headers (ModestWindow *win)
334 if (MODEST_IS_MAIN_WINDOW(win)) {
335 GtkWidget *header_view;
337 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
338 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
339 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
341 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
342 /* for MsgViewWindows, we simply return a list with one element */
344 TnyList *list = NULL;
346 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
347 if (header != NULL) {
348 list = tny_simple_list_new ();
349 tny_list_prepend (list, G_OBJECT(header));
350 g_object_unref (G_OBJECT(header));
355 #ifdef MODEST_TOOLKIT_HILDON2
356 } else if (MODEST_IS_HEADER_WINDOW (win)) {
357 GtkWidget *header_view;
359 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
360 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
366 static GtkTreeRowReference *
367 get_next_after_selected_headers (ModestHeaderView *header_view)
369 GtkTreeSelection *sel;
370 GList *selected_rows, *node;
372 GtkTreeRowReference *result;
375 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
376 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
377 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
379 if (selected_rows == NULL)
382 node = g_list_last (selected_rows);
383 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
384 gtk_tree_path_next (path);
386 result = gtk_tree_row_reference_new (model, path);
388 gtk_tree_path_free (path);
389 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
390 g_list_free (selected_rows);
396 headers_action_mark_as_read (TnyHeader *header,
400 TnyHeaderFlags flags;
403 g_return_if_fail (TNY_IS_HEADER(header));
405 flags = tny_header_get_flags (header);
406 if (flags & TNY_HEADER_FLAG_SEEN) return;
407 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
408 uid = modest_tny_folder_get_header_unique_id (header);
409 modest_platform_emit_msg_read_changed_signal (uid, TRUE);
414 headers_action_mark_as_unread (TnyHeader *header,
418 TnyHeaderFlags flags;
420 g_return_if_fail (TNY_IS_HEADER(header));
422 flags = tny_header_get_flags (header);
423 if (flags & TNY_HEADER_FLAG_SEEN) {
425 uid = modest_tny_folder_get_header_unique_id (header);
426 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
427 modest_platform_emit_msg_read_changed_signal (uid, FALSE);
431 /** After deleing a message that is currently visible in a window,
432 * show the next message from the list, or close the window if there are no more messages.
435 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
437 /* Close msg view window or select next */
438 if (!modest_msg_view_window_select_next_message (win) &&
439 !modest_msg_view_window_select_previous_message (win)) {
441 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
447 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
449 modest_ui_actions_on_edit_mode_delete_message (win);
453 modest_ui_actions_on_edit_mode_delete_message (ModestWindow *win)
455 TnyList *header_list = NULL;
456 TnyIterator *iter = NULL;
457 TnyHeader *header = NULL;
458 gchar *message = NULL;
461 ModestWindowMgr *mgr;
462 GtkWidget *header_view = NULL;
463 gboolean retval = TRUE;
465 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
467 /* Check first if the header view has the focus */
468 if (MODEST_IS_MAIN_WINDOW (win)) {
470 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
471 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
472 if (!gtk_widget_is_focus (header_view))
476 /* Get the headers, either from the header view (if win is the main window),
477 * or from the message view window: */
478 header_list = get_selected_headers (win);
479 if (!header_list) return FALSE;
481 /* Check if any of the headers are already opened, or in the process of being opened */
482 if (MODEST_IS_MAIN_WINDOW (win)) {
483 gint opened_headers = 0;
485 iter = tny_list_create_iterator (header_list);
486 mgr = modest_runtime_get_window_mgr ();
487 while (!tny_iterator_is_done (iter)) {
488 header = TNY_HEADER (tny_iterator_get_current (iter));
490 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
492 g_object_unref (header);
494 tny_iterator_next (iter);
496 g_object_unref (iter);
498 if (opened_headers > 0) {
501 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
504 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg, FALSE);
507 g_object_unref (header_list);
513 if (tny_list_get_length(header_list) == 1) {
514 iter = tny_list_create_iterator (header_list);
515 header = TNY_HEADER (tny_iterator_get_current (iter));
518 subject = tny_header_dup_subject (header);
520 subject = g_strdup (_("mail_va_no_subject"));
521 desc = g_strdup_printf ("%s", subject);
523 g_object_unref (header);
526 g_object_unref (iter);
528 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
529 tny_list_get_length(header_list)), desc);
531 /* Confirmation dialog */
532 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
536 if (response == GTK_RESPONSE_OK) {
537 ModestWindowMgr *mgr = NULL;
538 GtkTreeModel *model = NULL;
539 GtkTreeSelection *sel = NULL;
540 GList *sel_list = NULL, *tmp = NULL;
541 GtkTreeRowReference *next_row_reference = NULL;
542 GtkTreeRowReference *prev_row_reference = NULL;
543 GtkTreePath *next_path = NULL;
544 GtkTreePath *prev_path = NULL;
545 ModestMailOperation *mail_op = NULL;
547 /* Find last selected row */
548 if (MODEST_IS_MAIN_WINDOW (win)) {
549 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
550 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
551 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
552 for (tmp=sel_list; tmp; tmp=tmp->next) {
553 if (tmp->next == NULL) {
554 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
555 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
557 gtk_tree_path_prev (prev_path);
558 gtk_tree_path_next (next_path);
560 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
561 next_row_reference = gtk_tree_row_reference_new (model, next_path);
566 /* Disable window dimming management */
567 modest_window_disable_dimming (win);
569 /* Remove each header. If it's a view window header_view == NULL */
570 mail_op = modest_mail_operation_new ((GObject *) win);
571 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
573 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
574 g_object_unref (mail_op);
576 /* Enable window dimming management */
578 gtk_tree_selection_unselect_all (sel);
580 modest_window_enable_dimming (win);
582 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
583 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
585 /* Get main window */
586 mgr = modest_runtime_get_window_mgr ();
587 } else if (MODEST_IS_MAIN_WINDOW (win)) {
588 /* Select next or previous row */
589 if (gtk_tree_row_reference_valid (next_row_reference)) {
590 gtk_tree_selection_select_path (sel, next_path);
592 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
593 gtk_tree_selection_select_path (sel, prev_path);
597 if (gtk_tree_row_reference_valid (next_row_reference))
598 gtk_tree_row_reference_free (next_row_reference);
599 if (next_path != NULL)
600 gtk_tree_path_free (next_path);
601 if (gtk_tree_row_reference_valid (prev_row_reference))
602 gtk_tree_row_reference_free (prev_row_reference);
603 if (prev_path != NULL)
604 gtk_tree_path_free (prev_path);
607 /* Update toolbar dimming state */
608 modest_ui_actions_check_menu_dimming_rules (win);
609 modest_ui_actions_check_toolbar_dimming_rules (win);
612 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
613 g_list_free (sel_list);
622 g_object_unref (header_list);
630 /* delete either message or folder, based on where we are */
632 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
634 g_return_if_fail (MODEST_IS_WINDOW(win));
636 /* Check first if the header view has the focus */
637 if (MODEST_IS_MAIN_WINDOW (win)) {
639 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
640 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
641 if (gtk_widget_is_focus (w)) {
642 modest_ui_actions_on_delete_folder (action, MODEST_WINDOW(win));
646 modest_ui_actions_on_delete_message (action, win);
650 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
652 ModestWindowMgr *mgr = NULL;
654 #ifdef MODEST_PLATFORM_MAEMO
655 modest_window_mgr_save_state_for_all_windows (modest_runtime_get_window_mgr ());
656 #endif /* MODEST_PLATFORM_MAEMO */
658 g_debug ("closing down, clearing %d item(s) from operation queue",
659 modest_mail_operation_queue_num_elements
660 (modest_runtime_get_mail_operation_queue()));
662 /* cancel all outstanding operations */
663 modest_mail_operation_queue_cancel_all
664 (modest_runtime_get_mail_operation_queue());
666 g_debug ("queue has been cleared");
669 /* Check if there are opened editing windows */
670 mgr = modest_runtime_get_window_mgr ();
671 modest_window_mgr_close_all_windows (mgr);
673 /* note: when modest-tny-account-store is finalized,
674 it will automatically set all network connections
677 /* gtk_main_quit (); */
681 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
685 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
687 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
688 /* gtk_widget_destroy (GTK_WIDGET (win)); */
689 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
690 /* gboolean ret_value; */
691 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
692 /* } else if (MODEST_IS_WINDOW (win)) { */
693 /* gtk_widget_destroy (GTK_WIDGET (win)); */
695 /* g_return_if_reached (); */
700 modest_ui_actions_add_to_contacts (GtkAction *action, ModestWindow *win)
702 if (MODEST_IS_MSG_VIEW_WINDOW (win))
703 modest_msg_view_window_add_to_contacts (MODEST_MSG_VIEW_WINDOW (win));
704 else if (MODEST_IS_MSG_EDIT_WINDOW (win))
705 modest_msg_edit_window_add_to_contacts (MODEST_MSG_EDIT_WINDOW (win));
709 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
711 GtkClipboard *clipboard = NULL;
712 gchar *selection = NULL;
714 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
715 selection = gtk_clipboard_wait_for_text (clipboard);
718 modest_address_book_add_address (selection, (GtkWindow *) win);
724 modest_ui_actions_on_new_account (GtkAction *action,
725 ModestWindow *window)
727 if (!modest_ui_actions_run_account_setup_wizard (window)) {
728 g_debug ("%s: wizard was already running", __FUNCTION__);
733 modest_ui_actions_on_accounts (GtkAction *action,
736 /* This is currently only implemented for Maemo */
737 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
738 if (!modest_ui_actions_run_account_setup_wizard (win))
739 g_debug ("%s: wizard was already running", __FUNCTION__);
743 /* Show the list of accounts */
744 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
746 /* The accounts dialog must be modal */
747 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
748 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
753 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
755 /* This is currently only implemented for Maemo,
756 * because it requires an API (libconic) to detect different connection
759 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
761 /* Create the window if necessary: */
762 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
763 modest_connection_specific_smtp_window_fill_with_connections (
764 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
765 modest_runtime_get_account_mgr());
767 /* Show the window: */
768 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
769 GTK_WINDOW (specific_window), (GtkWindow *) win);
770 gtk_widget_show (specific_window);
771 #endif /* !MODEST_TOOLKIT_GTK */
775 count_part_size (const gchar *part)
777 GnomeVFSURI *vfs_uri;
778 gchar *escaped_filename;
780 GnomeVFSFileInfo *info;
783 /* Estimation of attachment size if we cannot get it from file info */
786 vfs_uri = gnome_vfs_uri_new (part);
788 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
789 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
790 g_free (escaped_filename);
791 gnome_vfs_uri_unref (vfs_uri);
793 info = gnome_vfs_file_info_new ();
795 if (gnome_vfs_get_file_info (part,
797 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
799 if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) {
804 gnome_vfs_file_info_unref (info);
810 count_parts_size (GSList *parts)
815 for (node = parts; node != NULL; node = g_slist_next (node)) {
816 result += count_part_size ((const gchar *) node->data);
823 modest_ui_actions_compose_msg(ModestWindow *win,
826 const gchar *bcc_str,
827 const gchar *subject_str,
828 const gchar *body_str,
830 gboolean set_as_modified)
832 gchar *account_name = NULL;
833 const gchar *mailbox;
835 TnyAccount *account = NULL;
836 TnyFolder *folder = NULL;
837 gchar *from_str = NULL, *signature = NULL, *body = NULL, *recipient = NULL, *tmp = NULL;
838 gboolean use_signature = FALSE;
839 ModestWindow *msg_win = NULL;
840 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
841 ModestTnyAccountStore *store = modest_runtime_get_account_store();
842 GnomeVFSFileSize total_size, allowed_size;
843 guint64 available_disk, expected_size, parts_size;
845 TnyList *header_pairs;
847 /* we check for low-mem */
848 if (modest_platform_check_memory_low (win, TRUE))
851 available_disk = modest_utils_get_available_space (NULL);
852 parts_count = g_slist_length (attachments);
853 parts_size = count_parts_size (attachments);
854 expected_size = modest_tny_msg_estimate_size (body, NULL, parts_count, parts_size);
856 /* Double check: disk full condition or message too big */
857 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
858 expected_size > available_disk) {
859 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
860 modest_platform_system_banner (NULL, NULL, msg);
866 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
867 modest_platform_run_information_dialog (
869 _("mail_ib_error_attachment_size"),
875 #ifdef MODEST_TOOLKIT_HILDON2
877 account_name = g_strdup (modest_window_get_active_account(win));
880 account_name = modest_account_mgr_get_default_account(mgr);
883 g_printerr ("modest: no account found\n");
888 mailbox = modest_window_get_active_mailbox (win);
891 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
893 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
896 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
898 g_printerr ("modest: failed to find Drafts folder\n");
901 from_str = modest_account_mgr_get_from_string (mgr, account_name, mailbox);
903 g_printerr ("modest: failed get from string for '%s'\n", account_name);
908 recipient = modest_text_utils_get_email_address (from_str);
909 tmp = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr (),
912 signature = modest_text_utils_create_colored_signature (tmp);
916 body = use_signature ? g_strconcat ((body_str) ? body_str : "", signature, NULL) :
919 header_pairs = TNY_LIST (tny_simple_list_new ());
920 msg = modest_tny_msg_new_html_plain (to_str, from_str, cc_str, bcc_str, subject_str,
921 NULL, NULL, body, NULL, NULL, NULL, NULL, header_pairs, NULL);
922 g_object_unref (header_pairs);
925 g_printerr ("modest: failed to create new msg\n");
929 /* Create and register edit window */
930 /* This is destroyed by TODO. */
932 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
933 msg_win = modest_msg_edit_window_new (msg, account_name, mailbox, FALSE);
935 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, win)) {
936 gtk_widget_destroy (GTK_WIDGET (msg_win));
939 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
940 gtk_widget_show_all (GTK_WIDGET (msg_win));
942 while (attachments) {
943 GnomeVFSFileSize att_size;
945 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
946 attachments->data, allowed_size);
947 total_size += att_size;
949 if (att_size > allowed_size) {
950 g_debug ("%s: total size: %u",
951 __FUNCTION__, (unsigned int)total_size);
954 allowed_size -= att_size;
956 attachments = g_slist_next(attachments);
963 g_free (account_name);
965 g_object_unref (G_OBJECT(account));
967 g_object_unref (G_OBJECT(folder));
969 g_object_unref (G_OBJECT(msg));
973 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
975 /* if there are no accounts yet, just show the wizard */
976 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
977 if (!modest_ui_actions_run_account_setup_wizard (win))
980 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
985 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
989 ModestMailOperationStatus status;
991 /* If there is no message or the operation was not successful */
992 status = modest_mail_operation_get_status (mail_op);
993 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
996 /* If it's a memory low issue, then show a banner */
997 error = modest_mail_operation_get_error (mail_op);
998 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
999 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
1000 GObject *source = modest_mail_operation_get_source (mail_op);
1001 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
1002 _KR("memr_ib_operation_disabled"),
1004 g_object_unref (source);
1007 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
1008 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
1009 gchar *subject, *msg, *format = NULL;
1010 TnyAccount *account;
1012 subject = (header) ? tny_header_dup_subject (header) : NULL;
1014 subject = g_strdup (_("mail_va_no_subject"));
1016 account = modest_mail_operation_get_account (mail_op);
1018 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
1019 ModestProtocol *protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), proto);
1022 if (tny_account_get_connection_status (account) ==
1023 TNY_CONNECTION_STATUS_CONNECTED) {
1025 format = modest_protocol_get_translation (protocol,
1026 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE,
1029 format = modest_protocol_get_translation (protocol,
1030 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE_LOST_HEADER);
1033 format = g_strdup_printf (_("mail_ib_backend_server_invalid"),
1034 tny_account_get_hostname (account));
1037 g_object_unref (account);
1042 format = g_strdup (_("emev_ni_ui_imap_message_not_available_in_server"));
1044 format = g_strdup (_("emev_ni_ui_pop3_msg_recv_error"));
1048 msg = g_strdup_printf (format, subject);
1049 modest_platform_run_information_dialog (NULL, msg, FALSE);
1055 /* Remove the header from the preregistered uids */
1056 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1069 } OpenMsgBannerInfo;
1072 GtkTreeModel *model;
1074 ModestWindow *caller_window;
1075 OpenMsgBannerInfo *banner_info;
1076 GtkTreeRowReference *rowref;
1080 open_msg_banner_idle (gpointer userdata)
1082 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
1084 gdk_threads_enter ();
1085 banner_info->idle_handler = 0;
1086 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
1087 if (banner_info->banner)
1088 g_object_ref (banner_info->banner);
1090 gdk_threads_leave ();
1096 get_header_view_from_window (ModestWindow *window)
1098 GtkWidget *header_view;
1100 if (MODEST_IS_MAIN_WINDOW (window)) {
1101 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
1102 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1103 #ifdef MODEST_TOOLKIT_HILDON2
1104 } else if (MODEST_IS_HEADER_WINDOW (window)){
1105 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
1115 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
1118 gchar *account = NULL;
1119 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
1124 folder = tny_header_get_folder (header);
1125 /* Gets folder type (OUTBOX headers will be opened in edit window */
1126 if (modest_tny_folder_is_local_folder (folder)) {
1127 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1128 if (folder_type == TNY_FOLDER_TYPE_INVALID)
1129 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1132 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
1133 TnyTransportAccount *traccount = NULL;
1134 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
1135 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
1137 ModestTnySendQueue *send_queue = NULL;
1138 ModestTnySendQueueStatus status;
1140 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
1141 TNY_ACCOUNT(traccount)));
1142 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
1143 if (TNY_IS_SEND_QUEUE (send_queue)) {
1144 msg_id = modest_tny_send_queue_get_msg_id (header);
1145 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
1147 /* Only open messages in outbox with the editor if they are in Failed state */
1148 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
1151 #ifdef MODEST_TOOLKIT_HILDON2
1153 /* In Fremantle we can not
1154 open any message from
1155 outbox which is not in
1161 g_object_unref(traccount);
1163 g_warning("Cannot get transport account for message in outbox!!");
1165 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
1166 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
1170 TnyAccount *acc = tny_folder_get_account (folder);
1173 g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (acc));
1174 g_object_unref (acc);
1178 g_object_unref (folder);
1184 open_msg_cb (ModestMailOperation *mail_op,
1191 ModestWindowMgr *mgr = NULL;
1192 ModestWindow *parent_win = NULL;
1193 ModestWindow *win = NULL;
1194 gchar *account = NULL;
1195 gboolean open_in_editor = FALSE;
1197 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1199 /* Do nothing if there was any problem with the mail
1200 operation. The error will be shown by the error_handler of
1201 the mail operation */
1202 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1205 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1207 /* Mark header as read */
1208 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1210 account = get_info_from_header (header, &open_in_editor, &can_open);
1214 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1216 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1218 if (open_in_editor) {
1219 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1220 gchar *from_header = NULL, *acc_name;
1221 gchar *mailbox = NULL;
1223 from_header = tny_header_dup_from (header);
1225 /* we cannot edit without a valid account... */
1226 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1227 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1228 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1230 g_free (from_header);
1235 acc_name = modest_utils_get_account_name_from_recipient (from_header, &mailbox);
1236 g_free (from_header);
1242 win = modest_msg_edit_window_new (msg, account, mailbox, TRUE);
1246 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1247 const gchar *mailbox = NULL;
1249 if (parent_win && MODEST_IS_WINDOW (parent_win))
1250 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_win));
1252 if (helper->rowref && helper->model) {
1253 win = modest_msg_view_window_new_with_header_model (msg, account, mailbox, (const gchar*) uid,
1254 helper->model, helper->rowref);
1256 win = modest_msg_view_window_new_for_attachment (msg, NULL, account, mailbox, (const gchar*) uid);
1261 /* Register and show new window */
1263 mgr = modest_runtime_get_window_mgr ();
1264 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1265 gtk_widget_destroy (GTK_WIDGET (win));
1268 gtk_widget_show_all (GTK_WIDGET(win));
1271 /* Update toolbar dimming state */
1272 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1273 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1279 g_object_unref (parent_win);
1283 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1286 const GError *error;
1287 GObject *win = NULL;
1288 ModestMailOperationStatus status;
1290 win = modest_mail_operation_get_source (mail_op);
1291 error = modest_mail_operation_get_error (mail_op);
1292 status = modest_mail_operation_get_status (mail_op);
1294 /* If the mail op has been cancelled then it's not an error:
1295 don't show any message */
1296 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1297 TnyAccount *account = modest_mail_operation_get_account (mail_op);
1298 if (modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
1299 (GError *) error, account)) {
1300 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
1301 modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
1303 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1304 modest_platform_information_banner ((GtkWidget *) win,
1305 NULL, _("emev_ui_imap_inbox_select_error"));
1306 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1307 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1308 modest_platform_information_banner ((GtkWidget *) win,
1309 NULL, _CS ("sfil_ni_unable_to_open_file_not_found"));
1310 } else if (user_data) {
1311 modest_platform_information_banner ((GtkWidget *) win,
1315 g_object_unref (account);
1319 g_object_unref (win);
1323 * Returns the account a list of headers belongs to. It returns a
1324 * *new* reference so don't forget to unref it
1327 get_account_from_header_list (TnyList *headers)
1329 TnyAccount *account = NULL;
1331 if (tny_list_get_length (headers) > 0) {
1332 TnyIterator *iter = tny_list_create_iterator (headers);
1333 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1334 TnyFolder *folder = tny_header_get_folder (header);
1337 g_object_unref (header);
1339 while (!tny_iterator_is_done (iter)) {
1340 header = TNY_HEADER (tny_iterator_get_current (iter));
1341 folder = tny_header_get_folder (header);
1344 g_object_unref (header);
1346 tny_iterator_next (iter);
1351 account = tny_folder_get_account (folder);
1352 g_object_unref (folder);
1356 g_object_unref (header);
1358 g_object_unref (iter);
1364 get_account_from_header (TnyHeader *header)
1366 TnyAccount *account = NULL;
1369 folder = tny_header_get_folder (header);
1372 account = tny_folder_get_account (folder);
1373 g_object_unref (folder);
1379 caller_win_destroyed (OpenMsgHelper *helper, GObject *object)
1381 if (helper->caller_window)
1382 helper->caller_window = NULL;
1386 open_msg_helper_destroyer (gpointer user_data)
1388 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1390 if (helper->caller_window) {
1391 g_object_weak_unref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1392 helper->caller_window = NULL;
1395 if (helper->banner_info) {
1396 g_free (helper->banner_info->message);
1397 if (helper->banner_info->idle_handler > 0) {
1398 g_source_remove (helper->banner_info->idle_handler);
1399 helper->banner_info->idle_handler = 0;
1401 if (helper->banner_info->banner != NULL) {
1402 gtk_widget_destroy (helper->banner_info->banner);
1403 g_object_unref (helper->banner_info->banner);
1404 helper->banner_info->banner = NULL;
1406 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1407 helper->banner_info = NULL;
1409 g_object_unref (helper->model);
1410 g_object_unref (helper->header);
1411 gtk_tree_row_reference_free (helper->rowref);
1412 g_slice_free (OpenMsgHelper, helper);
1416 open_msg_performer(gboolean canceled,
1418 GtkWindow *parent_window,
1419 TnyAccount *account,
1422 ModestMailOperation *mail_op = NULL;
1423 gchar *error_msg = NULL;
1424 ModestProtocolType proto;
1425 TnyConnectionStatus status;
1426 OpenMsgHelper *helper = NULL;
1427 ModestProtocol *protocol;
1428 ModestProtocolRegistry *protocol_registry;
1431 helper = (OpenMsgHelper *) user_data;
1433 status = tny_account_get_connection_status (account);
1434 if (err || canceled || helper->caller_window == NULL) {
1435 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1436 /* Free the helper */
1437 open_msg_helper_destroyer (helper);
1439 /* In disk full conditions we could get this error here */
1440 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
1441 (GtkWidget *) parent_window, err,
1447 /* Get the error message depending on the protocol */
1448 proto = modest_tny_account_get_protocol_type (account);
1449 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1450 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1453 protocol_registry = modest_runtime_get_protocol_registry ();
1454 subject = tny_header_dup_subject (helper->header);
1456 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1457 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1461 if (error_msg == NULL) {
1462 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1465 #ifndef MODEST_TOOLKIT_HILDON2
1466 gboolean show_open_draft = FALSE;
1467 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1469 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1471 TnyFolderType folder_type;
1473 folder = tny_header_get_folder (helper->header);
1474 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1475 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1476 g_object_unref (folder);
1480 #ifdef MODEST_TOOLKIT_HILDON2
1483 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1485 if (!g_strcmp0 (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) ||
1486 !g_strcmp0 (account_name, MODEST_MMC_ACCOUNT_ID)) {
1487 g_free (account_name);
1488 account_name = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_window)));
1492 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1493 g_free (account_name);
1494 open_msg_helper_destroyer (helper);
1499 ModestWindow *window;
1500 GtkWidget *header_view;
1503 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1504 uid = modest_tny_folder_get_header_unique_id (helper->header);
1506 const gchar *mailbox = NULL;
1507 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_window));
1508 window = modest_msg_view_window_new_from_header_view
1509 (MODEST_HEADER_VIEW (header_view), account_name, mailbox, uid, helper->rowref);
1510 if (window != NULL) {
1511 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1513 gtk_widget_destroy (GTK_WIDGET (window));
1515 gtk_widget_show_all (GTK_WIDGET(window));
1519 g_free (account_name);
1521 open_msg_helper_destroyer (helper);
1524 g_free (account_name);
1526 /* Create the mail operation */
1528 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1529 modest_ui_actions_disk_operations_error_handler,
1530 g_strdup (error_msg), g_free);
1531 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1535 #ifndef MODEST_TOOLKIT_HILDON2
1536 if (show_open_draft) {
1537 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1538 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1539 helper->banner_info->banner = NULL;
1540 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1541 helper->banner_info);
1547 headers = TNY_LIST (tny_simple_list_new ());
1548 tny_list_prepend (headers, G_OBJECT (helper->header));
1549 modest_mail_operation_get_msgs_full (mail_op,
1553 open_msg_helper_destroyer);
1554 g_object_unref (headers);
1561 g_object_unref (mail_op);
1562 g_object_unref (account);
1566 * This function is used by both modest_ui_actions_on_open and
1567 * modest_ui_actions_on_header_activated. This way we always do the
1568 * same when trying to open messages.
1571 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1573 ModestWindowMgr *mgr = NULL;
1574 TnyAccount *account;
1575 gboolean cached = FALSE;
1577 GtkWidget *header_view = NULL;
1578 OpenMsgHelper *helper;
1579 ModestWindow *window;
1581 g_return_if_fail (header != NULL && rowref != NULL && gtk_tree_row_reference_valid (rowref));
1583 mgr = modest_runtime_get_window_mgr ();
1586 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1587 if (header_view == NULL)
1590 /* Get the account */
1591 account = get_account_from_header (header);
1596 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1598 /* Do not open again the message and present the
1599 window to the user */
1602 #ifndef MODEST_TOOLKIT_HILDON2
1603 gtk_window_present (GTK_WINDOW (window));
1606 /* the header has been registered already, we don't do
1607 * anything but wait for the window to come up*/
1608 g_debug ("header %p already registered, waiting for window", header);
1613 /* Open each message */
1614 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1616 /* Allways download if we are online. */
1617 if (!tny_device_is_online (modest_runtime_get_device ())) {
1620 /* If ask for user permission to download the messages */
1621 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1622 _("mcen_nc_get_msg"));
1624 /* End if the user does not want to continue */
1625 if (response == GTK_RESPONSE_CANCEL) {
1631 /* We register the window for opening */
1632 modest_window_mgr_register_header (mgr, header, NULL);
1634 /* Create the helper. We need to get a reference to the model
1635 here because it could change while the message is readed
1636 (the user could switch between folders) */
1637 helper = g_slice_new (OpenMsgHelper);
1638 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1639 helper->caller_window = win;
1640 g_object_weak_ref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1641 helper->header = g_object_ref (header);
1642 helper->rowref = gtk_tree_row_reference_copy (rowref);
1643 helper->banner_info = NULL;
1645 /* Connect to the account and perform */
1647 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1648 open_msg_performer, helper);
1650 /* Call directly the performer, do not need to connect */
1651 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1652 g_object_ref (account), helper);
1657 g_object_unref (account);
1661 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1668 /* we check for low-mem; in that case, show a warning, and don't allow
1671 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1675 headers = get_selected_headers (win);
1679 headers_count = tny_list_get_length (headers);
1680 if (headers_count != 1) {
1681 if (headers_count > 1) {
1682 /* Don't allow activation if there are more than one message selected */
1683 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1686 g_object_unref (headers);
1690 iter = tny_list_create_iterator (headers);
1691 header = TNY_HEADER (tny_iterator_get_current (iter));
1692 g_object_unref (iter);
1696 open_msg_from_header (header, NULL, win);
1697 g_object_unref (header);
1700 g_object_unref(headers);
1704 rf_helper_window_closed (gpointer data,
1707 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1709 helper->parent_window = NULL;
1712 static ReplyForwardHelper*
1713 create_reply_forward_helper (ReplyForwardAction action,
1715 guint reply_forward_type,
1718 TnyHeader *top_header,
1721 ReplyForwardHelper *rf_helper = NULL;
1722 const gchar *active_acc = modest_window_get_active_account (win);
1723 const gchar *active_mailbox = modest_window_get_active_mailbox (win);
1725 rf_helper = g_slice_new0 (ReplyForwardHelper);
1726 rf_helper->reply_forward_type = reply_forward_type;
1727 rf_helper->action = action;
1728 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1729 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1730 rf_helper->top_header = (top_header) ? g_object_ref (top_header) : NULL;
1731 rf_helper->msg_part = (msg_part) ? g_object_ref (msg_part) : NULL;
1732 rf_helper->account_name = (active_acc) ?
1733 g_strdup (active_acc) :
1734 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1735 rf_helper->mailbox = g_strdup (active_mailbox);
1737 rf_helper->parts = g_object_ref (parts);
1739 rf_helper->parts = NULL;
1741 /* Note that window could be destroyed just AFTER calling
1742 register_window so we must ensure that this pointer does
1743 not hold invalid references */
1744 if (rf_helper->parent_window)
1745 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1746 rf_helper_window_closed, rf_helper);
1752 free_reply_forward_helper (gpointer data)
1754 ReplyForwardHelper *helper;
1756 helper = (ReplyForwardHelper *) data;
1757 g_free (helper->account_name);
1758 g_free (helper->mailbox);
1760 g_object_unref (helper->header);
1761 if (helper->top_header)
1762 g_object_unref (helper->top_header);
1763 if (helper->msg_part)
1764 g_object_unref (helper->msg_part);
1766 g_object_unref (helper->parts);
1767 if (helper->parent_window)
1768 g_object_weak_unref (G_OBJECT (helper->parent_window),
1769 rf_helper_window_closed, helper);
1770 g_slice_free (ReplyForwardHelper, helper);
1774 reply_forward_cb (ModestMailOperation *mail_op,
1781 TnyMsg *new_msg = NULL;
1782 ReplyForwardHelper *rf_helper;
1783 ModestWindow *msg_win = NULL;
1784 ModestEditType edit_type;
1786 TnyAccount *account = NULL;
1787 ModestWindowMgr *mgr = NULL;
1788 gchar *signature = NULL, *recipient = NULL;
1789 gboolean use_signature;
1791 /* If there was any error. The mail operation could be NULL,
1792 this means that we already have the message downloaded and
1793 that we didn't do a mail operation to retrieve it */
1794 rf_helper = (ReplyForwardHelper *) user_data;
1795 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1798 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1799 rf_helper->account_name, rf_helper->mailbox);
1801 recipient = modest_text_utils_get_email_address (from);
1802 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr (),
1807 /* Create reply mail */
1808 switch (rf_helper->action) {
1809 /* Use the msg_header to ensure that we have all the
1810 information. The summary can lack some data */
1811 TnyHeader *msg_header;
1813 msg_header = tny_msg_get_header (rf_helper->msg_part?rf_helper->msg_part:msg);
1815 modest_tny_msg_create_reply_msg (rf_helper->msg_part?rf_helper->msg_part:msg, msg_header, from,
1816 (use_signature) ? signature : NULL,
1817 rf_helper->reply_forward_type,
1818 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1819 g_object_unref (msg_header);
1821 case ACTION_REPLY_TO_ALL:
1822 msg_header = tny_msg_get_header (rf_helper->msg_part?rf_helper->msg_part:msg);
1824 modest_tny_msg_create_reply_msg (rf_helper->msg_part?rf_helper->msg_part:msg, msg_header, from,
1825 (use_signature) ? signature : NULL,
1826 rf_helper->reply_forward_type,
1827 MODEST_TNY_MSG_REPLY_MODE_ALL);
1828 edit_type = MODEST_EDIT_TYPE_REPLY;
1829 g_object_unref (msg_header);
1831 case ACTION_FORWARD:
1833 modest_tny_msg_create_forward_msg (rf_helper->msg_part?rf_helper->msg_part:msg, from,
1834 (use_signature) ? signature : NULL,
1835 rf_helper->reply_forward_type);
1836 edit_type = MODEST_EDIT_TYPE_FORWARD;
1839 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1841 g_return_if_reached ();
1849 g_warning ("%s: failed to create message\n", __FUNCTION__);
1853 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1854 rf_helper->account_name,
1855 TNY_ACCOUNT_TYPE_STORE);
1857 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1861 /* Create and register the windows */
1862 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, rf_helper->mailbox, FALSE);
1863 mgr = modest_runtime_get_window_mgr ();
1864 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1866 /* Note that register_window could have deleted the account */
1867 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1868 gdouble parent_zoom;
1870 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1871 modest_window_set_zoom (msg_win, parent_zoom);
1874 /* Show edit window */
1875 gtk_widget_show_all (GTK_WIDGET (msg_win));
1878 /* We always unregister the header because the message is
1879 forwarded or replied so the original one is no longer
1881 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1884 g_object_unref (G_OBJECT (new_msg));
1886 g_object_unref (G_OBJECT (account));
1887 free_reply_forward_helper (rf_helper);
1890 /* Checks a list of headers. If any of them are not currently
1891 * downloaded (CACHED) then returns TRUE else returns FALSE.
1894 header_list_count_uncached_msgs (TnyList *header_list)
1897 gint uncached_messages = 0;
1899 iter = tny_list_create_iterator (header_list);
1900 while (!tny_iterator_is_done (iter)) {
1903 header = TNY_HEADER (tny_iterator_get_current (iter));
1905 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1906 uncached_messages ++;
1907 g_object_unref (header);
1910 tny_iterator_next (iter);
1912 g_object_unref (iter);
1914 return uncached_messages;
1917 /* Returns FALSE if the user does not want to download the
1918 * messages. Returns TRUE if the user allowed the download.
1921 connect_to_get_msg (ModestWindow *win,
1922 gint num_of_uncached_msgs,
1923 TnyAccount *account)
1925 GtkResponseType response;
1927 /* Allways download if we are online. */
1928 if (tny_device_is_online (modest_runtime_get_device ()))
1931 /* If offline, then ask for user permission to download the messages */
1932 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1933 ngettext("mcen_nc_get_msg",
1935 num_of_uncached_msgs));
1937 if (response == GTK_RESPONSE_CANCEL)
1940 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1944 reply_forward_performer (gboolean canceled,
1946 GtkWindow *parent_window,
1947 TnyAccount *account,
1950 ReplyForwardHelper *rf_helper = NULL;
1951 ModestMailOperation *mail_op;
1953 rf_helper = (ReplyForwardHelper *) user_data;
1955 if (canceled || err) {
1956 free_reply_forward_helper (rf_helper);
1960 /* Retrieve the message */
1961 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1962 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1963 modest_ui_actions_disk_operations_error_handler,
1965 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1966 modest_mail_operation_get_msg_and_parts (mail_op, rf_helper->top_header, rf_helper->parts, TRUE, reply_forward_cb, rf_helper);
1969 g_object_unref(mail_op);
1973 all_parts_retrieved (TnyMimePart *part)
1975 if (!TNY_IS_CAMEL_BS_MIME_PART (part)) {
1978 TnyList *pending_parts;
1979 TnyIterator *iterator;
1980 gboolean all_retrieved = TRUE;
1982 pending_parts = TNY_LIST (tny_simple_list_new ());
1983 tny_mime_part_get_parts (part, pending_parts);
1984 iterator = tny_list_create_iterator (pending_parts);
1985 while (all_retrieved && !tny_iterator_is_done (iterator)) {
1988 child = TNY_MIME_PART (tny_iterator_get_current (iterator));
1990 if (tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (child))) {
1991 all_retrieved = all_parts_retrieved (TNY_MIME_PART (child));
1993 all_retrieved = FALSE;
1996 g_object_unref (child);
1997 tny_iterator_next (iterator);
1999 g_object_unref (iterator);
2000 g_object_unref (pending_parts);
2001 return all_retrieved;
2006 forward_pending_parts_helper (TnyMimePart *part, TnyList *list)
2009 TnyIterator *iterator;
2011 if (!tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (part))) {
2012 tny_list_append (list, G_OBJECT (part));
2014 parts = TNY_LIST (tny_simple_list_new ());
2015 tny_mime_part_get_parts (part, parts);
2016 for (iterator = tny_list_create_iterator (parts);
2017 !tny_iterator_is_done (iterator);
2018 tny_iterator_next (iterator)) {
2021 child = TNY_MIME_PART (tny_iterator_get_current (iterator));
2022 forward_pending_parts_helper (child, list);
2023 g_object_unref (child);
2025 g_object_unref (iterator);
2026 g_object_unref (parts);
2030 forward_pending_parts (TnyMsg *msg)
2032 TnyList *result = TNY_LIST (tny_simple_list_new ());
2033 if (TNY_IS_CAMEL_BS_MIME_PART (msg)) {
2034 forward_pending_parts_helper (TNY_MIME_PART (msg), result);
2041 * Common code for the reply and forward actions
2044 reply_forward (ReplyForwardAction action, ModestWindow *win)
2046 ReplyForwardHelper *rf_helper = NULL;
2047 guint reply_forward_type;
2049 g_return_if_fail (win && MODEST_IS_WINDOW(win));
2051 /* we check for low-mem; in that case, show a warning, and don't allow
2052 * reply/forward (because it could potentially require a lot of memory */
2053 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2057 /* we need an account when editing */
2058 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
2059 if (!modest_ui_actions_run_account_setup_wizard (win))
2063 reply_forward_type =
2064 modest_conf_get_int (modest_runtime_get_conf (),
2065 (action == ACTION_FORWARD) ?
2066 MODEST_CONF_FORWARD_TYPE :
2067 MODEST_CONF_REPLY_TYPE,
2070 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2072 TnyMsg *top_msg = NULL;
2073 TnyHeader *header = NULL;
2074 /* Get header and message. Do not free them here, the
2075 reply_forward_cb must do it */
2076 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
2077 top_msg = modest_msg_view_window_get_top_message (MODEST_MSG_VIEW_WINDOW(win));
2078 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
2080 if (msg && header && (action != ACTION_FORWARD || all_parts_retrieved (TNY_MIME_PART (msg)))) {
2082 rf_helper = create_reply_forward_helper (action, win,
2083 reply_forward_type, header, NULL, NULL, NULL);
2084 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
2086 gboolean do_download = TRUE;
2088 if (msg && header && action == ACTION_FORWARD) {
2089 if (top_msg == NULL)
2090 top_msg = g_object_ref (msg);
2091 /* Not all parts retrieved. Then we have to retrieve them all before
2092 * creating the forward message */
2093 if (!tny_device_is_online (modest_runtime_get_device ())) {
2096 /* If ask for user permission to download the messages */
2097 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2098 ngettext("mcen_nc_get_msg",
2102 /* End if the user does not want to continue */
2103 if (response == GTK_RESPONSE_CANCEL)
2104 do_download = FALSE;
2108 TnyList *pending_parts;
2110 TnyAccount *account;
2111 TnyHeader *top_header;
2114 top_header = tny_msg_get_header (top_msg);
2115 pending_parts = forward_pending_parts (top_msg);
2116 rf_helper = create_reply_forward_helper (action, win,
2117 reply_forward_type, header, msg, top_header, pending_parts);
2118 g_object_unref (pending_parts);
2120 folder = tny_header_get_folder (top_header);
2121 account = tny_folder_get_account (folder);
2122 modest_platform_connect_and_perform (GTK_WINDOW (win),
2124 reply_forward_performer,
2126 if (folder) g_object_unref (folder);
2127 g_object_unref (account);
2128 if (top_header) g_object_unref (top_header);
2132 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
2137 g_object_unref (msg);
2139 g_object_unref (top_msg);
2141 g_object_unref (header);
2143 TnyHeader *header = NULL;
2145 gboolean do_retrieve = TRUE;
2146 TnyList *header_list = NULL;
2148 header_list = get_selected_headers (win);
2151 /* Check that only one message is selected for replying */
2152 if (tny_list_get_length (header_list) != 1) {
2153 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
2154 NULL, _("mcen_ib_select_one_message"));
2155 g_object_unref (header_list);
2159 /* Only reply/forward to one message */
2160 iter = tny_list_create_iterator (header_list);
2161 header = TNY_HEADER (tny_iterator_get_current (iter));
2162 g_object_unref (iter);
2164 /* Retrieve messages */
2165 do_retrieve = (action == ACTION_FORWARD) ||
2166 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
2169 TnyAccount *account = NULL;
2170 TnyFolder *folder = NULL;
2171 gdouble download = TRUE;
2172 guint uncached_msgs = 0;
2174 folder = tny_header_get_folder (header);
2176 goto do_retrieve_frees;
2177 account = tny_folder_get_account (folder);
2179 goto do_retrieve_frees;
2181 uncached_msgs = header_list_count_uncached_msgs (header_list);
2183 if (uncached_msgs > 0) {
2184 /* Allways download if we are online. */
2185 if (!tny_device_is_online (modest_runtime_get_device ())) {
2188 /* If ask for user permission to download the messages */
2189 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2190 ngettext("mcen_nc_get_msg",
2194 /* End if the user does not want to continue */
2195 if (response == GTK_RESPONSE_CANCEL)
2202 rf_helper = create_reply_forward_helper (action, win,
2203 reply_forward_type, header, NULL, NULL, NULL);
2204 if (uncached_msgs > 0) {
2205 modest_platform_connect_and_perform (GTK_WINDOW (win),
2207 reply_forward_performer,
2210 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
2211 account, rf_helper);
2216 g_object_unref (account);
2218 g_object_unref (folder);
2220 reply_forward_cb (NULL, header, FALSE, NULL, NULL, NULL);
2223 g_object_unref (header_list);
2224 g_object_unref (header);
2229 modest_ui_actions_reply_calendar (ModestWindow *win, TnyList *header_pairs)
2234 gboolean use_signature;
2237 const gchar *account_name;
2238 const gchar *mailbox;
2239 TnyHeader *msg_header;
2240 ModestWindowMgr *mgr;
2243 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW(win));
2245 /* we check for low-mem; in that case, show a warning, and don't allow
2246 * reply/forward (because it could potentially require a lot of memory */
2247 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2250 account_name = modest_window_get_active_account (MODEST_WINDOW (win));
2251 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (win));
2252 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
2253 account_name, mailbox);
2254 recipient = modest_text_utils_get_email_address (from);
2255 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr(),
2260 msg = modest_msg_view_window_get_message(MODEST_MSG_VIEW_WINDOW(win));
2261 g_return_if_fail(msg);
2263 msg_header = tny_msg_get_header (msg);
2265 modest_tny_msg_create_reply_calendar_msg (msg, msg_header, from,
2266 (use_signature) ? signature : NULL,
2268 g_object_unref (msg_header);
2274 g_warning ("%s: failed to create message\n", __FUNCTION__);
2278 msg_win = (GtkWidget *) modest_msg_edit_window_new (new_msg, account_name, mailbox, FALSE);
2279 mgr = modest_runtime_get_window_mgr ();
2280 modest_window_mgr_register_window (mgr, MODEST_WINDOW (msg_win), (ModestWindow *) win);
2282 /* Show edit window */
2283 gtk_widget_show_all (GTK_WIDGET (msg_win));
2287 g_object_unref (G_OBJECT (new_msg));
2291 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
2293 g_return_if_fail (MODEST_IS_WINDOW(win));
2295 reply_forward (ACTION_REPLY, win);
2299 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
2301 g_return_if_fail (MODEST_IS_WINDOW(win));
2303 reply_forward (ACTION_FORWARD, win);
2307 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
2309 g_return_if_fail (MODEST_IS_WINDOW(win));
2311 reply_forward (ACTION_REPLY_TO_ALL, win);
2315 modest_ui_actions_on_next (GtkAction *action,
2316 ModestWindow *window)
2318 if (MODEST_IS_MAIN_WINDOW (window)) {
2319 GtkWidget *header_view;
2321 header_view = modest_main_window_get_child_widget (
2322 MODEST_MAIN_WINDOW(window),
2323 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2327 modest_header_view_select_next (
2328 MODEST_HEADER_VIEW(header_view));
2329 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2330 modest_msg_view_window_select_next_message (
2331 MODEST_MSG_VIEW_WINDOW (window));
2333 g_return_if_reached ();
2338 modest_ui_actions_on_prev (GtkAction *action,
2339 ModestWindow *window)
2341 g_return_if_fail (MODEST_IS_WINDOW(window));
2343 if (MODEST_IS_MAIN_WINDOW (window)) {
2344 GtkWidget *header_view;
2345 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2346 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2350 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
2351 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2352 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
2354 g_return_if_reached ();
2359 modest_ui_actions_on_sort (GtkAction *action,
2360 ModestWindow *window)
2362 GtkWidget *header_view = NULL;
2364 g_return_if_fail (MODEST_IS_WINDOW(window));
2366 if (MODEST_IS_MAIN_WINDOW (window)) {
2367 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2368 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2369 #ifdef MODEST_TOOLKIT_HILDON2
2370 } else if (MODEST_IS_HEADER_WINDOW (window)) {
2371 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2376 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
2381 /* Show sorting dialog */
2382 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
2386 sync_folder_cb (ModestMailOperation *mail_op,
2390 ModestHeaderView *header_view = (ModestHeaderView *) user_data;
2392 if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
2393 ModestWindow *parent = (ModestWindow *) modest_mail_operation_get_source (mail_op);
2395 /* We must clear first, because otherwise set_folder will ignore */
2396 /* the change as the folders are the same */
2397 modest_header_view_clear (header_view);
2398 modest_header_view_set_folder (header_view, folder, TRUE, parent, NULL, NULL);
2400 g_object_unref (parent);
2403 g_object_unref (header_view);
2407 idle_refresh_folder (gpointer source)
2409 ModestHeaderView *header_view = NULL;
2411 /* If the window still exists */
2412 if (!GTK_IS_WIDGET (source) ||
2413 !GTK_WIDGET_VISIBLE (source))
2416 /* Refresh the current view */
2417 #ifdef MODEST_TOOLKIT_HILDON2
2418 if (MODEST_IS_HEADER_WINDOW (source))
2419 header_view = modest_header_window_get_header_view ((ModestHeaderWindow *) source);
2421 if (MODEST_IS_MAIN_WINDOW (source))
2422 header_view = MODEST_HEADER_VIEW (modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source),
2423 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
2426 TnyFolder *folder = modest_header_view_get_folder (header_view);
2428 /* Sync the folder status */
2429 ModestMailOperation *mail_op = modest_mail_operation_new (source);
2430 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2431 modest_mail_operation_sync_folder (mail_op, folder, FALSE, sync_folder_cb, g_object_ref (header_view));
2432 g_object_unref (folder);
2433 g_object_unref (mail_op);
2441 update_account_cb (ModestMailOperation *self,
2442 TnyList *new_headers,
2446 gboolean show_visual_notifications;
2448 top = modest_window_mgr_get_current_top (modest_runtime_get_window_mgr ());
2449 show_visual_notifications = (top) ? FALSE : TRUE;
2451 /* Notify new messages have been downloaded. If the
2452 send&receive was invoked by the user then do not show any
2453 visual notification, only play a sound and activate the LED
2454 (for the Maemo version) */
2455 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0) {
2457 /* We only notify about really new messages (not seen) we get */
2458 TnyList *actually_new_list;
2459 TnyIterator *iterator;
2460 actually_new_list = TNY_LIST (tny_simple_list_new ());
2461 for (iterator = tny_list_create_iterator (new_headers);
2462 !tny_iterator_is_done (iterator);
2463 tny_iterator_next (iterator)) {
2465 TnyHeaderFlags flags;
2466 header = TNY_HEADER (tny_iterator_get_current (iterator));
2467 flags = tny_header_get_flags (header);
2469 if (!(flags & TNY_HEADER_FLAG_SEEN)) {
2470 /* Messages are ordered from most
2471 recent to oldest. But we want to
2472 show notifications starting from
2473 the oldest message. That's why we
2475 tny_list_prepend (actually_new_list, G_OBJECT (header));
2477 g_object_unref (header);
2479 g_object_unref (iterator);
2481 if (tny_list_get_length (actually_new_list) > 0) {
2482 GList *new_headers_list = NULL;
2484 new_headers_list = modest_utils_create_notification_list_from_header_list (actually_new_list);
2486 /* Send notifications */
2487 if (new_headers_list) {
2488 modest_platform_on_new_headers_received (new_headers_list,
2489 show_visual_notifications);
2491 modest_utils_free_notification_list (new_headers_list);
2494 g_object_unref (actually_new_list);
2498 /* Refresh the current folder in an idle. We do this
2499 in order to avoid refresh cancelations if the
2500 currently viewed folder is the inbox */
2501 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
2502 idle_refresh_folder,
2509 TnyAccount *account;
2511 gchar *account_name;
2512 gboolean poke_status;
2513 gboolean interactive;
2514 ModestMailOperation *mail_op;
2518 do_send_receive_performer (gboolean canceled,
2520 GtkWindow *parent_window,
2521 TnyAccount *account,
2524 SendReceiveInfo *info;
2526 info = (SendReceiveInfo *) user_data;
2528 if (err || canceled) {
2529 /* In disk full conditions we could get this error here */
2530 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
2531 (GtkWidget *) parent_window, err,
2534 if (info->mail_op) {
2535 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2541 /* Set send/receive operation in progress */
2542 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2543 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2546 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2547 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2548 G_CALLBACK (on_send_receive_finished),
2551 /* Send & receive. */
2552 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2553 update_account_cb, info->win);
2558 g_object_unref (G_OBJECT (info->mail_op));
2559 if (info->account_name)
2560 g_free (info->account_name);
2562 g_object_unref (info->win);
2564 g_object_unref (info->account);
2565 g_slice_free (SendReceiveInfo, info);
2569 * This function performs the send & receive required actions. The
2570 * window is used to create the mail operation. Typically it should
2571 * always be the main window, but we pass it as argument in order to
2575 modest_ui_actions_do_send_receive (const gchar *account_name,
2576 gboolean force_connection,
2577 gboolean poke_status,
2578 gboolean interactive,
2581 gchar *acc_name = NULL;
2582 SendReceiveInfo *info;
2583 ModestTnyAccountStore *acc_store;
2584 TnyAccount *account;
2586 /* If no account name was provided then get the current account, and if
2587 there is no current account then pick the default one: */
2588 if (!account_name) {
2590 acc_name = g_strdup (modest_window_get_active_account (win));
2592 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2594 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2598 acc_name = g_strdup (account_name);
2601 acc_store = modest_runtime_get_account_store ();
2602 account = modest_tny_account_store_get_server_account (acc_store, acc_name, TNY_ACCOUNT_TYPE_STORE);
2606 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2610 /* Do not automatically refresh accounts that are flagged as
2611 NO_AUTO_UPDATE. This could be useful for accounts that
2612 handle their own update times */
2614 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
2615 if (proto != MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
2616 const gchar *tag = MODEST_PROTOCOL_REGISTRY_NO_AUTO_UPDATE_PROTOCOLS;
2617 ModestProtocolRegistry *registry = modest_runtime_get_protocol_registry ();
2619 if (modest_protocol_registry_protocol_type_has_tag (registry, proto, tag)) {
2620 g_debug ("%s no auto update allowed for account %s", __FUNCTION__, account_name);
2621 g_object_unref (account);
2628 /* Create the info for the connect and perform */
2629 info = g_slice_new (SendReceiveInfo);
2630 info->account_name = acc_name;
2631 info->win = (win) ? g_object_ref (win) : NULL;
2632 info->poke_status = poke_status;
2633 info->interactive = interactive;
2634 info->account = account;
2635 /* We need to create the operation here, because otherwise it
2636 could happen that the queue emits the queue-empty signal
2637 while we're trying to connect the account */
2638 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2639 modest_ui_actions_disk_operations_error_handler,
2641 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2643 /* Invoke the connect and perform */
2644 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2645 force_connection, info->account,
2646 do_send_receive_performer, info);
2651 modest_ui_actions_do_cancel_send (const gchar *account_name,
2654 TnyTransportAccount *transport_account;
2655 TnySendQueue *send_queue = NULL;
2656 GError *error = NULL;
2658 /* Get transport account */
2660 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2661 (modest_runtime_get_account_store(),
2663 TNY_ACCOUNT_TYPE_TRANSPORT));
2664 if (!transport_account) {
2665 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2670 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2671 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2672 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2673 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2674 "modest: could not find send queue for account\n");
2676 /* Cancel the current send */
2677 tny_account_cancel (TNY_ACCOUNT (transport_account));
2679 /* Suspend all pending messages */
2680 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2684 if (transport_account != NULL)
2685 g_object_unref (G_OBJECT (transport_account));
2689 modest_ui_actions_cancel_send_all (ModestWindow *win)
2691 GSList *account_names, *iter;
2693 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2696 iter = account_names;
2698 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2699 iter = g_slist_next (iter);
2702 modest_account_mgr_free_account_names (account_names);
2703 account_names = NULL;
2707 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2710 /* Check if accounts exist */
2711 gboolean accounts_exist =
2712 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2714 /* If not, allow the user to create an account before trying to send/receive. */
2715 if (!accounts_exist)
2716 modest_ui_actions_on_accounts (NULL, win);
2718 /* Cancel all sending operaitons */
2719 modest_ui_actions_cancel_send_all (win);
2723 * Refreshes all accounts. This function will be used by automatic
2727 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2728 gboolean force_connection,
2729 gboolean poke_status,
2730 gboolean interactive)
2732 GSList *account_names, *iter;
2734 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2737 iter = account_names;
2739 modest_ui_actions_do_send_receive ((const char*) iter->data,
2741 poke_status, interactive, win);
2742 iter = g_slist_next (iter);
2745 modest_account_mgr_free_account_names (account_names);
2746 account_names = NULL;
2750 * Handler of the click on Send&Receive button in the main toolbar
2753 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2755 /* Check if accounts exist */
2756 gboolean accounts_exist;
2759 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2761 /* If not, allow the user to create an account before trying to send/receive. */
2762 if (!accounts_exist)
2763 modest_ui_actions_on_accounts (NULL, win);
2765 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2766 if (MODEST_IS_MAIN_WINDOW (win)) {
2767 GtkWidget *folder_view;
2768 TnyFolderStore *folder_store;
2771 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2772 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2776 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2779 g_object_unref (folder_store);
2780 /* Refresh the active account. Force the connection if needed
2781 and poke the status of all folders */
2782 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2783 #ifdef MODEST_TOOLKIT_HILDON2
2784 } else if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2785 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2788 const gchar *active_account;
2789 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2791 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2798 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2801 GtkWidget *header_view;
2803 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2805 header_view = modest_main_window_get_child_widget (main_window,
2806 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2810 conf = modest_runtime_get_conf ();
2812 /* what is saved/restored is depending on the style; thus; we save with
2813 * old style, then update the style, and restore for this new style
2815 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2817 if (modest_header_view_get_style
2818 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2819 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2820 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2822 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2823 MODEST_HEADER_VIEW_STYLE_DETAILS);
2825 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2826 MODEST_CONF_HEADER_VIEW_KEY);
2831 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2833 ModestMainWindow *main_window)
2835 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2836 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2838 /* in the case the folder is empty, show the empty folder message and focus
2840 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2841 if (modest_header_view_is_empty (header_view)) {
2842 TnyFolder *folder = modest_header_view_get_folder (header_view);
2843 GtkWidget *folder_view =
2844 modest_main_window_get_child_widget (main_window,
2845 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2846 if (folder != NULL) {
2847 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2848 g_object_unref (folder);
2850 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2854 /* If no header has been selected then exit */
2859 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2860 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2862 /* Update toolbar dimming state */
2863 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2864 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2868 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2871 ModestWindow *window)
2873 GtkWidget *open_widget;
2874 GtkTreeRowReference *rowref;
2876 g_return_if_fail (MODEST_IS_WINDOW(window));
2877 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2878 g_return_if_fail (TNY_IS_HEADER (header));
2880 if (modest_header_view_count_selected_headers (header_view) > 1) {
2881 /* Don't allow activation if there are more than one message selected */
2882 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2886 /* we check for low-mem; in that case, show a warning, and don't allow
2887 * activating headers
2889 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2892 if (MODEST_IS_MAIN_WINDOW (window)) {
2893 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2894 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2895 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2899 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2900 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2901 gtk_tree_row_reference_free (rowref);
2905 set_active_account_from_tny_account (TnyAccount *account,
2906 ModestWindow *window)
2908 const gchar *server_acc_name = tny_account_get_id (account);
2910 /* We need the TnyAccount provided by the
2911 account store because that is the one that
2912 knows the name of the Modest account */
2913 TnyAccount *modest_server_account =
2914 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2915 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2917 if (!modest_server_account) {
2918 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2922 /* Update active account, but only if it's not a pseudo-account */
2923 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2924 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2925 const gchar *modest_acc_name =
2926 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2927 if (modest_acc_name)
2928 modest_window_set_active_account (window, modest_acc_name);
2931 g_object_unref (modest_server_account);
2936 folder_refreshed_cb (ModestMailOperation *mail_op,
2940 ModestMainWindow *win = NULL;
2941 GtkWidget *folder_view, *header_view;
2942 const GError *error;
2944 g_return_if_fail (TNY_IS_FOLDER (folder));
2946 win = MODEST_MAIN_WINDOW (user_data);
2948 /* Check if the operation failed due to memory low conditions */
2949 error = modest_mail_operation_get_error (mail_op);
2950 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2951 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2952 modest_platform_run_information_dialog (GTK_WINDOW (win),
2953 _KR("memr_ib_operation_disabled"),
2959 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2961 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2964 TnyFolderStore *current_folder;
2966 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2967 if (current_folder) {
2968 gboolean different = ((TnyFolderStore *) folder != current_folder);
2969 g_object_unref (current_folder);
2975 /* Check if folder is empty and set headers view contents style */
2976 if ((tny_folder_get_all_count (folder) == 0) ||
2977 modest_header_view_is_empty (MODEST_HEADER_VIEW (header_view)))
2978 modest_main_window_set_contents_style (win,
2979 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2983 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2984 TnyFolderStore *folder_store,
2986 ModestMainWindow *main_window)
2988 GtkWidget *header_view;
2990 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2992 header_view = modest_main_window_get_child_widget(main_window,
2993 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2998 if (TNY_IS_ACCOUNT (folder_store)) {
3000 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
3002 /* Show account details */
3003 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
3006 if (TNY_IS_FOLDER (folder_store) && selected) {
3007 TnyAccount *account;
3009 /* Update the active account */
3010 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
3012 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
3013 g_object_unref (account);
3017 /* Set the header style by default, it could
3018 be changed later by the refresh callback to
3020 modest_main_window_set_contents_style (main_window,
3021 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
3023 /* Set folder on header view. This function
3024 will call tny_folder_refresh_async so we
3025 pass a callback that will be called when
3026 finished. We use that callback to set the
3027 empty view if there are no messages */
3028 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
3029 TNY_FOLDER (folder_store),
3031 MODEST_WINDOW (main_window),
3032 folder_refreshed_cb,
3035 /* Restore configuration. We need to do this
3036 *after* the set_folder because the widget
3037 memory asks the header view about its
3039 modest_widget_memory_restore (modest_runtime_get_conf (),
3040 G_OBJECT(header_view),
3041 MODEST_CONF_HEADER_VIEW_KEY);
3043 /* No need to save the header view
3044 configuration for Maemo because it only
3045 saves the sorting stuff and that it's
3046 already being done by the sort
3047 dialog. Remove it when the GNOME version
3048 has the same behaviour */
3049 #ifdef MODEST_TOOLKIT_GTK
3050 if (modest_main_window_get_contents_style (main_window) ==
3051 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
3052 modest_widget_memory_save (modest_runtime_get_conf (),
3053 G_OBJECT (header_view),
3054 MODEST_CONF_HEADER_VIEW_KEY);
3056 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
3060 /* Update dimming state */
3061 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
3062 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
3066 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
3073 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
3075 online = tny_device_is_online (modest_runtime_get_device());
3078 /* already online -- the item is simply not there... */
3079 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
3081 GTK_MESSAGE_WARNING,
3083 _("The %s you selected cannot be found"),
3085 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
3086 gtk_dialog_run (GTK_DIALOG(dialog));
3088 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
3091 _("mcen_bd_dialog_cancel"),
3092 GTK_RESPONSE_REJECT,
3093 _("mcen_bd_dialog_ok"),
3094 GTK_RESPONSE_ACCEPT,
3096 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
3097 "Do you want to get online?"), item);
3098 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
3099 gtk_label_new (txt), FALSE, FALSE, 0);
3100 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3103 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
3104 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3105 /* TODO: Comment about why is this commented out: */
3106 /* modest_platform_connect_and_wait (); */
3109 gtk_widget_destroy (dialog);
3113 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
3116 /* g_debug ("%s %s", __FUNCTION__, link); */
3121 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
3124 modest_platform_activate_uri (link);
3128 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
3131 modest_platform_show_uri_popup (link);
3135 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
3138 /* we check for low-mem; in that case, show a warning, and don't allow
3139 * viewing attachments
3141 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
3144 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
3148 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
3149 const gchar *address,
3152 /* g_debug ("%s %s", __FUNCTION__, address); */
3156 on_save_to_drafts_cb (ModestMailOperation *mail_op,
3157 TnyMsg *saved_draft,
3160 ModestMsgEditWindow *edit_window;
3162 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
3163 #ifndef MODEST_TOOLKIT_HILDON2
3164 ModestMainWindow *win;
3166 /* FIXME. Make the header view sensitive again. This is a
3167 * temporary hack. See modest_ui_actions_on_save_to_drafts()
3169 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
3170 modest_runtime_get_window_mgr(), FALSE));
3172 GtkWidget *hdrview = modest_main_window_get_child_widget(
3173 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3174 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
3178 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
3180 /* Set draft is there was no error */
3181 if (!modest_mail_operation_get_error (mail_op))
3182 modest_msg_edit_window_set_draft (edit_window, saved_draft);
3184 g_object_unref(edit_window);
3188 enough_space_for_message (ModestMsgEditWindow *edit_window,
3191 guint64 available_disk, expected_size;
3196 available_disk = modest_utils_get_available_space (NULL);
3197 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
3198 expected_size = modest_tny_msg_estimate_size (data->plain_body,
3203 /* Double check: disk full condition or message too big */
3204 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
3205 expected_size > available_disk) {
3206 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3207 modest_platform_information_banner (NULL, NULL, msg);
3214 * djcb: if we're in low-memory state, we only allow for
3215 * saving messages smaller than
3216 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
3217 * should still allow for sending anything critical...
3219 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
3220 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
3224 * djcb: we also make sure that the attachments are smaller than the max size
3225 * this is for the case where we'd try to forward a message with attachments
3226 * bigger than our max allowed size, or sending an message from drafts which
3227 * somehow got past our checks when attaching.
3229 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
3230 modest_platform_run_information_dialog (
3231 GTK_WINDOW(edit_window),
3232 _("mail_ib_error_attachment_size"),
3241 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3243 TnyTransportAccount *transport_account;
3244 ModestMailOperation *mail_operation;
3246 gchar *account_name;
3247 ModestAccountMgr *account_mgr;
3248 gboolean had_error = FALSE;
3249 ModestMainWindow *win = NULL;
3251 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
3253 data = modest_msg_edit_window_get_msg_data (edit_window);
3256 if (!enough_space_for_message (edit_window, data)) {
3257 modest_msg_edit_window_free_msg_data (edit_window, data);
3261 account_name = g_strdup (data->account_name);
3262 account_mgr = modest_runtime_get_account_mgr();
3264 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3266 account_name = modest_account_mgr_get_default_account (account_mgr);
3267 if (!account_name) {
3268 g_printerr ("modest: no account found\n");
3269 modest_msg_edit_window_free_msg_data (edit_window, data);
3273 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
3274 account_name = g_strdup (data->account_name);
3278 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3279 (modest_runtime_get_account_store (),
3281 TNY_ACCOUNT_TYPE_TRANSPORT));
3282 if (!transport_account) {
3283 g_printerr ("modest: no transport account found for '%s'\n", account_name);
3284 g_free (account_name);
3285 modest_msg_edit_window_free_msg_data (edit_window, data);
3289 /* Create the mail operation */
3290 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
3292 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3294 modest_mail_operation_save_to_drafts (mail_operation,
3306 data->priority_flags,
3309 data->custom_header_pairs,
3310 on_save_to_drafts_cb,
3311 g_object_ref(edit_window));
3313 #ifdef MODEST_TOOLKIT_HILDON2
3314 /* In hildon2 we always show the information banner on saving to drafts.
3315 * It will be a system information banner in this case.
3317 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3318 modest_platform_information_banner (NULL, NULL, text);
3321 /* Use the main window as the parent of the banner, if the
3322 main window does not exist it won't be shown, if the parent
3323 window exists then it's properly shown. We don't use the
3324 editor window because it could be closed (save to drafts
3325 could happen after closing the window */
3326 win = (ModestMainWindow *)
3327 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
3329 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3330 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
3334 modest_msg_edit_window_set_modified (edit_window, FALSE);
3337 g_free (account_name);
3338 g_object_unref (G_OBJECT (transport_account));
3339 g_object_unref (G_OBJECT (mail_operation));
3341 modest_msg_edit_window_free_msg_data (edit_window, data);
3344 * If the drafts folder is selected then make the header view
3345 * insensitive while the message is being saved to drafts
3346 * (it'll be sensitive again in on_save_to_drafts_cb()). This
3347 * is not very clean but it avoids letting the drafts folder
3348 * in an inconsistent state: the user could edit the message
3349 * being saved and undesirable things would happen.
3350 * In the average case the user won't notice anything at
3351 * all. In the worst case (the user is editing a really big
3352 * file from Drafts) the header view will be insensitive
3353 * during the saving process (10 or 20 seconds, depending on
3354 * the message). Anyway this is just a quick workaround: once
3355 * we find a better solution it should be removed
3356 * See NB#65125 (commend #18) for details.
3358 if (!had_error && win != NULL) {
3359 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
3360 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
3362 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
3364 if (modest_tny_folder_is_local_folder(folder)) {
3365 TnyFolderType folder_type;
3366 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
3367 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
3368 GtkWidget *hdrview = modest_main_window_get_child_widget(
3369 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3370 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
3374 if (folder != NULL) g_object_unref(folder);
3381 /* For instance, when clicking the Send toolbar button when editing a message: */
3383 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3385 TnyTransportAccount *transport_account = NULL;
3386 gboolean result = TRUE, add_to_contacts;
3388 ModestAccountMgr *account_mgr;
3389 gchar *account_name;
3392 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
3394 /* Check whether to automatically add new contacts to addressbook or not */
3395 add_to_contacts = modest_conf_get_bool (modest_runtime_get_conf (),
3396 MODEST_CONF_AUTO_ADD_TO_CONTACTS, NULL);
3397 if (!modest_msg_edit_window_check_names (edit_window, add_to_contacts))
3400 data = modest_msg_edit_window_get_msg_data (edit_window);
3402 recipients = g_strconcat (data->to?data->to:"",
3403 data->cc?data->cc:"",
3404 data->bcc?data->bcc:"",
3406 if (recipients == NULL || recipients[0] == '\0') {
3407 /* Empty subject -> no send */
3408 g_free (recipients);
3409 modest_msg_edit_window_free_msg_data (edit_window, data);
3412 g_free (recipients);
3415 if (!enough_space_for_message (edit_window, data)) {
3416 modest_msg_edit_window_free_msg_data (edit_window, data);
3420 account_mgr = modest_runtime_get_account_mgr();
3421 account_name = g_strdup (data->account_name);
3423 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3426 account_name = modest_account_mgr_get_default_account (account_mgr);
3428 if (!account_name) {
3429 modest_msg_edit_window_free_msg_data (edit_window, data);
3430 /* Run account setup wizard */
3431 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
3436 /* Get the currently-active transport account for this modest account: */
3437 if (account_name && strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
3439 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3440 (modest_runtime_get_account_store (),
3441 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
3444 if (!transport_account) {
3445 modest_msg_edit_window_free_msg_data (edit_window, data);
3446 /* Run account setup wizard */
3447 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
3451 result = modest_ui_actions_send_msg_with_transport (transport_account,
3464 data->priority_flags,
3465 data->custom_header_pairs);
3469 g_free (account_name);
3470 g_object_unref (G_OBJECT (transport_account));
3472 modest_msg_edit_window_free_msg_data (edit_window, data);
3475 modest_msg_edit_window_set_sent (edit_window, TRUE);
3477 /* Save settings and close the window: */
3478 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3484 /* For instance, when clicking the Send toolbar button when editing a message: */
3486 modest_ui_actions_on_send_custom_msg (const gchar *account_name,
3487 const gchar *from, const gchar *to, const gchar *cc, const gchar *bcc,
3488 const gchar *subject,
3489 const gchar *plain_body, const gchar *html_body,
3490 const GList *attachments_list, const GList *images_list,
3491 const gchar *references, const gchar *in_reply_to,
3492 TnyHeaderFlags priority_flags, TnyList *header_pairs)
3494 TnyTransportAccount *transport_account = NULL;
3495 gboolean result = FALSE;
3497 g_return_val_if_fail (account_name, FALSE);
3500 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3501 (modest_runtime_get_account_store (),
3502 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
3504 g_return_val_if_fail (transport_account, FALSE);
3506 result = modest_ui_actions_send_msg_with_transport (transport_account,
3510 plain_body, html_body,
3511 attachments_list, images_list,
3512 references, in_reply_to,
3513 priority_flags, header_pairs);
3516 g_object_unref (G_OBJECT (transport_account));
3522 modest_ui_actions_send_msg_with_transport (TnyTransportAccount *transport_account,
3524 const gchar *from, const gchar *to, const gchar *cc, const gchar *bcc,
3525 const gchar *subject,
3526 const gchar *plain_body, const gchar *html_body,
3527 const GList *attachments_list, const GList *images_list,
3528 const gchar *references, const gchar *in_reply_to,
3529 TnyHeaderFlags priority_flags, TnyList *header_pairs)
3531 gboolean had_error = FALSE;
3532 ModestMailOperation *mail_operation;
3534 g_return_val_if_fail (transport_account, FALSE);
3536 /* Create the mail operation */
3537 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
3538 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3540 modest_mail_operation_send_new_mail (mail_operation,
3557 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3558 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
3560 if (modest_mail_operation_get_error (mail_operation) != NULL) {
3561 const GError *error = modest_mail_operation_get_error (mail_operation);
3562 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3563 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3564 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3565 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3571 g_object_unref (G_OBJECT (mail_operation));
3577 modest_ui_actions_on_send_msg (ModestWindow *window,
3580 TnyTransportAccount *transport_account = NULL;
3581 gboolean had_error = FALSE;
3582 ModestAccountMgr *account_mgr;
3583 gchar *account_name;
3584 ModestMailOperation *mail_operation;
3586 account_mgr = modest_runtime_get_account_mgr();
3587 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(window)));
3590 account_name = modest_account_mgr_get_default_account (account_mgr);
3592 /* Get the currently-active transport account for this modest account: */
3593 if (account_name && strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
3595 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3596 (modest_runtime_get_account_store (),
3597 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
3600 /* Create the mail operation */
3601 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
3602 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3604 modest_mail_operation_send_mail (mail_operation,
3608 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3609 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
3611 if (modest_mail_operation_get_error (mail_operation) != NULL) {
3612 const GError *error = modest_mail_operation_get_error (mail_operation);
3613 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3614 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3615 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3616 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3622 g_free (account_name);
3623 g_object_unref (G_OBJECT (transport_account));
3624 g_object_unref (G_OBJECT (mail_operation));
3630 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3631 ModestMsgEditWindow *window)
3633 ModestMsgEditFormatState *format_state = NULL;
3635 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3636 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3638 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3641 format_state = modest_msg_edit_window_get_format_state (window);
3642 g_return_if_fail (format_state != NULL);
3644 format_state->bold = gtk_toggle_action_get_active (action);
3645 modest_msg_edit_window_set_format_state (window, format_state);
3646 g_free (format_state);
3651 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3652 ModestMsgEditWindow *window)
3654 ModestMsgEditFormatState *format_state = NULL;
3656 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3657 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3659 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3662 format_state = modest_msg_edit_window_get_format_state (window);
3663 g_return_if_fail (format_state != NULL);
3665 format_state->italics = gtk_toggle_action_get_active (action);
3666 modest_msg_edit_window_set_format_state (window, format_state);
3667 g_free (format_state);
3672 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3673 ModestMsgEditWindow *window)
3675 ModestMsgEditFormatState *format_state = NULL;
3677 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3678 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3680 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3683 format_state = modest_msg_edit_window_get_format_state (window);
3684 g_return_if_fail (format_state != NULL);
3686 format_state->bullet = gtk_toggle_action_get_active (action);
3687 modest_msg_edit_window_set_format_state (window, format_state);
3688 g_free (format_state);
3693 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3694 GtkRadioAction *selected,
3695 ModestMsgEditWindow *window)
3697 ModestMsgEditFormatState *format_state = NULL;
3698 GtkJustification value;
3700 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3702 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3705 value = gtk_radio_action_get_current_value (selected);
3707 format_state = modest_msg_edit_window_get_format_state (window);
3708 g_return_if_fail (format_state != NULL);
3710 format_state->justification = value;
3711 modest_msg_edit_window_set_format_state (window, format_state);
3712 g_free (format_state);
3716 modest_ui_actions_on_select_editor_color (GtkAction *action,
3717 ModestMsgEditWindow *window)
3719 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3720 g_return_if_fail (GTK_IS_ACTION (action));
3722 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3725 modest_msg_edit_window_select_color (window);
3729 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3730 ModestMsgEditWindow *window)
3732 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3733 g_return_if_fail (GTK_IS_ACTION (action));
3735 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3738 modest_msg_edit_window_select_background_color (window);
3742 modest_ui_actions_on_insert_image (GObject *object,
3743 ModestMsgEditWindow *window)
3745 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3748 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3751 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3754 modest_msg_edit_window_insert_image (window);
3758 modest_ui_actions_on_attach_file (GtkAction *action,
3759 ModestMsgEditWindow *window)
3761 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3762 g_return_if_fail (GTK_IS_ACTION (action));
3764 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3767 modest_msg_edit_window_offer_attach_file (window);
3771 modest_ui_actions_on_remove_attachments (GtkAction *action,
3772 ModestMsgEditWindow *window)
3774 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3776 modest_msg_edit_window_remove_attachments (window, NULL);
3780 do_create_folder_cb (ModestMailOperation *mail_op,
3781 TnyFolderStore *parent_folder,
3782 TnyFolder *new_folder,
3785 gchar *suggested_name = (gchar *) user_data;
3786 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3787 const GError *error;
3789 error = modest_mail_operation_get_error (mail_op);
3791 gboolean disk_full = FALSE;
3792 TnyAccount *account;
3793 /* Show an error. If there was some problem writing to
3794 disk, show it, otherwise show the generic folder
3795 create error. We do it here and not in an error
3796 handler because the call to do_create_folder will
3797 stop the main loop in a gtk_dialog_run and then,
3798 the message won't be shown until that dialog is
3800 account = modest_mail_operation_get_account (mail_op);
3803 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3804 (GtkWidget *) source_win,
3807 _("mail_in_ui_folder_create_error_memory"));
3808 g_object_unref (account);
3811 /* Show an error and try again if there is no
3812 full memory condition */
3813 modest_platform_information_banner ((GtkWidget *) source_win, NULL,
3814 _("mail_in_ui_folder_create_error"));
3815 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3819 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3820 * FIXME: any other? */
3821 GtkWidget *folder_view;
3823 if (MODEST_IS_MAIN_WINDOW(source_win))
3825 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3826 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3828 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3829 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3831 /* Select the newly created folder. It could happen
3832 that the widget is no longer there (i.e. the window
3833 has been destroyed, so we need to check this */
3835 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3837 g_object_unref (new_folder);
3839 /* Free. Note that the first time it'll be NULL so noop */
3840 g_free (suggested_name);
3841 g_object_unref (source_win);
3846 TnyFolderStore *parent;
3847 } CreateFolderConnect;
3850 do_create_folder_performer (gboolean canceled,
3852 GtkWindow *parent_window,
3853 TnyAccount *account,
3856 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3857 ModestMailOperation *mail_op;
3859 if (canceled || err) {
3860 /* In disk full conditions we could get this error here */
3861 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3862 (GtkWidget *) parent_window, err,
3863 NULL, _("mail_in_ui_folder_create_error_memory"));
3865 /* This happens if we have selected the outbox folder
3867 if (err && err->code == TNY_SERVICE_ERROR_UNKNOWN &&
3868 TNY_IS_MERGE_FOLDER (helper->parent)) {
3869 /* Show an error and retry */
3870 modest_platform_information_banner ((GtkWidget *) parent_window,
3872 _("mail_in_ui_folder_create_error"));
3874 do_create_folder (parent_window, helper->parent, helper->folder_name);
3880 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3881 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3883 modest_mail_operation_create_folder (mail_op,
3885 (const gchar *) helper->folder_name,
3886 do_create_folder_cb,
3887 g_strdup (helper->folder_name));
3888 g_object_unref (mail_op);
3892 g_object_unref (helper->parent);
3893 if (helper->folder_name)
3894 g_free (helper->folder_name);
3895 g_slice_free (CreateFolderConnect, helper);
3900 do_create_folder (GtkWindow *parent_window,
3901 TnyFolderStore *suggested_parent,
3902 const gchar *suggested_name)
3905 gchar *folder_name = NULL;
3906 TnyFolderStore *parent_folder = NULL;
3908 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3910 (gchar *) suggested_name,
3914 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3915 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3916 helper->folder_name = g_strdup (folder_name);
3917 helper->parent = g_object_ref (parent_folder);
3919 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3922 do_create_folder_performer,
3927 g_free (folder_name);
3929 g_object_unref (parent_folder);
3933 modest_ui_actions_create_folder(GtkWidget *parent_window,
3934 GtkWidget *folder_view,
3935 TnyFolderStore *parent_folder)
3937 if (!parent_folder) {
3938 #ifdef MODEST_TOOLKIT_HILDON2
3939 ModestTnyAccountStore *acc_store;
3941 acc_store = modest_runtime_get_account_store ();
3943 parent_folder = (TnyFolderStore *)
3944 modest_tny_account_store_get_local_folders_account (acc_store);
3946 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3950 if (parent_folder) {
3951 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3952 g_object_unref (parent_folder);
3957 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3960 g_return_if_fail (MODEST_IS_WINDOW(window));
3962 if (MODEST_IS_MAIN_WINDOW (window)) {
3963 GtkWidget *folder_view;
3965 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3966 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3970 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3971 #ifdef MODEST_TOOLKIT_HILDON2
3972 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3973 GtkWidget *folder_view;
3975 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3976 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3979 g_assert_not_reached ();
3984 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3987 const GError *error = NULL;
3988 gchar *message = NULL;
3990 TnyAccount *account = modest_mail_operation_get_account (mail_op);
3992 /* Get error message */
3993 error = modest_mail_operation_get_error (mail_op);
3995 g_return_if_reached ();
3997 mem_full = modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
3998 (GError *) error, account);
4000 message = g_strdup_printf (_KR("cerm_device_memory_full"), "");
4001 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
4002 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
4003 message = _CS("ckdg_ib_folder_already_exists");
4004 } else if (error->domain == TNY_ERROR_DOMAIN &&
4005 error->code == TNY_SERVICE_ERROR_STATE) {
4006 /* This means that the folder is already in use (a
4007 message is opened for example */
4008 message = _("emev_ni_internal_error");
4010 message = _CS("ckdg_ib_unable_to_rename");
4013 /* We don't set a parent for the dialog because the dialog
4014 will be destroyed so the banner won't appear */
4015 modest_platform_information_banner (NULL, NULL, message);
4018 g_object_unref (account);
4024 TnyFolderStore *folder;
4029 on_rename_folder_cb (ModestMailOperation *mail_op,
4030 TnyFolder *new_folder,
4033 ModestFolderView *folder_view;
4035 /* If the window was closed when renaming a folder, or if
4036 * it's not a main window this will happen */
4037 if (!MODEST_IS_FOLDER_VIEW (user_data))
4040 folder_view = MODEST_FOLDER_VIEW (user_data);
4041 /* Note that if the rename fails new_folder will be NULL */
4043 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
4045 modest_folder_view_select_first_inbox_or_local (folder_view);
4047 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
4051 on_rename_folder_performer (gboolean canceled,
4053 GtkWindow *parent_window,
4054 TnyAccount *account,
4057 ModestMailOperation *mail_op = NULL;
4058 GtkTreeSelection *sel = NULL;
4059 GtkWidget *folder_view = NULL;
4060 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
4062 if (canceled || err) {
4063 /* In disk full conditions we could get this error here */
4064 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4065 (GtkWidget *) parent_window, err,
4070 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
4071 modest_ui_actions_rename_folder_error_handler,
4072 parent_window, NULL);
4074 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4077 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
4079 folder_view = modest_main_window_get_child_widget (
4080 MODEST_MAIN_WINDOW (parent_window),
4081 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4083 #ifdef MODEST_TOOLKIT_HILDON2
4084 else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
4085 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
4086 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
4090 /* Clear the folders view */
4091 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
4092 gtk_tree_selection_unselect_all (sel);
4094 /* Actually rename the folder */
4095 modest_mail_operation_rename_folder (mail_op,
4096 TNY_FOLDER (data->folder),
4097 (const gchar *) (data->new_name),
4098 on_rename_folder_cb,
4100 g_object_unref (mail_op);
4103 g_object_unref (data->folder);
4104 g_free (data->new_name);
4109 modest_ui_actions_on_rename_folder (GtkAction *action,
4110 ModestWindow *window)
4112 modest_ui_actions_on_edit_mode_rename_folder (window);
4116 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
4118 TnyFolderStore *folder;
4119 GtkWidget *folder_view;
4120 gboolean do_rename = TRUE;
4122 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
4124 if (MODEST_IS_MAIN_WINDOW (window)) {
4125 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4126 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4130 #ifdef MODEST_TOOLKIT_HILDON2
4131 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
4132 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
4138 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
4143 if (TNY_IS_FOLDER (folder)) {
4144 gchar *folder_name = NULL;
4146 const gchar *current_name;
4147 TnyFolderStore *parent;
4149 current_name = tny_folder_get_name (TNY_FOLDER (folder));
4150 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
4151 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
4152 parent, current_name,
4154 g_object_unref (parent);
4156 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
4159 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
4160 rename_folder_data->folder = g_object_ref (folder);
4161 rename_folder_data->new_name = folder_name;
4162 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
4163 folder, on_rename_folder_performer, rename_folder_data);
4166 g_object_unref (folder);
4171 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
4174 GObject *win = modest_mail_operation_get_source (mail_op);
4176 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
4177 _("mail_in_ui_folder_delete_error"),
4179 g_object_unref (win);
4183 TnyFolderStore *folder;
4184 gboolean move_to_trash;
4188 on_delete_folder_cb (gboolean canceled,
4190 GtkWindow *parent_window,
4191 TnyAccount *account,
4194 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
4195 GtkWidget *folder_view;
4196 ModestMailOperation *mail_op;
4197 GtkTreeSelection *sel;
4199 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
4200 /* Note that the connection process can fail due to
4201 memory low conditions as it can not successfully
4202 store the summary */
4203 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4204 (GtkWidget*) parent_window, err,
4206 g_debug ("Error connecting when trying to delete a folder");
4207 g_object_unref (G_OBJECT (info->folder));
4212 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
4213 folder_view = modest_main_window_get_child_widget (
4214 MODEST_MAIN_WINDOW (parent_window),
4215 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4216 #ifdef MODEST_TOOLKIT_HILDON2
4217 } else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
4218 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
4221 g_object_unref (G_OBJECT (info->folder));
4226 /* Unselect the folder before deleting it to free the headers */
4227 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
4228 gtk_tree_selection_unselect_all (sel);
4230 /* Create the mail operation */
4232 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
4233 modest_ui_actions_delete_folder_error_handler,
4236 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4238 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
4240 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
4242 g_object_unref (mail_op);
4243 g_object_unref (info->folder);
4248 delete_folder (ModestWindow *window, gboolean move_to_trash)
4250 TnyFolderStore *folder;
4251 GtkWidget *folder_view;
4255 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
4257 if (MODEST_IS_MAIN_WINDOW (window)) {
4259 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4260 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4261 #ifdef MODEST_TOOLKIT_HILDON2
4262 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
4263 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
4271 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4276 /* Show an error if it's an account */
4277 if (!TNY_IS_FOLDER (folder)) {
4278 modest_platform_run_information_dialog (GTK_WINDOW (window),
4279 _("mail_in_ui_folder_delete_error"),
4281 g_object_unref (G_OBJECT (folder));
4286 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
4287 tny_folder_get_name (TNY_FOLDER (folder)));
4288 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
4289 (const gchar *) message);
4292 if (response == GTK_RESPONSE_OK) {
4293 TnyAccount *account = NULL;
4294 DeleteFolderInfo *info = NULL;
4295 info = g_new0(DeleteFolderInfo, 1);
4296 info->folder = g_object_ref (folder);
4297 info->move_to_trash = move_to_trash;
4299 account = tny_folder_get_account (TNY_FOLDER (folder));
4300 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
4302 TNY_FOLDER_STORE (account),
4303 on_delete_folder_cb, info);
4304 g_object_unref (account);
4305 g_object_unref (folder);
4313 modest_ui_actions_on_delete_folder (GtkAction *action,
4314 ModestWindow *window)
4316 modest_ui_actions_on_edit_mode_delete_folder (window);
4320 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
4322 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
4324 return delete_folder (window, FALSE);
4328 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
4330 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4332 delete_folder (MODEST_WINDOW (main_window), TRUE);
4336 typedef struct _PasswordDialogFields {
4337 GtkWidget *username;
4338 GtkWidget *password;
4340 } PasswordDialogFields;
4343 password_dialog_check_field (GtkEditable *editable,
4344 PasswordDialogFields *fields)
4347 gboolean any_value_empty = FALSE;
4349 #ifdef MODEST_TOOLKIT_HILDON2
4350 value = hildon_entry_get_text (HILDON_ENTRY (fields->username));
4352 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
4354 if ((value == NULL) || value[0] == '\0') {
4355 any_value_empty = TRUE;
4357 #ifdef MODEST_TOOLKIT_HILDON2
4358 value = hildon_entry_get_text (HILDON_ENTRY (fields->password));
4360 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
4362 if ((value == NULL) || value[0] == '\0') {
4363 any_value_empty = TRUE;
4365 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
4369 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
4370 const gchar* server_account_name,
4375 ModestMainWindow *main_window)
4377 g_return_if_fail(server_account_name);
4378 gboolean completed = FALSE;
4379 PasswordDialogFields *fields = NULL;
4381 /* Initalize output parameters: */
4388 #ifndef MODEST_TOOLKIT_GTK
4389 /* Maemo uses a different (awkward) button order,
4390 * It should probably just use gtk_alternative_dialog_button_order ().
4392 #ifdef MODEST_TOOLKIT_HILDON2
4394 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4397 _HL("wdgt_bd_done"),
4398 GTK_RESPONSE_ACCEPT,
4400 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
4401 HILDON_MARGIN_DOUBLE);
4404 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4407 _("mcen_bd_dialog_ok"),
4408 GTK_RESPONSE_ACCEPT,
4409 _("mcen_bd_dialog_cancel"),
4410 GTK_RESPONSE_REJECT,
4412 #endif /* MODEST_TOOLKIT_HILDON2 */
4415 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4419 GTK_RESPONSE_REJECT,
4421 GTK_RESPONSE_ACCEPT,
4423 #endif /* MODEST_TOOLKIT_GTK */
4425 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
4427 gchar *server_name = modest_account_mgr_get_server_account_hostname (
4428 modest_runtime_get_account_mgr(), server_account_name);
4429 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
4430 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
4433 gtk_widget_destroy (dialog);
4437 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
4438 GtkWidget *label = gtk_label_new (txt);
4439 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
4441 g_free (server_name);
4442 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
4447 gchar *initial_username = modest_account_mgr_get_server_account_username (
4448 modest_runtime_get_account_mgr(), server_account_name);
4450 #ifdef MODEST_TOOLKIT_HILDON2
4451 GtkWidget *entry_username = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4452 if (initial_username)
4453 hildon_entry_set_text (HILDON_ENTRY (entry_username), initial_username);
4455 GtkWidget *entry_username = gtk_entry_new ();
4456 if (initial_username)
4457 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
4459 /* Dim this if a connection has ever succeeded with this username,
4460 * as per the UI spec: */
4461 /* const gboolean username_known = */
4462 /* modest_account_mgr_get_server_account_username_has_succeeded( */
4463 /* modest_runtime_get_account_mgr(), server_account_name); */
4464 /* gtk_widget_set_sensitive (entry_username, !username_known); */
4466 /* We drop the username sensitive code and disallow changing it here
4467 * as tinymail does not support really changing the username in the callback
4469 gtk_widget_set_sensitive (entry_username, FALSE);
4471 #ifndef MODEST_TOOLKIT_GTK
4472 /* Auto-capitalization is the default, so let's turn it off: */
4473 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
4475 /* Create a size group to be used by all captions.
4476 * Note that HildonCaption does not create a default size group if we do not specify one.
4477 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
4478 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
4480 #ifdef MODEST_TOOLKIT_HILDON2
4481 GtkWidget *caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4482 _("mail_fi_username"), FALSE,
4485 GtkWidget *caption = hildon_caption_new (sizegroup,
4486 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
4488 gtk_widget_show (entry_username);
4489 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4490 FALSE, FALSE, MODEST_MARGIN_HALF);
4491 gtk_widget_show (caption);
4493 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
4495 #endif /* !MODEST_TOOLKIT_GTK */
4498 #ifdef MODEST_TOOLKIT_HILDON2
4499 GtkWidget *entry_password = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4501 GtkWidget *entry_password = gtk_entry_new ();
4503 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
4504 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
4506 #ifndef MODEST_TOOLKIT_GTK
4507 /* Auto-capitalization is the default, so let's turn it off: */
4508 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
4509 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
4511 #ifdef MODEST_TOOLKIT_HILDON2
4512 caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4513 _("mail_fi_password"), FALSE,
4516 caption = hildon_caption_new (sizegroup,
4517 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
4519 gtk_widget_show (entry_password);
4520 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4521 FALSE, FALSE, MODEST_MARGIN_HALF);
4522 gtk_widget_show (caption);
4523 g_object_unref (sizegroup);
4525 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
4527 #endif /* !MODEST_TOOLKIT_GTK */
4529 if (initial_username != NULL)
4530 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
4532 /* This is not in the Maemo UI spec:
4533 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
4534 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
4538 fields = g_slice_new0 (PasswordDialogFields);
4539 fields->username = entry_username;
4540 fields->password = entry_password;
4541 fields->dialog = dialog;
4543 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
4544 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
4545 password_dialog_check_field (NULL, fields);
4547 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4549 while (!completed) {
4551 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
4553 #ifdef MODEST_TOOLKIT_HILDON2
4554 *username = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_username)));
4556 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
4559 /* Note that an empty field becomes the "" string */
4560 if (*username && strlen (*username) > 0) {
4561 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
4562 server_account_name,
4566 const gboolean username_was_changed =
4567 (strcmp (*username, initial_username) != 0);
4568 if (username_was_changed) {
4569 g_warning ("%s: tinymail does not yet support changing the "
4570 "username in the get_password() callback.\n", __FUNCTION__);
4576 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
4577 _("mcen_ib_username_pw_incorrect"));
4583 #ifdef MODEST_TOOLKIT_HILDON2
4584 *password = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_password)));
4586 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
4589 /* We do not save the password in the configuration,
4590 * because this function is only called for passwords that should
4591 * not be remembered:
4592 modest_server_account_set_password (
4593 modest_runtime_get_account_mgr(), server_account_name,
4600 #ifndef MODEST_TOOLKIT_HILDON2
4601 /* Set parent to NULL or the banner will disappear with its parent dialog */
4602 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
4614 /* This is not in the Maemo UI spec:
4615 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
4621 g_free (initial_username);
4622 gtk_widget_destroy (dialog);
4623 g_slice_free (PasswordDialogFields, fields);
4625 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
4629 modest_ui_actions_on_cut (GtkAction *action,
4630 ModestWindow *window)
4632 GtkWidget *focused_widget;
4633 GtkClipboard *clipboard;
4635 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4636 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4637 if (GTK_IS_EDITABLE (focused_widget)) {
4638 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
4639 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4640 gtk_clipboard_store (clipboard);
4641 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4642 GtkTextBuffer *buffer;
4644 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4645 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4646 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
4647 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4648 gtk_clipboard_store (clipboard);
4650 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4651 TnyList *header_list = modest_header_view_get_selected_headers (
4652 MODEST_HEADER_VIEW (focused_widget));
4653 gboolean continue_download = FALSE;
4654 gint num_of_unc_msgs;
4656 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4658 if (num_of_unc_msgs) {
4659 TnyAccount *account = get_account_from_header_list (header_list);
4661 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4662 g_object_unref (account);
4666 if (num_of_unc_msgs == 0 || continue_download) {
4667 /* modest_platform_information_banner (
4668 NULL, NULL, _CS("mcen_ib_getting_items"));*/
4669 modest_header_view_cut_selection (
4670 MODEST_HEADER_VIEW (focused_widget));
4673 g_object_unref (header_list);
4674 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4675 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4680 modest_ui_actions_on_copy (GtkAction *action,
4681 ModestWindow *window)
4683 GtkClipboard *clipboard;
4684 GtkWidget *focused_widget;
4685 gboolean copied = TRUE;
4687 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4688 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4690 if (GTK_IS_LABEL (focused_widget)) {
4692 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4693 gtk_clipboard_set_text (clipboard, selection, -1);
4695 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4696 gtk_clipboard_store (clipboard);
4697 } else if (GTK_IS_EDITABLE (focused_widget)) {
4698 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4699 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4700 gtk_clipboard_store (clipboard);
4701 } else if (GTK_IS_HTML (focused_widget)) {
4704 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4705 if ((sel == NULL) || (sel[0] == '\0')) {
4708 gtk_html_copy (GTK_HTML (focused_widget));
4709 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4710 gtk_clipboard_store (clipboard);
4712 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4713 GtkTextBuffer *buffer;
4714 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4715 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4716 gtk_text_buffer_copy_clipboard (buffer, clipboard);
4717 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4718 gtk_clipboard_store (clipboard);
4720 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4721 TnyList *header_list = modest_header_view_get_selected_headers (
4722 MODEST_HEADER_VIEW (focused_widget));
4723 gboolean continue_download = FALSE;
4724 gint num_of_unc_msgs;
4726 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4728 if (num_of_unc_msgs) {
4729 TnyAccount *account = get_account_from_header_list (header_list);
4731 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4732 g_object_unref (account);
4736 if (num_of_unc_msgs == 0 || continue_download) {
4737 modest_platform_information_banner (
4738 NULL, NULL, _CS("mcen_ib_getting_items"));
4739 modest_header_view_copy_selection (
4740 MODEST_HEADER_VIEW (focused_widget));
4744 g_object_unref (header_list);
4746 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4747 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4750 /* Show information banner if there was a copy to clipboard */
4752 modest_platform_information_banner (
4753 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4757 modest_ui_actions_on_undo (GtkAction *action,
4758 ModestWindow *window)
4760 ModestEmailClipboard *clipboard = NULL;
4762 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4763 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4764 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4765 /* Clear clipboard source */
4766 clipboard = modest_runtime_get_email_clipboard ();
4767 modest_email_clipboard_clear (clipboard);
4770 g_return_if_reached ();
4775 modest_ui_actions_on_redo (GtkAction *action,
4776 ModestWindow *window)
4778 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4779 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4782 g_return_if_reached ();
4788 destroy_information_note (ModestMailOperation *mail_op,
4791 /* destroy information note */
4792 gtk_widget_destroy (GTK_WIDGET(user_data));
4796 destroy_folder_information_note (ModestMailOperation *mail_op,
4797 TnyFolder *new_folder,
4800 /* destroy information note */
4801 gtk_widget_destroy (GTK_WIDGET(user_data));
4806 paste_as_attachment_free (gpointer data)
4808 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4810 if (helper->banner) {
4811 gtk_widget_destroy (helper->banner);
4812 g_object_unref (helper->banner);
4818 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4823 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4824 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4829 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4834 modest_ui_actions_on_paste (GtkAction *action,
4835 ModestWindow *window)
4837 GtkWidget *focused_widget = NULL;
4838 GtkWidget *inf_note = NULL;
4839 ModestMailOperation *mail_op = NULL;
4841 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4842 if (GTK_IS_EDITABLE (focused_widget)) {
4843 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4844 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4845 ModestEmailClipboard *e_clipboard = NULL;
4846 e_clipboard = modest_runtime_get_email_clipboard ();
4847 if (modest_email_clipboard_cleared (e_clipboard)) {
4848 GtkTextBuffer *buffer;
4849 GtkClipboard *clipboard;
4851 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4852 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4853 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4854 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4855 ModestMailOperation *mail_op;
4856 TnyFolder *src_folder = NULL;
4857 TnyList *data = NULL;
4859 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4860 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4861 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4862 _CS("ckct_nw_pasting"));
4863 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4864 mail_op = modest_mail_operation_new (G_OBJECT (window));
4865 if (helper->banner != NULL) {
4866 g_object_ref (G_OBJECT (helper->banner));
4867 gtk_widget_show (GTK_WIDGET (helper->banner));
4871 modest_mail_operation_get_msgs_full (mail_op,
4873 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4875 paste_as_attachment_free);
4879 g_object_unref (data);
4881 g_object_unref (src_folder);
4884 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4885 ModestEmailClipboard *clipboard = NULL;
4886 TnyFolder *src_folder = NULL;
4887 TnyFolderStore *folder_store = NULL;
4888 TnyList *data = NULL;
4889 gboolean delete = FALSE;
4891 /* Check clipboard source */
4892 clipboard = modest_runtime_get_email_clipboard ();
4893 if (modest_email_clipboard_cleared (clipboard))
4896 /* Get elements to paste */
4897 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4899 /* Create a new mail operation */
4900 mail_op = modest_mail_operation_new (G_OBJECT(window));
4902 /* Get destination folder */
4903 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4905 /* transfer messages */
4909 /* Ask for user confirmation */
4911 modest_ui_actions_msgs_move_to_confirmation (window,
4912 TNY_FOLDER (folder_store),
4916 if (response == GTK_RESPONSE_OK) {
4917 /* Launch notification */
4918 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4919 _CS("ckct_nw_pasting"));
4920 if (inf_note != NULL) {
4921 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4922 gtk_widget_show (GTK_WIDGET(inf_note));
4925 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4926 modest_mail_operation_xfer_msgs (mail_op,
4928 TNY_FOLDER (folder_store),
4930 destroy_information_note,
4933 g_object_unref (mail_op);
4936 } else if (src_folder != NULL) {
4937 /* Launch notification */
4938 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4939 _CS("ckct_nw_pasting"));
4940 if (inf_note != NULL) {
4941 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4942 gtk_widget_show (GTK_WIDGET(inf_note));
4945 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4946 modest_mail_operation_xfer_folder (mail_op,
4950 destroy_folder_information_note,
4956 g_object_unref (data);
4957 if (src_folder != NULL)
4958 g_object_unref (src_folder);
4959 if (folder_store != NULL)
4960 g_object_unref (folder_store);
4966 modest_ui_actions_on_select_all (GtkAction *action,
4967 ModestWindow *window)
4969 GtkWidget *focused_widget;
4971 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4972 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4973 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4974 } else if (GTK_IS_LABEL (focused_widget)) {
4975 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4976 } else if (GTK_IS_EDITABLE (focused_widget)) {
4977 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4978 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4979 GtkTextBuffer *buffer;
4980 GtkTextIter start, end;
4982 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4983 gtk_text_buffer_get_start_iter (buffer, &start);
4984 gtk_text_buffer_get_end_iter (buffer, &end);
4985 gtk_text_buffer_select_range (buffer, &start, &end);
4986 } else if (GTK_IS_HTML (focused_widget)) {
4987 gtk_html_select_all (GTK_HTML (focused_widget));
4988 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4989 GtkWidget *header_view = focused_widget;
4990 GtkTreeSelection *selection = NULL;
4992 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4993 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4994 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4997 /* Disable window dimming management */
4998 modest_window_disable_dimming (MODEST_WINDOW(window));
5000 /* Select all messages */
5001 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
5002 gtk_tree_selection_select_all (selection);
5004 /* Set focuse on header view */
5005 gtk_widget_grab_focus (header_view);
5007 /* Enable window dimming management */
5008 modest_window_enable_dimming (MODEST_WINDOW(window));
5009 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
5010 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
5016 modest_ui_actions_on_mark_as_read (GtkAction *action,
5017 ModestWindow *window)
5019 g_return_if_fail (MODEST_IS_WINDOW(window));
5021 /* Mark each header as read */
5022 do_headers_action (window, headers_action_mark_as_read, NULL);
5026 modest_ui_actions_on_mark_as_unread (GtkAction *action,
5027 ModestWindow *window)
5029 g_return_if_fail (MODEST_IS_WINDOW(window));
5031 /* Mark each header as read */
5032 do_headers_action (window, headers_action_mark_as_unread, NULL);
5036 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
5037 GtkRadioAction *selected,
5038 ModestWindow *window)
5042 value = gtk_radio_action_get_current_value (selected);
5043 if (MODEST_IS_WINDOW (window)) {
5044 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
5049 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
5050 GtkRadioAction *selected,
5051 ModestWindow *window)
5053 TnyHeaderFlags flags;
5054 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5056 flags = gtk_radio_action_get_current_value (selected);
5057 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
5061 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
5062 GtkRadioAction *selected,
5063 ModestWindow *window)
5067 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5069 file_format = gtk_radio_action_get_current_value (selected);
5070 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
5075 modest_ui_actions_on_zoom_plus (GtkAction *action,
5076 ModestWindow *window)
5078 g_return_if_fail (MODEST_IS_WINDOW (window));
5080 modest_window_zoom_plus (MODEST_WINDOW (window));
5084 modest_ui_actions_on_zoom_minus (GtkAction *action,
5085 ModestWindow *window)
5087 g_return_if_fail (MODEST_IS_WINDOW (window));
5089 modest_window_zoom_minus (MODEST_WINDOW (window));
5093 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
5094 ModestWindow *window)
5096 ModestWindowMgr *mgr;
5097 gboolean fullscreen, active;
5098 g_return_if_fail (MODEST_IS_WINDOW (window));
5100 mgr = modest_runtime_get_window_mgr ();
5102 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
5103 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
5105 if (active != fullscreen) {
5106 modest_window_mgr_set_fullscreen_mode (mgr, active);
5107 #ifndef MODEST_TOOLKIT_HILDON2
5108 gtk_window_present (GTK_WINDOW (window));
5114 modest_ui_actions_on_change_fullscreen (GtkAction *action,
5115 ModestWindow *window)
5117 ModestWindowMgr *mgr;
5118 gboolean fullscreen;
5120 g_return_if_fail (MODEST_IS_WINDOW (window));
5122 mgr = modest_runtime_get_window_mgr ();
5123 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
5124 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
5126 #ifndef MODEST_TOOLKIT_HILDON2
5127 gtk_window_present (GTK_WINDOW (window));
5132 * Used by modest_ui_actions_on_details to call do_headers_action
5135 headers_action_show_details (TnyHeader *header,
5136 ModestWindow *window,
5140 gboolean async_retrieval;
5143 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5144 async_retrieval = TRUE;
5145 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
5146 async_retrieval = !TNY_IS_CAMEL_BS_MSG (msg);
5148 async_retrieval = FALSE;
5150 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header, async_retrieval, msg);
5152 g_object_unref (msg);
5156 * Show the header details in a ModestDetailsDialog widget
5159 modest_ui_actions_on_details (GtkAction *action,
5162 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
5166 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
5170 header = tny_msg_get_header (msg);
5172 headers_action_show_details (header, win, NULL);
5173 g_object_unref (header);
5175 g_object_unref (msg);
5177 } else if (MODEST_IS_MAIN_WINDOW (win)) {
5178 GtkWidget *folder_view, *header_view;
5180 /* Check which widget has the focus */
5181 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5182 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5183 if (gtk_widget_is_focus (folder_view)) {
5184 TnyFolderStore *folder_store
5185 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5186 if (!folder_store) {
5187 g_warning ("%s: No item was selected.\n", __FUNCTION__);
5190 /* Show only when it's a folder */
5191 /* This function should not be called for account items,
5192 * because we dim the menu item for them. */
5193 if (TNY_IS_FOLDER (folder_store)) {
5194 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
5195 TNY_FOLDER (folder_store));
5198 g_object_unref (folder_store);
5201 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5202 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5203 /* Show details of each header */
5204 do_headers_action (win, headers_action_show_details, header_view);
5206 #ifdef MODEST_TOOLKIT_HILDON2
5207 } else if (MODEST_IS_HEADER_WINDOW (win)) {
5209 GtkWidget *header_view;
5211 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
5212 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
5214 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
5216 g_object_unref (folder);
5223 modest_ui_actions_on_limit_error (GtkAction *action,
5226 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
5228 modest_platform_information_banner ((GtkWidget *) win, NULL, _CS("ckdg_ib_maximum_characters_reached"));
5233 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
5234 ModestMsgEditWindow *window)
5236 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5238 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
5242 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
5243 ModestMsgEditWindow *window)
5245 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5247 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
5251 modest_ui_actions_toggle_folders_view (GtkAction *action,
5252 ModestMainWindow *main_window)
5254 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
5256 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
5257 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
5259 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
5263 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
5264 ModestWindow *window)
5266 gboolean active, fullscreen = FALSE;
5267 ModestWindowMgr *mgr;
5269 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
5271 /* Check if we want to toggle the toolbar view in fullscreen
5273 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
5274 "ViewShowToolbarFullScreen")) {
5278 /* Toggle toolbar */
5279 mgr = modest_runtime_get_window_mgr ();
5280 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
5284 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
5285 ModestMsgEditWindow *window)
5287 modest_msg_edit_window_select_font (window);
5292 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
5293 const gchar *display_name,
5296 /* don't update the display name if it was already set;
5297 * updating the display name apparently is expensive */
5298 const gchar* old_name = gtk_window_get_title (window);
5300 if (display_name == NULL)
5303 if (old_name && display_name && strcmp (old_name, display_name) == 0)
5304 return; /* don't do anything */
5306 /* This is usually used to change the title of the main window, which
5307 * is the one that holds the folder view. Note that this change can
5308 * happen even when the widget doesn't have the focus. */
5309 gtk_window_set_title (window, display_name);
5314 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
5316 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5317 modest_msg_edit_window_select_contacts (window);
5321 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
5323 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5324 modest_msg_edit_window_check_names (window, FALSE);
5327 #ifndef MODEST_TOOLKIT_HILDON2
5329 * This function is used to track changes in the selection of the
5330 * folder view that is inside the "move to" dialog to enable/disable
5331 * the OK button because we do not want the user to select a disallowed
5332 * destination for a folder.
5333 * The user also not desired to be able to use NEW button on items where
5334 * folder creation is not possibel.
5337 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
5338 TnyFolderStore *folder_store,
5342 GtkWidget *dialog = NULL;
5343 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
5344 gboolean moving_folder = FALSE;
5345 gboolean is_local_account = TRUE;
5346 GtkWidget *folder_view = NULL;
5347 ModestTnyFolderRules rules;
5349 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
5354 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
5358 /* check if folder_store is an remote account */
5359 if (TNY_IS_ACCOUNT (folder_store)) {
5360 TnyAccount *local_account = NULL;
5361 TnyAccount *mmc_account = NULL;
5362 ModestTnyAccountStore *account_store = NULL;
5364 account_store = modest_runtime_get_account_store ();
5365 local_account = modest_tny_account_store_get_local_folders_account (account_store);
5366 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
5368 if ((gpointer) local_account != (gpointer) folder_store &&
5369 (gpointer) mmc_account != (gpointer) folder_store) {
5370 ModestProtocolType proto;
5371 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
5372 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
5373 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
5375 is_local_account = FALSE;
5376 /* New button should be dimmed on remote
5378 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5380 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
5382 g_object_unref (local_account);
5384 /* It could not exist */
5386 g_object_unref (mmc_account);
5389 /* Check the target folder rules */
5390 if (TNY_IS_FOLDER (folder_store)) {
5391 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
5392 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
5393 ok_sensitive = FALSE;
5394 new_sensitive = FALSE;
5399 /* Check if we're moving a folder */
5400 if (MODEST_IS_MAIN_WINDOW (user_data)) {
5401 /* Get the widgets */
5402 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
5403 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5404 if (gtk_widget_is_focus (folder_view))
5405 moving_folder = TRUE;
5408 if (moving_folder) {
5409 TnyFolderStore *moved_folder = NULL, *parent = NULL;
5411 /* Get the folder to move */
5412 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5414 /* Check that we're not moving to the same folder */
5415 if (TNY_IS_FOLDER (moved_folder)) {
5416 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
5417 if (parent == folder_store)
5418 ok_sensitive = FALSE;
5419 g_object_unref (parent);
5422 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
5423 /* Do not allow to move to an account unless it's the
5424 local folders account */
5425 if (!is_local_account)
5426 ok_sensitive = FALSE;
5429 if (ok_sensitive && (moved_folder == folder_store)) {
5430 /* Do not allow to move to itself */
5431 ok_sensitive = FALSE;
5433 g_object_unref (moved_folder);
5435 TnyFolder *src_folder = NULL;
5437 /* Moving a message */
5438 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
5440 TnyHeader *header = NULL;
5441 header = modest_msg_view_window_get_header
5442 (MODEST_MSG_VIEW_WINDOW (user_data));
5443 if (!TNY_IS_HEADER(header))
5444 g_warning ("%s: could not get source header", __FUNCTION__);
5446 src_folder = tny_header_get_folder (header);
5449 g_object_unref (header);
5452 TNY_FOLDER (modest_folder_view_get_selected
5453 (MODEST_FOLDER_VIEW (folder_view)));
5456 if (TNY_IS_FOLDER(src_folder)) {
5457 /* Do not allow to move the msg to the same folder */
5458 /* Do not allow to move the msg to an account */
5459 if ((gpointer) src_folder == (gpointer) folder_store ||
5460 TNY_IS_ACCOUNT (folder_store))
5461 ok_sensitive = FALSE;
5462 g_object_unref (src_folder);
5464 g_warning ("%s: could not get source folder", __FUNCTION__);
5468 /* Set sensitivity of the OK and NEW button */
5469 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
5470 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
5475 on_move_to_dialog_response (GtkDialog *dialog,
5479 GtkWidget *parent_win;
5480 MoveToInfo *helper = NULL;
5481 ModestFolderView *folder_view;
5482 gboolean unset_edit_mode = FALSE;
5484 helper = (MoveToInfo *) user_data;
5486 parent_win = (GtkWidget *) helper->win;
5487 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
5488 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
5490 TnyFolderStore *dst_folder;
5491 TnyFolderStore *selected;
5493 case MODEST_GTK_RESPONSE_NEW_FOLDER:
5494 selected = modest_folder_view_get_selected (folder_view);
5495 modest_ui_actions_create_folder (GTK_WIDGET (dialog), GTK_WIDGET (folder_view), selected);
5496 g_object_unref (selected);
5498 case GTK_RESPONSE_NONE:
5499 case GTK_RESPONSE_CANCEL:
5500 case GTK_RESPONSE_DELETE_EVENT:
5502 case GTK_RESPONSE_OK:
5503 dst_folder = modest_folder_view_get_selected (folder_view);
5505 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
5506 /* Clean list to move used for filtering */
5507 modest_folder_view_set_list_to_move (folder_view, NULL);
5509 modest_ui_actions_on_main_window_move_to (NULL,
5510 GTK_WIDGET (folder_view),
5512 MODEST_MAIN_WINDOW (parent_win));
5513 #ifdef MODEST_TOOLKIT_HILDON2
5514 } else if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
5515 /* Clean list to move used for filtering */
5516 modest_folder_view_set_list_to_move (folder_view, NULL);
5518 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
5521 GTK_WINDOW (parent_win));
5524 /* if the user selected a root folder
5525 (account) then do not perform any action */
5526 if (TNY_IS_ACCOUNT (dst_folder)) {
5527 g_signal_stop_emission_by_name (dialog, "response");
5531 /* Clean list to move used for filtering */
5532 modest_folder_view_set_list_to_move (folder_view, NULL);
5534 /* Moving from headers window in edit mode */
5535 modest_ui_actions_on_window_move_to (NULL, helper->list,
5537 MODEST_WINDOW (parent_win));
5541 g_object_unref (dst_folder);
5543 unset_edit_mode = TRUE;
5546 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
5549 /* Free the helper and exit */
5551 g_object_unref (helper->list);
5552 if (unset_edit_mode) {
5553 #ifdef MODEST_TOOLKIT_HILDON2
5554 modest_hildon2_window_unset_edit_mode (MODEST_HILDON2_WINDOW (helper->win));
5557 g_slice_free (MoveToInfo, helper);
5558 gtk_widget_destroy (GTK_WIDGET (dialog));
5562 create_move_to_dialog (GtkWindow *win,
5563 GtkWidget *folder_view,
5564 TnyList *list_to_move)
5566 GtkWidget *dialog, *tree_view = NULL;
5568 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
5570 #ifndef MODEST_TOOLKIT_HILDON2
5571 /* Track changes in the selection to
5572 * disable the OK button whenever "Move to" is not possible
5573 * disbale NEW button whenever New is not possible */
5574 g_signal_connect (tree_view,
5575 "folder_selection_changed",
5576 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
5580 /* It could happen that we're trying to move a message from a
5581 window (msg window for example) after the main window was
5582 closed, so we can not just get the model of the folder
5584 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
5585 const gchar *visible_id = NULL;
5587 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5588 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5589 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
5590 MODEST_FOLDER_VIEW(tree_view));
5593 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
5595 /* Show the same account than the one that is shown in the main window */
5596 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
5599 const gchar *active_account_name = NULL;
5600 ModestAccountMgr *mgr = NULL;
5601 ModestAccountSettings *settings = NULL;
5602 ModestServerAccountSettings *store_settings = NULL;
5604 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5605 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5607 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
5608 mgr = modest_runtime_get_account_mgr ();
5609 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
5612 const gchar *store_account_name;
5613 store_settings = modest_account_settings_get_store_settings (settings);
5614 store_account_name = modest_server_account_settings_get_account_name (store_settings);
5616 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
5617 store_account_name);
5618 g_object_unref (store_settings);
5619 g_object_unref (settings);
5623 /* we keep a pointer to the embedded folder view, so we can
5624 * retrieve it with get_folder_view_from_move_to_dialog (see
5625 * above) later (needed for focus handling)
5627 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
5629 /* Hide special folders */
5630 #ifndef MODEST_TOOLKIT_HILDON2
5631 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
5634 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
5635 #ifndef MODEST_TOOLKIT_HILDON2
5636 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5639 gtk_widget_show (GTK_WIDGET (tree_view));
5645 * Shows a confirmation dialog to the user when we're moving messages
5646 * from a remote server to the local storage. Returns the dialog
5647 * response. If it's other kind of movement then it always returns
5650 * This one is used by the next functions:
5651 * modest_ui_actions_on_paste - commented out
5652 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
5655 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
5656 TnyFolder *dest_folder,
5660 gint response = GTK_RESPONSE_OK;
5661 TnyAccount *account = NULL;
5662 TnyFolder *src_folder = NULL;
5663 TnyIterator *iter = NULL;
5664 TnyHeader *header = NULL;
5666 /* return with OK if the destination is a remote folder */
5667 if (modest_tny_folder_is_remote_folder (dest_folder))
5668 return GTK_RESPONSE_OK;
5670 /* Get source folder */
5671 iter = tny_list_create_iterator (headers);
5672 header = TNY_HEADER (tny_iterator_get_current (iter));
5674 src_folder = tny_header_get_folder (header);
5675 g_object_unref (header);
5677 g_object_unref (iter);
5679 /* if no src_folder, message may be an attahcment */
5680 if (src_folder == NULL)
5681 return GTK_RESPONSE_CANCEL;
5683 /* If the source is a local or MMC folder */
5684 if (!modest_tny_folder_is_remote_folder (src_folder)) {
5685 g_object_unref (src_folder);
5686 return GTK_RESPONSE_OK;
5689 /* Get the account */
5690 account = tny_folder_get_account (src_folder);
5692 /* now if offline we ask the user */
5693 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
5694 response = GTK_RESPONSE_OK;
5696 response = GTK_RESPONSE_CANCEL;
5699 g_object_unref (src_folder);
5700 g_object_unref (account);
5706 move_to_helper_destroyer (gpointer user_data)
5708 MoveToHelper *helper = (MoveToHelper *) user_data;
5710 /* Close the "Pasting" information banner */
5711 if (helper->banner) {
5712 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5713 g_object_unref (helper->banner);
5715 if (gtk_tree_row_reference_valid (helper->reference)) {
5716 gtk_tree_row_reference_free (helper->reference);
5717 helper->reference = NULL;
5723 move_to_cb (ModestMailOperation *mail_op,
5726 MoveToHelper *helper = (MoveToHelper *) user_data;
5727 GObject *object = modest_mail_operation_get_source (mail_op);
5729 /* Note that the operation could have failed, in that case do
5731 if (modest_mail_operation_get_status (mail_op) !=
5732 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5735 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5736 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5738 if (!modest_msg_view_window_select_next_message (self) &&
5739 !modest_msg_view_window_select_previous_message (self)) {
5740 /* No more messages to view, so close this window */
5741 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5743 } else if (MODEST_IS_MAIN_WINDOW (object) &&
5744 gtk_tree_row_reference_valid (helper->reference)) {
5745 GtkWidget *header_view;
5747 GtkTreeSelection *sel;
5749 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5750 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5751 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5752 path = gtk_tree_row_reference_get_path (helper->reference);
5753 /* We need to unselect the previous one
5754 because we could be copying instead of
5756 gtk_tree_selection_unselect_all (sel);
5757 gtk_tree_selection_select_path (sel, path);
5758 gtk_tree_path_free (path);
5760 g_object_unref (object);
5763 /* Destroy the helper */
5764 move_to_helper_destroyer (helper);
5768 folder_move_to_cb (ModestMailOperation *mail_op,
5769 TnyFolder *new_folder,
5772 GtkWidget *folder_view;
5775 object = modest_mail_operation_get_source (mail_op);
5776 if (MODEST_IS_MAIN_WINDOW (object)) {
5777 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5778 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5779 g_object_ref (folder_view);
5780 g_object_unref (object);
5781 move_to_cb (mail_op, user_data);
5782 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5783 g_object_unref (folder_view);
5785 move_to_cb (mail_op, user_data);
5790 msgs_move_to_cb (ModestMailOperation *mail_op,
5793 move_to_cb (mail_op, user_data);
5797 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5800 GObject *win = NULL;
5801 const GError *error;
5802 TnyAccount *account = NULL;
5804 #ifndef MODEST_TOOLKIT_HILDON2
5805 ModestWindow *main_window = NULL;
5807 /* Disable next automatic folder selection */
5808 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5809 FALSE); /* don't create */
5811 /* Show notification dialog only if the main window exists */
5813 GtkWidget *folder_view = NULL;
5815 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5816 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5817 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5819 if (user_data && TNY_IS_FOLDER (user_data)) {
5820 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5821 TNY_FOLDER (user_data), FALSE);
5825 win = modest_mail_operation_get_source (mail_op);
5826 error = modest_mail_operation_get_error (mail_op);
5828 if (TNY_IS_FOLDER (user_data))
5829 account = modest_tny_folder_get_account (TNY_FOLDER (user_data));
5830 else if (TNY_IS_ACCOUNT (user_data))
5831 account = g_object_ref (user_data);
5833 /* If it's not a disk full error then show a generic error */
5834 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5835 (GtkWidget *) win, (GError *) error,
5837 modest_platform_run_information_dialog ((GtkWindow *) win,
5838 _("mail_in_ui_folder_move_target_error"),
5841 g_object_unref (account);
5843 g_object_unref (win);
5847 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5856 gint pending_purges = 0;
5857 gboolean some_purged = FALSE;
5858 ModestWindow *win = MODEST_WINDOW (user_data);
5859 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5861 /* If there was any error */
5862 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5863 modest_window_mgr_unregister_header (mgr, header);
5867 /* Once the message has been retrieved for purging, we check if
5868 * it's all ok for purging */
5870 parts = tny_simple_list_new ();
5871 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5872 iter = tny_list_create_iterator (parts);
5874 while (!tny_iterator_is_done (iter)) {
5876 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5877 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5878 if (tny_mime_part_is_purged (part))
5885 g_object_unref (part);
5887 tny_iterator_next (iter);
5889 g_object_unref (iter);
5892 if (pending_purges>0) {
5894 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5896 if (response == GTK_RESPONSE_OK) {
5899 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5900 iter = tny_list_create_iterator (parts);
5901 while (!tny_iterator_is_done (iter)) {
5904 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5905 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5906 tny_mime_part_set_purged (part);
5909 g_object_unref (part);
5911 tny_iterator_next (iter);
5913 g_object_unref (iter);
5915 tny_msg_rewrite_cache (msg);
5917 gtk_widget_destroy (info);
5921 modest_window_mgr_unregister_header (mgr, header);
5923 g_object_unref (parts);
5927 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5928 ModestMainWindow *win)
5930 GtkWidget *header_view;
5931 TnyList *header_list;
5933 TnyHeaderFlags flags;
5934 ModestWindow *msg_view_window = NULL;
5937 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5939 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5940 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5942 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5944 g_warning ("%s: no header selected", __FUNCTION__);
5948 if (tny_list_get_length (header_list) == 1) {
5949 TnyIterator *iter = tny_list_create_iterator (header_list);
5950 header = TNY_HEADER (tny_iterator_get_current (iter));
5951 g_object_unref (iter);
5955 if (!header || !TNY_IS_HEADER(header)) {
5956 g_warning ("%s: header is not valid", __FUNCTION__);
5960 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5961 header, &msg_view_window);
5962 flags = tny_header_get_flags (header);
5963 if (!(flags & TNY_HEADER_FLAG_CACHED))
5966 if (msg_view_window != NULL)
5967 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5969 /* do nothing; uid was registered before, so window is probably on it's way */
5970 g_debug ("header %p has already been registered", header);
5973 ModestMailOperation *mail_op = NULL;
5974 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5975 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5976 modest_ui_actions_disk_operations_error_handler,
5978 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5979 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5981 g_object_unref (mail_op);
5984 g_object_unref (header);
5986 g_object_unref (header_list);
5990 * Checks if we need a connection to do the transfer and if the user
5991 * wants to connect to complete it
5994 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5995 TnyFolderStore *src_folder,
5997 TnyFolder *dst_folder,
5998 gboolean delete_originals,
5999 gboolean *need_connection,
6002 TnyAccount *src_account;
6003 gint uncached_msgs = 0;
6005 /* We don't need any further check if
6007 * 1- the source folder is local OR
6008 * 2- the device is already online
6010 if (!modest_tny_folder_store_is_remote (src_folder) ||
6011 tny_device_is_online (modest_runtime_get_device())) {
6012 *need_connection = FALSE;
6017 /* We must ask for a connection when
6019 * - the message(s) is not already cached OR
6020 * - the message(s) is cached but the leave_on_server setting
6021 * is FALSE (because we need to sync the source folder to
6022 * delete the message from the server (for IMAP we could do it
6023 * offline, it'll take place the next time we get a
6026 uncached_msgs = header_list_count_uncached_msgs (headers);
6027 src_account = get_account_from_folder_store (src_folder);
6028 if (uncached_msgs > 0) {
6032 *need_connection = TRUE;
6033 num_headers = tny_list_get_length (headers);
6034 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
6036 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
6037 GTK_RESPONSE_CANCEL) {
6043 /* The transfer is possible and the user wants to */
6046 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
6047 const gchar *account_name;
6048 gboolean leave_on_server;
6050 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
6051 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
6054 if (leave_on_server == TRUE) {
6055 *need_connection = FALSE;
6057 *need_connection = TRUE;
6060 *need_connection = FALSE;
6065 g_object_unref (src_account);
6069 xfer_messages_error_handler (ModestMailOperation *mail_op,
6073 const GError *error;
6074 TnyAccount *account;
6076 win = modest_mail_operation_get_source (mail_op);
6077 error = modest_mail_operation_get_error (mail_op);
6079 /* We cannot get the account from the mail op as that is the
6080 source account and for checking memory full conditions we
6081 need the destination one */
6082 account = TNY_ACCOUNT (user_data);
6085 !modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6086 (GtkWidget *) win, (GError*) error,
6087 account, _KR("cerm_memory_card_full"))) {
6088 modest_platform_run_information_dialog ((GtkWindow *) win,
6089 _("mail_in_ui_folder_move_target_error"),
6093 g_object_unref (win);
6097 TnyFolderStore *dst_folder;
6102 * Utility function that transfer messages from both the main window
6103 * and the msg view window when using the "Move to" dialog
6106 xfer_messages_performer (gboolean canceled,
6108 GtkWindow *parent_window,
6109 TnyAccount *account,
6112 ModestWindow *win = MODEST_WINDOW (parent_window);
6113 TnyAccount *dst_account = NULL;
6114 gboolean dst_forbids_message_add = FALSE;
6115 XferMsgsHelper *helper;
6116 MoveToHelper *movehelper;
6117 ModestMailOperation *mail_op;
6119 helper = (XferMsgsHelper *) user_data;
6121 if (canceled || err) {
6122 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6123 (GtkWidget *) parent_window, err,
6125 /* Show the proper error message */
6126 modest_ui_actions_on_account_connection_error (parent_window, account);
6131 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
6133 /* tinymail will return NULL for local folders it seems */
6134 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
6135 modest_tny_account_get_protocol_type (dst_account),
6136 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
6138 if (dst_forbids_message_add) {
6139 modest_platform_information_banner (GTK_WIDGET (win),
6141 ngettext("mail_in_ui_folder_move_target_error",
6142 "mail_in_ui_folder_move_targets_error",
6143 tny_list_get_length (helper->headers)));
6147 movehelper = g_new0 (MoveToHelper, 1);
6149 #ifndef MODEST_TOOLKIT_HILDON2
6150 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
6151 _CS("ckct_nw_pasting"));
6152 if (movehelper->banner != NULL) {
6153 g_object_ref (movehelper->banner);
6154 gtk_widget_show (GTK_WIDGET (movehelper->banner));
6158 if (MODEST_IS_MAIN_WINDOW (win)) {
6159 GtkWidget *header_view =
6160 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6161 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6162 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
6165 /* Perform the mail operation */
6166 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
6167 xfer_messages_error_handler,
6168 g_object_ref (dst_account),
6170 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
6173 modest_mail_operation_xfer_msgs (mail_op,
6175 TNY_FOLDER (helper->dst_folder),
6180 g_object_unref (G_OBJECT (mail_op));
6183 g_object_unref (dst_account);
6184 g_object_unref (helper->dst_folder);
6185 g_object_unref (helper->headers);
6186 g_slice_free (XferMsgsHelper, helper);
6190 TnyFolder *src_folder;
6191 TnyFolderStore *dst_folder;
6192 gboolean delete_original;
6193 GtkWidget *folder_view;
6197 on_move_folder_cb (gboolean canceled,
6199 GtkWindow *parent_window,
6200 TnyAccount *account,
6203 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
6204 GtkTreeSelection *sel;
6205 ModestMailOperation *mail_op = NULL;
6207 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
6208 /* Note that the connection process can fail due to
6209 memory low conditions as it can not successfully
6210 store the summary */
6211 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6212 (GtkWidget*) parent_window, err,
6214 g_debug ("Error connecting when trying to move a folder");
6216 g_object_unref (G_OBJECT (info->src_folder));
6217 g_object_unref (G_OBJECT (info->dst_folder));
6222 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
6223 #ifndef MODEST_TOOLKIT_HILDON2
6224 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
6225 _CS("ckct_nw_pasting"));
6226 if (helper->banner != NULL) {
6227 g_object_ref (helper->banner);
6228 gtk_widget_show (GTK_WIDGET(helper->banner));
6231 /* Clean folder on header view before moving it */
6232 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
6233 gtk_tree_selection_unselect_all (sel);
6235 /* Let gtk events run. We need that the folder
6236 view frees its reference to the source
6237 folder *before* issuing the mail operation
6238 so we need the signal handler of selection
6239 changed to happen before the mail
6241 while (gtk_events_pending ())
6242 gtk_main_iteration (); */
6245 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
6246 modest_ui_actions_move_folder_error_handler,
6247 g_object_ref (info->dst_folder), g_object_unref);
6248 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
6251 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
6252 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
6253 TNY_FOLDER (info->dst_folder), TRUE);
6255 modest_mail_operation_xfer_folder (mail_op,
6256 TNY_FOLDER (info->src_folder),
6258 info->delete_original,
6261 g_object_unref (G_OBJECT (info->src_folder));
6263 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
6266 /* Unref mail operation */
6267 g_object_unref (G_OBJECT (mail_op));
6268 g_object_unref (G_OBJECT (info->dst_folder));
6273 get_account_from_folder_store (TnyFolderStore *folder_store)
6275 if (TNY_IS_ACCOUNT (folder_store))
6276 return g_object_ref (folder_store);
6278 return tny_folder_get_account (TNY_FOLDER (folder_store));
6282 * UI handler for the "Move to" action when invoked from the
6286 modest_ui_actions_on_main_window_move_to (GtkAction *action,
6287 GtkWidget *folder_view,
6288 TnyFolderStore *dst_folder,
6289 ModestMainWindow *win)
6291 ModestHeaderView *header_view = NULL;
6292 TnyFolderStore *src_folder = NULL;
6294 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
6296 /* Get the source folder */
6297 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6299 /* Get header view */
6300 header_view = (ModestHeaderView *)
6301 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6303 /* Get folder or messages to transfer */
6304 if (gtk_widget_is_focus (folder_view)) {
6305 gboolean do_xfer = TRUE;
6307 /* Allow only to transfer folders to the local root folder */
6308 if (TNY_IS_ACCOUNT (dst_folder) &&
6309 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
6310 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
6312 } else if (!TNY_IS_FOLDER (src_folder)) {
6313 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
6318 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
6319 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6321 info->src_folder = g_object_ref (src_folder);
6322 info->dst_folder = g_object_ref (dst_folder);
6323 info->delete_original = TRUE;
6324 info->folder_view = folder_view;
6326 connect_info->callback = on_move_folder_cb;
6327 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6328 connect_info->data = info;
6330 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6331 TNY_FOLDER_STORE (src_folder),
6334 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
6337 headers = modest_header_view_get_selected_headers(header_view);
6339 /* Transfer the messages */
6340 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
6341 headers, TNY_FOLDER (dst_folder));
6343 g_object_unref (headers);
6347 g_object_unref (src_folder);
6350 #ifdef MODEST_TOOLKIT_HILDON2
6352 * UI handler for the "Move to" action when invoked from the
6353 * ModestFolderWindow
6356 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
6357 TnyFolderStore *dst_folder,
6361 TnyFolderStore *src_folder = NULL;
6362 TnyIterator *iterator;
6364 if (tny_list_get_length (selection) != 1)
6367 iterator = tny_list_create_iterator (selection);
6368 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
6369 g_object_unref (iterator);
6372 gboolean do_xfer = TRUE;
6374 /* Allow only to transfer folders to the local root folder */
6375 if (TNY_IS_ACCOUNT (dst_folder) &&
6376 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
6377 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
6380 modest_platform_run_information_dialog (win,
6381 _("mail_in_ui_folder_move_target_error"),
6383 } else if (!TNY_IS_FOLDER (src_folder)) {
6384 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
6389 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
6390 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6392 info->src_folder = g_object_ref (src_folder);
6393 info->dst_folder = g_object_ref (dst_folder);
6394 info->delete_original = TRUE;
6395 info->folder_view = folder_view;
6397 connect_info->callback = on_move_folder_cb;
6398 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6399 connect_info->data = info;
6401 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6402 TNY_FOLDER_STORE (src_folder),
6407 g_object_unref (src_folder);
6413 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
6414 TnyFolder *src_folder,
6416 TnyFolder *dst_folder)
6418 gboolean need_connection = TRUE;
6419 gboolean do_xfer = TRUE;
6420 XferMsgsHelper *helper;
6422 g_return_if_fail (TNY_IS_FOLDER (src_folder));
6423 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6424 g_return_if_fail (TNY_IS_LIST (headers));
6426 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
6427 headers, TNY_FOLDER (dst_folder),
6428 TRUE, &need_connection,
6431 /* If we don't want to transfer just return */
6435 /* Create the helper */
6436 helper = g_slice_new (XferMsgsHelper);
6437 helper->dst_folder = g_object_ref (dst_folder);
6438 helper->headers = g_object_ref (headers);
6440 if (need_connection) {
6441 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6442 connect_info->callback = xfer_messages_performer;
6443 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
6444 connect_info->data = helper;
6446 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6447 TNY_FOLDER_STORE (src_folder),
6450 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
6451 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
6452 src_account, helper);
6453 g_object_unref (src_account);
6458 * UI handler for the "Move to" action when invoked from the
6459 * ModestMsgViewWindow
6462 modest_ui_actions_on_window_move_to (GtkAction *action,
6464 TnyFolderStore *dst_folder,
6467 TnyFolder *src_folder = NULL;
6469 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6472 TnyHeader *header = NULL;
6475 iter = tny_list_create_iterator (headers);
6476 header = (TnyHeader *) tny_iterator_get_current (iter);
6477 src_folder = tny_header_get_folder (header);
6479 /* Transfer the messages */
6480 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
6482 TNY_FOLDER (dst_folder));
6485 g_object_unref (header);
6486 g_object_unref (iter);
6487 g_object_unref (src_folder);
6492 modest_ui_actions_on_move_to (GtkAction *action,
6495 modest_ui_actions_on_edit_mode_move_to (win);
6499 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
6501 GtkWidget *dialog = NULL;
6502 MoveToInfo *helper = NULL;
6503 TnyList *list_to_move;
6505 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
6507 #ifndef MODEST_TOOLKIT_HILDON2
6508 /* Get the main window if exists */
6509 ModestMainWindow *main_window;
6510 if (MODEST_IS_MAIN_WINDOW (win))
6511 main_window = MODEST_MAIN_WINDOW (win);
6514 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
6515 FALSE)); /* don't create */
6518 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
6523 if (tny_list_get_length (list_to_move) < 1) {
6524 g_object_unref (list_to_move);
6528 /* Create and run the dialog */
6529 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
6530 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
6531 GTK_WINDOW (dialog),
6535 helper = g_slice_new0 (MoveToInfo);
6536 helper->list = list_to_move;
6539 /* Listen to response signal */
6540 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
6542 /* Show the dialog */
6543 gtk_widget_show (dialog);
6549 * Calls #HeadersFunc for each header already selected in the main
6550 * window or the message currently being shown in the msg view window
6553 do_headers_action (ModestWindow *win,
6557 TnyList *headers_list = NULL;
6558 TnyIterator *iter = NULL;
6559 TnyHeader *header = NULL;
6560 TnyFolder *folder = NULL;
6563 headers_list = get_selected_headers (win);
6567 /* Get the folder */
6568 iter = tny_list_create_iterator (headers_list);
6569 header = TNY_HEADER (tny_iterator_get_current (iter));
6571 folder = tny_header_get_folder (header);
6572 g_object_unref (header);
6575 /* Call the function for each header */
6576 while (!tny_iterator_is_done (iter)) {
6577 header = TNY_HEADER (tny_iterator_get_current (iter));
6578 func (header, win, user_data);
6579 g_object_unref (header);
6580 tny_iterator_next (iter);
6583 /* Trick: do a poke status in order to speed up the signaling
6586 tny_folder_poke_status (folder);
6587 g_object_unref (folder);
6591 g_object_unref (iter);
6592 g_object_unref (headers_list);
6596 modest_ui_actions_view_attachment (GtkAction *action,
6597 ModestWindow *window)
6599 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6600 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
6602 /* not supported window for this action */
6603 g_return_if_reached ();
6608 modest_ui_actions_save_attachments (GtkAction *action,
6609 ModestWindow *window)
6611 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6613 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
6616 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
6618 /* not supported window for this action */
6619 g_return_if_reached ();
6624 modest_ui_actions_remove_attachments (GtkAction *action,
6625 ModestWindow *window)
6627 if (MODEST_IS_MAIN_WINDOW (window)) {
6628 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
6629 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6630 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
6632 /* not supported window for this action */
6633 g_return_if_reached ();
6638 modest_ui_actions_on_settings (GtkAction *action,
6643 dialog = modest_platform_get_global_settings_dialog ();
6644 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
6645 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
6646 gtk_widget_show_all (dialog);
6648 gtk_dialog_run (GTK_DIALOG (dialog));
6650 gtk_widget_destroy (dialog);
6654 modest_ui_actions_on_help (GtkAction *action,
6657 /* Help app is not available at all in fremantle */
6658 #ifndef MODEST_TOOLKIT_HILDON2
6659 const gchar *help_id;
6661 g_return_if_fail (win && GTK_IS_WINDOW(win));
6663 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
6666 modest_platform_show_help (GTK_WINDOW (win), help_id);
6671 modest_ui_actions_on_csm_help (GtkAction *action,
6674 /* Help app is not available at all in fremantle */
6675 #ifndef MODEST_TOOLKIT_HILDON2
6677 const gchar* help_id = NULL;
6678 GtkWidget *folder_view;
6679 TnyFolderStore *folder_store;
6681 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
6683 /* Get selected folder */
6684 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
6685 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6686 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6688 /* Switch help_id */
6689 if (folder_store && TNY_IS_FOLDER (folder_store))
6690 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
6693 g_object_unref (folder_store);
6696 modest_platform_show_help (GTK_WINDOW (win), help_id);
6698 modest_ui_actions_on_help (action, win);
6703 retrieve_contents_cb (ModestMailOperation *mail_op,
6710 /* We only need this callback to show an error in case of
6711 memory low condition */
6712 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
6713 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
6718 retrieve_msg_contents_performer (gboolean canceled,
6720 GtkWindow *parent_window,
6721 TnyAccount *account,
6724 ModestMailOperation *mail_op;
6725 TnyList *headers = TNY_LIST (user_data);
6727 if (err || canceled) {
6728 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6729 (GtkWidget *) parent_window, err,
6734 /* Create mail operation */
6735 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
6736 modest_ui_actions_disk_operations_error_handler,
6738 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
6739 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
6742 g_object_unref (mail_op);
6744 g_object_unref (headers);
6745 g_object_unref (account);
6749 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
6750 ModestWindow *window)
6752 TnyList *headers = NULL;
6753 TnyAccount *account = NULL;
6754 TnyIterator *iter = NULL;
6755 TnyHeader *header = NULL;
6756 TnyFolder *folder = NULL;
6759 headers = get_selected_headers (window);
6763 /* Pick the account */
6764 iter = tny_list_create_iterator (headers);
6765 header = TNY_HEADER (tny_iterator_get_current (iter));
6766 folder = tny_header_get_folder (header);
6767 account = tny_folder_get_account (folder);
6768 g_object_unref (folder);
6769 g_object_unref (header);
6770 g_object_unref (iter);
6772 /* Connect and perform the message retrieval */
6773 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6774 g_object_ref (account),
6775 retrieve_msg_contents_performer,
6776 g_object_ref (headers));
6779 g_object_unref (account);
6780 g_object_unref (headers);
6784 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6786 g_return_if_fail (MODEST_IS_WINDOW (window));
6789 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6793 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6795 g_return_if_fail (MODEST_IS_WINDOW (window));
6798 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6802 modest_ui_actions_on_email_menu_activated (GtkAction *action,
6803 ModestWindow *window)
6805 g_return_if_fail (MODEST_IS_WINDOW (window));
6808 modest_ui_actions_check_menu_dimming_rules (window);
6812 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
6813 ModestWindow *window)
6815 g_return_if_fail (MODEST_IS_WINDOW (window));
6818 modest_ui_actions_check_menu_dimming_rules (window);
6822 modest_ui_actions_on_view_menu_activated (GtkAction *action,
6823 ModestWindow *window)
6825 g_return_if_fail (MODEST_IS_WINDOW (window));
6828 modest_ui_actions_check_menu_dimming_rules (window);
6832 modest_ui_actions_on_format_menu_activated (GtkAction *action,
6833 ModestWindow *window)
6835 g_return_if_fail (MODEST_IS_WINDOW (window));
6838 modest_ui_actions_check_menu_dimming_rules (window);
6842 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
6843 ModestWindow *window)
6845 g_return_if_fail (MODEST_IS_WINDOW (window));
6848 modest_ui_actions_check_menu_dimming_rules (window);
6852 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
6853 ModestWindow *window)
6855 g_return_if_fail (MODEST_IS_WINDOW (window));
6858 modest_ui_actions_check_menu_dimming_rules (window);
6862 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
6863 ModestWindow *window)
6865 g_return_if_fail (MODEST_IS_WINDOW (window));
6868 modest_ui_actions_check_menu_dimming_rules (window);
6872 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
6873 ModestWindow *window)
6875 g_return_if_fail (MODEST_IS_WINDOW (window));
6878 modest_ui_actions_check_menu_dimming_rules (window);
6882 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
6883 ModestWindow *window)
6885 g_return_if_fail (MODEST_IS_WINDOW (window));
6888 modest_ui_actions_check_menu_dimming_rules (window);
6892 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6894 g_return_if_fail (MODEST_IS_WINDOW (window));
6896 /* we check for low-mem; in that case, show a warning, and don't allow
6899 if (modest_platform_check_memory_low (window, TRUE))
6902 modest_platform_show_search_messages (GTK_WINDOW (window));
6906 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6908 g_return_if_fail (MODEST_IS_WINDOW (win));
6911 /* we check for low-mem; in that case, show a warning, and don't allow
6912 * for the addressbook
6914 if (modest_platform_check_memory_low (win, TRUE))
6918 modest_platform_show_addressbook (GTK_WINDOW (win));
6923 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6924 ModestWindow *window)
6927 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6929 if (GTK_IS_TOGGLE_ACTION (action))
6930 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6934 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window),
6939 on_send_receive_finished (ModestMailOperation *mail_op,
6942 GtkWidget *header_view, *folder_view;
6943 TnyFolderStore *folder_store;
6944 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6946 /* Set send/receive operation finished */
6947 modest_main_window_notify_send_receive_completed (main_win);
6949 /* Don't refresh the current folder if there were any errors */
6950 if (modest_mail_operation_get_status (mail_op) !=
6951 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6954 /* Refresh the current folder if we're viewing a window. We do
6955 this because the user won't be able to see the new mails in
6956 the selected folder after a Send&Receive because it only
6957 performs a poke_status, i.e, only the number of read/unread
6958 messages is updated, but the new headers are not
6960 folder_view = modest_main_window_get_child_widget (main_win,
6961 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6965 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6967 /* Do not need to refresh INBOX again because the
6968 update_account does it always automatically */
6969 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6970 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6971 ModestMailOperation *refresh_op;
6973 header_view = modest_main_window_get_child_widget (main_win,
6974 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6976 /* We do not need to set the contents style
6977 because it hasn't changed. We also do not
6978 need to save the widget status. Just force
6980 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6981 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6982 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6983 folder_refreshed_cb, main_win);
6984 g_object_unref (refresh_op);
6988 g_object_unref (folder_store);
6993 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6999 const gchar* server_name = NULL;
7000 TnyTransportAccount *transport;
7001 gchar *message = NULL;
7002 ModestProtocol *protocol;
7004 /* Don't show anything if the user cancelled something or the
7005 * send receive request is not interactive. Authentication
7006 * errors are managed by the account store so no need to show
7007 * a dialog here again */
7008 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
7009 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
7010 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
7014 /* Get the server name. Note that we could be using a
7015 connection specific transport account */
7016 transport = (TnyTransportAccount *)
7017 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
7019 ModestTnyAccountStore *acc_store;
7020 const gchar *acc_name;
7021 TnyTransportAccount *conn_specific;
7023 acc_store = modest_runtime_get_account_store();
7024 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
7025 conn_specific = (TnyTransportAccount *)
7026 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
7027 if (conn_specific) {
7028 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
7029 g_object_unref (conn_specific);
7031 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
7033 g_object_unref (transport);
7037 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
7038 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
7039 tny_account_get_proto (TNY_ACCOUNT (transport)));
7041 g_warning ("%s: Account with no proto", __FUNCTION__);
7045 /* Show the appropriate message text for the GError: */
7046 switch (err->code) {
7047 case TNY_SERVICE_ERROR_CONNECT:
7048 message = modest_protocol_get_translation (protocol,
7049 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
7052 case TNY_SERVICE_ERROR_SEND:
7053 message = g_strdup (_CS("sfil_ib_unable_to_send"));
7055 case TNY_SERVICE_ERROR_UNAVAILABLE:
7056 message = modest_protocol_get_translation (protocol,
7057 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
7061 g_warning ("%s: unexpected ERROR %d",
7062 __FUNCTION__, err->code);
7063 message = g_strdup (_CS("sfil_ib_unable_to_send"));
7067 modest_platform_run_information_dialog (NULL, message, FALSE);
7072 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
7077 ModestWindow *top_window = NULL;
7078 ModestWindowMgr *mgr = NULL;
7079 GtkWidget *header_view = NULL;
7080 TnyFolder *selected_folder = NULL;
7081 TnyFolderType folder_type;
7083 mgr = modest_runtime_get_window_mgr ();
7084 top_window = modest_window_mgr_get_current_top (mgr);
7089 #ifndef MODEST_TOOLKIT_HILDON2
7090 if (MODEST_IS_MAIN_WINDOW (top_window)) {
7091 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (top_window),
7092 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
7095 if (MODEST_IS_HEADER_WINDOW (top_window)) {
7096 header_view = (GtkWidget *)
7097 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
7101 /* Get selected folder */
7103 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
7104 if (!selected_folder)
7107 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
7108 #if GTK_CHECK_VERSION(2, 8, 0)
7109 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
7110 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
7111 GtkTreeViewColumn *tree_column;
7113 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
7114 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
7116 gtk_tree_view_column_queue_resize (tree_column);
7118 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
7119 gtk_widget_queue_draw (header_view);
7122 #ifndef MODEST_TOOLKIT_HILDON2
7123 /* Rerun dimming rules, because the message could become deletable for example */
7124 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
7125 MODEST_DIMMING_RULES_TOOLBAR);
7126 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
7127 MODEST_DIMMING_RULES_MENU);
7131 g_object_unref (selected_folder);
7135 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
7136 TnyAccount *account)
7138 ModestProtocolType protocol_type;
7139 ModestProtocol *protocol;
7140 gchar *error_note = NULL;
7142 protocol_type = modest_tny_account_get_protocol_type (account);
7143 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
7146 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
7147 if (error_note == NULL) {
7148 g_warning ("%s: This should not be reached", __FUNCTION__);
7150 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
7151 g_free (error_note);
7156 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
7160 TnyFolderStore *folder = NULL;
7161 TnyAccount *account = NULL;
7162 ModestProtocolType proto;
7163 ModestProtocol *protocol;
7164 TnyHeader *header = NULL;
7166 if (MODEST_IS_MAIN_WINDOW (win)) {
7167 GtkWidget *header_view;
7168 TnyList* headers = NULL;
7170 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
7171 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
7172 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
7173 if (!headers || tny_list_get_length (headers) == 0) {
7175 g_object_unref (headers);
7178 iter = tny_list_create_iterator (headers);
7179 header = TNY_HEADER (tny_iterator_get_current (iter));
7180 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
7181 g_object_unref (iter);
7182 g_object_unref (headers);
7183 #ifdef MODEST_TOOLKIT_HILDON2
7184 } else if (MODEST_IS_HEADER_WINDOW (win)) {
7185 GtkWidget *header_view;
7186 TnyList* headers = NULL;
7188 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
7189 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
7190 if (!headers || tny_list_get_length (headers) == 0) {
7192 g_object_unref (headers);
7195 iter = tny_list_create_iterator (headers);
7196 header = TNY_HEADER (tny_iterator_get_current (iter));
7198 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
7200 g_warning ("List should contain headers");
7202 g_object_unref (iter);
7203 g_object_unref (headers);
7205 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
7206 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
7208 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
7211 if (!header || !folder)
7214 /* Get the account type */
7215 account = tny_folder_get_account (TNY_FOLDER (folder));
7216 proto = modest_tny_account_get_protocol_type (account);
7217 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
7220 subject = tny_header_dup_subject (header);
7221 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
7225 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
7231 g_object_unref (account);
7233 g_object_unref (folder);
7235 g_object_unref (header);
7241 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
7242 const gchar *account_name,
7243 const gchar *account_title)
7245 ModestAccountMgr *account_mgr;
7248 ModestProtocol *protocol;
7249 gboolean removed = FALSE;
7251 g_return_val_if_fail (account_name, FALSE);
7252 g_return_val_if_fail (account_title, FALSE);
7254 account_mgr = modest_runtime_get_account_mgr();
7256 /* The warning text depends on the account type: */
7257 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
7258 modest_account_mgr_get_store_protocol (account_mgr,
7260 txt = modest_protocol_get_translation (protocol,
7261 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
7264 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
7266 response = modest_platform_run_confirmation_dialog (parent_window, txt);
7270 if (response == GTK_RESPONSE_OK) {
7271 /* Remove account. If it succeeds then it also removes
7272 the account from the ModestAccountView: */
7273 gboolean is_default = FALSE;
7274 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
7275 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
7277 g_free (default_account_name);
7279 removed = modest_account_mgr_remove_account (account_mgr, account_name);
7281 #ifdef MODEST_TOOLKIT_HILDON2
7282 hildon_gtk_window_take_screenshot (parent_window, FALSE);
7284 /* Close all email notifications, we cannot
7285 distinguish if the notification belongs to
7286 this account or not, so for safety reasons
7287 we remove them all */
7288 modest_platform_remove_new_mail_notifications (FALSE, account_name);
7290 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
7297 on_fetch_images_performer (gboolean canceled,
7299 GtkWindow *parent_window,
7300 TnyAccount *account,
7303 if (err || canceled) {
7304 /* Show an unable to retrieve images ??? */
7308 /* Note that the user could have closed the window while connecting */
7309 if (GTK_WIDGET_VISIBLE (parent_window))
7310 modest_msg_view_window_fetch_images ((ModestMsgViewWindow *) parent_window);
7311 g_object_unref ((GObject *) user_data);
7315 modest_ui_actions_on_fetch_images (GtkAction *action,
7316 ModestWindow *window)
7318 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
7320 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
7322 on_fetch_images_performer,
7323 g_object_ref (window));
7327 modest_ui_actions_on_reload_message (const gchar *msg_id)
7329 ModestWindow *window = NULL;
7331 g_return_if_fail (msg_id && msg_id[0] != '\0');
7332 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
7338 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
7341 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));
7344 /** Check whether any connections are active, and cancel them if
7346 * Returns TRUE is there was no problem,
7347 * or if an operation was cancelled so we can continue.
7348 * Returns FALSE if the user chose to cancel his request instead.
7352 modest_ui_actions_check_for_active_account (ModestWindow *self,
7353 const gchar* account_name)
7355 ModestTnySendQueue *send_queue;
7356 ModestTnyAccountStore *acc_store;
7357 ModestMailOperationQueue* queue;
7358 TnyConnectionStatus store_conn_status;
7359 TnyAccount *store_account = NULL, *transport_account = NULL;
7360 gboolean retval = TRUE, sending = FALSE;
7362 acc_store = modest_runtime_get_account_store ();
7363 queue = modest_runtime_get_mail_operation_queue ();
7366 modest_tny_account_store_get_server_account (acc_store,
7368 TNY_ACCOUNT_TYPE_STORE);
7370 /* This could happen if the account was deleted before the
7371 call to this function */
7376 modest_tny_account_store_get_server_account (acc_store,
7378 TNY_ACCOUNT_TYPE_TRANSPORT);
7380 /* This could happen if the account was deleted before the
7381 call to this function */
7382 if (!transport_account) {
7383 g_object_unref (store_account);
7387 /* If the transport account was not used yet, then the send
7388 queue could not exist (it's created on demand) */
7389 send_queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (transport_account), FALSE);
7390 if (TNY_IS_SEND_QUEUE (send_queue))
7391 sending = modest_tny_send_queue_sending_in_progress (send_queue);
7393 store_conn_status = tny_account_get_connection_status (store_account);
7394 if (store_conn_status == TNY_CONNECTION_STATUS_CONNECTED || sending) {
7397 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (self),
7398 _("emev_nc_disconnect_account"));
7399 if (response == GTK_RESPONSE_OK) {
7408 /* FIXME: We should only cancel those of this account */
7409 modest_mail_operation_queue_cancel_all (queue);
7411 /* Also disconnect the account */
7412 if ((tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED) &&
7413 (tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)) {
7414 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
7418 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (transport_account),
7424 g_object_unref (store_account);
7425 g_object_unref (transport_account);