1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #endif /*HAVE_CONFIG_H*/
34 #include <glib/gi18n.h>
35 #include <glib/gprintf.h>
37 #include <modest-runtime.h>
38 #include <modest-defs.h>
39 #include <modest-tny-folder.h>
40 #include <modest-tny-msg.h>
41 #include <modest-tny-account.h>
42 #include <modest-address-book.h>
43 #include "modest-error.h"
44 #include "modest-ui-actions.h"
45 #include "modest-tny-platform-factory.h"
46 #include "modest-platform.h"
47 #include "modest-debug.h"
48 #include <tny-mime-part.h>
49 #include <tny-error.h>
50 #include <tny-camel-folder.h>
51 #include <tny-camel-imap-folder.h>
52 #include <tny-camel-pop-folder.h>
53 #ifdef MODEST_TOOLKIT_HILDON2
54 #include <modest-accounts-window.h>
55 #include <hildon/hildon-pannable-area.h>
56 #include <hildon/hildon-gtk.h>
57 #include <modest-header-window.h>
58 #include <modest-folder-window.h>
59 #include <modest-maemo-utils.h>
62 #ifdef MODEST_PLATFORM_MAEMO
63 #include "maemo/modest-osso-state-saving.h"
64 #endif /* MODEST_PLATFORM_MAEMO */
65 #ifndef MODEST_TOOLKIT_GTK
66 #include "maemo/modest-hildon-includes.h"
67 #include "maemo/modest-connection-specific-smtp-window.h"
68 #endif /* !MODEST_TOOLKIT_GTK */
70 #include <modest-utils.h>
71 #include "widgets/modest-ui-constants.h"
72 #include <widgets/modest-main-window.h>
73 #include <widgets/modest-msg-view-window.h>
74 #include <widgets/modest-account-view-window.h>
75 #include <widgets/modest-details-dialog.h>
76 #include <widgets/modest-attachments-view.h>
77 #include "widgets/modest-folder-view.h"
78 #include "widgets/modest-global-settings-dialog.h"
79 #include "modest-account-mgr-helpers.h"
80 #include "modest-mail-operation.h"
81 #include "modest-text-utils.h"
82 #include <modest-widget-memory.h>
83 #include <tny-error.h>
84 #include <tny-simple-list.h>
85 #include <tny-msg-view.h>
86 #include <tny-device.h>
87 #include <tny-merge-folder.h>
88 #include <tny-camel-bs-msg.h>
89 #include <tny-camel-bs-mime-part.h>
92 #include <gtkhtml/gtkhtml.h>
94 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
96 typedef struct _GetMsgAsyncHelper {
98 ModestMailOperation *mail_op;
105 typedef enum _ReplyForwardAction {
109 } ReplyForwardAction;
111 typedef struct _ReplyForwardHelper {
112 guint reply_forward_type;
113 ReplyForwardAction action;
116 GtkWidget *parent_window;
118 TnyHeader *top_header;
121 } ReplyForwardHelper;
123 typedef struct _MoveToHelper {
124 GtkTreeRowReference *reference;
128 typedef struct _PasteAsAttachmentHelper {
129 ModestMsgEditWindow *window;
131 } PasteAsAttachmentHelper;
139 * The do_headers_action uses this kind of functions to perform some
140 * action to each member of a list of headers
142 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
144 static void do_headers_action (ModestWindow *win,
148 static void open_msg_cb (ModestMailOperation *mail_op,
155 static void reply_forward_cb (ModestMailOperation *mail_op,
162 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
164 static void folder_refreshed_cb (ModestMailOperation *mail_op,
168 static void on_send_receive_finished (ModestMailOperation *mail_op,
171 static gint header_list_count_uncached_msgs (TnyList *header_list);
173 static gboolean connect_to_get_msg (ModestWindow *win,
174 gint num_of_uncached_msgs,
175 TnyAccount *account);
177 static gboolean remote_folder_has_leave_on_server (TnyFolderStore *folder);
179 static void do_create_folder (GtkWindow *window,
180 TnyFolderStore *parent_folder,
181 const gchar *suggested_name);
183 static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store);
185 static void modest_ui_actions_on_main_window_move_to (GtkAction *action,
186 GtkWidget *folder_view,
187 TnyFolderStore *dst_folder,
188 ModestMainWindow *win);
189 #ifdef MODEST_TOOLKIT_HILDON2
190 static void modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
191 TnyFolderStore *dst_folder,
196 static void modest_ui_actions_on_window_move_to (GtkAction *action,
197 TnyList *list_to_move,
198 TnyFolderStore *dst_folder,
202 * This function checks whether a TnyFolderStore is a pop account
205 remote_folder_has_leave_on_server (TnyFolderStore *folder)
210 g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
212 account = get_account_from_folder_store (folder);
213 result = (modest_protocol_registry_protocol_type_has_leave_on_server (modest_runtime_get_protocol_registry (),
214 modest_tny_account_get_protocol_type (account)));
215 g_object_unref (account);
220 /* FIXME: this should be merged with the similar code in modest-account-view-window */
221 /* Show the account creation wizard dialog.
222 * returns: TRUE if an account was created. FALSE if the user cancelled.
225 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
227 gboolean result = FALSE;
229 gint dialog_response;
231 /* there is no such wizard yet */
232 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
233 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (wizard), (GtkWindow *) win);
235 #ifndef MODEST_TOOLKIT_HILDON2
236 /* always present a main window in the background
237 * we do it here, so we cannot end up with two wizards (as this
238 * function might be called in modest_window_mgr_get_main_window as well */
240 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
241 TRUE); /* create if not existent */
245 ModestWindowMgr *mgr;
247 mgr = modest_runtime_get_window_mgr ();
249 window_list = modest_window_mgr_get_window_list (mgr);
250 if (window_list == NULL) {
251 win = MODEST_WINDOW (modest_accounts_window_new ());
252 if (modest_window_mgr_register_window (mgr, win, NULL)) {
253 gtk_widget_show_all (GTK_WIDGET (win));
255 gtk_widget_destroy (GTK_WIDGET (win));
260 g_list_free (window_list);
266 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
268 /* make sure the mainwindow is visible. We need to present the
269 wizard again to give it the focus back. show_all are needed
270 in order to get the widgets properly drawn (MainWindow main
271 paned won't be in its right position and the dialog will be
273 #ifndef MODEST_TOOLKIT_HILDON2
274 gtk_widget_show_all (GTK_WIDGET (win));
275 gtk_widget_show_all (GTK_WIDGET (wizard));
276 gtk_window_present (GTK_WINDOW (win));
277 gtk_window_present (GTK_WINDOW (wizard));
280 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
281 gtk_widget_destroy (GTK_WIDGET (wizard));
282 if (gtk_events_pending ())
283 gtk_main_iteration ();
285 if (dialog_response == GTK_RESPONSE_CANCEL) {
288 /* Check whether an account was created: */
289 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
296 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
299 const gchar *authors[] = {
300 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
303 about = gtk_about_dialog_new ();
304 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
305 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
306 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
307 _("Copyright (c) 2006, Nokia Corporation\n"
308 "All rights reserved."));
309 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
310 _("a modest e-mail client\n\n"
311 "design and implementation: Dirk-Jan C. Binnema\n"
312 "contributions from the fine people at KC and Ig\n"
313 "uses the tinymail email framework written by Philip van Hoof"));
314 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
315 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
316 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
317 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
319 gtk_dialog_run (GTK_DIALOG (about));
320 gtk_widget_destroy(about);
324 * Gets the list of currently selected messages. If the win is the
325 * main window, then it returns a newly allocated list of the headers
326 * selected in the header view. If win is the msg view window, then
327 * the value returned is a list with just a single header.
329 * The caller of this funcion must free the list.
332 get_selected_headers (ModestWindow *win)
334 if (MODEST_IS_MAIN_WINDOW(win)) {
335 GtkWidget *header_view;
337 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
338 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
339 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
341 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
342 /* for MsgViewWindows, we simply return a list with one element */
344 TnyList *list = NULL;
346 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
347 if (header != NULL) {
348 list = tny_simple_list_new ();
349 tny_list_prepend (list, G_OBJECT(header));
350 g_object_unref (G_OBJECT(header));
355 #ifdef MODEST_TOOLKIT_HILDON2
356 } else if (MODEST_IS_HEADER_WINDOW (win)) {
357 GtkWidget *header_view;
359 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
360 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
366 static GtkTreeRowReference *
367 get_next_after_selected_headers (ModestHeaderView *header_view)
369 GtkTreeSelection *sel;
370 GList *selected_rows, *node;
372 GtkTreeRowReference *result;
375 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
376 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
377 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
379 if (selected_rows == NULL)
382 node = g_list_last (selected_rows);
383 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
384 gtk_tree_path_next (path);
386 result = gtk_tree_row_reference_new (model, path);
388 gtk_tree_path_free (path);
389 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
390 g_list_free (selected_rows);
396 headers_action_mark_as_read (TnyHeader *header,
400 TnyHeaderFlags flags;
403 g_return_if_fail (TNY_IS_HEADER(header));
405 flags = tny_header_get_flags (header);
406 if (flags & TNY_HEADER_FLAG_SEEN) return;
407 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
408 uid = modest_tny_folder_get_header_unique_id (header);
409 modest_platform_emit_msg_read_changed_signal (uid, TRUE);
414 headers_action_mark_as_unread (TnyHeader *header,
418 TnyHeaderFlags flags;
420 g_return_if_fail (TNY_IS_HEADER(header));
422 flags = tny_header_get_flags (header);
423 if (flags & TNY_HEADER_FLAG_SEEN) {
425 uid = modest_tny_folder_get_header_unique_id (header);
426 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
427 modest_platform_emit_msg_read_changed_signal (uid, FALSE);
431 /** After deleing a message that is currently visible in a window,
432 * show the next message from the list, or close the window if there are no more messages.
435 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
437 /* Close msg view window or select next */
438 if (!modest_msg_view_window_select_next_message (win) &&
439 !modest_msg_view_window_select_previous_message (win)) {
441 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
447 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
449 modest_ui_actions_on_edit_mode_delete_message (win);
453 modest_ui_actions_on_edit_mode_delete_message (ModestWindow *win)
455 TnyList *header_list = NULL;
456 TnyIterator *iter = NULL;
457 TnyHeader *header = NULL;
458 gchar *message = NULL;
461 ModestWindowMgr *mgr;
462 GtkWidget *header_view = NULL;
463 gboolean retval = TRUE;
465 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
467 /* Check first if the header view has the focus */
468 if (MODEST_IS_MAIN_WINDOW (win)) {
470 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
471 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
472 if (!gtk_widget_is_focus (header_view))
476 /* Get the headers, either from the header view (if win is the main window),
477 * or from the message view window: */
478 header_list = get_selected_headers (win);
479 if (!header_list) return FALSE;
481 /* Check if any of the headers are already opened, or in the process of being opened */
482 if (MODEST_IS_MAIN_WINDOW (win)) {
483 gint opened_headers = 0;
485 iter = tny_list_create_iterator (header_list);
486 mgr = modest_runtime_get_window_mgr ();
487 while (!tny_iterator_is_done (iter)) {
488 header = TNY_HEADER (tny_iterator_get_current (iter));
490 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
492 g_object_unref (header);
494 tny_iterator_next (iter);
496 g_object_unref (iter);
498 if (opened_headers > 0) {
501 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
504 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg, FALSE);
507 g_object_unref (header_list);
513 if (tny_list_get_length(header_list) == 1) {
514 iter = tny_list_create_iterator (header_list);
515 header = TNY_HEADER (tny_iterator_get_current (iter));
518 subject = tny_header_dup_subject (header);
520 subject = g_strdup (_("mail_va_no_subject"));
521 desc = g_strdup_printf ("%s", subject);
523 g_object_unref (header);
526 g_object_unref (iter);
528 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
529 tny_list_get_length(header_list)), desc);
531 /* Confirmation dialog */
532 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
536 if (response == GTK_RESPONSE_OK) {
537 ModestWindowMgr *mgr = NULL;
538 GtkTreeModel *model = NULL;
539 GtkTreeSelection *sel = NULL;
540 GList *sel_list = NULL, *tmp = NULL;
541 GtkTreeRowReference *next_row_reference = NULL;
542 GtkTreeRowReference *prev_row_reference = NULL;
543 GtkTreePath *next_path = NULL;
544 GtkTreePath *prev_path = NULL;
545 ModestMailOperation *mail_op = NULL;
547 /* Find last selected row */
548 if (MODEST_IS_MAIN_WINDOW (win)) {
549 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
550 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
551 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
552 for (tmp=sel_list; tmp; tmp=tmp->next) {
553 if (tmp->next == NULL) {
554 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
555 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
557 gtk_tree_path_prev (prev_path);
558 gtk_tree_path_next (next_path);
560 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
561 next_row_reference = gtk_tree_row_reference_new (model, next_path);
566 /* Disable window dimming management */
567 modest_window_disable_dimming (win);
569 /* Remove each header. If it's a view window header_view == NULL */
570 mail_op = modest_mail_operation_new ((GObject *) win);
571 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
573 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
574 g_object_unref (mail_op);
576 /* Enable window dimming management */
578 gtk_tree_selection_unselect_all (sel);
580 modest_window_enable_dimming (win);
582 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
583 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
585 /* Get main window */
586 mgr = modest_runtime_get_window_mgr ();
587 } else if (MODEST_IS_MAIN_WINDOW (win)) {
588 /* Select next or previous row */
589 if (gtk_tree_row_reference_valid (next_row_reference)) {
590 gtk_tree_selection_select_path (sel, next_path);
592 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
593 gtk_tree_selection_select_path (sel, prev_path);
597 if (gtk_tree_row_reference_valid (next_row_reference))
598 gtk_tree_row_reference_free (next_row_reference);
599 if (next_path != NULL)
600 gtk_tree_path_free (next_path);
601 if (gtk_tree_row_reference_valid (prev_row_reference))
602 gtk_tree_row_reference_free (prev_row_reference);
603 if (prev_path != NULL)
604 gtk_tree_path_free (prev_path);
607 /* Update toolbar dimming state */
608 modest_ui_actions_check_menu_dimming_rules (win);
609 modest_ui_actions_check_toolbar_dimming_rules (win);
612 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
613 g_list_free (sel_list);
622 g_object_unref (header_list);
630 /* delete either message or folder, based on where we are */
632 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
634 g_return_if_fail (MODEST_IS_WINDOW(win));
636 /* Check first if the header view has the focus */
637 if (MODEST_IS_MAIN_WINDOW (win)) {
639 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
640 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
641 if (gtk_widget_is_focus (w)) {
642 modest_ui_actions_on_delete_folder (action, MODEST_WINDOW(win));
646 modest_ui_actions_on_delete_message (action, win);
650 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
652 ModestWindowMgr *mgr = NULL;
654 #ifdef MODEST_PLATFORM_MAEMO
655 modest_window_mgr_save_state_for_all_windows (modest_runtime_get_window_mgr ());
656 #endif /* MODEST_PLATFORM_MAEMO */
658 g_debug ("closing down, clearing %d item(s) from operation queue",
659 modest_mail_operation_queue_num_elements
660 (modest_runtime_get_mail_operation_queue()));
662 /* cancel all outstanding operations */
663 modest_mail_operation_queue_cancel_all
664 (modest_runtime_get_mail_operation_queue());
666 g_debug ("queue has been cleared");
669 /* Check if there are opened editing windows */
670 mgr = modest_runtime_get_window_mgr ();
671 modest_window_mgr_close_all_windows (mgr);
673 /* note: when modest-tny-account-store is finalized,
674 it will automatically set all network connections
677 /* gtk_main_quit (); */
681 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
685 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
687 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
688 /* gtk_widget_destroy (GTK_WIDGET (win)); */
689 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
690 /* gboolean ret_value; */
691 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
692 /* } else if (MODEST_IS_WINDOW (win)) { */
693 /* gtk_widget_destroy (GTK_WIDGET (win)); */
695 /* g_return_if_reached (); */
700 modest_ui_actions_add_to_contacts (GtkAction *action, ModestWindow *win)
702 if (MODEST_IS_MSG_VIEW_WINDOW (win))
703 modest_msg_view_window_add_to_contacts (MODEST_MSG_VIEW_WINDOW (win));
704 else if (MODEST_IS_MSG_EDIT_WINDOW (win))
705 modest_msg_edit_window_add_to_contacts (MODEST_MSG_EDIT_WINDOW (win));
709 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
711 GtkClipboard *clipboard = NULL;
712 gchar *selection = NULL;
714 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
715 selection = gtk_clipboard_wait_for_text (clipboard);
718 modest_address_book_add_address (selection, (GtkWindow *) win);
724 modest_ui_actions_on_new_account (GtkAction *action,
725 ModestWindow *window)
727 if (!modest_ui_actions_run_account_setup_wizard (window)) {
728 g_debug ("%s: wizard was already running", __FUNCTION__);
733 modest_ui_actions_on_accounts (GtkAction *action,
736 /* This is currently only implemented for Maemo */
737 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
738 if (!modest_ui_actions_run_account_setup_wizard (win))
739 g_debug ("%s: wizard was already running", __FUNCTION__);
743 /* Show the list of accounts */
744 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
746 /* The accounts dialog must be modal */
747 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
748 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
753 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
755 /* This is currently only implemented for Maemo,
756 * because it requires an API (libconic) to detect different connection
759 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
761 /* Create the window if necessary: */
762 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
763 modest_connection_specific_smtp_window_fill_with_connections (
764 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
765 modest_runtime_get_account_mgr());
767 /* Show the window: */
768 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
769 GTK_WINDOW (specific_window), (GtkWindow *) win);
770 gtk_widget_show (specific_window);
771 #endif /* !MODEST_TOOLKIT_GTK */
775 count_part_size (const gchar *part)
777 GnomeVFSURI *vfs_uri;
778 gchar *escaped_filename;
780 GnomeVFSFileInfo *info;
783 /* Estimation of attachment size if we cannot get it from file info */
786 vfs_uri = gnome_vfs_uri_new (part);
788 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
789 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
790 g_free (escaped_filename);
791 gnome_vfs_uri_unref (vfs_uri);
793 info = gnome_vfs_file_info_new ();
795 if (gnome_vfs_get_file_info (part,
797 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
799 if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) {
804 gnome_vfs_file_info_unref (info);
810 count_parts_size (GSList *parts)
815 for (node = parts; node != NULL; node = g_slist_next (node)) {
816 result += count_part_size ((const gchar *) node->data);
823 modest_ui_actions_compose_msg(ModestWindow *win,
826 const gchar *bcc_str,
827 const gchar *subject_str,
828 const gchar *body_str,
830 gboolean set_as_modified)
832 gchar *account_name = NULL;
833 const gchar *mailbox;
835 TnyAccount *account = NULL;
836 TnyFolder *folder = NULL;
837 gchar *from_str = NULL, *signature = NULL, *body = NULL, *recipient = NULL, *tmp = NULL;
838 gboolean use_signature = FALSE;
839 ModestWindow *msg_win = NULL;
840 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
841 ModestTnyAccountStore *store = modest_runtime_get_account_store();
842 GnomeVFSFileSize total_size, allowed_size;
843 guint64 available_disk, expected_size, parts_size;
845 TnyList *header_pairs;
847 /* we check for low-mem */
848 if (modest_platform_check_memory_low (win, TRUE))
851 available_disk = modest_utils_get_available_space (NULL);
852 parts_count = g_slist_length (attachments);
853 parts_size = count_parts_size (attachments);
854 expected_size = modest_tny_msg_estimate_size (body, NULL, parts_count, parts_size);
856 /* Double check: disk full condition or message too big */
857 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
858 expected_size > available_disk) {
859 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
860 modest_platform_system_banner (NULL, NULL, msg);
866 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
867 modest_platform_run_information_dialog (
869 _("mail_ib_error_attachment_size"),
875 #ifdef MODEST_TOOLKIT_HILDON2
877 account_name = g_strdup (modest_window_get_active_account(win));
880 account_name = modest_account_mgr_get_default_account(mgr);
883 g_printerr ("modest: no account found\n");
888 mailbox = modest_window_get_active_mailbox (win);
891 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
893 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
896 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
898 g_printerr ("modest: failed to find Drafts folder\n");
901 from_str = modest_account_mgr_get_from_string (mgr, account_name, mailbox);
903 g_printerr ("modest: failed get from string for '%s'\n", account_name);
908 recipient = modest_text_utils_get_email_address (from_str);
909 tmp = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr (),
912 signature = modest_text_utils_create_colored_signature (tmp);
916 body = use_signature ? g_strconcat ((body_str) ? body_str : "", signature, NULL) :
919 header_pairs = TNY_LIST (tny_simple_list_new ());
920 msg = modest_tny_msg_new_html_plain (to_str, from_str, cc_str, bcc_str, subject_str,
921 NULL, NULL, body, NULL, NULL, NULL, NULL, header_pairs, NULL);
922 g_object_unref (header_pairs);
925 g_printerr ("modest: failed to create new msg\n");
929 /* Create and register edit window */
930 /* This is destroyed by TODO. */
932 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
933 msg_win = modest_msg_edit_window_new (msg, account_name, mailbox, FALSE);
935 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, win)) {
936 gtk_widget_destroy (GTK_WIDGET (msg_win));
939 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
940 gtk_widget_show_all (GTK_WIDGET (msg_win));
942 while (attachments) {
943 GnomeVFSFileSize att_size;
945 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
946 attachments->data, allowed_size);
947 total_size += att_size;
949 if (att_size > allowed_size) {
950 g_debug ("%s: total size: %u",
951 __FUNCTION__, (unsigned int)total_size);
954 allowed_size -= att_size;
956 attachments = g_slist_next(attachments);
963 g_free (account_name);
965 g_object_unref (G_OBJECT(account));
967 g_object_unref (G_OBJECT(folder));
969 g_object_unref (G_OBJECT(msg));
973 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
975 /* if there are no accounts yet, just show the wizard */
976 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
977 if (!modest_ui_actions_run_account_setup_wizard (win))
980 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
985 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
989 ModestMailOperationStatus status;
991 /* If there is no message or the operation was not successful */
992 status = modest_mail_operation_get_status (mail_op);
993 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
996 /* If it's a memory low issue, then show a banner */
997 error = modest_mail_operation_get_error (mail_op);
998 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
999 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
1000 GObject *source = modest_mail_operation_get_source (mail_op);
1001 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
1002 _KR("memr_ib_operation_disabled"),
1004 g_object_unref (source);
1007 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
1008 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
1009 gchar *subject, *msg, *format = NULL;
1010 TnyAccount *account;
1012 subject = (header) ? tny_header_dup_subject (header) : NULL;
1014 subject = g_strdup (_("mail_va_no_subject"));
1016 account = modest_mail_operation_get_account (mail_op);
1018 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
1019 ModestProtocol *protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), proto);
1022 if (tny_account_get_connection_status (account) ==
1023 TNY_CONNECTION_STATUS_CONNECTED) {
1025 format = modest_protocol_get_translation (protocol,
1026 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE,
1029 format = modest_protocol_get_translation (protocol,
1030 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE_LOST_HEADER);
1033 format = g_strdup_printf (_("mail_ib_backend_server_invalid"),
1034 tny_account_get_hostname (account));
1037 g_object_unref (account);
1042 format = g_strdup (_("emev_ni_ui_imap_message_not_available_in_server"));
1044 format = g_strdup (_("emev_ni_ui_pop3_msg_recv_error"));
1048 msg = g_strdup_printf (format, subject);
1049 modest_platform_run_information_dialog (NULL, msg, FALSE);
1055 /* Remove the header from the preregistered uids */
1056 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1069 } OpenMsgBannerInfo;
1072 GtkTreeModel *model;
1074 ModestWindow *caller_window;
1075 OpenMsgBannerInfo *banner_info;
1076 GtkTreeRowReference *rowref;
1080 open_msg_banner_idle (gpointer userdata)
1082 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
1084 gdk_threads_enter ();
1085 banner_info->idle_handler = 0;
1086 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
1087 if (banner_info->banner)
1088 g_object_ref (banner_info->banner);
1090 gdk_threads_leave ();
1096 get_header_view_from_window (ModestWindow *window)
1098 GtkWidget *header_view;
1100 if (MODEST_IS_MAIN_WINDOW (window)) {
1101 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
1102 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1103 #ifdef MODEST_TOOLKIT_HILDON2
1104 } else if (MODEST_IS_HEADER_WINDOW (window)){
1105 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
1115 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
1118 gchar *account = NULL;
1119 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
1124 folder = tny_header_get_folder (header);
1125 /* Gets folder type (OUTBOX headers will be opened in edit window */
1126 if (modest_tny_folder_is_local_folder (folder)) {
1127 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1128 if (folder_type == TNY_FOLDER_TYPE_INVALID)
1129 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1132 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
1133 TnyTransportAccount *traccount = NULL;
1134 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
1135 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
1137 ModestTnySendQueue *send_queue = NULL;
1138 ModestTnySendQueueStatus status;
1140 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
1141 TNY_ACCOUNT(traccount)));
1142 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
1143 if (TNY_IS_SEND_QUEUE (send_queue)) {
1144 msg_id = modest_tny_send_queue_get_msg_id (header);
1145 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
1147 /* Only open messages in outbox with the editor if they are in Failed state */
1148 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
1151 #ifdef MODEST_TOOLKIT_HILDON2
1153 /* In Fremantle we can not
1154 open any message from
1155 outbox which is not in
1161 g_object_unref(traccount);
1163 g_warning("Cannot get transport account for message in outbox!!");
1165 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
1166 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
1170 TnyAccount *acc = tny_folder_get_account (folder);
1173 g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (acc));
1174 g_object_unref (acc);
1178 g_object_unref (folder);
1184 open_msg_cb (ModestMailOperation *mail_op,
1191 ModestWindowMgr *mgr = NULL;
1192 ModestWindow *parent_win = NULL;
1193 ModestWindow *win = NULL;
1194 gchar *account = NULL;
1195 gboolean open_in_editor = FALSE;
1197 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1199 /* Do nothing if there was any problem with the mail
1200 operation. The error will be shown by the error_handler of
1201 the mail operation */
1202 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1205 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1207 /* Mark header as read */
1208 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1210 account = get_info_from_header (header, &open_in_editor, &can_open);
1214 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1216 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1218 if (open_in_editor) {
1219 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1220 gchar *from_header = NULL, *acc_name;
1221 gchar *mailbox = NULL;
1223 from_header = tny_header_dup_from (header);
1225 /* we cannot edit without a valid account... */
1226 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1227 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1228 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1230 g_free (from_header);
1235 acc_name = modest_utils_get_account_name_from_recipient (from_header, &mailbox);
1236 g_free (from_header);
1242 win = modest_msg_edit_window_new (msg, account, mailbox, TRUE);
1246 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1247 const gchar *mailbox = NULL;
1249 if (parent_win && MODEST_IS_WINDOW (parent_win))
1250 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_win));
1252 if (helper->rowref && helper->model) {
1253 win = modest_msg_view_window_new_with_header_model (msg, account, mailbox, (const gchar*) uid,
1254 helper->model, helper->rowref);
1256 win = modest_msg_view_window_new_for_attachment (msg, NULL, account, mailbox, (const gchar*) uid);
1261 /* Register and show new window */
1263 mgr = modest_runtime_get_window_mgr ();
1264 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1265 gtk_widget_destroy (GTK_WIDGET (win));
1268 gtk_widget_show_all (GTK_WIDGET(win));
1271 /* Update toolbar dimming state */
1272 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1273 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1279 g_object_unref (parent_win);
1283 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1286 const GError *error;
1287 GObject *win = NULL;
1288 ModestMailOperationStatus status;
1290 win = modest_mail_operation_get_source (mail_op);
1291 error = modest_mail_operation_get_error (mail_op);
1292 status = modest_mail_operation_get_status (mail_op);
1294 /* If the mail op has been cancelled then it's not an error:
1295 don't show any message */
1296 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1297 TnyAccount *account = modest_mail_operation_get_account (mail_op);
1298 if (modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
1299 (GError *) error, account)) {
1300 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
1301 modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
1303 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1304 modest_platform_information_banner ((GtkWidget *) win,
1305 NULL, _("emev_ui_imap_inbox_select_error"));
1306 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1307 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1308 modest_platform_information_banner ((GtkWidget *) win,
1309 NULL, _CS ("sfil_ni_unable_to_open_file_not_found"));
1310 } else if (user_data) {
1311 modest_platform_information_banner ((GtkWidget *) win,
1315 g_object_unref (account);
1319 g_object_unref (win);
1323 * Returns the account a list of headers belongs to. It returns a
1324 * *new* reference so don't forget to unref it
1327 get_account_from_header_list (TnyList *headers)
1329 TnyAccount *account = NULL;
1331 if (tny_list_get_length (headers) > 0) {
1332 TnyIterator *iter = tny_list_create_iterator (headers);
1333 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1334 TnyFolder *folder = tny_header_get_folder (header);
1337 g_object_unref (header);
1339 while (!tny_iterator_is_done (iter)) {
1340 header = TNY_HEADER (tny_iterator_get_current (iter));
1341 folder = tny_header_get_folder (header);
1344 g_object_unref (header);
1346 tny_iterator_next (iter);
1351 account = tny_folder_get_account (folder);
1352 g_object_unref (folder);
1356 g_object_unref (header);
1358 g_object_unref (iter);
1364 get_account_from_header (TnyHeader *header)
1366 TnyAccount *account = NULL;
1369 folder = tny_header_get_folder (header);
1372 account = tny_folder_get_account (folder);
1373 g_object_unref (folder);
1379 caller_win_destroyed (OpenMsgHelper *helper, GObject *object)
1381 if (helper->caller_window)
1382 helper->caller_window = NULL;
1386 open_msg_helper_destroyer (gpointer user_data)
1388 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1390 if (helper->caller_window) {
1391 g_object_weak_unref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1392 helper->caller_window = NULL;
1395 if (helper->banner_info) {
1396 g_free (helper->banner_info->message);
1397 if (helper->banner_info->idle_handler > 0) {
1398 g_source_remove (helper->banner_info->idle_handler);
1399 helper->banner_info->idle_handler = 0;
1401 if (helper->banner_info->banner != NULL) {
1402 gtk_widget_destroy (helper->banner_info->banner);
1403 g_object_unref (helper->banner_info->banner);
1404 helper->banner_info->banner = NULL;
1406 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1407 helper->banner_info = NULL;
1409 g_object_unref (helper->model);
1410 g_object_unref (helper->header);
1411 gtk_tree_row_reference_free (helper->rowref);
1412 g_slice_free (OpenMsgHelper, helper);
1416 open_msg_performer(gboolean canceled,
1418 GtkWindow *parent_window,
1419 TnyAccount *account,
1422 ModestMailOperation *mail_op = NULL;
1423 gchar *error_msg = NULL;
1424 ModestProtocolType proto;
1425 TnyConnectionStatus status;
1426 OpenMsgHelper *helper = NULL;
1427 ModestProtocol *protocol;
1428 ModestProtocolRegistry *protocol_registry;
1431 helper = (OpenMsgHelper *) user_data;
1433 status = tny_account_get_connection_status (account);
1434 if (err || canceled || helper->caller_window == NULL) {
1435 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1436 /* Free the helper */
1437 open_msg_helper_destroyer (helper);
1439 /* In disk full conditions we could get this error here */
1440 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
1441 (GtkWidget *) parent_window, err,
1447 /* Get the error message depending on the protocol */
1448 proto = modest_tny_account_get_protocol_type (account);
1449 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1450 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1453 protocol_registry = modest_runtime_get_protocol_registry ();
1454 subject = tny_header_dup_subject (helper->header);
1456 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1457 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1461 if (error_msg == NULL) {
1462 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1465 #ifndef MODEST_TOOLKIT_HILDON2
1466 gboolean show_open_draft = FALSE;
1467 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1469 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1471 TnyFolderType folder_type;
1473 folder = tny_header_get_folder (helper->header);
1474 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1475 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1476 g_object_unref (folder);
1480 #ifdef MODEST_TOOLKIT_HILDON2
1483 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1485 if (!g_strcmp0 (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) ||
1486 !g_strcmp0 (account_name, MODEST_MMC_ACCOUNT_ID)) {
1487 g_free (account_name);
1488 account_name = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_window)));
1492 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1493 g_free (account_name);
1494 open_msg_helper_destroyer (helper);
1499 ModestWindow *window;
1500 GtkWidget *header_view;
1503 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1504 uid = modest_tny_folder_get_header_unique_id (helper->header);
1506 const gchar *mailbox = NULL;
1507 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_window));
1508 window = modest_msg_view_window_new_from_header_view
1509 (MODEST_HEADER_VIEW (header_view), account_name, mailbox, uid, helper->rowref);
1510 if (window != NULL) {
1511 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1513 gtk_widget_destroy (GTK_WIDGET (window));
1515 gtk_widget_show_all (GTK_WIDGET(window));
1519 g_free (account_name);
1521 open_msg_helper_destroyer (helper);
1524 g_free (account_name);
1526 /* Create the mail operation */
1528 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1529 modest_ui_actions_disk_operations_error_handler,
1530 g_strdup (error_msg), g_free);
1531 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1535 #ifndef MODEST_TOOLKIT_HILDON2
1536 if (show_open_draft) {
1537 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1538 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1539 helper->banner_info->banner = NULL;
1540 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1541 helper->banner_info);
1547 headers = TNY_LIST (tny_simple_list_new ());
1548 tny_list_prepend (headers, G_OBJECT (helper->header));
1549 modest_mail_operation_get_msgs_full (mail_op,
1553 open_msg_helper_destroyer);
1554 g_object_unref (headers);
1561 g_object_unref (mail_op);
1562 g_object_unref (account);
1566 * This function is used by both modest_ui_actions_on_open and
1567 * modest_ui_actions_on_header_activated. This way we always do the
1568 * same when trying to open messages.
1571 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1573 ModestWindowMgr *mgr = NULL;
1574 TnyAccount *account;
1575 gboolean cached = FALSE;
1577 GtkWidget *header_view = NULL;
1578 OpenMsgHelper *helper;
1579 ModestWindow *window;
1581 g_return_if_fail (header != NULL && rowref != NULL && gtk_tree_row_reference_valid (rowref));
1583 mgr = modest_runtime_get_window_mgr ();
1586 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1587 if (header_view == NULL)
1590 /* Get the account */
1591 account = get_account_from_header (header);
1596 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1598 /* Do not open again the message and present the
1599 window to the user */
1602 #ifndef MODEST_TOOLKIT_HILDON2
1603 gtk_window_present (GTK_WINDOW (window));
1606 /* the header has been registered already, we don't do
1607 * anything but wait for the window to come up*/
1608 g_debug ("header %p already registered, waiting for window", header);
1613 /* Open each message */
1614 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1616 /* Allways download if we are online. */
1617 if (!tny_device_is_online (modest_runtime_get_device ())) {
1620 /* If ask for user permission to download the messages */
1621 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1622 _("mcen_nc_get_msg"));
1624 /* End if the user does not want to continue */
1625 if (response == GTK_RESPONSE_CANCEL) {
1631 /* We register the window for opening */
1632 modest_window_mgr_register_header (mgr, header, NULL);
1634 /* Create the helper. We need to get a reference to the model
1635 here because it could change while the message is readed
1636 (the user could switch between folders) */
1637 helper = g_slice_new (OpenMsgHelper);
1638 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1639 helper->caller_window = win;
1640 g_object_weak_ref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1641 helper->header = g_object_ref (header);
1642 helper->rowref = gtk_tree_row_reference_copy (rowref);
1643 helper->banner_info = NULL;
1645 /* Connect to the account and perform */
1647 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1648 open_msg_performer, helper);
1650 /* Call directly the performer, do not need to connect */
1651 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1652 g_object_ref (account), helper);
1657 g_object_unref (account);
1661 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1668 /* we check for low-mem; in that case, show a warning, and don't allow
1671 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1675 headers = get_selected_headers (win);
1679 headers_count = tny_list_get_length (headers);
1680 if (headers_count != 1) {
1681 if (headers_count > 1) {
1682 /* Don't allow activation if there are more than one message selected */
1683 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1686 g_object_unref (headers);
1690 iter = tny_list_create_iterator (headers);
1691 header = TNY_HEADER (tny_iterator_get_current (iter));
1692 g_object_unref (iter);
1696 open_msg_from_header (header, NULL, win);
1697 g_object_unref (header);
1700 g_object_unref(headers);
1704 rf_helper_window_closed (gpointer data,
1707 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1709 helper->parent_window = NULL;
1712 static ReplyForwardHelper*
1713 create_reply_forward_helper (ReplyForwardAction action,
1715 guint reply_forward_type,
1718 TnyHeader *top_header,
1721 ReplyForwardHelper *rf_helper = NULL;
1722 const gchar *active_acc = modest_window_get_active_account (win);
1723 const gchar *active_mailbox = modest_window_get_active_mailbox (win);
1725 rf_helper = g_slice_new0 (ReplyForwardHelper);
1726 rf_helper->reply_forward_type = reply_forward_type;
1727 rf_helper->action = action;
1728 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1729 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1730 rf_helper->top_header = (top_header) ? g_object_ref (top_header) : NULL;
1731 rf_helper->msg_part = (msg_part) ? g_object_ref (msg_part) : NULL;
1732 rf_helper->account_name = (active_acc) ?
1733 g_strdup (active_acc) :
1734 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1735 rf_helper->mailbox = g_strdup (active_mailbox);
1737 rf_helper->parts = g_object_ref (parts);
1739 rf_helper->parts = NULL;
1741 /* Note that window could be destroyed just AFTER calling
1742 register_window so we must ensure that this pointer does
1743 not hold invalid references */
1744 if (rf_helper->parent_window)
1745 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1746 rf_helper_window_closed, rf_helper);
1752 free_reply_forward_helper (gpointer data)
1754 ReplyForwardHelper *helper;
1756 helper = (ReplyForwardHelper *) data;
1757 g_free (helper->account_name);
1758 g_free (helper->mailbox);
1760 g_object_unref (helper->header);
1761 if (helper->top_header)
1762 g_object_unref (helper->top_header);
1763 if (helper->msg_part)
1764 g_object_unref (helper->msg_part);
1766 g_object_unref (helper->parts);
1767 if (helper->parent_window)
1768 g_object_weak_unref (G_OBJECT (helper->parent_window),
1769 rf_helper_window_closed, helper);
1770 g_slice_free (ReplyForwardHelper, helper);
1774 reply_forward_cb (ModestMailOperation *mail_op,
1781 TnyMsg *new_msg = NULL;
1782 ReplyForwardHelper *rf_helper;
1783 ModestWindow *msg_win = NULL;
1784 ModestEditType edit_type;
1786 TnyAccount *account = NULL;
1787 ModestWindowMgr *mgr = NULL;
1788 gchar *signature = NULL, *recipient = NULL;
1789 gboolean use_signature;
1791 /* If there was any error. The mail operation could be NULL,
1792 this means that we already have the message downloaded and
1793 that we didn't do a mail operation to retrieve it */
1794 rf_helper = (ReplyForwardHelper *) user_data;
1795 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1798 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1799 rf_helper->account_name, rf_helper->mailbox);
1801 recipient = modest_text_utils_get_email_address (from);
1802 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr (),
1807 /* Create reply mail */
1808 switch (rf_helper->action) {
1809 /* Use the msg_header to ensure that we have all the
1810 information. The summary can lack some data */
1811 TnyHeader *msg_header;
1813 msg_header = tny_msg_get_header (rf_helper->msg_part?rf_helper->msg_part:msg);
1815 modest_tny_msg_create_reply_msg (rf_helper->msg_part?rf_helper->msg_part:msg, msg_header, from,
1816 (use_signature) ? signature : NULL,
1817 rf_helper->reply_forward_type,
1818 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1819 g_object_unref (msg_header);
1821 case ACTION_REPLY_TO_ALL:
1822 msg_header = tny_msg_get_header (rf_helper->msg_part?rf_helper->msg_part:msg);
1824 modest_tny_msg_create_reply_msg (rf_helper->msg_part?rf_helper->msg_part:msg, msg_header, from,
1825 (use_signature) ? signature : NULL,
1826 rf_helper->reply_forward_type,
1827 MODEST_TNY_MSG_REPLY_MODE_ALL);
1828 edit_type = MODEST_EDIT_TYPE_REPLY;
1829 g_object_unref (msg_header);
1831 case ACTION_FORWARD:
1833 modest_tny_msg_create_forward_msg (rf_helper->msg_part?rf_helper->msg_part:msg, from,
1834 (use_signature) ? signature : NULL,
1835 rf_helper->reply_forward_type);
1836 edit_type = MODEST_EDIT_TYPE_FORWARD;
1839 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1841 g_return_if_reached ();
1849 g_warning ("%s: failed to create message\n", __FUNCTION__);
1853 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1854 rf_helper->account_name,
1855 TNY_ACCOUNT_TYPE_STORE);
1857 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1861 /* Create and register the windows */
1862 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, rf_helper->mailbox, FALSE);
1863 mgr = modest_runtime_get_window_mgr ();
1864 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1866 /* Note that register_window could have deleted the account */
1867 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1868 gdouble parent_zoom;
1870 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1871 modest_window_set_zoom (msg_win, parent_zoom);
1874 /* Show edit window */
1875 gtk_widget_show_all (GTK_WIDGET (msg_win));
1878 /* We always unregister the header because the message is
1879 forwarded or replied so the original one is no longer
1881 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1884 g_object_unref (G_OBJECT (new_msg));
1886 g_object_unref (G_OBJECT (account));
1887 free_reply_forward_helper (rf_helper);
1890 /* Checks a list of headers. If any of them are not currently
1891 * downloaded (CACHED) then returns TRUE else returns FALSE.
1894 header_list_count_uncached_msgs (TnyList *header_list)
1897 gint uncached_messages = 0;
1899 iter = tny_list_create_iterator (header_list);
1900 while (!tny_iterator_is_done (iter)) {
1903 header = TNY_HEADER (tny_iterator_get_current (iter));
1905 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1906 uncached_messages ++;
1907 g_object_unref (header);
1910 tny_iterator_next (iter);
1912 g_object_unref (iter);
1914 return uncached_messages;
1917 /* Returns FALSE if the user does not want to download the
1918 * messages. Returns TRUE if the user allowed the download.
1921 connect_to_get_msg (ModestWindow *win,
1922 gint num_of_uncached_msgs,
1923 TnyAccount *account)
1925 GtkResponseType response;
1927 /* Allways download if we are online. */
1928 if (tny_device_is_online (modest_runtime_get_device ()))
1931 /* If offline, then ask for user permission to download the messages */
1932 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1933 ngettext("mcen_nc_get_msg",
1935 num_of_uncached_msgs));
1937 if (response == GTK_RESPONSE_CANCEL)
1940 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1944 reply_forward_performer (gboolean canceled,
1946 GtkWindow *parent_window,
1947 TnyAccount *account,
1950 ReplyForwardHelper *rf_helper = NULL;
1951 ModestMailOperation *mail_op;
1953 rf_helper = (ReplyForwardHelper *) user_data;
1955 if (canceled || err) {
1956 free_reply_forward_helper (rf_helper);
1960 /* Retrieve the message */
1961 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1962 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1963 modest_ui_actions_disk_operations_error_handler,
1965 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1966 modest_mail_operation_get_msg_and_parts (mail_op, rf_helper->top_header, rf_helper->parts, TRUE, reply_forward_cb, rf_helper);
1969 g_object_unref(mail_op);
1973 all_parts_retrieved (TnyMimePart *part)
1975 if (!TNY_IS_CAMEL_BS_MIME_PART (part)) {
1978 TnyList *pending_parts;
1979 TnyIterator *iterator;
1980 gboolean all_retrieved = TRUE;
1982 pending_parts = TNY_LIST (tny_simple_list_new ());
1983 tny_mime_part_get_parts (part, pending_parts);
1984 iterator = tny_list_create_iterator (pending_parts);
1985 while (all_retrieved && !tny_iterator_is_done (iterator)) {
1988 child = TNY_MIME_PART (tny_iterator_get_current (iterator));
1990 if (tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (child))) {
1991 all_retrieved = all_parts_retrieved (TNY_MIME_PART (child));
1993 all_retrieved = FALSE;
1996 g_object_unref (child);
1997 tny_iterator_next (iterator);
1999 g_object_unref (iterator);
2000 g_object_unref (pending_parts);
2001 return all_retrieved;
2006 forward_pending_parts_helper (TnyMimePart *part, TnyList *list)
2009 TnyIterator *iterator;
2011 if (!tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (part))) {
2012 tny_list_append (list, G_OBJECT (part));
2014 parts = TNY_LIST (tny_simple_list_new ());
2015 tny_mime_part_get_parts (part, parts);
2016 for (iterator = tny_list_create_iterator (parts);
2017 !tny_iterator_is_done (iterator);
2018 tny_iterator_next (iterator)) {
2021 child = TNY_MIME_PART (tny_iterator_get_current (iterator));
2022 forward_pending_parts_helper (child, list);
2023 g_object_unref (child);
2025 g_object_unref (iterator);
2026 g_object_unref (parts);
2030 forward_pending_parts (TnyMsg *msg)
2032 TnyList *result = TNY_LIST (tny_simple_list_new ());
2033 if (TNY_IS_CAMEL_BS_MIME_PART (msg)) {
2034 forward_pending_parts_helper (TNY_MIME_PART (msg), result);
2041 * Common code for the reply and forward actions
2044 reply_forward (ReplyForwardAction action, ModestWindow *win)
2046 ReplyForwardHelper *rf_helper = NULL;
2047 guint reply_forward_type;
2049 g_return_if_fail (win && MODEST_IS_WINDOW(win));
2051 /* we check for low-mem; in that case, show a warning, and don't allow
2052 * reply/forward (because it could potentially require a lot of memory */
2053 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2057 /* we need an account when editing */
2058 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
2059 if (!modest_ui_actions_run_account_setup_wizard (win))
2063 reply_forward_type =
2064 modest_conf_get_int (modest_runtime_get_conf (),
2065 (action == ACTION_FORWARD) ?
2066 MODEST_CONF_FORWARD_TYPE :
2067 MODEST_CONF_REPLY_TYPE,
2070 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2072 TnyMsg *top_msg = NULL;
2073 TnyHeader *header = NULL;
2074 /* Get header and message. Do not free them here, the
2075 reply_forward_cb must do it */
2076 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
2077 top_msg = modest_msg_view_window_get_top_message (MODEST_MSG_VIEW_WINDOW(win));
2078 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
2080 if (msg && header && (action != ACTION_FORWARD || all_parts_retrieved (TNY_MIME_PART (msg)))) {
2082 rf_helper = create_reply_forward_helper (action, win,
2083 reply_forward_type, header, NULL, NULL, NULL);
2084 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
2086 gboolean do_download = TRUE;
2088 if (msg && header && action == ACTION_FORWARD) {
2089 if (top_msg == NULL)
2090 top_msg = g_object_ref (msg);
2091 /* Not all parts retrieved. Then we have to retrieve them all before
2092 * creating the forward message */
2093 if (!tny_device_is_online (modest_runtime_get_device ())) {
2096 /* If ask for user permission to download the messages */
2097 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2098 ngettext("mcen_nc_get_msg",
2102 /* End if the user does not want to continue */
2103 if (response == GTK_RESPONSE_CANCEL)
2104 do_download = FALSE;
2108 TnyList *pending_parts;
2110 TnyAccount *account;
2111 TnyHeader *top_header;
2114 top_header = tny_msg_get_header (top_msg);
2115 pending_parts = forward_pending_parts (top_msg);
2116 rf_helper = create_reply_forward_helper (action, win,
2117 reply_forward_type, header, msg, top_header, pending_parts);
2118 g_object_unref (pending_parts);
2120 folder = tny_header_get_folder (top_header);
2121 account = tny_folder_get_account (folder);
2122 modest_platform_connect_and_perform (GTK_WINDOW (win),
2124 reply_forward_performer,
2126 if (folder) g_object_unref (folder);
2127 g_object_unref (account);
2128 if (top_header) g_object_unref (top_header);
2132 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
2137 g_object_unref (msg);
2139 g_object_unref (top_msg);
2141 g_object_unref (header);
2143 TnyHeader *header = NULL;
2145 gboolean do_retrieve = TRUE;
2146 TnyList *header_list = NULL;
2148 header_list = get_selected_headers (win);
2151 /* Check that only one message is selected for replying */
2152 if (tny_list_get_length (header_list) != 1) {
2153 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
2154 NULL, _("mcen_ib_select_one_message"));
2155 g_object_unref (header_list);
2159 /* Only reply/forward to one message */
2160 iter = tny_list_create_iterator (header_list);
2161 header = TNY_HEADER (tny_iterator_get_current (iter));
2162 g_object_unref (iter);
2164 /* Retrieve messages */
2165 do_retrieve = (action == ACTION_FORWARD) ||
2166 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
2169 TnyAccount *account = NULL;
2170 TnyFolder *folder = NULL;
2171 gdouble download = TRUE;
2172 guint uncached_msgs = 0;
2174 folder = tny_header_get_folder (header);
2176 goto do_retrieve_frees;
2177 account = tny_folder_get_account (folder);
2179 goto do_retrieve_frees;
2181 uncached_msgs = header_list_count_uncached_msgs (header_list);
2183 if (uncached_msgs > 0) {
2184 /* Allways download if we are online. */
2185 if (!tny_device_is_online (modest_runtime_get_device ())) {
2188 /* If ask for user permission to download the messages */
2189 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2190 ngettext("mcen_nc_get_msg",
2194 /* End if the user does not want to continue */
2195 if (response == GTK_RESPONSE_CANCEL)
2202 rf_helper = create_reply_forward_helper (action, win,
2203 reply_forward_type, header, NULL, NULL, NULL);
2204 if (uncached_msgs > 0) {
2205 modest_platform_connect_and_perform (GTK_WINDOW (win),
2207 reply_forward_performer,
2210 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
2211 account, rf_helper);
2216 g_object_unref (account);
2218 g_object_unref (folder);
2220 reply_forward_cb (NULL, header, FALSE, NULL, NULL, NULL);
2223 g_object_unref (header_list);
2224 g_object_unref (header);
2229 modest_ui_actions_reply_calendar (ModestWindow *win, TnyList *header_pairs)
2234 gboolean use_signature;
2237 const gchar *account_name;
2238 const gchar *mailbox;
2239 TnyHeader *msg_header;
2240 ModestWindowMgr *mgr;
2243 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW(win));
2245 /* we check for low-mem; in that case, show a warning, and don't allow
2246 * reply/forward (because it could potentially require a lot of memory */
2247 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2250 account_name = modest_window_get_active_account (MODEST_WINDOW (win));
2251 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (win));
2252 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
2253 account_name, mailbox);
2254 recipient = modest_text_utils_get_email_address (from);
2255 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr(),
2260 msg = modest_msg_view_window_get_message(MODEST_MSG_VIEW_WINDOW(win));
2261 g_return_if_fail(msg);
2263 msg_header = tny_msg_get_header (msg);
2265 modest_tny_msg_create_reply_calendar_msg (msg, msg_header, from,
2266 (use_signature) ? signature : NULL,
2268 g_object_unref (msg_header);
2274 g_warning ("%s: failed to create message\n", __FUNCTION__);
2278 msg_win = (GtkWidget *) modest_msg_edit_window_new (new_msg, account_name, mailbox, FALSE);
2279 mgr = modest_runtime_get_window_mgr ();
2280 modest_window_mgr_register_window (mgr, MODEST_WINDOW (msg_win), (ModestWindow *) win);
2282 /* Show edit window */
2283 gtk_widget_show_all (GTK_WIDGET (msg_win));
2287 g_object_unref (G_OBJECT (new_msg));
2291 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
2293 g_return_if_fail (MODEST_IS_WINDOW(win));
2295 reply_forward (ACTION_REPLY, win);
2299 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
2301 g_return_if_fail (MODEST_IS_WINDOW(win));
2303 reply_forward (ACTION_FORWARD, win);
2307 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
2309 g_return_if_fail (MODEST_IS_WINDOW(win));
2311 reply_forward (ACTION_REPLY_TO_ALL, win);
2315 modest_ui_actions_on_next (GtkAction *action,
2316 ModestWindow *window)
2318 if (MODEST_IS_MAIN_WINDOW (window)) {
2319 GtkWidget *header_view;
2321 header_view = modest_main_window_get_child_widget (
2322 MODEST_MAIN_WINDOW(window),
2323 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2327 modest_header_view_select_next (
2328 MODEST_HEADER_VIEW(header_view));
2329 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2330 modest_msg_view_window_select_next_message (
2331 MODEST_MSG_VIEW_WINDOW (window));
2333 g_return_if_reached ();
2338 modest_ui_actions_on_prev (GtkAction *action,
2339 ModestWindow *window)
2341 g_return_if_fail (MODEST_IS_WINDOW(window));
2343 if (MODEST_IS_MAIN_WINDOW (window)) {
2344 GtkWidget *header_view;
2345 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2346 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2350 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
2351 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2352 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
2354 g_return_if_reached ();
2359 modest_ui_actions_on_sort (GtkAction *action,
2360 ModestWindow *window)
2362 GtkWidget *header_view = NULL;
2364 g_return_if_fail (MODEST_IS_WINDOW(window));
2366 if (MODEST_IS_MAIN_WINDOW (window)) {
2367 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2368 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2369 #ifdef MODEST_TOOLKIT_HILDON2
2370 } else if (MODEST_IS_HEADER_WINDOW (window)) {
2371 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2376 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
2381 /* Show sorting dialog */
2382 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
2386 sync_folder_cb (ModestMailOperation *mail_op,
2390 ModestHeaderView *header_view = (ModestHeaderView *) user_data;
2392 if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
2393 ModestWindow *parent = (ModestWindow *) modest_mail_operation_get_source (mail_op);
2395 /* We must clear first, because otherwise set_folder will ignore */
2396 /* the change as the folders are the same */
2397 modest_header_view_clear (header_view);
2398 modest_header_view_set_folder (header_view, folder, TRUE, parent, NULL, NULL);
2400 g_object_unref (parent);
2403 g_object_unref (header_view);
2407 idle_refresh_folder (gpointer source)
2409 ModestHeaderView *header_view = NULL;
2411 /* If the window still exists */
2412 if (!GTK_IS_WIDGET (source) ||
2413 !GTK_WIDGET_VISIBLE (source))
2416 /* Refresh the current view */
2417 #ifdef MODEST_TOOLKIT_HILDON2
2418 if (MODEST_IS_HEADER_WINDOW (source))
2419 header_view = modest_header_window_get_header_view ((ModestHeaderWindow *) source);
2421 if (MODEST_IS_MAIN_WINDOW (source))
2422 header_view = MODEST_HEADER_VIEW (modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source),
2423 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
2426 TnyFolder *folder = modest_header_view_get_folder (header_view);
2428 /* Sync the folder status */
2429 ModestMailOperation *mail_op = modest_mail_operation_new (source);
2430 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2431 modest_mail_operation_sync_folder (mail_op, folder, FALSE, sync_folder_cb, g_object_ref (header_view));
2432 g_object_unref (folder);
2433 g_object_unref (mail_op);
2441 update_account_cb (ModestMailOperation *self,
2442 TnyList *new_headers,
2446 gboolean show_visual_notifications;
2448 top = modest_window_mgr_get_current_top (modest_runtime_get_window_mgr ());
2449 show_visual_notifications = (top) ? FALSE : TRUE;
2451 /* Notify new messages have been downloaded. If the
2452 send&receive was invoked by the user then do not show any
2453 visual notification, only play a sound and activate the LED
2454 (for the Maemo version) */
2455 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0) {
2457 /* We only notify about really new messages (not seen) we get */
2458 TnyList *actually_new_list;
2459 TnyIterator *iterator;
2460 actually_new_list = TNY_LIST (tny_simple_list_new ());
2461 for (iterator = tny_list_create_iterator (new_headers);
2462 !tny_iterator_is_done (iterator);
2463 tny_iterator_next (iterator)) {
2465 TnyHeaderFlags flags;
2466 header = TNY_HEADER (tny_iterator_get_current (iterator));
2467 flags = tny_header_get_flags (header);
2469 if (!(flags & TNY_HEADER_FLAG_SEEN)) {
2470 /* Messages are ordered from most
2471 recent to oldest. But we want to
2472 show notifications starting from
2473 the oldest message. That's why we
2475 tny_list_prepend (actually_new_list, G_OBJECT (header));
2477 g_object_unref (header);
2479 g_object_unref (iterator);
2481 if (tny_list_get_length (actually_new_list) > 0) {
2482 GList *new_headers_list = NULL;
2484 new_headers_list = modest_utils_create_notification_list_from_header_list (actually_new_list);
2486 /* Send notifications */
2487 if (new_headers_list) {
2488 modest_platform_on_new_headers_received (new_headers_list,
2489 show_visual_notifications);
2491 modest_utils_free_notification_list (new_headers_list);
2494 g_object_unref (actually_new_list);
2498 /* Refresh the current folder in an idle. We do this
2499 in order to avoid refresh cancelations if the
2500 currently viewed folder is the inbox */
2501 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
2502 idle_refresh_folder,
2509 TnyAccount *account;
2511 gchar *account_name;
2512 gboolean poke_status;
2513 gboolean interactive;
2514 ModestMailOperation *mail_op;
2518 do_send_receive_performer (gboolean canceled,
2520 GtkWindow *parent_window,
2521 TnyAccount *account,
2524 SendReceiveInfo *info;
2526 info = (SendReceiveInfo *) user_data;
2528 if (err || canceled) {
2529 /* In disk full conditions we could get this error here */
2530 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
2531 (GtkWidget *) parent_window, err,
2534 if (info->mail_op) {
2535 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2541 /* Set send/receive operation in progress */
2542 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2543 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2546 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2547 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2548 G_CALLBACK (on_send_receive_finished),
2551 /* Send & receive. */
2552 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2553 update_account_cb, info->win);
2558 g_object_unref (G_OBJECT (info->mail_op));
2559 if (info->account_name)
2560 g_free (info->account_name);
2562 g_object_unref (info->win);
2564 g_object_unref (info->account);
2565 g_slice_free (SendReceiveInfo, info);
2569 * This function performs the send & receive required actions. The
2570 * window is used to create the mail operation. Typically it should
2571 * always be the main window, but we pass it as argument in order to
2575 modest_ui_actions_do_send_receive (const gchar *account_name,
2576 gboolean force_connection,
2577 gboolean poke_status,
2578 gboolean interactive,
2581 gchar *acc_name = NULL;
2582 SendReceiveInfo *info;
2583 ModestTnyAccountStore *acc_store;
2584 TnyAccount *account;
2586 /* If no account name was provided then get the current account, and if
2587 there is no current account then pick the default one: */
2588 if (!account_name) {
2590 acc_name = g_strdup (modest_window_get_active_account (win));
2592 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2594 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2598 acc_name = g_strdup (account_name);
2601 acc_store = modest_runtime_get_account_store ();
2602 account = modest_tny_account_store_get_server_account (acc_store, acc_name, TNY_ACCOUNT_TYPE_STORE);
2606 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2610 /* Do not automatically refresh accounts that are flagged as
2611 NO_AUTO_UPDATE. This could be useful for accounts that
2612 handle their own update times */
2614 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
2615 if (proto != MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
2616 const gchar *tag = MODEST_PROTOCOL_REGISTRY_NO_AUTO_UPDATE_PROTOCOLS;
2617 ModestProtocolRegistry *registry = modest_runtime_get_protocol_registry ();
2619 if (modest_protocol_registry_protocol_type_has_tag (registry, proto, tag)) {
2620 g_debug ("%s no auto update allowed for account %s", __FUNCTION__, account_name);
2621 g_object_unref (account);
2628 /* Create the info for the connect and perform */
2629 info = g_slice_new (SendReceiveInfo);
2630 info->account_name = acc_name;
2631 info->win = (win) ? g_object_ref (win) : NULL;
2632 info->poke_status = poke_status;
2633 info->interactive = interactive;
2634 info->account = account;
2635 /* We need to create the operation here, because otherwise it
2636 could happen that the queue emits the queue-empty signal
2637 while we're trying to connect the account */
2638 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2639 modest_ui_actions_disk_operations_error_handler,
2641 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2643 /* Invoke the connect and perform */
2644 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2645 force_connection, info->account,
2646 do_send_receive_performer, info);
2651 modest_ui_actions_do_cancel_send (const gchar *account_name,
2654 TnyTransportAccount *transport_account;
2655 TnySendQueue *send_queue = NULL;
2656 GError *error = NULL;
2658 /* Get transport account */
2660 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2661 (modest_runtime_get_account_store(),
2663 TNY_ACCOUNT_TYPE_TRANSPORT));
2664 if (!transport_account) {
2665 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2670 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2671 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2672 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2673 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2674 "modest: could not find send queue for account\n");
2676 /* Cancel the current send */
2677 tny_account_cancel (TNY_ACCOUNT (transport_account));
2679 /* Suspend all pending messages */
2680 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2684 if (transport_account != NULL)
2685 g_object_unref (G_OBJECT (transport_account));
2689 modest_ui_actions_cancel_send_all (ModestWindow *win)
2691 GSList *account_names, *iter;
2693 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2696 iter = account_names;
2698 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2699 iter = g_slist_next (iter);
2702 modest_account_mgr_free_account_names (account_names);
2703 account_names = NULL;
2707 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2710 /* Check if accounts exist */
2711 gboolean accounts_exist =
2712 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2714 /* If not, allow the user to create an account before trying to send/receive. */
2715 if (!accounts_exist)
2716 modest_ui_actions_on_accounts (NULL, win);
2718 /* Cancel all sending operaitons */
2719 modest_ui_actions_cancel_send_all (win);
2723 * Refreshes all accounts. This function will be used by automatic
2727 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2728 gboolean force_connection,
2729 gboolean poke_status,
2730 gboolean interactive)
2732 GSList *account_names, *iter;
2734 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2737 iter = account_names;
2739 modest_ui_actions_do_send_receive ((const char*) iter->data,
2741 poke_status, interactive, win);
2742 iter = g_slist_next (iter);
2745 modest_account_mgr_free_account_names (account_names);
2746 account_names = NULL;
2750 * Handler of the click on Send&Receive button in the main toolbar
2753 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2755 /* Check if accounts exist */
2756 gboolean accounts_exist;
2759 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2761 /* If not, allow the user to create an account before trying to send/receive. */
2762 if (!accounts_exist)
2763 modest_ui_actions_on_accounts (NULL, win);
2765 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2766 if (MODEST_IS_MAIN_WINDOW (win)) {
2767 GtkWidget *folder_view;
2768 TnyFolderStore *folder_store;
2771 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2772 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2776 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2779 g_object_unref (folder_store);
2780 /* Refresh the active account. Force the connection if needed
2781 and poke the status of all folders */
2782 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2783 #ifdef MODEST_TOOLKIT_HILDON2
2784 } else if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2785 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2788 const gchar *active_account;
2789 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2791 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2798 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2801 GtkWidget *header_view;
2803 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2805 header_view = modest_main_window_get_child_widget (main_window,
2806 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2810 conf = modest_runtime_get_conf ();
2812 /* what is saved/restored is depending on the style; thus; we save with
2813 * old style, then update the style, and restore for this new style
2815 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2817 if (modest_header_view_get_style
2818 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2819 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2820 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2822 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2823 MODEST_HEADER_VIEW_STYLE_DETAILS);
2825 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2826 MODEST_CONF_HEADER_VIEW_KEY);
2831 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2833 ModestMainWindow *main_window)
2835 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2836 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2838 /* in the case the folder is empty, show the empty folder message and focus
2840 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2841 if (modest_header_view_is_empty (header_view)) {
2842 TnyFolder *folder = modest_header_view_get_folder (header_view);
2843 GtkWidget *folder_view =
2844 modest_main_window_get_child_widget (main_window,
2845 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2846 if (folder != NULL) {
2847 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2848 g_object_unref (folder);
2850 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2854 /* If no header has been selected then exit */
2859 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2860 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2862 /* Update toolbar dimming state */
2863 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2864 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2868 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2871 ModestWindow *window)
2873 GtkWidget *open_widget;
2874 GtkTreeRowReference *rowref;
2876 g_return_if_fail (MODEST_IS_WINDOW(window));
2877 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2878 g_return_if_fail (TNY_IS_HEADER (header));
2880 if (modest_header_view_count_selected_headers (header_view) > 1) {
2881 /* Don't allow activation if there are more than one message selected */
2882 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2886 /* we check for low-mem; in that case, show a warning, and don't allow
2887 * activating headers
2889 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2892 if (MODEST_IS_MAIN_WINDOW (window)) {
2893 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2894 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2895 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2899 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2900 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2901 gtk_tree_row_reference_free (rowref);
2905 set_active_account_from_tny_account (TnyAccount *account,
2906 ModestWindow *window)
2908 const gchar *server_acc_name = tny_account_get_id (account);
2910 /* We need the TnyAccount provided by the
2911 account store because that is the one that
2912 knows the name of the Modest account */
2913 TnyAccount *modest_server_account =
2914 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2915 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2917 if (!modest_server_account) {
2918 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2922 /* Update active account, but only if it's not a pseudo-account */
2923 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2924 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2925 const gchar *modest_acc_name =
2926 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2927 if (modest_acc_name)
2928 modest_window_set_active_account (window, modest_acc_name);
2931 g_object_unref (modest_server_account);
2936 folder_refreshed_cb (ModestMailOperation *mail_op,
2940 ModestMainWindow *win = NULL;
2941 GtkWidget *folder_view, *header_view;
2942 const GError *error;
2944 g_return_if_fail (TNY_IS_FOLDER (folder));
2946 win = MODEST_MAIN_WINDOW (user_data);
2948 /* Check if the operation failed due to memory low conditions */
2949 error = modest_mail_operation_get_error (mail_op);
2950 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2951 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2952 modest_platform_run_information_dialog (GTK_WINDOW (win),
2953 _KR("memr_ib_operation_disabled"),
2959 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2961 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2964 TnyFolderStore *current_folder;
2966 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2967 if (current_folder) {
2968 gboolean different = ((TnyFolderStore *) folder != current_folder);
2969 g_object_unref (current_folder);
2975 /* Check if folder is empty and set headers view contents style */
2976 if ((tny_folder_get_all_count (folder) == 0) ||
2977 modest_header_view_is_empty (MODEST_HEADER_VIEW (header_view)))
2978 modest_main_window_set_contents_style (win,
2979 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2983 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2984 TnyFolderStore *folder_store,
2986 ModestMainWindow *main_window)
2988 GtkWidget *header_view;
2990 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2992 header_view = modest_main_window_get_child_widget(main_window,
2993 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2998 if (TNY_IS_ACCOUNT (folder_store)) {
3000 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
3002 /* Show account details */
3003 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
3006 if (TNY_IS_FOLDER (folder_store) && selected) {
3007 TnyAccount *account;
3009 /* Update the active account */
3010 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
3012 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
3013 g_object_unref (account);
3017 /* Set the header style by default, it could
3018 be changed later by the refresh callback to
3020 modest_main_window_set_contents_style (main_window,
3021 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
3023 /* Set folder on header view. This function
3024 will call tny_folder_refresh_async so we
3025 pass a callback that will be called when
3026 finished. We use that callback to set the
3027 empty view if there are no messages */
3028 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
3029 TNY_FOLDER (folder_store),
3031 MODEST_WINDOW (main_window),
3032 folder_refreshed_cb,
3035 /* Restore configuration. We need to do this
3036 *after* the set_folder because the widget
3037 memory asks the header view about its
3039 modest_widget_memory_restore (modest_runtime_get_conf (),
3040 G_OBJECT(header_view),
3041 MODEST_CONF_HEADER_VIEW_KEY);
3043 /* No need to save the header view
3044 configuration for Maemo because it only
3045 saves the sorting stuff and that it's
3046 already being done by the sort
3047 dialog. Remove it when the GNOME version
3048 has the same behaviour */
3049 #ifdef MODEST_TOOLKIT_GTK
3050 if (modest_main_window_get_contents_style (main_window) ==
3051 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
3052 modest_widget_memory_save (modest_runtime_get_conf (),
3053 G_OBJECT (header_view),
3054 MODEST_CONF_HEADER_VIEW_KEY);
3056 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
3060 /* Update dimming state */
3061 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
3062 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
3066 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
3073 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
3075 online = tny_device_is_online (modest_runtime_get_device());
3078 /* already online -- the item is simply not there... */
3079 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
3081 GTK_MESSAGE_WARNING,
3083 _("The %s you selected cannot be found"),
3085 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
3086 gtk_dialog_run (GTK_DIALOG(dialog));
3088 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
3091 _("mcen_bd_dialog_cancel"),
3092 GTK_RESPONSE_REJECT,
3093 _("mcen_bd_dialog_ok"),
3094 GTK_RESPONSE_ACCEPT,
3096 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
3097 "Do you want to get online?"), item);
3098 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
3099 gtk_label_new (txt), FALSE, FALSE, 0);
3100 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3103 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
3104 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3105 /* TODO: Comment about why is this commented out: */
3106 /* modest_platform_connect_and_wait (); */
3109 gtk_widget_destroy (dialog);
3113 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
3116 /* g_debug ("%s %s", __FUNCTION__, link); */
3121 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
3124 modest_platform_activate_uri (link);
3128 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
3131 modest_platform_show_uri_popup (link);
3135 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
3138 /* we check for low-mem; in that case, show a warning, and don't allow
3139 * viewing attachments
3141 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
3144 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
3148 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
3149 const gchar *address,
3152 /* g_debug ("%s %s", __FUNCTION__, address); */
3156 on_save_to_drafts_cb (ModestMailOperation *mail_op,
3157 TnyMsg *saved_draft,
3160 ModestMsgEditWindow *edit_window;
3162 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
3163 #ifndef MODEST_TOOLKIT_HILDON2
3164 ModestMainWindow *win;
3166 /* FIXME. Make the header view sensitive again. This is a
3167 * temporary hack. See modest_ui_actions_on_save_to_drafts()
3169 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
3170 modest_runtime_get_window_mgr(), FALSE));
3172 GtkWidget *hdrview = modest_main_window_get_child_widget(
3173 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3174 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
3178 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
3180 /* Set draft is there was no error */
3181 if (!modest_mail_operation_get_error (mail_op))
3182 modest_msg_edit_window_set_draft (edit_window, saved_draft);
3184 g_object_unref(edit_window);
3188 enough_space_for_message (ModestMsgEditWindow *edit_window,
3191 guint64 available_disk, expected_size;
3196 available_disk = modest_utils_get_available_space (NULL);
3197 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
3198 expected_size = modest_tny_msg_estimate_size (data->plain_body,
3203 /* Double check: disk full condition or message too big */
3204 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
3205 expected_size > available_disk) {
3206 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3207 modest_platform_information_banner (NULL, NULL, msg);
3214 * djcb: if we're in low-memory state, we only allow for
3215 * saving messages smaller than
3216 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
3217 * should still allow for sending anything critical...
3219 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
3220 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
3224 * djcb: we also make sure that the attachments are smaller than the max size
3225 * this is for the case where we'd try to forward a message with attachments
3226 * bigger than our max allowed size, or sending an message from drafts which
3227 * somehow got past our checks when attaching.
3229 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
3230 modest_platform_run_information_dialog (
3231 GTK_WINDOW(edit_window),
3232 _("mail_ib_error_attachment_size"),
3241 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3243 TnyTransportAccount *transport_account;
3244 ModestMailOperation *mail_operation;
3246 gchar *account_name;
3247 ModestAccountMgr *account_mgr;
3248 gboolean had_error = FALSE;
3249 ModestMainWindow *win = NULL;
3251 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
3253 data = modest_msg_edit_window_get_msg_data (edit_window);
3256 if (!enough_space_for_message (edit_window, data)) {
3257 modest_msg_edit_window_free_msg_data (edit_window, data);
3261 account_name = g_strdup (data->account_name);
3262 account_mgr = modest_runtime_get_account_mgr();
3264 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3266 account_name = modest_account_mgr_get_default_account (account_mgr);
3267 if (!account_name) {
3268 g_printerr ("modest: no account found\n");
3269 modest_msg_edit_window_free_msg_data (edit_window, data);
3273 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
3274 account_name = g_strdup (data->account_name);
3278 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3279 (modest_runtime_get_account_store (),
3281 TNY_ACCOUNT_TYPE_TRANSPORT));
3282 if (!transport_account) {
3283 g_printerr ("modest: no transport account found for '%s'\n", account_name);
3284 g_free (account_name);
3285 modest_msg_edit_window_free_msg_data (edit_window, data);
3289 /* Create the mail operation */
3290 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
3292 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3294 modest_mail_operation_save_to_drafts (mail_operation,
3306 data->priority_flags,
3309 data->custom_header_pairs,
3310 on_save_to_drafts_cb,
3311 g_object_ref(edit_window));
3313 #ifdef MODEST_TOOLKIT_HILDON2
3314 /* In hildon2 we always show the information banner on saving to drafts.
3315 * It will be a system information banner in this case.
3317 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3318 modest_platform_information_banner (NULL, NULL, text);
3321 /* Use the main window as the parent of the banner, if the
3322 main window does not exist it won't be shown, if the parent
3323 window exists then it's properly shown. We don't use the
3324 editor window because it could be closed (save to drafts
3325 could happen after closing the window */
3326 win = (ModestMainWindow *)
3327 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
3329 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
3330 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
3334 modest_msg_edit_window_set_modified (edit_window, FALSE);
3337 g_free (account_name);
3338 g_object_unref (G_OBJECT (transport_account));
3339 g_object_unref (G_OBJECT (mail_operation));
3341 modest_msg_edit_window_free_msg_data (edit_window, data);
3344 * If the drafts folder is selected then make the header view
3345 * insensitive while the message is being saved to drafts
3346 * (it'll be sensitive again in on_save_to_drafts_cb()). This
3347 * is not very clean but it avoids letting the drafts folder
3348 * in an inconsistent state: the user could edit the message
3349 * being saved and undesirable things would happen.
3350 * In the average case the user won't notice anything at
3351 * all. In the worst case (the user is editing a really big
3352 * file from Drafts) the header view will be insensitive
3353 * during the saving process (10 or 20 seconds, depending on
3354 * the message). Anyway this is just a quick workaround: once
3355 * we find a better solution it should be removed
3356 * See NB#65125 (commend #18) for details.
3358 if (!had_error && win != NULL) {
3359 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
3360 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
3362 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
3364 if (modest_tny_folder_is_local_folder(folder)) {
3365 TnyFolderType folder_type;
3366 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
3367 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
3368 GtkWidget *hdrview = modest_main_window_get_child_widget(
3369 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3370 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
3374 if (folder != NULL) g_object_unref(folder);
3381 /* For instance, when clicking the Send toolbar button when editing a message: */
3383 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3385 TnyTransportAccount *transport_account = NULL;
3386 gboolean had_error = FALSE, add_to_contacts;
3388 ModestAccountMgr *account_mgr;
3389 gchar *account_name;
3390 ModestMailOperation *mail_operation;
3393 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
3395 /* Check whether to automatically add new contacts to addressbook or not */
3396 add_to_contacts = modest_conf_get_bool (modest_runtime_get_conf (),
3397 MODEST_CONF_AUTO_ADD_TO_CONTACTS, NULL);
3398 if (!modest_msg_edit_window_check_names (edit_window, add_to_contacts))
3401 data = modest_msg_edit_window_get_msg_data (edit_window);
3403 recipients = g_strconcat (data->to?data->to:"",
3404 data->cc?data->cc:"",
3405 data->bcc?data->bcc:"",
3407 if (recipients == NULL || recipients[0] == '\0') {
3408 /* Empty subject -> no send */
3409 g_free (recipients);
3410 modest_msg_edit_window_free_msg_data (edit_window, data);
3413 g_free (recipients);
3416 if (!enough_space_for_message (edit_window, data)) {
3417 modest_msg_edit_window_free_msg_data (edit_window, data);
3421 account_mgr = modest_runtime_get_account_mgr();
3422 account_name = g_strdup (data->account_name);
3424 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3427 account_name = modest_account_mgr_get_default_account (account_mgr);
3429 if (!account_name) {
3430 modest_msg_edit_window_free_msg_data (edit_window, data);
3431 /* Run account setup wizard */
3432 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
3437 /* Get the currently-active transport account for this modest account: */
3438 if (account_name && strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
3440 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3441 (modest_runtime_get_account_store (),
3442 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
3445 if (!transport_account) {
3446 modest_msg_edit_window_free_msg_data (edit_window, data);
3447 /* Run account setup wizard */
3448 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
3453 /* Create the mail operation */
3454 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
3455 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3457 modest_mail_operation_send_new_mail (mail_operation,
3471 data->priority_flags,
3472 data->custom_header_pairs);
3474 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3475 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
3477 if (modest_mail_operation_get_error (mail_operation) != NULL) {
3478 const GError *error = modest_mail_operation_get_error (mail_operation);
3479 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3480 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3481 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3482 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3488 g_free (account_name);
3489 g_object_unref (G_OBJECT (transport_account));
3490 g_object_unref (G_OBJECT (mail_operation));
3492 modest_msg_edit_window_free_msg_data (edit_window, data);
3495 modest_msg_edit_window_set_sent (edit_window, TRUE);
3497 /* Save settings and close the window: */
3498 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3505 modest_ui_actions_on_send_msg (ModestWindow *window,
3508 TnyTransportAccount *transport_account = NULL;
3509 gboolean had_error = FALSE;
3510 ModestAccountMgr *account_mgr;
3511 gchar *account_name;
3512 ModestMailOperation *mail_operation;
3514 account_mgr = modest_runtime_get_account_mgr();
3515 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(window)));
3518 account_name = modest_account_mgr_get_default_account (account_mgr);
3520 /* Get the currently-active transport account for this modest account: */
3521 if (account_name && strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
3523 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3524 (modest_runtime_get_account_store (),
3525 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
3528 /* Create the mail operation */
3529 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
3530 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3532 modest_mail_operation_send_mail (mail_operation,
3536 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3537 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
3539 if (modest_mail_operation_get_error (mail_operation) != NULL) {
3540 const GError *error = modest_mail_operation_get_error (mail_operation);
3541 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3542 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3543 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3544 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3550 g_free (account_name);
3551 g_object_unref (G_OBJECT (transport_account));
3552 g_object_unref (G_OBJECT (mail_operation));
3558 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3559 ModestMsgEditWindow *window)
3561 ModestMsgEditFormatState *format_state = NULL;
3563 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3564 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3566 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3569 format_state = modest_msg_edit_window_get_format_state (window);
3570 g_return_if_fail (format_state != NULL);
3572 format_state->bold = gtk_toggle_action_get_active (action);
3573 modest_msg_edit_window_set_format_state (window, format_state);
3574 g_free (format_state);
3579 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3580 ModestMsgEditWindow *window)
3582 ModestMsgEditFormatState *format_state = NULL;
3584 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3585 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3587 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3590 format_state = modest_msg_edit_window_get_format_state (window);
3591 g_return_if_fail (format_state != NULL);
3593 format_state->italics = gtk_toggle_action_get_active (action);
3594 modest_msg_edit_window_set_format_state (window, format_state);
3595 g_free (format_state);
3600 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3601 ModestMsgEditWindow *window)
3603 ModestMsgEditFormatState *format_state = NULL;
3605 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3606 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3608 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3611 format_state = modest_msg_edit_window_get_format_state (window);
3612 g_return_if_fail (format_state != NULL);
3614 format_state->bullet = gtk_toggle_action_get_active (action);
3615 modest_msg_edit_window_set_format_state (window, format_state);
3616 g_free (format_state);
3621 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3622 GtkRadioAction *selected,
3623 ModestMsgEditWindow *window)
3625 ModestMsgEditFormatState *format_state = NULL;
3626 GtkJustification value;
3628 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3630 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3633 value = gtk_radio_action_get_current_value (selected);
3635 format_state = modest_msg_edit_window_get_format_state (window);
3636 g_return_if_fail (format_state != NULL);
3638 format_state->justification = value;
3639 modest_msg_edit_window_set_format_state (window, format_state);
3640 g_free (format_state);
3644 modest_ui_actions_on_select_editor_color (GtkAction *action,
3645 ModestMsgEditWindow *window)
3647 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3648 g_return_if_fail (GTK_IS_ACTION (action));
3650 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3653 modest_msg_edit_window_select_color (window);
3657 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3658 ModestMsgEditWindow *window)
3660 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3661 g_return_if_fail (GTK_IS_ACTION (action));
3663 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3666 modest_msg_edit_window_select_background_color (window);
3670 modest_ui_actions_on_insert_image (GObject *object,
3671 ModestMsgEditWindow *window)
3673 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3676 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3679 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3682 modest_msg_edit_window_insert_image (window);
3686 modest_ui_actions_on_attach_file (GtkAction *action,
3687 ModestMsgEditWindow *window)
3689 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3690 g_return_if_fail (GTK_IS_ACTION (action));
3692 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3695 modest_msg_edit_window_offer_attach_file (window);
3699 modest_ui_actions_on_remove_attachments (GtkAction *action,
3700 ModestMsgEditWindow *window)
3702 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3704 modest_msg_edit_window_remove_attachments (window, NULL);
3708 do_create_folder_cb (ModestMailOperation *mail_op,
3709 TnyFolderStore *parent_folder,
3710 TnyFolder *new_folder,
3713 gchar *suggested_name = (gchar *) user_data;
3714 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3715 const GError *error;
3717 error = modest_mail_operation_get_error (mail_op);
3719 gboolean disk_full = FALSE;
3720 TnyAccount *account;
3721 /* Show an error. If there was some problem writing to
3722 disk, show it, otherwise show the generic folder
3723 create error. We do it here and not in an error
3724 handler because the call to do_create_folder will
3725 stop the main loop in a gtk_dialog_run and then,
3726 the message won't be shown until that dialog is
3728 account = modest_mail_operation_get_account (mail_op);
3731 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3732 (GtkWidget *) source_win,
3735 _("mail_in_ui_folder_create_error_memory"));
3736 g_object_unref (account);
3739 /* Show an error and try again if there is no
3740 full memory condition */
3741 modest_platform_information_banner ((GtkWidget *) source_win, NULL,
3742 _("mail_in_ui_folder_create_error"));
3743 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3747 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3748 * FIXME: any other? */
3749 GtkWidget *folder_view;
3751 if (MODEST_IS_MAIN_WINDOW(source_win))
3753 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3754 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3756 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3757 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3759 /* Select the newly created folder. It could happen
3760 that the widget is no longer there (i.e. the window
3761 has been destroyed, so we need to check this */
3763 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3765 g_object_unref (new_folder);
3767 /* Free. Note that the first time it'll be NULL so noop */
3768 g_free (suggested_name);
3769 g_object_unref (source_win);
3774 TnyFolderStore *parent;
3775 } CreateFolderConnect;
3778 do_create_folder_performer (gboolean canceled,
3780 GtkWindow *parent_window,
3781 TnyAccount *account,
3784 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3785 ModestMailOperation *mail_op;
3787 if (canceled || err) {
3788 /* In disk full conditions we could get this error here */
3789 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3790 (GtkWidget *) parent_window, err,
3791 NULL, _("mail_in_ui_folder_create_error_memory"));
3793 /* This happens if we have selected the outbox folder
3795 if (err && err->code == TNY_SERVICE_ERROR_UNKNOWN &&
3796 TNY_IS_MERGE_FOLDER (helper->parent)) {
3797 /* Show an error and retry */
3798 modest_platform_information_banner ((GtkWidget *) parent_window,
3800 _("mail_in_ui_folder_create_error"));
3802 do_create_folder (parent_window, helper->parent, helper->folder_name);
3808 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3809 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3811 modest_mail_operation_create_folder (mail_op,
3813 (const gchar *) helper->folder_name,
3814 do_create_folder_cb,
3815 g_strdup (helper->folder_name));
3816 g_object_unref (mail_op);
3820 g_object_unref (helper->parent);
3821 if (helper->folder_name)
3822 g_free (helper->folder_name);
3823 g_slice_free (CreateFolderConnect, helper);
3828 do_create_folder (GtkWindow *parent_window,
3829 TnyFolderStore *suggested_parent,
3830 const gchar *suggested_name)
3833 gchar *folder_name = NULL;
3834 TnyFolderStore *parent_folder = NULL;
3836 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3838 (gchar *) suggested_name,
3842 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3843 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3844 helper->folder_name = g_strdup (folder_name);
3845 helper->parent = g_object_ref (parent_folder);
3847 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3850 do_create_folder_performer,
3855 g_free (folder_name);
3857 g_object_unref (parent_folder);
3861 modest_ui_actions_create_folder(GtkWidget *parent_window,
3862 GtkWidget *folder_view,
3863 TnyFolderStore *parent_folder)
3865 if (!parent_folder) {
3866 #ifdef MODEST_TOOLKIT_HILDON2
3867 ModestTnyAccountStore *acc_store;
3869 acc_store = modest_runtime_get_account_store ();
3871 parent_folder = (TnyFolderStore *)
3872 modest_tny_account_store_get_local_folders_account (acc_store);
3874 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3878 if (parent_folder) {
3879 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3880 g_object_unref (parent_folder);
3885 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3888 g_return_if_fail (MODEST_IS_WINDOW(window));
3890 if (MODEST_IS_MAIN_WINDOW (window)) {
3891 GtkWidget *folder_view;
3893 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3894 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3898 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3899 #ifdef MODEST_TOOLKIT_HILDON2
3900 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3901 GtkWidget *folder_view;
3903 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3904 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3907 g_assert_not_reached ();
3912 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3915 const GError *error = NULL;
3916 gchar *message = NULL;
3918 TnyAccount *account = modest_mail_operation_get_account (mail_op);
3920 /* Get error message */
3921 error = modest_mail_operation_get_error (mail_op);
3923 g_return_if_reached ();
3925 mem_full = modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
3926 (GError *) error, account);
3928 message = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3929 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3930 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3931 message = _CS("ckdg_ib_folder_already_exists");
3932 } else if (error->domain == TNY_ERROR_DOMAIN &&
3933 error->code == TNY_SERVICE_ERROR_STATE) {
3934 /* This means that the folder is already in use (a
3935 message is opened for example */
3936 message = _("emev_ni_internal_error");
3938 message = _CS("ckdg_ib_unable_to_rename");
3941 /* We don't set a parent for the dialog because the dialog
3942 will be destroyed so the banner won't appear */
3943 modest_platform_information_banner (NULL, NULL, message);
3946 g_object_unref (account);
3952 TnyFolderStore *folder;
3957 on_rename_folder_cb (ModestMailOperation *mail_op,
3958 TnyFolder *new_folder,
3961 ModestFolderView *folder_view;
3963 /* If the window was closed when renaming a folder, or if
3964 * it's not a main window this will happen */
3965 if (!MODEST_IS_FOLDER_VIEW (user_data))
3968 folder_view = MODEST_FOLDER_VIEW (user_data);
3969 /* Note that if the rename fails new_folder will be NULL */
3971 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3973 modest_folder_view_select_first_inbox_or_local (folder_view);
3975 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3979 on_rename_folder_performer (gboolean canceled,
3981 GtkWindow *parent_window,
3982 TnyAccount *account,
3985 ModestMailOperation *mail_op = NULL;
3986 GtkTreeSelection *sel = NULL;
3987 GtkWidget *folder_view = NULL;
3988 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3990 if (canceled || err) {
3991 /* In disk full conditions we could get this error here */
3992 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3993 (GtkWidget *) parent_window, err,
3998 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3999 modest_ui_actions_rename_folder_error_handler,
4000 parent_window, NULL);
4002 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4005 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
4007 folder_view = modest_main_window_get_child_widget (
4008 MODEST_MAIN_WINDOW (parent_window),
4009 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4011 #ifdef MODEST_TOOLKIT_HILDON2
4012 else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
4013 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
4014 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
4018 /* Clear the folders view */
4019 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
4020 gtk_tree_selection_unselect_all (sel);
4022 /* Actually rename the folder */
4023 modest_mail_operation_rename_folder (mail_op,
4024 TNY_FOLDER (data->folder),
4025 (const gchar *) (data->new_name),
4026 on_rename_folder_cb,
4028 g_object_unref (mail_op);
4031 g_object_unref (data->folder);
4032 g_free (data->new_name);
4037 modest_ui_actions_on_rename_folder (GtkAction *action,
4038 ModestWindow *window)
4040 modest_ui_actions_on_edit_mode_rename_folder (window);
4044 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
4046 TnyFolderStore *folder;
4047 GtkWidget *folder_view;
4048 gboolean do_rename = TRUE;
4050 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
4052 if (MODEST_IS_MAIN_WINDOW (window)) {
4053 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4054 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4058 #ifdef MODEST_TOOLKIT_HILDON2
4059 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
4060 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
4066 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
4071 if (TNY_IS_FOLDER (folder)) {
4072 gchar *folder_name = NULL;
4074 const gchar *current_name;
4075 TnyFolderStore *parent;
4077 current_name = tny_folder_get_name (TNY_FOLDER (folder));
4078 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
4079 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
4080 parent, current_name,
4082 g_object_unref (parent);
4084 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
4087 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
4088 rename_folder_data->folder = g_object_ref (folder);
4089 rename_folder_data->new_name = folder_name;
4090 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
4091 folder, on_rename_folder_performer, rename_folder_data);
4094 g_object_unref (folder);
4099 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
4102 GObject *win = modest_mail_operation_get_source (mail_op);
4104 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
4105 _("mail_in_ui_folder_delete_error"),
4107 g_object_unref (win);
4111 TnyFolderStore *folder;
4112 gboolean move_to_trash;
4116 on_delete_folder_cb (gboolean canceled,
4118 GtkWindow *parent_window,
4119 TnyAccount *account,
4122 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
4123 GtkWidget *folder_view;
4124 ModestMailOperation *mail_op;
4125 GtkTreeSelection *sel;
4127 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
4128 /* Note that the connection process can fail due to
4129 memory low conditions as it can not successfully
4130 store the summary */
4131 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4132 (GtkWidget*) parent_window, err,
4134 g_debug ("Error connecting when trying to delete a folder");
4135 g_object_unref (G_OBJECT (info->folder));
4140 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
4141 folder_view = modest_main_window_get_child_widget (
4142 MODEST_MAIN_WINDOW (parent_window),
4143 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4144 #ifdef MODEST_TOOLKIT_HILDON2
4145 } else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
4146 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
4149 g_object_unref (G_OBJECT (info->folder));
4154 /* Unselect the folder before deleting it to free the headers */
4155 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
4156 gtk_tree_selection_unselect_all (sel);
4158 /* Create the mail operation */
4160 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
4161 modest_ui_actions_delete_folder_error_handler,
4164 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4166 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
4168 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
4170 g_object_unref (mail_op);
4171 g_object_unref (info->folder);
4176 delete_folder (ModestWindow *window, gboolean move_to_trash)
4178 TnyFolderStore *folder;
4179 GtkWidget *folder_view;
4183 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
4185 if (MODEST_IS_MAIN_WINDOW (window)) {
4187 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4188 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4189 #ifdef MODEST_TOOLKIT_HILDON2
4190 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
4191 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
4199 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4204 /* Show an error if it's an account */
4205 if (!TNY_IS_FOLDER (folder)) {
4206 modest_platform_run_information_dialog (GTK_WINDOW (window),
4207 _("mail_in_ui_folder_delete_error"),
4209 g_object_unref (G_OBJECT (folder));
4214 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
4215 tny_folder_get_name (TNY_FOLDER (folder)));
4216 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
4217 (const gchar *) message);
4220 if (response == GTK_RESPONSE_OK) {
4221 TnyAccount *account = NULL;
4222 DeleteFolderInfo *info = NULL;
4223 info = g_new0(DeleteFolderInfo, 1);
4224 info->folder = g_object_ref (folder);
4225 info->move_to_trash = move_to_trash;
4227 account = tny_folder_get_account (TNY_FOLDER (folder));
4228 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
4230 TNY_FOLDER_STORE (account),
4231 on_delete_folder_cb, info);
4232 g_object_unref (account);
4233 g_object_unref (folder);
4241 modest_ui_actions_on_delete_folder (GtkAction *action,
4242 ModestWindow *window)
4244 modest_ui_actions_on_edit_mode_delete_folder (window);
4248 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
4250 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
4252 return delete_folder (window, FALSE);
4256 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
4258 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4260 delete_folder (MODEST_WINDOW (main_window), TRUE);
4264 typedef struct _PasswordDialogFields {
4265 GtkWidget *username;
4266 GtkWidget *password;
4268 } PasswordDialogFields;
4271 password_dialog_check_field (GtkEditable *editable,
4272 PasswordDialogFields *fields)
4275 gboolean any_value_empty = FALSE;
4277 #ifdef MODEST_TOOLKIT_HILDON2
4278 value = hildon_entry_get_text (HILDON_ENTRY (fields->username));
4280 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
4282 if ((value == NULL) || value[0] == '\0') {
4283 any_value_empty = TRUE;
4285 #ifdef MODEST_TOOLKIT_HILDON2
4286 value = hildon_entry_get_text (HILDON_ENTRY (fields->password));
4288 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
4290 if ((value == NULL) || value[0] == '\0') {
4291 any_value_empty = TRUE;
4293 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
4297 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
4298 const gchar* server_account_name,
4303 ModestMainWindow *main_window)
4305 g_return_if_fail(server_account_name);
4306 gboolean completed = FALSE;
4307 PasswordDialogFields *fields = NULL;
4309 /* Initalize output parameters: */
4316 #ifndef MODEST_TOOLKIT_GTK
4317 /* Maemo uses a different (awkward) button order,
4318 * It should probably just use gtk_alternative_dialog_button_order ().
4320 #ifdef MODEST_TOOLKIT_HILDON2
4322 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4325 _HL("wdgt_bd_done"),
4326 GTK_RESPONSE_ACCEPT,
4328 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
4329 HILDON_MARGIN_DOUBLE);
4332 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4335 _("mcen_bd_dialog_ok"),
4336 GTK_RESPONSE_ACCEPT,
4337 _("mcen_bd_dialog_cancel"),
4338 GTK_RESPONSE_REJECT,
4340 #endif /* MODEST_TOOLKIT_HILDON2 */
4343 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
4347 GTK_RESPONSE_REJECT,
4349 GTK_RESPONSE_ACCEPT,
4351 #endif /* MODEST_TOOLKIT_GTK */
4353 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
4355 gchar *server_name = modest_account_mgr_get_server_account_hostname (
4356 modest_runtime_get_account_mgr(), server_account_name);
4357 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
4358 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
4361 gtk_widget_destroy (dialog);
4365 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
4366 GtkWidget *label = gtk_label_new (txt);
4367 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
4369 g_free (server_name);
4370 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
4375 gchar *initial_username = modest_account_mgr_get_server_account_username (
4376 modest_runtime_get_account_mgr(), server_account_name);
4378 #ifdef MODEST_TOOLKIT_HILDON2
4379 GtkWidget *entry_username = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4380 if (initial_username)
4381 hildon_entry_set_text (HILDON_ENTRY (entry_username), initial_username);
4383 GtkWidget *entry_username = gtk_entry_new ();
4384 if (initial_username)
4385 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
4387 /* Dim this if a connection has ever succeeded with this username,
4388 * as per the UI spec: */
4389 /* const gboolean username_known = */
4390 /* modest_account_mgr_get_server_account_username_has_succeeded( */
4391 /* modest_runtime_get_account_mgr(), server_account_name); */
4392 /* gtk_widget_set_sensitive (entry_username, !username_known); */
4394 /* We drop the username sensitive code and disallow changing it here
4395 * as tinymail does not support really changing the username in the callback
4397 gtk_widget_set_sensitive (entry_username, FALSE);
4399 #ifndef MODEST_TOOLKIT_GTK
4400 /* Auto-capitalization is the default, so let's turn it off: */
4401 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
4403 /* Create a size group to be used by all captions.
4404 * Note that HildonCaption does not create a default size group if we do not specify one.
4405 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
4406 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
4408 #ifdef MODEST_TOOLKIT_HILDON2
4409 GtkWidget *caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4410 _("mail_fi_username"), FALSE,
4413 GtkWidget *caption = hildon_caption_new (sizegroup,
4414 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
4416 gtk_widget_show (entry_username);
4417 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4418 FALSE, FALSE, MODEST_MARGIN_HALF);
4419 gtk_widget_show (caption);
4421 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
4423 #endif /* !MODEST_TOOLKIT_GTK */
4426 #ifdef MODEST_TOOLKIT_HILDON2
4427 GtkWidget *entry_password = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
4429 GtkWidget *entry_password = gtk_entry_new ();
4431 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
4432 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
4434 #ifndef MODEST_TOOLKIT_GTK
4435 /* Auto-capitalization is the default, so let's turn it off: */
4436 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
4437 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
4439 #ifdef MODEST_TOOLKIT_HILDON2
4440 caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
4441 _("mail_fi_password"), FALSE,
4444 caption = hildon_caption_new (sizegroup,
4445 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
4447 gtk_widget_show (entry_password);
4448 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
4449 FALSE, FALSE, MODEST_MARGIN_HALF);
4450 gtk_widget_show (caption);
4451 g_object_unref (sizegroup);
4453 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
4455 #endif /* !MODEST_TOOLKIT_GTK */
4457 if (initial_username != NULL)
4458 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
4460 /* This is not in the Maemo UI spec:
4461 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
4462 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
4466 fields = g_slice_new0 (PasswordDialogFields);
4467 fields->username = entry_username;
4468 fields->password = entry_password;
4469 fields->dialog = dialog;
4471 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
4472 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
4473 password_dialog_check_field (NULL, fields);
4475 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4477 while (!completed) {
4479 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
4481 #ifdef MODEST_TOOLKIT_HILDON2
4482 *username = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_username)));
4484 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
4487 /* Note that an empty field becomes the "" string */
4488 if (*username && strlen (*username) > 0) {
4489 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
4490 server_account_name,
4494 const gboolean username_was_changed =
4495 (strcmp (*username, initial_username) != 0);
4496 if (username_was_changed) {
4497 g_warning ("%s: tinymail does not yet support changing the "
4498 "username in the get_password() callback.\n", __FUNCTION__);
4504 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
4505 _("mcen_ib_username_pw_incorrect"));
4511 #ifdef MODEST_TOOLKIT_HILDON2
4512 *password = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_password)));
4514 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
4517 /* We do not save the password in the configuration,
4518 * because this function is only called for passwords that should
4519 * not be remembered:
4520 modest_server_account_set_password (
4521 modest_runtime_get_account_mgr(), server_account_name,
4528 #ifndef MODEST_TOOLKIT_HILDON2
4529 /* Set parent to NULL or the banner will disappear with its parent dialog */
4530 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
4542 /* This is not in the Maemo UI spec:
4543 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
4549 g_free (initial_username);
4550 gtk_widget_destroy (dialog);
4551 g_slice_free (PasswordDialogFields, fields);
4553 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
4557 modest_ui_actions_on_cut (GtkAction *action,
4558 ModestWindow *window)
4560 GtkWidget *focused_widget;
4561 GtkClipboard *clipboard;
4563 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4564 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4565 if (GTK_IS_EDITABLE (focused_widget)) {
4566 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
4567 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4568 gtk_clipboard_store (clipboard);
4569 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4570 GtkTextBuffer *buffer;
4572 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4573 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4574 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
4575 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4576 gtk_clipboard_store (clipboard);
4578 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4579 TnyList *header_list = modest_header_view_get_selected_headers (
4580 MODEST_HEADER_VIEW (focused_widget));
4581 gboolean continue_download = FALSE;
4582 gint num_of_unc_msgs;
4584 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4586 if (num_of_unc_msgs) {
4587 TnyAccount *account = get_account_from_header_list (header_list);
4589 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4590 g_object_unref (account);
4594 if (num_of_unc_msgs == 0 || continue_download) {
4595 /* modest_platform_information_banner (
4596 NULL, NULL, _CS("mcen_ib_getting_items"));*/
4597 modest_header_view_cut_selection (
4598 MODEST_HEADER_VIEW (focused_widget));
4601 g_object_unref (header_list);
4602 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4603 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4608 modest_ui_actions_on_copy (GtkAction *action,
4609 ModestWindow *window)
4611 GtkClipboard *clipboard;
4612 GtkWidget *focused_widget;
4613 gboolean copied = TRUE;
4615 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4616 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4618 if (GTK_IS_LABEL (focused_widget)) {
4620 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4621 gtk_clipboard_set_text (clipboard, selection, -1);
4623 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4624 gtk_clipboard_store (clipboard);
4625 } else if (GTK_IS_EDITABLE (focused_widget)) {
4626 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4627 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4628 gtk_clipboard_store (clipboard);
4629 } else if (GTK_IS_HTML (focused_widget)) {
4632 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4633 if ((sel == NULL) || (sel[0] == '\0')) {
4636 gtk_html_copy (GTK_HTML (focused_widget));
4637 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4638 gtk_clipboard_store (clipboard);
4640 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4641 GtkTextBuffer *buffer;
4642 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4643 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4644 gtk_text_buffer_copy_clipboard (buffer, clipboard);
4645 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4646 gtk_clipboard_store (clipboard);
4648 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4649 TnyList *header_list = modest_header_view_get_selected_headers (
4650 MODEST_HEADER_VIEW (focused_widget));
4651 gboolean continue_download = FALSE;
4652 gint num_of_unc_msgs;
4654 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4656 if (num_of_unc_msgs) {
4657 TnyAccount *account = get_account_from_header_list (header_list);
4659 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4660 g_object_unref (account);
4664 if (num_of_unc_msgs == 0 || continue_download) {
4665 modest_platform_information_banner (
4666 NULL, NULL, _CS("mcen_ib_getting_items"));
4667 modest_header_view_copy_selection (
4668 MODEST_HEADER_VIEW (focused_widget));
4672 g_object_unref (header_list);
4674 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4675 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4678 /* Show information banner if there was a copy to clipboard */
4680 modest_platform_information_banner (
4681 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4685 modest_ui_actions_on_undo (GtkAction *action,
4686 ModestWindow *window)
4688 ModestEmailClipboard *clipboard = NULL;
4690 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4691 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4692 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4693 /* Clear clipboard source */
4694 clipboard = modest_runtime_get_email_clipboard ();
4695 modest_email_clipboard_clear (clipboard);
4698 g_return_if_reached ();
4703 modest_ui_actions_on_redo (GtkAction *action,
4704 ModestWindow *window)
4706 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4707 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4710 g_return_if_reached ();
4716 destroy_information_note (ModestMailOperation *mail_op,
4719 /* destroy information note */
4720 gtk_widget_destroy (GTK_WIDGET(user_data));
4724 destroy_folder_information_note (ModestMailOperation *mail_op,
4725 TnyFolder *new_folder,
4728 /* destroy information note */
4729 gtk_widget_destroy (GTK_WIDGET(user_data));
4734 paste_as_attachment_free (gpointer data)
4736 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4738 if (helper->banner) {
4739 gtk_widget_destroy (helper->banner);
4740 g_object_unref (helper->banner);
4746 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4751 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4752 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4757 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4762 modest_ui_actions_on_paste (GtkAction *action,
4763 ModestWindow *window)
4765 GtkWidget *focused_widget = NULL;
4766 GtkWidget *inf_note = NULL;
4767 ModestMailOperation *mail_op = NULL;
4769 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4770 if (GTK_IS_EDITABLE (focused_widget)) {
4771 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4772 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4773 ModestEmailClipboard *e_clipboard = NULL;
4774 e_clipboard = modest_runtime_get_email_clipboard ();
4775 if (modest_email_clipboard_cleared (e_clipboard)) {
4776 GtkTextBuffer *buffer;
4777 GtkClipboard *clipboard;
4779 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4780 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4781 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4782 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4783 ModestMailOperation *mail_op;
4784 TnyFolder *src_folder = NULL;
4785 TnyList *data = NULL;
4787 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4788 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4789 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4790 _CS("ckct_nw_pasting"));
4791 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4792 mail_op = modest_mail_operation_new (G_OBJECT (window));
4793 if (helper->banner != NULL) {
4794 g_object_ref (G_OBJECT (helper->banner));
4795 gtk_widget_show (GTK_WIDGET (helper->banner));
4799 modest_mail_operation_get_msgs_full (mail_op,
4801 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4803 paste_as_attachment_free);
4807 g_object_unref (data);
4809 g_object_unref (src_folder);
4812 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4813 ModestEmailClipboard *clipboard = NULL;
4814 TnyFolder *src_folder = NULL;
4815 TnyFolderStore *folder_store = NULL;
4816 TnyList *data = NULL;
4817 gboolean delete = FALSE;
4819 /* Check clipboard source */
4820 clipboard = modest_runtime_get_email_clipboard ();
4821 if (modest_email_clipboard_cleared (clipboard))
4824 /* Get elements to paste */
4825 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4827 /* Create a new mail operation */
4828 mail_op = modest_mail_operation_new (G_OBJECT(window));
4830 /* Get destination folder */
4831 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4833 /* transfer messages */
4837 /* Ask for user confirmation */
4839 modest_ui_actions_msgs_move_to_confirmation (window,
4840 TNY_FOLDER (folder_store),
4844 if (response == GTK_RESPONSE_OK) {
4845 /* Launch notification */
4846 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4847 _CS("ckct_nw_pasting"));
4848 if (inf_note != NULL) {
4849 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4850 gtk_widget_show (GTK_WIDGET(inf_note));
4853 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4854 modest_mail_operation_xfer_msgs (mail_op,
4856 TNY_FOLDER (folder_store),
4858 destroy_information_note,
4861 g_object_unref (mail_op);
4864 } else if (src_folder != NULL) {
4865 /* Launch notification */
4866 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4867 _CS("ckct_nw_pasting"));
4868 if (inf_note != NULL) {
4869 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4870 gtk_widget_show (GTK_WIDGET(inf_note));
4873 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4874 modest_mail_operation_xfer_folder (mail_op,
4878 destroy_folder_information_note,
4884 g_object_unref (data);
4885 if (src_folder != NULL)
4886 g_object_unref (src_folder);
4887 if (folder_store != NULL)
4888 g_object_unref (folder_store);
4894 modest_ui_actions_on_select_all (GtkAction *action,
4895 ModestWindow *window)
4897 GtkWidget *focused_widget;
4899 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4900 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4901 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4902 } else if (GTK_IS_LABEL (focused_widget)) {
4903 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4904 } else if (GTK_IS_EDITABLE (focused_widget)) {
4905 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4906 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4907 GtkTextBuffer *buffer;
4908 GtkTextIter start, end;
4910 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4911 gtk_text_buffer_get_start_iter (buffer, &start);
4912 gtk_text_buffer_get_end_iter (buffer, &end);
4913 gtk_text_buffer_select_range (buffer, &start, &end);
4914 } else if (GTK_IS_HTML (focused_widget)) {
4915 gtk_html_select_all (GTK_HTML (focused_widget));
4916 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4917 GtkWidget *header_view = focused_widget;
4918 GtkTreeSelection *selection = NULL;
4920 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4921 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4922 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4925 /* Disable window dimming management */
4926 modest_window_disable_dimming (MODEST_WINDOW(window));
4928 /* Select all messages */
4929 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4930 gtk_tree_selection_select_all (selection);
4932 /* Set focuse on header view */
4933 gtk_widget_grab_focus (header_view);
4935 /* Enable window dimming management */
4936 modest_window_enable_dimming (MODEST_WINDOW(window));
4937 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4938 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4944 modest_ui_actions_on_mark_as_read (GtkAction *action,
4945 ModestWindow *window)
4947 g_return_if_fail (MODEST_IS_WINDOW(window));
4949 /* Mark each header as read */
4950 do_headers_action (window, headers_action_mark_as_read, NULL);
4954 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4955 ModestWindow *window)
4957 g_return_if_fail (MODEST_IS_WINDOW(window));
4959 /* Mark each header as read */
4960 do_headers_action (window, headers_action_mark_as_unread, NULL);
4964 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4965 GtkRadioAction *selected,
4966 ModestWindow *window)
4970 value = gtk_radio_action_get_current_value (selected);
4971 if (MODEST_IS_WINDOW (window)) {
4972 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4977 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4978 GtkRadioAction *selected,
4979 ModestWindow *window)
4981 TnyHeaderFlags flags;
4982 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4984 flags = gtk_radio_action_get_current_value (selected);
4985 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4989 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4990 GtkRadioAction *selected,
4991 ModestWindow *window)
4995 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4997 file_format = gtk_radio_action_get_current_value (selected);
4998 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
5003 modest_ui_actions_on_zoom_plus (GtkAction *action,
5004 ModestWindow *window)
5006 g_return_if_fail (MODEST_IS_WINDOW (window));
5008 modest_window_zoom_plus (MODEST_WINDOW (window));
5012 modest_ui_actions_on_zoom_minus (GtkAction *action,
5013 ModestWindow *window)
5015 g_return_if_fail (MODEST_IS_WINDOW (window));
5017 modest_window_zoom_minus (MODEST_WINDOW (window));
5021 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
5022 ModestWindow *window)
5024 ModestWindowMgr *mgr;
5025 gboolean fullscreen, active;
5026 g_return_if_fail (MODEST_IS_WINDOW (window));
5028 mgr = modest_runtime_get_window_mgr ();
5030 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
5031 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
5033 if (active != fullscreen) {
5034 modest_window_mgr_set_fullscreen_mode (mgr, active);
5035 #ifndef MODEST_TOOLKIT_HILDON2
5036 gtk_window_present (GTK_WINDOW (window));
5042 modest_ui_actions_on_change_fullscreen (GtkAction *action,
5043 ModestWindow *window)
5045 ModestWindowMgr *mgr;
5046 gboolean fullscreen;
5048 g_return_if_fail (MODEST_IS_WINDOW (window));
5050 mgr = modest_runtime_get_window_mgr ();
5051 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
5052 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
5054 #ifndef MODEST_TOOLKIT_HILDON2
5055 gtk_window_present (GTK_WINDOW (window));
5060 * Used by modest_ui_actions_on_details to call do_headers_action
5063 headers_action_show_details (TnyHeader *header,
5064 ModestWindow *window,
5068 gboolean async_retrieval;
5071 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5072 async_retrieval = TRUE;
5073 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
5074 async_retrieval = !TNY_IS_CAMEL_BS_MSG (msg);
5076 async_retrieval = FALSE;
5078 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header, async_retrieval, msg);
5080 g_object_unref (msg);
5084 * Show the header details in a ModestDetailsDialog widget
5087 modest_ui_actions_on_details (GtkAction *action,
5090 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
5094 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
5098 header = tny_msg_get_header (msg);
5100 headers_action_show_details (header, win, NULL);
5101 g_object_unref (header);
5103 g_object_unref (msg);
5105 } else if (MODEST_IS_MAIN_WINDOW (win)) {
5106 GtkWidget *folder_view, *header_view;
5108 /* Check which widget has the focus */
5109 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5110 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5111 if (gtk_widget_is_focus (folder_view)) {
5112 TnyFolderStore *folder_store
5113 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5114 if (!folder_store) {
5115 g_warning ("%s: No item was selected.\n", __FUNCTION__);
5118 /* Show only when it's a folder */
5119 /* This function should not be called for account items,
5120 * because we dim the menu item for them. */
5121 if (TNY_IS_FOLDER (folder_store)) {
5122 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
5123 TNY_FOLDER (folder_store));
5126 g_object_unref (folder_store);
5129 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5130 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5131 /* Show details of each header */
5132 do_headers_action (win, headers_action_show_details, header_view);
5134 #ifdef MODEST_TOOLKIT_HILDON2
5135 } else if (MODEST_IS_HEADER_WINDOW (win)) {
5137 GtkWidget *header_view;
5139 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
5140 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
5142 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
5144 g_object_unref (folder);
5151 modest_ui_actions_on_limit_error (GtkAction *action,
5154 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
5156 modest_platform_information_banner ((GtkWidget *) win, NULL, _CS("ckdg_ib_maximum_characters_reached"));
5161 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
5162 ModestMsgEditWindow *window)
5164 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5166 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
5170 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
5171 ModestMsgEditWindow *window)
5173 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5175 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
5179 modest_ui_actions_toggle_folders_view (GtkAction *action,
5180 ModestMainWindow *main_window)
5182 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
5184 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
5185 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
5187 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
5191 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
5192 ModestWindow *window)
5194 gboolean active, fullscreen = FALSE;
5195 ModestWindowMgr *mgr;
5197 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
5199 /* Check if we want to toggle the toolbar view in fullscreen
5201 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
5202 "ViewShowToolbarFullScreen")) {
5206 /* Toggle toolbar */
5207 mgr = modest_runtime_get_window_mgr ();
5208 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
5212 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
5213 ModestMsgEditWindow *window)
5215 modest_msg_edit_window_select_font (window);
5220 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
5221 const gchar *display_name,
5224 /* don't update the display name if it was already set;
5225 * updating the display name apparently is expensive */
5226 const gchar* old_name = gtk_window_get_title (window);
5228 if (display_name == NULL)
5231 if (old_name && display_name && strcmp (old_name, display_name) == 0)
5232 return; /* don't do anything */
5234 /* This is usually used to change the title of the main window, which
5235 * is the one that holds the folder view. Note that this change can
5236 * happen even when the widget doesn't have the focus. */
5237 gtk_window_set_title (window, display_name);
5242 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
5244 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5245 modest_msg_edit_window_select_contacts (window);
5249 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
5251 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5252 modest_msg_edit_window_check_names (window, FALSE);
5255 #ifndef MODEST_TOOLKIT_HILDON2
5257 * This function is used to track changes in the selection of the
5258 * folder view that is inside the "move to" dialog to enable/disable
5259 * the OK button because we do not want the user to select a disallowed
5260 * destination for a folder.
5261 * The user also not desired to be able to use NEW button on items where
5262 * folder creation is not possibel.
5265 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
5266 TnyFolderStore *folder_store,
5270 GtkWidget *dialog = NULL;
5271 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
5272 gboolean moving_folder = FALSE;
5273 gboolean is_local_account = TRUE;
5274 GtkWidget *folder_view = NULL;
5275 ModestTnyFolderRules rules;
5277 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
5282 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
5286 /* check if folder_store is an remote account */
5287 if (TNY_IS_ACCOUNT (folder_store)) {
5288 TnyAccount *local_account = NULL;
5289 TnyAccount *mmc_account = NULL;
5290 ModestTnyAccountStore *account_store = NULL;
5292 account_store = modest_runtime_get_account_store ();
5293 local_account = modest_tny_account_store_get_local_folders_account (account_store);
5294 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
5296 if ((gpointer) local_account != (gpointer) folder_store &&
5297 (gpointer) mmc_account != (gpointer) folder_store) {
5298 ModestProtocolType proto;
5299 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
5300 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
5301 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
5303 is_local_account = FALSE;
5304 /* New button should be dimmed on remote
5306 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5308 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
5310 g_object_unref (local_account);
5312 /* It could not exist */
5314 g_object_unref (mmc_account);
5317 /* Check the target folder rules */
5318 if (TNY_IS_FOLDER (folder_store)) {
5319 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
5320 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
5321 ok_sensitive = FALSE;
5322 new_sensitive = FALSE;
5327 /* Check if we're moving a folder */
5328 if (MODEST_IS_MAIN_WINDOW (user_data)) {
5329 /* Get the widgets */
5330 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
5331 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5332 if (gtk_widget_is_focus (folder_view))
5333 moving_folder = TRUE;
5336 if (moving_folder) {
5337 TnyFolderStore *moved_folder = NULL, *parent = NULL;
5339 /* Get the folder to move */
5340 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5342 /* Check that we're not moving to the same folder */
5343 if (TNY_IS_FOLDER (moved_folder)) {
5344 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
5345 if (parent == folder_store)
5346 ok_sensitive = FALSE;
5347 g_object_unref (parent);
5350 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
5351 /* Do not allow to move to an account unless it's the
5352 local folders account */
5353 if (!is_local_account)
5354 ok_sensitive = FALSE;
5357 if (ok_sensitive && (moved_folder == folder_store)) {
5358 /* Do not allow to move to itself */
5359 ok_sensitive = FALSE;
5361 g_object_unref (moved_folder);
5363 TnyFolder *src_folder = NULL;
5365 /* Moving a message */
5366 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
5368 TnyHeader *header = NULL;
5369 header = modest_msg_view_window_get_header
5370 (MODEST_MSG_VIEW_WINDOW (user_data));
5371 if (!TNY_IS_HEADER(header))
5372 g_warning ("%s: could not get source header", __FUNCTION__);
5374 src_folder = tny_header_get_folder (header);
5377 g_object_unref (header);
5380 TNY_FOLDER (modest_folder_view_get_selected
5381 (MODEST_FOLDER_VIEW (folder_view)));
5384 if (TNY_IS_FOLDER(src_folder)) {
5385 /* Do not allow to move the msg to the same folder */
5386 /* Do not allow to move the msg to an account */
5387 if ((gpointer) src_folder == (gpointer) folder_store ||
5388 TNY_IS_ACCOUNT (folder_store))
5389 ok_sensitive = FALSE;
5390 g_object_unref (src_folder);
5392 g_warning ("%s: could not get source folder", __FUNCTION__);
5396 /* Set sensitivity of the OK and NEW button */
5397 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
5398 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
5403 on_move_to_dialog_response (GtkDialog *dialog,
5407 GtkWidget *parent_win;
5408 MoveToInfo *helper = NULL;
5409 ModestFolderView *folder_view;
5410 gboolean unset_edit_mode = FALSE;
5412 helper = (MoveToInfo *) user_data;
5414 parent_win = (GtkWidget *) helper->win;
5415 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
5416 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
5418 TnyFolderStore *dst_folder;
5419 TnyFolderStore *selected;
5421 case MODEST_GTK_RESPONSE_NEW_FOLDER:
5422 selected = modest_folder_view_get_selected (folder_view);
5423 modest_ui_actions_create_folder (GTK_WIDGET (dialog), GTK_WIDGET (folder_view), selected);
5424 g_object_unref (selected);
5426 case GTK_RESPONSE_NONE:
5427 case GTK_RESPONSE_CANCEL:
5428 case GTK_RESPONSE_DELETE_EVENT:
5430 case GTK_RESPONSE_OK:
5431 dst_folder = modest_folder_view_get_selected (folder_view);
5433 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
5434 /* Clean list to move used for filtering */
5435 modest_folder_view_set_list_to_move (folder_view, NULL);
5437 modest_ui_actions_on_main_window_move_to (NULL,
5438 GTK_WIDGET (folder_view),
5440 MODEST_MAIN_WINDOW (parent_win));
5441 #ifdef MODEST_TOOLKIT_HILDON2
5442 } else if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
5443 /* Clean list to move used for filtering */
5444 modest_folder_view_set_list_to_move (folder_view, NULL);
5446 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
5449 GTK_WINDOW (parent_win));
5452 /* if the user selected a root folder
5453 (account) then do not perform any action */
5454 if (TNY_IS_ACCOUNT (dst_folder)) {
5455 g_signal_stop_emission_by_name (dialog, "response");
5459 /* Clean list to move used for filtering */
5460 modest_folder_view_set_list_to_move (folder_view, NULL);
5462 /* Moving from headers window in edit mode */
5463 modest_ui_actions_on_window_move_to (NULL, helper->list,
5465 MODEST_WINDOW (parent_win));
5469 g_object_unref (dst_folder);
5471 unset_edit_mode = TRUE;
5474 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
5477 /* Free the helper and exit */
5479 g_object_unref (helper->list);
5480 if (unset_edit_mode) {
5481 #ifdef MODEST_TOOLKIT_HILDON2
5482 modest_hildon2_window_unset_edit_mode (MODEST_HILDON2_WINDOW (helper->win));
5485 g_slice_free (MoveToInfo, helper);
5486 gtk_widget_destroy (GTK_WIDGET (dialog));
5490 create_move_to_dialog (GtkWindow *win,
5491 GtkWidget *folder_view,
5492 TnyList *list_to_move)
5494 GtkWidget *dialog, *tree_view = NULL;
5496 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
5498 #ifndef MODEST_TOOLKIT_HILDON2
5499 /* Track changes in the selection to
5500 * disable the OK button whenever "Move to" is not possible
5501 * disbale NEW button whenever New is not possible */
5502 g_signal_connect (tree_view,
5503 "folder_selection_changed",
5504 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
5508 /* It could happen that we're trying to move a message from a
5509 window (msg window for example) after the main window was
5510 closed, so we can not just get the model of the folder
5512 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
5513 const gchar *visible_id = NULL;
5515 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5516 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5517 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
5518 MODEST_FOLDER_VIEW(tree_view));
5521 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
5523 /* Show the same account than the one that is shown in the main window */
5524 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
5527 const gchar *active_account_name = NULL;
5528 ModestAccountMgr *mgr = NULL;
5529 ModestAccountSettings *settings = NULL;
5530 ModestServerAccountSettings *store_settings = NULL;
5532 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5533 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5535 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
5536 mgr = modest_runtime_get_account_mgr ();
5537 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
5540 const gchar *store_account_name;
5541 store_settings = modest_account_settings_get_store_settings (settings);
5542 store_account_name = modest_server_account_settings_get_account_name (store_settings);
5544 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
5545 store_account_name);
5546 g_object_unref (store_settings);
5547 g_object_unref (settings);
5551 /* we keep a pointer to the embedded folder view, so we can
5552 * retrieve it with get_folder_view_from_move_to_dialog (see
5553 * above) later (needed for focus handling)
5555 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
5557 /* Hide special folders */
5558 #ifndef MODEST_TOOLKIT_HILDON2
5559 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
5562 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
5563 #ifndef MODEST_TOOLKIT_HILDON2
5564 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5567 gtk_widget_show (GTK_WIDGET (tree_view));
5573 * Shows a confirmation dialog to the user when we're moving messages
5574 * from a remote server to the local storage. Returns the dialog
5575 * response. If it's other kind of movement then it always returns
5578 * This one is used by the next functions:
5579 * modest_ui_actions_on_paste - commented out
5580 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
5583 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
5584 TnyFolder *dest_folder,
5588 gint response = GTK_RESPONSE_OK;
5589 TnyAccount *account = NULL;
5590 TnyFolder *src_folder = NULL;
5591 TnyIterator *iter = NULL;
5592 TnyHeader *header = NULL;
5594 /* return with OK if the destination is a remote folder */
5595 if (modest_tny_folder_is_remote_folder (dest_folder))
5596 return GTK_RESPONSE_OK;
5598 /* Get source folder */
5599 iter = tny_list_create_iterator (headers);
5600 header = TNY_HEADER (tny_iterator_get_current (iter));
5602 src_folder = tny_header_get_folder (header);
5603 g_object_unref (header);
5605 g_object_unref (iter);
5607 /* if no src_folder, message may be an attahcment */
5608 if (src_folder == NULL)
5609 return GTK_RESPONSE_CANCEL;
5611 /* If the source is a local or MMC folder */
5612 if (!modest_tny_folder_is_remote_folder (src_folder)) {
5613 g_object_unref (src_folder);
5614 return GTK_RESPONSE_OK;
5617 /* Get the account */
5618 account = tny_folder_get_account (src_folder);
5620 /* now if offline we ask the user */
5621 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
5622 response = GTK_RESPONSE_OK;
5624 response = GTK_RESPONSE_CANCEL;
5627 g_object_unref (src_folder);
5628 g_object_unref (account);
5634 move_to_helper_destroyer (gpointer user_data)
5636 MoveToHelper *helper = (MoveToHelper *) user_data;
5638 /* Close the "Pasting" information banner */
5639 if (helper->banner) {
5640 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5641 g_object_unref (helper->banner);
5643 if (gtk_tree_row_reference_valid (helper->reference)) {
5644 gtk_tree_row_reference_free (helper->reference);
5645 helper->reference = NULL;
5651 move_to_cb (ModestMailOperation *mail_op,
5654 MoveToHelper *helper = (MoveToHelper *) user_data;
5655 GObject *object = modest_mail_operation_get_source (mail_op);
5657 /* Note that the operation could have failed, in that case do
5659 if (modest_mail_operation_get_status (mail_op) !=
5660 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5663 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5664 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5666 if (!modest_msg_view_window_select_next_message (self) &&
5667 !modest_msg_view_window_select_previous_message (self)) {
5668 /* No more messages to view, so close this window */
5669 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5671 } else if (MODEST_IS_MAIN_WINDOW (object) &&
5672 gtk_tree_row_reference_valid (helper->reference)) {
5673 GtkWidget *header_view;
5675 GtkTreeSelection *sel;
5677 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5678 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5679 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5680 path = gtk_tree_row_reference_get_path (helper->reference);
5681 /* We need to unselect the previous one
5682 because we could be copying instead of
5684 gtk_tree_selection_unselect_all (sel);
5685 gtk_tree_selection_select_path (sel, path);
5686 gtk_tree_path_free (path);
5688 g_object_unref (object);
5691 /* Destroy the helper */
5692 move_to_helper_destroyer (helper);
5696 folder_move_to_cb (ModestMailOperation *mail_op,
5697 TnyFolder *new_folder,
5700 GtkWidget *folder_view;
5703 object = modest_mail_operation_get_source (mail_op);
5704 if (MODEST_IS_MAIN_WINDOW (object)) {
5705 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5706 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5707 g_object_ref (folder_view);
5708 g_object_unref (object);
5709 move_to_cb (mail_op, user_data);
5710 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5711 g_object_unref (folder_view);
5713 move_to_cb (mail_op, user_data);
5718 msgs_move_to_cb (ModestMailOperation *mail_op,
5721 move_to_cb (mail_op, user_data);
5725 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5728 GObject *win = NULL;
5729 const GError *error;
5730 TnyAccount *account = NULL;
5732 #ifndef MODEST_TOOLKIT_HILDON2
5733 ModestWindow *main_window = NULL;
5735 /* Disable next automatic folder selection */
5736 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5737 FALSE); /* don't create */
5739 /* Show notification dialog only if the main window exists */
5741 GtkWidget *folder_view = NULL;
5743 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5744 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5745 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5747 if (user_data && TNY_IS_FOLDER (user_data)) {
5748 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5749 TNY_FOLDER (user_data), FALSE);
5753 win = modest_mail_operation_get_source (mail_op);
5754 error = modest_mail_operation_get_error (mail_op);
5756 if (TNY_IS_FOLDER (user_data))
5757 account = modest_tny_folder_get_account (TNY_FOLDER (user_data));
5758 else if (TNY_IS_ACCOUNT (user_data))
5759 account = g_object_ref (user_data);
5761 /* If it's not a disk full error then show a generic error */
5762 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5763 (GtkWidget *) win, (GError *) error,
5765 modest_platform_run_information_dialog ((GtkWindow *) win,
5766 _("mail_in_ui_folder_move_target_error"),
5769 g_object_unref (account);
5771 g_object_unref (win);
5775 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5784 gint pending_purges = 0;
5785 gboolean some_purged = FALSE;
5786 ModestWindow *win = MODEST_WINDOW (user_data);
5787 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5789 /* If there was any error */
5790 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5791 modest_window_mgr_unregister_header (mgr, header);
5795 /* Once the message has been retrieved for purging, we check if
5796 * it's all ok for purging */
5798 parts = tny_simple_list_new ();
5799 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5800 iter = tny_list_create_iterator (parts);
5802 while (!tny_iterator_is_done (iter)) {
5804 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5805 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5806 if (tny_mime_part_is_purged (part))
5813 g_object_unref (part);
5815 tny_iterator_next (iter);
5817 g_object_unref (iter);
5820 if (pending_purges>0) {
5822 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5824 if (response == GTK_RESPONSE_OK) {
5827 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5828 iter = tny_list_create_iterator (parts);
5829 while (!tny_iterator_is_done (iter)) {
5832 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5833 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5834 tny_mime_part_set_purged (part);
5837 g_object_unref (part);
5839 tny_iterator_next (iter);
5841 g_object_unref (iter);
5843 tny_msg_rewrite_cache (msg);
5845 gtk_widget_destroy (info);
5849 modest_window_mgr_unregister_header (mgr, header);
5851 g_object_unref (parts);
5855 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5856 ModestMainWindow *win)
5858 GtkWidget *header_view;
5859 TnyList *header_list;
5861 TnyHeaderFlags flags;
5862 ModestWindow *msg_view_window = NULL;
5865 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5867 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5868 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5870 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5872 g_warning ("%s: no header selected", __FUNCTION__);
5876 if (tny_list_get_length (header_list) == 1) {
5877 TnyIterator *iter = tny_list_create_iterator (header_list);
5878 header = TNY_HEADER (tny_iterator_get_current (iter));
5879 g_object_unref (iter);
5883 if (!header || !TNY_IS_HEADER(header)) {
5884 g_warning ("%s: header is not valid", __FUNCTION__);
5888 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5889 header, &msg_view_window);
5890 flags = tny_header_get_flags (header);
5891 if (!(flags & TNY_HEADER_FLAG_CACHED))
5894 if (msg_view_window != NULL)
5895 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5897 /* do nothing; uid was registered before, so window is probably on it's way */
5898 g_debug ("header %p has already been registered", header);
5901 ModestMailOperation *mail_op = NULL;
5902 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5903 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5904 modest_ui_actions_disk_operations_error_handler,
5906 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5907 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5909 g_object_unref (mail_op);
5912 g_object_unref (header);
5914 g_object_unref (header_list);
5918 * Checks if we need a connection to do the transfer and if the user
5919 * wants to connect to complete it
5922 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5923 TnyFolderStore *src_folder,
5925 TnyFolder *dst_folder,
5926 gboolean delete_originals,
5927 gboolean *need_connection,
5930 TnyAccount *src_account;
5931 gint uncached_msgs = 0;
5933 /* We don't need any further check if
5935 * 1- the source folder is local OR
5936 * 2- the device is already online
5938 if (!modest_tny_folder_store_is_remote (src_folder) ||
5939 tny_device_is_online (modest_runtime_get_device())) {
5940 *need_connection = FALSE;
5945 /* We must ask for a connection when
5947 * - the message(s) is not already cached OR
5948 * - the message(s) is cached but the leave_on_server setting
5949 * is FALSE (because we need to sync the source folder to
5950 * delete the message from the server (for IMAP we could do it
5951 * offline, it'll take place the next time we get a
5954 uncached_msgs = header_list_count_uncached_msgs (headers);
5955 src_account = get_account_from_folder_store (src_folder);
5956 if (uncached_msgs > 0) {
5960 *need_connection = TRUE;
5961 num_headers = tny_list_get_length (headers);
5962 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5964 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5965 GTK_RESPONSE_CANCEL) {
5971 /* The transfer is possible and the user wants to */
5974 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5975 const gchar *account_name;
5976 gboolean leave_on_server;
5978 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5979 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5982 if (leave_on_server == TRUE) {
5983 *need_connection = FALSE;
5985 *need_connection = TRUE;
5988 *need_connection = FALSE;
5993 g_object_unref (src_account);
5997 xfer_messages_error_handler (ModestMailOperation *mail_op,
6001 const GError *error;
6002 TnyAccount *account;
6004 win = modest_mail_operation_get_source (mail_op);
6005 error = modest_mail_operation_get_error (mail_op);
6007 /* We cannot get the account from the mail op as that is the
6008 source account and for checking memory full conditions we
6009 need the destination one */
6010 account = TNY_ACCOUNT (user_data);
6013 !modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6014 (GtkWidget *) win, (GError*) error,
6015 account, _KR("cerm_memory_card_full"))) {
6016 modest_platform_run_information_dialog ((GtkWindow *) win,
6017 _("mail_in_ui_folder_move_target_error"),
6021 g_object_unref (win);
6025 TnyFolderStore *dst_folder;
6030 * Utility function that transfer messages from both the main window
6031 * and the msg view window when using the "Move to" dialog
6034 xfer_messages_performer (gboolean canceled,
6036 GtkWindow *parent_window,
6037 TnyAccount *account,
6040 ModestWindow *win = MODEST_WINDOW (parent_window);
6041 TnyAccount *dst_account = NULL;
6042 gboolean dst_forbids_message_add = FALSE;
6043 XferMsgsHelper *helper;
6044 MoveToHelper *movehelper;
6045 ModestMailOperation *mail_op;
6047 helper = (XferMsgsHelper *) user_data;
6049 if (canceled || err) {
6050 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6051 (GtkWidget *) parent_window, err,
6053 /* Show the proper error message */
6054 modest_ui_actions_on_account_connection_error (parent_window, account);
6059 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
6061 /* tinymail will return NULL for local folders it seems */
6062 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
6063 modest_tny_account_get_protocol_type (dst_account),
6064 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
6066 if (dst_forbids_message_add) {
6067 modest_platform_information_banner (GTK_WIDGET (win),
6069 ngettext("mail_in_ui_folder_move_target_error",
6070 "mail_in_ui_folder_move_targets_error",
6071 tny_list_get_length (helper->headers)));
6075 movehelper = g_new0 (MoveToHelper, 1);
6077 #ifndef MODEST_TOOLKIT_HILDON2
6078 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
6079 _CS("ckct_nw_pasting"));
6080 if (movehelper->banner != NULL) {
6081 g_object_ref (movehelper->banner);
6082 gtk_widget_show (GTK_WIDGET (movehelper->banner));
6086 if (MODEST_IS_MAIN_WINDOW (win)) {
6087 GtkWidget *header_view =
6088 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6089 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6090 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
6093 /* Perform the mail operation */
6094 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
6095 xfer_messages_error_handler,
6096 g_object_ref (dst_account),
6098 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
6101 modest_mail_operation_xfer_msgs (mail_op,
6103 TNY_FOLDER (helper->dst_folder),
6108 g_object_unref (G_OBJECT (mail_op));
6111 g_object_unref (dst_account);
6112 g_object_unref (helper->dst_folder);
6113 g_object_unref (helper->headers);
6114 g_slice_free (XferMsgsHelper, helper);
6118 TnyFolder *src_folder;
6119 TnyFolderStore *dst_folder;
6120 gboolean delete_original;
6121 GtkWidget *folder_view;
6125 on_move_folder_cb (gboolean canceled,
6127 GtkWindow *parent_window,
6128 TnyAccount *account,
6131 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
6132 GtkTreeSelection *sel;
6133 ModestMailOperation *mail_op = NULL;
6135 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
6136 /* Note that the connection process can fail due to
6137 memory low conditions as it can not successfully
6138 store the summary */
6139 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6140 (GtkWidget*) parent_window, err,
6142 g_debug ("Error connecting when trying to move a folder");
6144 g_object_unref (G_OBJECT (info->src_folder));
6145 g_object_unref (G_OBJECT (info->dst_folder));
6150 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
6151 #ifndef MODEST_TOOLKIT_HILDON2
6152 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
6153 _CS("ckct_nw_pasting"));
6154 if (helper->banner != NULL) {
6155 g_object_ref (helper->banner);
6156 gtk_widget_show (GTK_WIDGET(helper->banner));
6159 /* Clean folder on header view before moving it */
6160 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
6161 gtk_tree_selection_unselect_all (sel);
6163 /* Let gtk events run. We need that the folder
6164 view frees its reference to the source
6165 folder *before* issuing the mail operation
6166 so we need the signal handler of selection
6167 changed to happen before the mail
6169 while (gtk_events_pending ())
6170 gtk_main_iteration (); */
6173 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
6174 modest_ui_actions_move_folder_error_handler,
6175 g_object_ref (info->dst_folder), g_object_unref);
6176 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
6179 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
6180 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
6181 TNY_FOLDER (info->dst_folder), TRUE);
6183 modest_mail_operation_xfer_folder (mail_op,
6184 TNY_FOLDER (info->src_folder),
6186 info->delete_original,
6189 g_object_unref (G_OBJECT (info->src_folder));
6191 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
6194 /* Unref mail operation */
6195 g_object_unref (G_OBJECT (mail_op));
6196 g_object_unref (G_OBJECT (info->dst_folder));
6201 get_account_from_folder_store (TnyFolderStore *folder_store)
6203 if (TNY_IS_ACCOUNT (folder_store))
6204 return g_object_ref (folder_store);
6206 return tny_folder_get_account (TNY_FOLDER (folder_store));
6210 * UI handler for the "Move to" action when invoked from the
6214 modest_ui_actions_on_main_window_move_to (GtkAction *action,
6215 GtkWidget *folder_view,
6216 TnyFolderStore *dst_folder,
6217 ModestMainWindow *win)
6219 ModestHeaderView *header_view = NULL;
6220 TnyFolderStore *src_folder = NULL;
6222 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
6224 /* Get the source folder */
6225 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6227 /* Get header view */
6228 header_view = (ModestHeaderView *)
6229 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6231 /* Get folder or messages to transfer */
6232 if (gtk_widget_is_focus (folder_view)) {
6233 gboolean do_xfer = TRUE;
6235 /* Allow only to transfer folders to the local root folder */
6236 if (TNY_IS_ACCOUNT (dst_folder) &&
6237 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
6238 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
6240 } else if (!TNY_IS_FOLDER (src_folder)) {
6241 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
6246 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
6247 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6249 info->src_folder = g_object_ref (src_folder);
6250 info->dst_folder = g_object_ref (dst_folder);
6251 info->delete_original = TRUE;
6252 info->folder_view = folder_view;
6254 connect_info->callback = on_move_folder_cb;
6255 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6256 connect_info->data = info;
6258 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6259 TNY_FOLDER_STORE (src_folder),
6262 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
6265 headers = modest_header_view_get_selected_headers(header_view);
6267 /* Transfer the messages */
6268 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
6269 headers, TNY_FOLDER (dst_folder));
6271 g_object_unref (headers);
6275 g_object_unref (src_folder);
6278 #ifdef MODEST_TOOLKIT_HILDON2
6280 * UI handler for the "Move to" action when invoked from the
6281 * ModestFolderWindow
6284 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
6285 TnyFolderStore *dst_folder,
6289 TnyFolderStore *src_folder = NULL;
6290 TnyIterator *iterator;
6292 if (tny_list_get_length (selection) != 1)
6295 iterator = tny_list_create_iterator (selection);
6296 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
6297 g_object_unref (iterator);
6300 gboolean do_xfer = TRUE;
6302 /* Allow only to transfer folders to the local root folder */
6303 if (TNY_IS_ACCOUNT (dst_folder) &&
6304 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
6305 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
6308 modest_platform_run_information_dialog (win,
6309 _("mail_in_ui_folder_move_target_error"),
6311 } else if (!TNY_IS_FOLDER (src_folder)) {
6312 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
6317 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
6318 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6320 info->src_folder = g_object_ref (src_folder);
6321 info->dst_folder = g_object_ref (dst_folder);
6322 info->delete_original = TRUE;
6323 info->folder_view = folder_view;
6325 connect_info->callback = on_move_folder_cb;
6326 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
6327 connect_info->data = info;
6329 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6330 TNY_FOLDER_STORE (src_folder),
6335 g_object_unref (src_folder);
6341 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
6342 TnyFolder *src_folder,
6344 TnyFolder *dst_folder)
6346 gboolean need_connection = TRUE;
6347 gboolean do_xfer = TRUE;
6348 XferMsgsHelper *helper;
6350 g_return_if_fail (TNY_IS_FOLDER (src_folder));
6351 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6352 g_return_if_fail (TNY_IS_LIST (headers));
6354 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
6355 headers, TNY_FOLDER (dst_folder),
6356 TRUE, &need_connection,
6359 /* If we don't want to transfer just return */
6363 /* Create the helper */
6364 helper = g_slice_new (XferMsgsHelper);
6365 helper->dst_folder = g_object_ref (dst_folder);
6366 helper->headers = g_object_ref (headers);
6368 if (need_connection) {
6369 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
6370 connect_info->callback = xfer_messages_performer;
6371 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
6372 connect_info->data = helper;
6374 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
6375 TNY_FOLDER_STORE (src_folder),
6378 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
6379 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
6380 src_account, helper);
6381 g_object_unref (src_account);
6386 * UI handler for the "Move to" action when invoked from the
6387 * ModestMsgViewWindow
6390 modest_ui_actions_on_window_move_to (GtkAction *action,
6392 TnyFolderStore *dst_folder,
6395 TnyFolder *src_folder = NULL;
6397 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
6400 TnyHeader *header = NULL;
6403 iter = tny_list_create_iterator (headers);
6404 header = (TnyHeader *) tny_iterator_get_current (iter);
6405 src_folder = tny_header_get_folder (header);
6407 /* Transfer the messages */
6408 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
6410 TNY_FOLDER (dst_folder));
6413 g_object_unref (header);
6414 g_object_unref (iter);
6415 g_object_unref (src_folder);
6420 modest_ui_actions_on_move_to (GtkAction *action,
6423 modest_ui_actions_on_edit_mode_move_to (win);
6427 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
6429 GtkWidget *dialog = NULL;
6430 MoveToInfo *helper = NULL;
6431 TnyList *list_to_move;
6433 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
6435 #ifndef MODEST_TOOLKIT_HILDON2
6436 /* Get the main window if exists */
6437 ModestMainWindow *main_window;
6438 if (MODEST_IS_MAIN_WINDOW (win))
6439 main_window = MODEST_MAIN_WINDOW (win);
6442 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
6443 FALSE)); /* don't create */
6446 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
6451 if (tny_list_get_length (list_to_move) < 1) {
6452 g_object_unref (list_to_move);
6456 /* Create and run the dialog */
6457 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
6458 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
6459 GTK_WINDOW (dialog),
6463 helper = g_slice_new0 (MoveToInfo);
6464 helper->list = list_to_move;
6467 /* Listen to response signal */
6468 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
6470 /* Show the dialog */
6471 gtk_widget_show (dialog);
6477 * Calls #HeadersFunc for each header already selected in the main
6478 * window or the message currently being shown in the msg view window
6481 do_headers_action (ModestWindow *win,
6485 TnyList *headers_list = NULL;
6486 TnyIterator *iter = NULL;
6487 TnyHeader *header = NULL;
6488 TnyFolder *folder = NULL;
6491 headers_list = get_selected_headers (win);
6495 /* Get the folder */
6496 iter = tny_list_create_iterator (headers_list);
6497 header = TNY_HEADER (tny_iterator_get_current (iter));
6499 folder = tny_header_get_folder (header);
6500 g_object_unref (header);
6503 /* Call the function for each header */
6504 while (!tny_iterator_is_done (iter)) {
6505 header = TNY_HEADER (tny_iterator_get_current (iter));
6506 func (header, win, user_data);
6507 g_object_unref (header);
6508 tny_iterator_next (iter);
6511 /* Trick: do a poke status in order to speed up the signaling
6514 tny_folder_poke_status (folder);
6515 g_object_unref (folder);
6519 g_object_unref (iter);
6520 g_object_unref (headers_list);
6524 modest_ui_actions_view_attachment (GtkAction *action,
6525 ModestWindow *window)
6527 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6528 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
6530 /* not supported window for this action */
6531 g_return_if_reached ();
6536 modest_ui_actions_save_attachments (GtkAction *action,
6537 ModestWindow *window)
6539 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6541 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
6544 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
6546 /* not supported window for this action */
6547 g_return_if_reached ();
6552 modest_ui_actions_remove_attachments (GtkAction *action,
6553 ModestWindow *window)
6555 if (MODEST_IS_MAIN_WINDOW (window)) {
6556 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
6557 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6558 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
6560 /* not supported window for this action */
6561 g_return_if_reached ();
6566 modest_ui_actions_on_settings (GtkAction *action,
6571 dialog = modest_platform_get_global_settings_dialog ();
6572 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
6573 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
6574 gtk_widget_show_all (dialog);
6576 gtk_dialog_run (GTK_DIALOG (dialog));
6578 gtk_widget_destroy (dialog);
6582 modest_ui_actions_on_help (GtkAction *action,
6585 /* Help app is not available at all in fremantle */
6586 #ifndef MODEST_TOOLKIT_HILDON2
6587 const gchar *help_id;
6589 g_return_if_fail (win && GTK_IS_WINDOW(win));
6591 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
6594 modest_platform_show_help (GTK_WINDOW (win), help_id);
6599 modest_ui_actions_on_csm_help (GtkAction *action,
6602 /* Help app is not available at all in fremantle */
6603 #ifndef MODEST_TOOLKIT_HILDON2
6605 const gchar* help_id = NULL;
6606 GtkWidget *folder_view;
6607 TnyFolderStore *folder_store;
6609 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
6611 /* Get selected folder */
6612 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
6613 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6614 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6616 /* Switch help_id */
6617 if (folder_store && TNY_IS_FOLDER (folder_store))
6618 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
6621 g_object_unref (folder_store);
6624 modest_platform_show_help (GTK_WINDOW (win), help_id);
6626 modest_ui_actions_on_help (action, win);
6631 retrieve_contents_cb (ModestMailOperation *mail_op,
6638 /* We only need this callback to show an error in case of
6639 memory low condition */
6640 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
6641 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
6646 retrieve_msg_contents_performer (gboolean canceled,
6648 GtkWindow *parent_window,
6649 TnyAccount *account,
6652 ModestMailOperation *mail_op;
6653 TnyList *headers = TNY_LIST (user_data);
6655 if (err || canceled) {
6656 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
6657 (GtkWidget *) parent_window, err,
6662 /* Create mail operation */
6663 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
6664 modest_ui_actions_disk_operations_error_handler,
6666 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
6667 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
6670 g_object_unref (mail_op);
6672 g_object_unref (headers);
6673 g_object_unref (account);
6677 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
6678 ModestWindow *window)
6680 TnyList *headers = NULL;
6681 TnyAccount *account = NULL;
6682 TnyIterator *iter = NULL;
6683 TnyHeader *header = NULL;
6684 TnyFolder *folder = NULL;
6687 headers = get_selected_headers (window);
6691 /* Pick the account */
6692 iter = tny_list_create_iterator (headers);
6693 header = TNY_HEADER (tny_iterator_get_current (iter));
6694 folder = tny_header_get_folder (header);
6695 account = tny_folder_get_account (folder);
6696 g_object_unref (folder);
6697 g_object_unref (header);
6698 g_object_unref (iter);
6700 /* Connect and perform the message retrieval */
6701 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6702 g_object_ref (account),
6703 retrieve_msg_contents_performer,
6704 g_object_ref (headers));
6707 g_object_unref (account);
6708 g_object_unref (headers);
6712 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6714 g_return_if_fail (MODEST_IS_WINDOW (window));
6717 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6721 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6723 g_return_if_fail (MODEST_IS_WINDOW (window));
6726 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6730 modest_ui_actions_on_email_menu_activated (GtkAction *action,
6731 ModestWindow *window)
6733 g_return_if_fail (MODEST_IS_WINDOW (window));
6736 modest_ui_actions_check_menu_dimming_rules (window);
6740 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
6741 ModestWindow *window)
6743 g_return_if_fail (MODEST_IS_WINDOW (window));
6746 modest_ui_actions_check_menu_dimming_rules (window);
6750 modest_ui_actions_on_view_menu_activated (GtkAction *action,
6751 ModestWindow *window)
6753 g_return_if_fail (MODEST_IS_WINDOW (window));
6756 modest_ui_actions_check_menu_dimming_rules (window);
6760 modest_ui_actions_on_format_menu_activated (GtkAction *action,
6761 ModestWindow *window)
6763 g_return_if_fail (MODEST_IS_WINDOW (window));
6766 modest_ui_actions_check_menu_dimming_rules (window);
6770 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
6771 ModestWindow *window)
6773 g_return_if_fail (MODEST_IS_WINDOW (window));
6776 modest_ui_actions_check_menu_dimming_rules (window);
6780 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
6781 ModestWindow *window)
6783 g_return_if_fail (MODEST_IS_WINDOW (window));
6786 modest_ui_actions_check_menu_dimming_rules (window);
6790 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
6791 ModestWindow *window)
6793 g_return_if_fail (MODEST_IS_WINDOW (window));
6796 modest_ui_actions_check_menu_dimming_rules (window);
6800 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
6801 ModestWindow *window)
6803 g_return_if_fail (MODEST_IS_WINDOW (window));
6806 modest_ui_actions_check_menu_dimming_rules (window);
6810 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
6811 ModestWindow *window)
6813 g_return_if_fail (MODEST_IS_WINDOW (window));
6816 modest_ui_actions_check_menu_dimming_rules (window);
6820 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6822 g_return_if_fail (MODEST_IS_WINDOW (window));
6824 /* we check for low-mem; in that case, show a warning, and don't allow
6827 if (modest_platform_check_memory_low (window, TRUE))
6830 modest_platform_show_search_messages (GTK_WINDOW (window));
6834 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6836 g_return_if_fail (MODEST_IS_WINDOW (win));
6839 /* we check for low-mem; in that case, show a warning, and don't allow
6840 * for the addressbook
6842 if (modest_platform_check_memory_low (win, TRUE))
6846 modest_platform_show_addressbook (GTK_WINDOW (win));
6851 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6852 ModestWindow *window)
6855 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6857 if (GTK_IS_TOGGLE_ACTION (action))
6858 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6862 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window),
6867 on_send_receive_finished (ModestMailOperation *mail_op,
6870 GtkWidget *header_view, *folder_view;
6871 TnyFolderStore *folder_store;
6872 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6874 /* Set send/receive operation finished */
6875 modest_main_window_notify_send_receive_completed (main_win);
6877 /* Don't refresh the current folder if there were any errors */
6878 if (modest_mail_operation_get_status (mail_op) !=
6879 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6882 /* Refresh the current folder if we're viewing a window. We do
6883 this because the user won't be able to see the new mails in
6884 the selected folder after a Send&Receive because it only
6885 performs a poke_status, i.e, only the number of read/unread
6886 messages is updated, but the new headers are not
6888 folder_view = modest_main_window_get_child_widget (main_win,
6889 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6893 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6895 /* Do not need to refresh INBOX again because the
6896 update_account does it always automatically */
6897 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6898 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6899 ModestMailOperation *refresh_op;
6901 header_view = modest_main_window_get_child_widget (main_win,
6902 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6904 /* We do not need to set the contents style
6905 because it hasn't changed. We also do not
6906 need to save the widget status. Just force
6908 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6909 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6910 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6911 folder_refreshed_cb, main_win);
6912 g_object_unref (refresh_op);
6916 g_object_unref (folder_store);
6921 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6927 const gchar* server_name = NULL;
6928 TnyTransportAccount *transport;
6929 gchar *message = NULL;
6930 ModestProtocol *protocol;
6932 /* Don't show anything if the user cancelled something or the
6933 * send receive request is not interactive. Authentication
6934 * errors are managed by the account store so no need to show
6935 * a dialog here again */
6936 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6937 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6938 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6942 /* Get the server name. Note that we could be using a
6943 connection specific transport account */
6944 transport = (TnyTransportAccount *)
6945 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
6947 ModestTnyAccountStore *acc_store;
6948 const gchar *acc_name;
6949 TnyTransportAccount *conn_specific;
6951 acc_store = modest_runtime_get_account_store();
6952 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
6953 conn_specific = (TnyTransportAccount *)
6954 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
6955 if (conn_specific) {
6956 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
6957 g_object_unref (conn_specific);
6959 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
6961 g_object_unref (transport);
6965 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
6966 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
6967 tny_account_get_proto (TNY_ACCOUNT (transport)));
6969 g_warning ("%s: Account with no proto", __FUNCTION__);
6973 /* Show the appropriate message text for the GError: */
6974 switch (err->code) {
6975 case TNY_SERVICE_ERROR_CONNECT:
6976 message = modest_protocol_get_translation (protocol,
6977 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
6980 case TNY_SERVICE_ERROR_SEND:
6981 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6983 case TNY_SERVICE_ERROR_UNAVAILABLE:
6984 message = modest_protocol_get_translation (protocol,
6985 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
6989 g_warning ("%s: unexpected ERROR %d",
6990 __FUNCTION__, err->code);
6991 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6995 modest_platform_run_information_dialog (NULL, message, FALSE);
7000 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
7005 ModestWindow *top_window = NULL;
7006 ModestWindowMgr *mgr = NULL;
7007 GtkWidget *header_view = NULL;
7008 TnyFolder *selected_folder = NULL;
7009 TnyFolderType folder_type;
7011 mgr = modest_runtime_get_window_mgr ();
7012 top_window = modest_window_mgr_get_current_top (mgr);
7017 #ifndef MODEST_TOOLKIT_HILDON2
7018 if (MODEST_IS_MAIN_WINDOW (top_window)) {
7019 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (top_window),
7020 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
7023 if (MODEST_IS_HEADER_WINDOW (top_window)) {
7024 header_view = (GtkWidget *)
7025 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
7029 /* Get selected folder */
7031 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
7032 if (!selected_folder)
7035 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
7036 #if GTK_CHECK_VERSION(2, 8, 0)
7037 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
7038 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
7039 GtkTreeViewColumn *tree_column;
7041 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
7042 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
7044 gtk_tree_view_column_queue_resize (tree_column);
7046 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
7047 gtk_widget_queue_draw (header_view);
7050 #ifndef MODEST_TOOLKIT_HILDON2
7051 /* Rerun dimming rules, because the message could become deletable for example */
7052 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
7053 MODEST_DIMMING_RULES_TOOLBAR);
7054 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
7055 MODEST_DIMMING_RULES_MENU);
7059 g_object_unref (selected_folder);
7063 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
7064 TnyAccount *account)
7066 ModestProtocolType protocol_type;
7067 ModestProtocol *protocol;
7068 gchar *error_note = NULL;
7070 protocol_type = modest_tny_account_get_protocol_type (account);
7071 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
7074 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
7075 if (error_note == NULL) {
7076 g_warning ("%s: This should not be reached", __FUNCTION__);
7078 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
7079 g_free (error_note);
7084 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
7088 TnyFolderStore *folder = NULL;
7089 TnyAccount *account = NULL;
7090 ModestProtocolType proto;
7091 ModestProtocol *protocol;
7092 TnyHeader *header = NULL;
7094 if (MODEST_IS_MAIN_WINDOW (win)) {
7095 GtkWidget *header_view;
7096 TnyList* headers = NULL;
7098 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
7099 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
7100 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
7101 if (!headers || tny_list_get_length (headers) == 0) {
7103 g_object_unref (headers);
7106 iter = tny_list_create_iterator (headers);
7107 header = TNY_HEADER (tny_iterator_get_current (iter));
7108 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
7109 g_object_unref (iter);
7110 g_object_unref (headers);
7111 #ifdef MODEST_TOOLKIT_HILDON2
7112 } else if (MODEST_IS_HEADER_WINDOW (win)) {
7113 GtkWidget *header_view;
7114 TnyList* headers = NULL;
7116 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
7117 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
7118 if (!headers || tny_list_get_length (headers) == 0) {
7120 g_object_unref (headers);
7123 iter = tny_list_create_iterator (headers);
7124 header = TNY_HEADER (tny_iterator_get_current (iter));
7126 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
7128 g_warning ("List should contain headers");
7130 g_object_unref (iter);
7131 g_object_unref (headers);
7133 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
7134 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
7136 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
7139 if (!header || !folder)
7142 /* Get the account type */
7143 account = tny_folder_get_account (TNY_FOLDER (folder));
7144 proto = modest_tny_account_get_protocol_type (account);
7145 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
7148 subject = tny_header_dup_subject (header);
7149 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
7153 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
7159 g_object_unref (account);
7161 g_object_unref (folder);
7163 g_object_unref (header);
7169 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
7170 const gchar *account_name,
7171 const gchar *account_title)
7173 ModestAccountMgr *account_mgr;
7176 ModestProtocol *protocol;
7177 gboolean removed = FALSE;
7179 g_return_val_if_fail (account_name, FALSE);
7180 g_return_val_if_fail (account_title, FALSE);
7182 account_mgr = modest_runtime_get_account_mgr();
7184 /* The warning text depends on the account type: */
7185 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
7186 modest_account_mgr_get_store_protocol (account_mgr,
7188 txt = modest_protocol_get_translation (protocol,
7189 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
7192 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
7194 response = modest_platform_run_confirmation_dialog (parent_window, txt);
7198 if (response == GTK_RESPONSE_OK) {
7199 /* Remove account. If it succeeds then it also removes
7200 the account from the ModestAccountView: */
7201 gboolean is_default = FALSE;
7202 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
7203 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
7205 g_free (default_account_name);
7207 removed = modest_account_mgr_remove_account (account_mgr, account_name);
7209 #ifdef MODEST_TOOLKIT_HILDON2
7210 hildon_gtk_window_take_screenshot (parent_window, FALSE);
7212 /* Close all email notifications, we cannot
7213 distinguish if the notification belongs to
7214 this account or not, so for safety reasons
7215 we remove them all */
7216 modest_platform_remove_new_mail_notifications (FALSE, account_name);
7218 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
7225 on_fetch_images_performer (gboolean canceled,
7227 GtkWindow *parent_window,
7228 TnyAccount *account,
7231 if (err || canceled) {
7232 /* Show an unable to retrieve images ??? */
7236 /* Note that the user could have closed the window while connecting */
7237 if (GTK_WIDGET_VISIBLE (parent_window))
7238 modest_msg_view_window_fetch_images ((ModestMsgViewWindow *) parent_window);
7239 g_object_unref ((GObject *) user_data);
7243 modest_ui_actions_on_fetch_images (GtkAction *action,
7244 ModestWindow *window)
7246 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
7248 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
7250 on_fetch_images_performer,
7251 g_object_ref (window));
7255 modest_ui_actions_on_reload_message (const gchar *msg_id)
7257 ModestWindow *window = NULL;
7259 g_return_if_fail (msg_id && msg_id[0] != '\0');
7260 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
7266 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
7269 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));
7272 /** Check whether any connections are active, and cancel them if
7274 * Returns TRUE is there was no problem,
7275 * or if an operation was cancelled so we can continue.
7276 * Returns FALSE if the user chose to cancel his request instead.
7280 modest_ui_actions_check_for_active_account (ModestWindow *self,
7281 const gchar* account_name)
7283 ModestTnySendQueue *send_queue;
7284 ModestTnyAccountStore *acc_store;
7285 ModestMailOperationQueue* queue;
7286 TnyConnectionStatus store_conn_status;
7287 TnyAccount *store_account = NULL, *transport_account = NULL;
7288 gboolean retval = TRUE, sending = FALSE;
7290 acc_store = modest_runtime_get_account_store ();
7291 queue = modest_runtime_get_mail_operation_queue ();
7294 modest_tny_account_store_get_server_account (acc_store,
7296 TNY_ACCOUNT_TYPE_STORE);
7298 /* This could happen if the account was deleted before the
7299 call to this function */
7304 modest_tny_account_store_get_server_account (acc_store,
7306 TNY_ACCOUNT_TYPE_TRANSPORT);
7308 /* This could happen if the account was deleted before the
7309 call to this function */
7310 if (!transport_account) {
7311 g_object_unref (store_account);
7315 /* If the transport account was not used yet, then the send
7316 queue could not exist (it's created on demand) */
7317 send_queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (transport_account), FALSE);
7318 if (TNY_IS_SEND_QUEUE (send_queue))
7319 sending = modest_tny_send_queue_sending_in_progress (send_queue);
7321 store_conn_status = tny_account_get_connection_status (store_account);
7322 if (store_conn_status == TNY_CONNECTION_STATUS_CONNECTED || sending) {
7325 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (self),
7326 _("emev_nc_disconnect_account"));
7327 if (response == GTK_RESPONSE_OK) {
7336 /* FIXME: We should only cancel those of this account */
7337 modest_mail_operation_queue_cancel_all (queue);
7339 /* Also disconnect the account */
7340 if ((tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED) &&
7341 (tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)) {
7342 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
7346 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (transport_account),
7352 g_object_unref (store_account);
7353 g_object_unref (transport_account);