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-camel-folder.h>
50 #include <tny-camel-imap-folder.h>
51 #include <tny-camel-pop-folder.h>
52 #ifdef MODEST_TOOLKIT_HILDON2
53 #include <modest-accounts-window.h>
54 #include <hildon/hildon-pannable-area.h>
55 #include <hildon/hildon-gtk.h>
56 #include <modest-header-window.h>
57 #include <modest-folder-window.h>
58 #include <modest-maemo-utils.h>
61 #ifdef MODEST_PLATFORM_MAEMO
62 #include "maemo/modest-osso-state-saving.h"
63 #endif /* MODEST_PLATFORM_MAEMO */
64 #ifndef MODEST_TOOLKIT_GTK
65 #include "maemo/modest-hildon-includes.h"
66 #include "maemo/modest-connection-specific-smtp-window.h"
67 #endif /* !MODEST_TOOLKIT_GTK */
68 #include <modest-utils.h>
70 #include "widgets/modest-ui-constants.h"
71 #include <widgets/modest-main-window.h>
72 #include <widgets/modest-msg-view-window.h>
73 #include <widgets/modest-account-view-window.h>
74 #include <widgets/modest-details-dialog.h>
75 #include <widgets/modest-attachments-view.h>
76 #include "widgets/modest-folder-view.h"
77 #include "widgets/modest-global-settings-dialog.h"
78 #include "modest-account-mgr-helpers.h"
79 #include "modest-mail-operation.h"
80 #include "modest-text-utils.h"
81 #include <modest-widget-memory.h>
82 #include <tny-error.h>
83 #include <tny-simple-list.h>
84 #include <tny-msg-view.h>
85 #include <tny-device.h>
86 #include <tny-merge-folder.h>
88 #include <gtkhtml/gtkhtml.h>
90 #define MIN_FREE_SPACE 5 * 1024 * 1024
91 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
93 typedef struct _GetMsgAsyncHelper {
95 ModestMailOperation *mail_op;
102 typedef enum _ReplyForwardAction {
106 } ReplyForwardAction;
108 typedef struct _ReplyForwardHelper {
109 guint reply_forward_type;
110 ReplyForwardAction action;
113 GtkWidget *parent_window;
115 } ReplyForwardHelper;
117 typedef struct _MoveToHelper {
118 GtkTreeRowReference *reference;
122 typedef struct _PasteAsAttachmentHelper {
123 ModestMsgEditWindow *window;
125 } PasteAsAttachmentHelper;
133 * The do_headers_action uses this kind of functions to perform some
134 * action to each member of a list of headers
136 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
138 static void do_headers_action (ModestWindow *win,
142 static void open_msg_cb (ModestMailOperation *mail_op,
149 static void reply_forward_cb (ModestMailOperation *mail_op,
156 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
158 static void folder_refreshed_cb (ModestMailOperation *mail_op,
162 static void on_send_receive_finished (ModestMailOperation *mail_op,
165 static gint header_list_count_uncached_msgs (TnyList *header_list);
167 static gboolean connect_to_get_msg (ModestWindow *win,
168 gint num_of_uncached_msgs,
169 TnyAccount *account);
171 static gboolean remote_folder_has_leave_on_server (TnyFolderStore *folder);
173 static void do_create_folder (GtkWindow *window,
174 TnyFolderStore *parent_folder,
175 const gchar *suggested_name);
177 static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store);
179 static void modest_ui_actions_on_main_window_move_to (GtkAction *action,
180 GtkWidget *folder_view,
181 TnyFolderStore *dst_folder,
182 ModestMainWindow *win);
183 #ifdef MODEST_TOOLKIT_HILDON2
184 static void modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
185 TnyFolderStore *dst_folder,
190 static void modest_ui_actions_on_window_move_to (GtkAction *action,
191 TnyList *list_to_move,
192 TnyFolderStore *dst_folder,
196 * This function checks whether a TnyFolderStore is a pop account
199 remote_folder_has_leave_on_server (TnyFolderStore *folder)
204 g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
206 account = get_account_from_folder_store (folder);
207 result = (modest_protocol_registry_protocol_type_has_leave_on_server (modest_runtime_get_protocol_registry (),
208 modest_tny_account_get_protocol_type (account)));
209 g_object_unref (account);
214 /* FIXME: this should be merged with the similar code in modest-account-view-window */
215 /* Show the account creation wizard dialog.
216 * returns: TRUE if an account was created. FALSE if the user cancelled.
219 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
221 gboolean result = FALSE;
223 gint dialog_response;
225 /* there is no such wizard yet */
226 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
227 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (wizard), (GtkWindow *) win);
229 #ifndef MODEST_TOOLKIT_HILDON2
230 /* always present a main window in the background
231 * we do it here, so we cannot end up with two wizards (as this
232 * function might be called in modest_window_mgr_get_main_window as well */
234 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
235 TRUE); /* create if not existent */
239 ModestWindowMgr *mgr;
241 mgr = modest_runtime_get_window_mgr ();
243 window_list = modest_window_mgr_get_window_list (mgr);
244 if (window_list == NULL) {
245 win = MODEST_WINDOW (modest_accounts_window_new ());
246 if (modest_window_mgr_register_window (mgr, win, NULL)) {
247 gtk_widget_show_all (GTK_WIDGET (win));
249 gtk_widget_destroy (GTK_WIDGET (win));
254 g_list_free (window_list);
260 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
262 /* make sure the mainwindow is visible. We need to present the
263 wizard again to give it the focus back. show_all are needed
264 in order to get the widgets properly drawn (MainWindow main
265 paned won't be in its right position and the dialog will be
267 #ifndef MODEST_TOOLKIT_HILDON2
268 gtk_widget_show_all (GTK_WIDGET (win));
269 gtk_widget_show_all (GTK_WIDGET (wizard));
270 gtk_window_present (GTK_WINDOW (win));
271 gtk_window_present (GTK_WINDOW (wizard));
274 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
275 gtk_widget_destroy (GTK_WIDGET (wizard));
276 if (gtk_events_pending ())
277 gtk_main_iteration ();
279 if (dialog_response == GTK_RESPONSE_CANCEL) {
282 /* Check whether an account was created: */
283 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
290 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
293 const gchar *authors[] = {
294 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
297 about = gtk_about_dialog_new ();
298 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
299 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
300 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
301 _("Copyright (c) 2006, Nokia Corporation\n"
302 "All rights reserved."));
303 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
304 _("a modest e-mail client\n\n"
305 "design and implementation: Dirk-Jan C. Binnema\n"
306 "contributions from the fine people at KC and Ig\n"
307 "uses the tinymail email framework written by Philip van Hoof"));
308 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
309 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
310 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
311 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
313 gtk_dialog_run (GTK_DIALOG (about));
314 gtk_widget_destroy(about);
318 * Gets the list of currently selected messages. If the win is the
319 * main window, then it returns a newly allocated list of the headers
320 * selected in the header view. If win is the msg view window, then
321 * the value returned is a list with just a single header.
323 * The caller of this funcion must free the list.
326 get_selected_headers (ModestWindow *win)
328 if (MODEST_IS_MAIN_WINDOW(win)) {
329 GtkWidget *header_view;
331 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
332 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
333 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
335 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
336 /* for MsgViewWindows, we simply return a list with one element */
338 TnyList *list = NULL;
340 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
341 if (header != NULL) {
342 list = tny_simple_list_new ();
343 tny_list_prepend (list, G_OBJECT(header));
344 g_object_unref (G_OBJECT(header));
349 #ifdef MODEST_TOOLKIT_HILDON2
350 } else if (MODEST_IS_HEADER_WINDOW (win)) {
351 GtkWidget *header_view;
353 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
354 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
360 static GtkTreeRowReference *
361 get_next_after_selected_headers (ModestHeaderView *header_view)
363 GtkTreeSelection *sel;
364 GList *selected_rows, *node;
366 GtkTreeRowReference *result;
369 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
370 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
371 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
373 if (selected_rows == NULL)
376 node = g_list_last (selected_rows);
377 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
378 gtk_tree_path_next (path);
380 result = gtk_tree_row_reference_new (model, path);
382 gtk_tree_path_free (path);
383 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
384 g_list_free (selected_rows);
390 headers_action_mark_as_read (TnyHeader *header,
394 TnyHeaderFlags flags;
396 g_return_if_fail (TNY_IS_HEADER(header));
398 flags = tny_header_get_flags (header);
399 if (flags & TNY_HEADER_FLAG_SEEN) return;
400 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
404 headers_action_mark_as_unread (TnyHeader *header,
408 TnyHeaderFlags flags;
410 g_return_if_fail (TNY_IS_HEADER(header));
412 flags = tny_header_get_flags (header);
413 if (flags & TNY_HEADER_FLAG_SEEN) {
414 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
418 /** After deleing a message that is currently visible in a window,
419 * show the next message from the list, or close the window if there are no more messages.
422 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
424 /* Close msg view window or select next */
425 if (!modest_msg_view_window_select_next_message (win) &&
426 !modest_msg_view_window_select_previous_message (win)) {
428 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
434 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
436 modest_ui_actions_on_edit_mode_delete_message (win);
440 modest_ui_actions_on_edit_mode_delete_message (ModestWindow *win)
442 TnyList *header_list = NULL;
443 TnyIterator *iter = NULL;
444 TnyHeader *header = NULL;
445 gchar *message = NULL;
448 ModestWindowMgr *mgr;
449 GtkWidget *header_view = NULL;
450 gboolean retval = TRUE;
452 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
454 /* Check first if the header view has the focus */
455 if (MODEST_IS_MAIN_WINDOW (win)) {
457 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
458 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
459 if (!gtk_widget_is_focus (header_view))
463 /* Get the headers, either from the header view (if win is the main window),
464 * or from the message view window: */
465 header_list = get_selected_headers (win);
466 if (!header_list) return FALSE;
468 /* Check if any of the headers are already opened, or in the process of being opened */
469 if (MODEST_IS_MAIN_WINDOW (win)) {
470 gint opened_headers = 0;
472 iter = tny_list_create_iterator (header_list);
473 mgr = modest_runtime_get_window_mgr ();
474 while (!tny_iterator_is_done (iter)) {
475 header = TNY_HEADER (tny_iterator_get_current (iter));
477 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
479 g_object_unref (header);
481 tny_iterator_next (iter);
483 g_object_unref (iter);
485 if (opened_headers > 0) {
488 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
491 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg, FALSE);
494 g_object_unref (header_list);
500 if (tny_list_get_length(header_list) == 1) {
501 iter = tny_list_create_iterator (header_list);
502 header = TNY_HEADER (tny_iterator_get_current (iter));
505 subject = tny_header_dup_subject (header);
507 subject = g_strdup (_("mail_va_no_subject"));
508 desc = g_strdup_printf ("%s", subject);
510 g_object_unref (header);
513 g_object_unref (iter);
515 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
516 tny_list_get_length(header_list)), desc);
518 /* Confirmation dialog */
519 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
523 if (response == GTK_RESPONSE_OK) {
524 ModestWindow *main_window = NULL;
525 ModestWindowMgr *mgr = NULL;
526 GtkTreeModel *model = NULL;
527 GtkTreeSelection *sel = NULL;
528 GList *sel_list = NULL, *tmp = NULL;
529 GtkTreeRowReference *next_row_reference = NULL;
530 GtkTreeRowReference *prev_row_reference = NULL;
531 GtkTreePath *next_path = NULL;
532 GtkTreePath *prev_path = NULL;
533 ModestMailOperation *mail_op = NULL;
535 /* Find last selected row */
536 if (MODEST_IS_MAIN_WINDOW (win)) {
537 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
538 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
539 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
540 for (tmp=sel_list; tmp; tmp=tmp->next) {
541 if (tmp->next == NULL) {
542 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
543 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
545 gtk_tree_path_prev (prev_path);
546 gtk_tree_path_next (next_path);
548 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
549 next_row_reference = gtk_tree_row_reference_new (model, next_path);
554 /* Disable window dimming management */
555 modest_window_disable_dimming (MODEST_WINDOW(win));
557 /* Remove each header. If it's a view window header_view == NULL */
558 mail_op = modest_mail_operation_new ((GObject *) win);
559 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
561 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
562 g_object_unref (mail_op);
564 /* Enable window dimming management */
566 gtk_tree_selection_unselect_all (sel);
568 modest_window_enable_dimming (MODEST_WINDOW(win));
570 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
571 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
573 /* Get main window */
574 mgr = modest_runtime_get_window_mgr ();
575 main_window = modest_window_mgr_get_main_window (mgr, FALSE); /* don't create */
576 } else if (MODEST_IS_MAIN_WINDOW (win)) {
577 /* Move cursor to next row */
580 /* Select next or previous row */
581 if (gtk_tree_row_reference_valid (next_row_reference)) {
582 gtk_tree_selection_select_path (sel, next_path);
584 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
585 gtk_tree_selection_select_path (sel, prev_path);
589 if (gtk_tree_row_reference_valid (next_row_reference))
590 gtk_tree_row_reference_free (next_row_reference);
591 if (next_path != NULL)
592 gtk_tree_path_free (next_path);
593 if (gtk_tree_row_reference_valid (prev_row_reference))
594 gtk_tree_row_reference_free (prev_row_reference);
595 if (prev_path != NULL)
596 gtk_tree_path_free (prev_path);
599 /* Update toolbar dimming state */
601 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
602 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
606 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
607 g_list_free (sel_list);
616 g_object_unref (header_list);
624 /* delete either message or folder, based on where we are */
626 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
628 g_return_if_fail (MODEST_IS_WINDOW(win));
630 /* Check first if the header view has the focus */
631 if (MODEST_IS_MAIN_WINDOW (win)) {
633 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
634 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
635 if (gtk_widget_is_focus (w)) {
636 modest_ui_actions_on_delete_folder (action, MODEST_WINDOW(win));
640 modest_ui_actions_on_delete_message (action, win);
644 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
646 ModestWindowMgr *mgr = NULL;
648 #ifdef MODEST_PLATFORM_MAEMO
649 modest_osso_save_state();
650 #endif /* MODEST_PLATFORM_MAEMO */
652 g_debug ("closing down, clearing %d item(s) from operation queue",
653 modest_mail_operation_queue_num_elements
654 (modest_runtime_get_mail_operation_queue()));
656 /* cancel all outstanding operations */
657 modest_mail_operation_queue_cancel_all
658 (modest_runtime_get_mail_operation_queue());
660 g_debug ("queue has been cleared");
663 /* Check if there are opened editing windows */
664 mgr = modest_runtime_get_window_mgr ();
665 modest_window_mgr_close_all_windows (mgr);
667 /* note: when modest-tny-account-store is finalized,
668 it will automatically set all network connections
671 /* gtk_main_quit (); */
675 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
679 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
681 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
682 /* gtk_widget_destroy (GTK_WIDGET (win)); */
683 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
684 /* gboolean ret_value; */
685 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
686 /* } else if (MODEST_IS_WINDOW (win)) { */
687 /* gtk_widget_destroy (GTK_WIDGET (win)); */
689 /* g_return_if_reached (); */
694 modest_ui_actions_add_to_contacts (GtkAction *action, ModestWindow *win)
696 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
698 modest_msg_view_window_add_to_contacts (MODEST_MSG_VIEW_WINDOW (win));
702 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
704 GtkClipboard *clipboard = NULL;
705 gchar *selection = NULL;
707 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
708 selection = gtk_clipboard_wait_for_text (clipboard);
710 /* Question: why is the clipboard being used here?
711 * It doesn't really make a lot of sense. */
715 modest_address_book_add_address (selection);
721 modest_ui_actions_on_new_account (GtkAction *action,
722 ModestWindow *window)
724 if (!modest_ui_actions_run_account_setup_wizard (window)) {
725 g_debug ("%s: wizard was already running", __FUNCTION__);
730 modest_ui_actions_on_accounts (GtkAction *action,
733 /* This is currently only implemented for Maemo */
734 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
735 if (!modest_ui_actions_run_account_setup_wizard (win))
736 g_debug ("%s: wizard was already running", __FUNCTION__);
740 /* Show the list of accounts */
741 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
743 /* The accounts dialog must be modal */
744 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
745 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
750 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
752 /* This is currently only implemented for Maemo,
753 * because it requires an API (libconic) to detect different connection
756 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
758 /* Create the window if necessary: */
759 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
760 modest_connection_specific_smtp_window_fill_with_connections (
761 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
762 modest_runtime_get_account_mgr());
764 /* Show the window: */
765 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
766 GTK_WINDOW (specific_window), (GtkWindow *) win);
767 gtk_widget_show (specific_window);
768 #endif /* !MODEST_TOOLKIT_GTK */
772 modest_ui_actions_compose_msg(ModestWindow *win,
775 const gchar *bcc_str,
776 const gchar *subject_str,
777 const gchar *body_str,
779 gboolean set_as_modified)
781 gchar *account_name = NULL;
782 const gchar *mailbox;
784 TnyAccount *account = NULL;
785 TnyFolder *folder = NULL;
786 gchar *from_str = NULL, *signature = NULL, *body = NULL;
787 gchar *recipient = NULL;
788 gboolean use_signature = FALSE;
789 ModestWindow *msg_win = NULL;
790 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
791 ModestTnyAccountStore *store = modest_runtime_get_account_store();
792 GnomeVFSFileSize total_size, allowed_size;
794 /* we check for low-mem */
795 if (modest_platform_check_memory_low (win, TRUE))
798 #ifdef MODEST_TOOLKIT_HILDON2
800 account_name = g_strdup (modest_window_get_active_account(win));
803 account_name = modest_account_mgr_get_default_account(mgr);
806 g_printerr ("modest: no account found\n");
811 mailbox = modest_window_get_active_mailbox (win);
814 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
816 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
819 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
821 g_printerr ("modest: failed to find Drafts folder\n");
824 from_str = modest_account_mgr_get_from_string (mgr, account_name, mailbox);
826 g_printerr ("modest: failed get from string for '%s'\n", account_name);
830 recipient = modest_text_utils_get_email_address (from_str);
831 signature = modest_account_mgr_get_signature_from_recipient (mgr, recipient, &use_signature);
833 if (body_str != NULL) {
834 body = use_signature ? g_strconcat(body_str, "\n--\n", signature, NULL) : g_strdup(body_str);
836 body = use_signature ? g_strconcat("\n--\n", signature, NULL) : g_strdup("");
839 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, NULL, NULL, body, NULL, NULL, NULL);
841 g_printerr ("modest: failed to create new msg\n");
845 /* Create and register edit window */
846 /* This is destroyed by TODO. */
848 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
849 msg_win = modest_msg_edit_window_new (msg, account_name, mailbox, FALSE);
851 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, win)) {
852 gtk_widget_destroy (GTK_WIDGET (msg_win));
855 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
856 gtk_widget_show_all (GTK_WIDGET (msg_win));
858 while (attachments) {
860 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
861 attachments->data, allowed_size);
863 if (total_size > allowed_size) {
864 g_warning ("%s: total size: %u",
865 __FUNCTION__, (unsigned int)total_size);
868 allowed_size -= total_size;
870 attachments = g_slist_next(attachments);
877 g_free (account_name);
879 g_object_unref (G_OBJECT(account));
881 g_object_unref (G_OBJECT(folder));
883 g_object_unref (G_OBJECT(msg));
887 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
889 /* if there are no accounts yet, just show the wizard */
890 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
891 if (!modest_ui_actions_run_account_setup_wizard (win))
894 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
899 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
903 ModestMailOperationStatus status;
905 /* If there is no message or the operation was not successful */
906 status = modest_mail_operation_get_status (mail_op);
907 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
910 /* If it's a memory low issue, then show a banner */
911 error = modest_mail_operation_get_error (mail_op);
912 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
913 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
914 GObject *source = modest_mail_operation_get_source (mail_op);
915 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
916 _KR("memr_ib_operation_disabled"),
918 g_object_unref (source);
921 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
922 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
923 gchar *subject, *msg, *format = NULL;
925 subject = tny_header_dup_subject (header);
927 subject = g_strdup (_("mail_va_no_subject"));
929 account = modest_mail_operation_get_account (mail_op);
931 ModestProtocol *protocol;
932 ModestProtocolType proto;
933 proto = modest_tny_account_get_protocol_type (account);
934 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), proto);
936 format = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
937 g_object_unref (account);
941 format = g_strdup (_("emev_ni_ui_imap_message_not_available_in_server"));
943 msg = g_strdup_printf (format, subject);
944 modest_platform_run_information_dialog (NULL, msg, FALSE);
950 /* Remove the header from the preregistered uids */
951 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
969 OpenMsgBannerInfo *banner_info;
970 GtkTreeRowReference *rowref;
974 open_msg_banner_idle (gpointer userdata)
976 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
978 gdk_threads_enter ();
979 banner_info->idle_handler = 0;
980 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
981 if (banner_info->banner)
982 g_object_ref (banner_info->banner);
984 gdk_threads_leave ();
990 get_header_view_from_window (ModestWindow *window)
992 GtkWidget *header_view;
994 if (MODEST_IS_MAIN_WINDOW (window)) {
995 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
996 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
997 #ifdef MODEST_TOOLKIT_HILDON2
998 } else if (MODEST_IS_HEADER_WINDOW (window)){
999 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
1009 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
1012 gchar *account = NULL;
1013 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
1018 folder = tny_header_get_folder (header);
1019 /* Gets folder type (OUTBOX headers will be opened in edit window */
1020 if (modest_tny_folder_is_local_folder (folder)) {
1021 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1022 if (folder_type == TNY_FOLDER_TYPE_INVALID)
1023 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
1026 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
1027 TnyTransportAccount *traccount = NULL;
1028 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
1029 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
1031 ModestTnySendQueue *send_queue = NULL;
1032 ModestTnySendQueueStatus status;
1034 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
1035 TNY_ACCOUNT(traccount)));
1036 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
1037 if (TNY_IS_SEND_QUEUE (send_queue)) {
1038 msg_id = modest_tny_send_queue_get_msg_id (header);
1039 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
1041 /* Only open messages in outbox with the editor if they are in Failed state */
1042 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
1045 #ifdef MODEST_TOOLKIT_HILDON2
1047 /* In Fremantle we can not
1048 open any message from
1049 outbox which is not in
1055 g_object_unref(traccount);
1057 g_warning("Cannot get transport account for message in outbox!!");
1059 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
1060 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
1064 TnyAccount *acc = tny_folder_get_account (folder);
1067 g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (acc));
1068 g_object_unref (acc);
1072 g_object_unref (folder);
1078 open_msg_cb (ModestMailOperation *mail_op,
1085 ModestWindowMgr *mgr = NULL;
1086 ModestWindow *parent_win = NULL;
1087 ModestWindow *win = NULL;
1088 gchar *account = NULL;
1089 gboolean open_in_editor = FALSE;
1091 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1093 /* Do nothing if there was any problem with the mail
1094 operation. The error will be shown by the error_handler of
1095 the mail operation */
1096 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1099 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1101 /* Mark header as read */
1102 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1104 account = get_info_from_header (header, &open_in_editor, &can_open);
1108 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1110 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1112 if (open_in_editor) {
1113 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1114 gchar *from_header = NULL, *acc_name;
1115 gchar *mailbox = NULL;
1117 from_header = tny_header_dup_from (header);
1119 /* we cannot edit without a valid account... */
1120 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1121 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1122 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1124 g_free (from_header);
1129 acc_name = modest_utils_get_account_name_from_recipient (from_header, &mailbox);
1130 g_free (from_header);
1136 win = modest_msg_edit_window_new (msg, account, mailbox, TRUE);
1140 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1141 const gchar *mailbox = NULL;
1143 if (parent_win && MODEST_IS_WINDOW (parent_win))
1144 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_win));
1146 if (helper->rowref && helper->model) {
1147 win = modest_msg_view_window_new_with_header_model (msg, account, mailbox, (const gchar*) uid,
1148 helper->model, helper->rowref);
1150 win = modest_msg_view_window_new_for_attachment (msg, account, mailbox, (const gchar*) uid);
1155 /* Register and show new window */
1157 mgr = modest_runtime_get_window_mgr ();
1158 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1159 gtk_widget_destroy (GTK_WIDGET (win));
1162 gtk_widget_show_all (GTK_WIDGET(win));
1165 /* Update toolbar dimming state */
1166 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1167 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1173 g_object_unref (parent_win);
1177 is_memory_full_error (GError *error, ModestMailOperation *mail_op)
1179 gboolean enough_free_space = TRUE;
1180 GnomeVFSURI *cache_dir_uri;
1181 const gchar *cache_dir = NULL;
1182 GnomeVFSFileSize free_space;
1183 TnyAccountStore *acc_store;
1185 acc_store = TNY_ACCOUNT_STORE (modest_runtime_get_account_store ());
1187 /* Cache dir is different in case we're using an external storage (like MMC account) */
1189 TnyAccount *account = modest_mail_operation_get_account (mail_op);
1191 if (modest_tny_account_is_memory_card_account (account)) {
1192 cache_dir = g_getenv (MODEST_MMC1_VOLUMEPATH_ENV);
1194 g_object_unref (account);
1198 /* Get the default local cache dir */
1200 cache_dir = tny_account_store_get_cache_dir (acc_store);
1202 cache_dir_uri = gnome_vfs_uri_new (cache_dir);
1203 if (cache_dir_uri) {
1204 if (gnome_vfs_get_volume_free_space (cache_dir_uri, &free_space) == GNOME_VFS_OK) {
1205 if (free_space < MIN_FREE_SPACE)
1206 enough_free_space = FALSE;
1208 gnome_vfs_uri_unref (cache_dir_uri);
1211 if ((error->code == TNY_SYSTEM_ERROR_MEMORY ||
1212 /* When asking for a mail and no space left on device
1213 tinymail returns this error */
1214 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE ||
1215 /* When the folder summary could not be read or
1217 error->code == TNY_IO_ERROR_WRITE ||
1218 error->code == TNY_IO_ERROR_READ) &&
1219 !enough_free_space) {
1227 check_memory_full_error (GtkWidget *parent_window, GError *err)
1232 if (is_memory_full_error (err, NULL)) {
1233 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
1234 modest_platform_information_banner (parent_window, NULL, msg);
1236 } else if (err->code == TNY_SYSTEM_ERROR_MEMORY)
1237 /* If the account was created in memory full
1238 conditions then tinymail won't be able to
1239 connect so it'll return this error code */
1240 modest_platform_information_banner (parent_window,
1241 NULL, _("emev_ui_imap_inbox_select_error"));
1249 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1252 const GError *error;
1253 GObject *win = NULL;
1254 ModestMailOperationStatus status;
1256 win = modest_mail_operation_get_source (mail_op);
1257 error = modest_mail_operation_get_error (mail_op);
1258 status = modest_mail_operation_get_status (mail_op);
1260 /* If the mail op has been cancelled then it's not an error:
1261 don't show any message */
1262 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1263 if (is_memory_full_error ((GError *) error, mail_op)) {
1264 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
1265 modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
1267 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1268 modest_platform_information_banner ((GtkWidget *) win,
1269 NULL, _("emev_ui_imap_inbox_select_error"));
1270 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1271 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1272 modest_platform_information_banner ((GtkWidget *) win,
1273 NULL, _CS ("sfil_ni_unable_to_open_file_not_found"));
1274 } else if (user_data) {
1275 modest_platform_information_banner ((GtkWidget *) win,
1281 g_object_unref (win);
1285 * Returns the account a list of headers belongs to. It returns a
1286 * *new* reference so don't forget to unref it
1289 get_account_from_header_list (TnyList *headers)
1291 TnyAccount *account = NULL;
1293 if (tny_list_get_length (headers) > 0) {
1294 TnyIterator *iter = tny_list_create_iterator (headers);
1295 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1296 TnyFolder *folder = tny_header_get_folder (header);
1299 g_object_unref (header);
1301 while (!tny_iterator_is_done (iter)) {
1302 header = TNY_HEADER (tny_iterator_get_current (iter));
1303 folder = tny_header_get_folder (header);
1306 g_object_unref (header);
1308 tny_iterator_next (iter);
1313 account = tny_folder_get_account (folder);
1314 g_object_unref (folder);
1318 g_object_unref (header);
1320 g_object_unref (iter);
1326 get_account_from_header (TnyHeader *header)
1328 TnyAccount *account = NULL;
1331 folder = tny_header_get_folder (header);
1334 account = tny_folder_get_account (folder);
1335 g_object_unref (folder);
1341 open_msg_helper_destroyer (gpointer user_data)
1343 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1345 if (helper->banner_info) {
1346 g_free (helper->banner_info->message);
1347 if (helper->banner_info->idle_handler > 0) {
1348 g_source_remove (helper->banner_info->idle_handler);
1349 helper->banner_info->idle_handler = 0;
1351 if (helper->banner_info->banner != NULL) {
1352 gtk_widget_destroy (helper->banner_info->banner);
1353 g_object_unref (helper->banner_info->banner);
1354 helper->banner_info->banner = NULL;
1356 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1357 helper->banner_info = NULL;
1359 g_object_unref (helper->model);
1360 g_object_unref (helper->header);
1361 gtk_tree_row_reference_free (helper->rowref);
1362 g_slice_free (OpenMsgHelper, helper);
1366 open_msg_performer(gboolean canceled,
1368 GtkWindow *parent_window,
1369 TnyAccount *account,
1372 ModestMailOperation *mail_op = NULL;
1373 gchar *error_msg = NULL;
1374 ModestProtocolType proto;
1375 TnyConnectionStatus status;
1376 OpenMsgHelper *helper = NULL;
1377 ModestProtocol *protocol;
1378 ModestProtocolRegistry *protocol_registry;
1381 helper = (OpenMsgHelper *) user_data;
1383 status = tny_account_get_connection_status (account);
1384 if (err || canceled) {
1385 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1386 /* Free the helper */
1387 open_msg_helper_destroyer (helper);
1389 /* In memory full conditions we could get this error here */
1390 check_memory_full_error ((GtkWidget *) parent_window, err);
1395 /* Get the error message depending on the protocol */
1396 proto = modest_tny_account_get_protocol_type (account);
1397 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1398 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1401 protocol_registry = modest_runtime_get_protocol_registry ();
1402 subject = tny_header_dup_subject (helper->header);
1404 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1405 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1409 if (error_msg == NULL) {
1410 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1413 #ifndef MODEST_TOOLKIT_HILDON2
1414 gboolean show_open_draft = FALSE;
1415 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1417 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1419 TnyFolderType folder_type;
1421 folder = tny_header_get_folder (helper->header);
1422 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1423 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1424 g_object_unref (folder);
1428 #ifdef MODEST_TOOLKIT_HILDON2
1431 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1434 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1435 g_free (account_name);
1436 open_msg_helper_destroyer (helper);
1441 ModestWindow *window;
1442 GtkWidget *header_view;
1445 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1446 uid = modest_tny_folder_get_header_unique_id (helper->header);
1448 const gchar *mailbox = NULL;
1449 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_window));
1450 window = modest_msg_view_window_new_from_header_view
1451 (MODEST_HEADER_VIEW (header_view), account_name, mailbox, uid, helper->rowref);
1452 if (window != NULL) {
1453 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1455 gtk_widget_destroy (GTK_WIDGET (window));
1457 gtk_widget_show_all (GTK_WIDGET(window));
1461 g_free (account_name);
1463 open_msg_helper_destroyer (helper);
1466 g_free (account_name);
1468 /* Create the mail operation */
1470 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1471 modest_ui_actions_disk_operations_error_handler,
1472 g_strdup (error_msg), g_free);
1473 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1477 #ifndef MODEST_TOOLKIT_HILDON2
1478 if (show_open_draft) {
1479 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1480 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1481 helper->banner_info->banner = NULL;
1482 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1483 helper->banner_info);
1489 headers = TNY_LIST (tny_simple_list_new ());
1490 tny_list_prepend (headers, G_OBJECT (helper->header));
1491 modest_mail_operation_get_msgs_full (mail_op,
1495 open_msg_helper_destroyer);
1496 g_object_unref (headers);
1503 g_object_unref (mail_op);
1504 g_object_unref (account);
1508 * This function is used by both modest_ui_actions_on_open and
1509 * modest_ui_actions_on_header_activated. This way we always do the
1510 * same when trying to open messages.
1513 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1515 ModestWindowMgr *mgr = NULL;
1516 TnyAccount *account;
1517 gboolean cached = FALSE;
1519 GtkWidget *header_view = NULL;
1520 OpenMsgHelper *helper;
1521 ModestWindow *window;
1523 g_return_if_fail (header != NULL && rowref != NULL);
1525 mgr = modest_runtime_get_window_mgr ();
1528 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1529 if (header_view == NULL)
1532 /* Get the account */
1533 account = get_account_from_header (header);
1538 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1540 /* Do not open again the message and present the
1541 window to the user */
1544 #ifndef MODEST_TOOLKIT_HILDON2
1545 gtk_window_present (GTK_WINDOW (window));
1548 /* the header has been registered already, we don't do
1549 * anything but wait for the window to come up*/
1550 g_debug ("header %p already registered, waiting for window", header);
1555 /* Open each message */
1556 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1558 /* Allways download if we are online. */
1559 if (!tny_device_is_online (modest_runtime_get_device ())) {
1562 /* If ask for user permission to download the messages */
1563 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1564 _("mcen_nc_get_msg"));
1566 /* End if the user does not want to continue */
1567 if (response == GTK_RESPONSE_CANCEL) {
1573 /* We register the window for opening */
1574 modest_window_mgr_register_header (mgr, header, NULL);
1576 /* Create the helper. We need to get a reference to the model
1577 here because it could change while the message is readed
1578 (the user could switch between folders) */
1579 helper = g_slice_new (OpenMsgHelper);
1580 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1581 helper->header = g_object_ref (header);
1582 helper->rowref = gtk_tree_row_reference_copy (rowref);
1583 helper->banner_info = NULL;
1585 /* Connect to the account and perform */
1587 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1588 open_msg_performer, helper);
1590 /* Call directly the performer, do not need to connect */
1591 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1592 g_object_ref (account), helper);
1597 g_object_unref (account);
1601 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1608 /* we check for low-mem; in that case, show a warning, and don't allow
1611 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1615 headers = get_selected_headers (win);
1619 headers_count = tny_list_get_length (headers);
1620 if (headers_count != 1) {
1621 if (headers_count > 1) {
1622 /* Don't allow activation if there are more than one message selected */
1623 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1626 g_object_unref (headers);
1630 iter = tny_list_create_iterator (headers);
1631 header = TNY_HEADER (tny_iterator_get_current (iter));
1632 g_object_unref (iter);
1636 open_msg_from_header (header, NULL, win);
1637 g_object_unref (header);
1640 g_object_unref(headers);
1644 rf_helper_window_closed (gpointer data,
1647 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1649 helper->parent_window = NULL;
1652 static ReplyForwardHelper*
1653 create_reply_forward_helper (ReplyForwardAction action,
1655 guint reply_forward_type,
1658 ReplyForwardHelper *rf_helper = NULL;
1659 const gchar *active_acc = modest_window_get_active_account (win);
1660 const gchar *active_mailbox = modest_window_get_active_mailbox (win);
1662 rf_helper = g_slice_new0 (ReplyForwardHelper);
1663 rf_helper->reply_forward_type = reply_forward_type;
1664 rf_helper->action = action;
1665 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1666 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1667 rf_helper->account_name = (active_acc) ?
1668 g_strdup (active_acc) :
1669 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1670 rf_helper->mailbox = g_strdup (active_mailbox);
1672 /* Note that window could be destroyed just AFTER calling
1673 register_window so we must ensure that this pointer does
1674 not hold invalid references */
1675 if (rf_helper->parent_window)
1676 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1677 rf_helper_window_closed, rf_helper);
1683 free_reply_forward_helper (gpointer data)
1685 ReplyForwardHelper *helper;
1687 helper = (ReplyForwardHelper *) data;
1688 g_free (helper->account_name);
1689 g_free (helper->mailbox);
1691 g_object_unref (helper->header);
1692 if (helper->parent_window)
1693 g_object_weak_unref (G_OBJECT (helper->parent_window),
1694 rf_helper_window_closed, helper);
1695 g_slice_free (ReplyForwardHelper, helper);
1699 reply_forward_cb (ModestMailOperation *mail_op,
1706 TnyMsg *new_msg = NULL;
1707 ReplyForwardHelper *rf_helper;
1708 ModestWindow *msg_win = NULL;
1709 ModestEditType edit_type;
1711 TnyAccount *account = NULL;
1712 ModestWindowMgr *mgr = NULL;
1713 gchar *signature = NULL;
1714 gboolean use_signature;
1717 /* If there was any error. The mail operation could be NULL,
1718 this means that we already have the message downloaded and
1719 that we didn't do a mail operation to retrieve it */
1720 rf_helper = (ReplyForwardHelper *) user_data;
1721 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1724 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1725 rf_helper->account_name, rf_helper->mailbox);
1726 recipient = modest_text_utils_get_email_address (from);
1727 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr(),
1732 /* Create reply mail */
1733 switch (rf_helper->action) {
1736 modest_tny_msg_create_reply_msg (msg, header, from,
1737 (use_signature) ? signature : NULL,
1738 rf_helper->reply_forward_type,
1739 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1741 case ACTION_REPLY_TO_ALL:
1743 modest_tny_msg_create_reply_msg (msg, header, from,
1744 (use_signature) ? signature : NULL,
1745 rf_helper->reply_forward_type,
1746 MODEST_TNY_MSG_REPLY_MODE_ALL);
1747 edit_type = MODEST_EDIT_TYPE_REPLY;
1749 case ACTION_FORWARD:
1751 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1752 rf_helper->reply_forward_type);
1753 edit_type = MODEST_EDIT_TYPE_FORWARD;
1756 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1758 g_return_if_reached ();
1766 g_warning ("%s: failed to create message\n", __FUNCTION__);
1770 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1771 rf_helper->account_name,
1772 TNY_ACCOUNT_TYPE_STORE);
1774 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1778 /* Create and register the windows */
1779 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, rf_helper->mailbox, FALSE);
1780 mgr = modest_runtime_get_window_mgr ();
1781 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1783 /* Note that register_window could have deleted the account */
1784 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1785 gdouble parent_zoom;
1787 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1788 modest_window_set_zoom (msg_win, parent_zoom);
1791 /* Show edit window */
1792 gtk_widget_show_all (GTK_WIDGET (msg_win));
1795 /* We always unregister the header because the message is
1796 forwarded or replied so the original one is no longer
1798 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1801 g_object_unref (G_OBJECT (new_msg));
1803 g_object_unref (G_OBJECT (account));
1804 free_reply_forward_helper (rf_helper);
1807 /* Checks a list of headers. If any of them are not currently
1808 * downloaded (CACHED) then returns TRUE else returns FALSE.
1811 header_list_count_uncached_msgs (TnyList *header_list)
1814 gint uncached_messages = 0;
1816 iter = tny_list_create_iterator (header_list);
1817 while (!tny_iterator_is_done (iter)) {
1820 header = TNY_HEADER (tny_iterator_get_current (iter));
1822 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1823 uncached_messages ++;
1824 g_object_unref (header);
1827 tny_iterator_next (iter);
1829 g_object_unref (iter);
1831 return uncached_messages;
1834 /* Returns FALSE if the user does not want to download the
1835 * messages. Returns TRUE if the user allowed the download.
1838 connect_to_get_msg (ModestWindow *win,
1839 gint num_of_uncached_msgs,
1840 TnyAccount *account)
1842 GtkResponseType response;
1844 /* Allways download if we are online. */
1845 if (tny_device_is_online (modest_runtime_get_device ()))
1848 /* If offline, then ask for user permission to download the messages */
1849 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1850 ngettext("mcen_nc_get_msg",
1852 num_of_uncached_msgs));
1854 if (response == GTK_RESPONSE_CANCEL)
1857 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1861 reply_forward_performer (gboolean canceled,
1863 GtkWindow *parent_window,
1864 TnyAccount *account,
1867 ReplyForwardHelper *rf_helper = NULL;
1868 ModestMailOperation *mail_op;
1870 rf_helper = (ReplyForwardHelper *) user_data;
1872 if (canceled || err) {
1873 free_reply_forward_helper (rf_helper);
1877 /* Retrieve the message */
1878 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1879 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1880 modest_ui_actions_disk_operations_error_handler,
1882 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1883 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1886 g_object_unref(mail_op);
1890 * Common code for the reply and forward actions
1893 reply_forward (ReplyForwardAction action, ModestWindow *win)
1895 ReplyForwardHelper *rf_helper = NULL;
1896 guint reply_forward_type;
1898 g_return_if_fail (MODEST_IS_WINDOW(win));
1900 /* we check for low-mem; in that case, show a warning, and don't allow
1901 * reply/forward (because it could potentially require a lot of memory */
1902 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1906 /* we need an account when editing */
1907 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1908 if (!modest_ui_actions_run_account_setup_wizard (win))
1912 reply_forward_type =
1913 modest_conf_get_int (modest_runtime_get_conf (),
1914 (action == ACTION_FORWARD) ?
1915 MODEST_CONF_FORWARD_TYPE :
1916 MODEST_CONF_REPLY_TYPE,
1919 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1921 TnyHeader *header = NULL;
1922 /* Get header and message. Do not free them here, the
1923 reply_forward_cb must do it */
1924 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1925 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1927 if (msg && header) {
1929 rf_helper = create_reply_forward_helper (action, win,
1930 reply_forward_type, header);
1931 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1933 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1937 g_object_unref (msg);
1939 g_object_unref (header);
1941 TnyHeader *header = NULL;
1943 gboolean do_retrieve = TRUE;
1944 TnyList *header_list = NULL;
1946 header_list = get_selected_headers (win);
1949 /* Check that only one message is selected for replying */
1950 if (tny_list_get_length (header_list) != 1) {
1951 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1952 NULL, _("mcen_ib_select_one_message"));
1953 g_object_unref (header_list);
1957 /* Only reply/forward to one message */
1958 iter = tny_list_create_iterator (header_list);
1959 header = TNY_HEADER (tny_iterator_get_current (iter));
1960 g_object_unref (iter);
1962 /* Retrieve messages */
1963 do_retrieve = (action == ACTION_FORWARD) ||
1964 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1967 TnyAccount *account = NULL;
1968 TnyFolder *folder = NULL;
1969 gdouble download = TRUE;
1970 guint uncached_msgs = 0;
1972 folder = tny_header_get_folder (header);
1974 goto do_retrieve_frees;
1975 account = tny_folder_get_account (folder);
1977 goto do_retrieve_frees;
1979 uncached_msgs = header_list_count_uncached_msgs (header_list);
1981 if (uncached_msgs > 0) {
1982 /* Allways download if we are online. */
1983 if (!tny_device_is_online (modest_runtime_get_device ())) {
1986 /* If ask for user permission to download the messages */
1987 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1988 ngettext("mcen_nc_get_msg",
1992 /* End if the user does not want to continue */
1993 if (response == GTK_RESPONSE_CANCEL)
2000 rf_helper = create_reply_forward_helper (action, win,
2001 reply_forward_type, header);
2002 if (uncached_msgs > 0) {
2003 modest_platform_connect_and_perform (GTK_WINDOW (win),
2005 reply_forward_performer,
2008 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
2009 account, rf_helper);
2014 g_object_unref (account);
2016 g_object_unref (folder);
2018 reply_forward_cb (NULL, header, FALSE, NULL, NULL, rf_helper);
2021 g_object_unref (header_list);
2022 g_object_unref (header);
2027 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
2029 g_return_if_fail (MODEST_IS_WINDOW(win));
2031 reply_forward (ACTION_REPLY, win);
2035 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
2037 g_return_if_fail (MODEST_IS_WINDOW(win));
2039 reply_forward (ACTION_FORWARD, win);
2043 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
2045 g_return_if_fail (MODEST_IS_WINDOW(win));
2047 reply_forward (ACTION_REPLY_TO_ALL, win);
2051 modest_ui_actions_on_next (GtkAction *action,
2052 ModestWindow *window)
2054 if (MODEST_IS_MAIN_WINDOW (window)) {
2055 GtkWidget *header_view;
2057 header_view = modest_main_window_get_child_widget (
2058 MODEST_MAIN_WINDOW(window),
2059 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2063 modest_header_view_select_next (
2064 MODEST_HEADER_VIEW(header_view));
2065 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2066 modest_msg_view_window_select_next_message (
2067 MODEST_MSG_VIEW_WINDOW (window));
2069 g_return_if_reached ();
2074 modest_ui_actions_on_prev (GtkAction *action,
2075 ModestWindow *window)
2077 g_return_if_fail (MODEST_IS_WINDOW(window));
2079 if (MODEST_IS_MAIN_WINDOW (window)) {
2080 GtkWidget *header_view;
2081 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2082 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2086 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
2087 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2088 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
2090 g_return_if_reached ();
2095 modest_ui_actions_on_sort (GtkAction *action,
2096 ModestWindow *window)
2098 GtkWidget *header_view = NULL;
2100 g_return_if_fail (MODEST_IS_WINDOW(window));
2102 if (MODEST_IS_MAIN_WINDOW (window)) {
2103 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2104 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2105 #ifdef MODEST_TOOLKIT_HILDON2
2106 } else if (MODEST_IS_HEADER_WINDOW (window)) {
2107 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2112 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
2117 /* Show sorting dialog */
2118 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
2122 new_messages_arrived (ModestMailOperation *self,
2123 TnyList *new_headers,
2127 gboolean show_visual_notifications;
2129 source = modest_mail_operation_get_source (self);
2130 show_visual_notifications = (source) ? FALSE : TRUE;
2132 g_object_unref (source);
2134 /* Notify new messages have been downloaded. If the
2135 send&receive was invoked by the user then do not show any
2136 visual notification, only play a sound and activate the LED
2137 (for the Maemo version) */
2138 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0) {
2140 /* We only notify about really new messages (not seen) we get */
2141 TnyList *actually_new_list;
2142 TnyIterator *iterator;
2143 actually_new_list = TNY_LIST (tny_simple_list_new ());
2144 for (iterator = tny_list_create_iterator (new_headers);
2145 !tny_iterator_is_done (iterator);
2146 tny_iterator_next (iterator)) {
2148 TnyHeaderFlags flags;
2149 header = TNY_HEADER (tny_iterator_get_current (iterator));
2150 flags = tny_header_get_flags (header);
2152 if (!(flags & TNY_HEADER_FLAG_SEEN)) {
2153 tny_list_append (actually_new_list, G_OBJECT (header));
2155 g_object_unref (header);
2158 g_object_unref (iterator);
2160 if (tny_list_get_length (actually_new_list) > 0) {
2161 modest_platform_on_new_headers_received (actually_new_list,
2162 show_visual_notifications);
2164 g_object_unref (actually_new_list);
2170 retrieve_all_messages_cb (GObject *source,
2172 guint retrieve_limit)
2178 window = GTK_WINDOW (source);
2179 msg = g_strdup_printf (_("mail_nc_msg_count_limit_exceeded"),
2180 num_msgs, retrieve_limit);
2182 /* Ask the user if they want to retrieve all the messages */
2184 modest_platform_run_confirmation_dialog_with_buttons (window, msg,
2185 _("mcen_bd_get_all"),
2186 _("mcen_bd_newest_only"));
2187 /* Free and return */
2189 return (response == GTK_RESPONSE_ACCEPT) ? TRUE : FALSE;
2193 TnyAccount *account;
2195 gchar *account_name;
2196 gboolean poke_status;
2197 gboolean interactive;
2198 ModestMailOperation *mail_op;
2202 do_send_receive_performer (gboolean canceled,
2204 GtkWindow *parent_window,
2205 TnyAccount *account,
2208 SendReceiveInfo *info;
2210 info = (SendReceiveInfo *) user_data;
2212 if (err || canceled) {
2213 /* In memory full conditions we could get this error here */
2214 check_memory_full_error ((GtkWidget *) parent_window, err);
2216 if (info->mail_op) {
2217 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2223 /* Set send/receive operation in progress */
2224 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2225 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2228 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2229 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2230 G_CALLBACK (on_send_receive_finished),
2233 /* Send & receive. */
2234 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2235 (info->win) ? retrieve_all_messages_cb : NULL,
2236 new_messages_arrived, info->win);
2241 g_object_unref (G_OBJECT (info->mail_op));
2242 if (info->account_name)
2243 g_free (info->account_name);
2245 g_object_unref (info->win);
2247 g_object_unref (info->account);
2248 g_slice_free (SendReceiveInfo, info);
2252 * This function performs the send & receive required actions. The
2253 * window is used to create the mail operation. Typically it should
2254 * always be the main window, but we pass it as argument in order to
2258 modest_ui_actions_do_send_receive (const gchar *account_name,
2259 gboolean force_connection,
2260 gboolean poke_status,
2261 gboolean interactive,
2264 gchar *acc_name = NULL;
2265 SendReceiveInfo *info;
2266 ModestTnyAccountStore *acc_store;
2268 /* If no account name was provided then get the current account, and if
2269 there is no current account then pick the default one: */
2270 if (!account_name) {
2272 acc_name = g_strdup (modest_window_get_active_account (win));
2274 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2276 g_printerr ("modest: cannot get default account\n");
2280 acc_name = g_strdup (account_name);
2283 acc_store = modest_runtime_get_account_store ();
2285 /* Create the info for the connect and perform */
2286 info = g_slice_new (SendReceiveInfo);
2287 info->account_name = acc_name;
2288 info->win = (win) ? g_object_ref (win) : NULL;
2289 info->poke_status = poke_status;
2290 info->interactive = interactive;
2291 info->account = modest_tny_account_store_get_server_account (acc_store, acc_name,
2292 TNY_ACCOUNT_TYPE_STORE);
2293 /* We need to create the operation here, because otherwise it
2294 could happen that the queue emits the queue-empty signal
2295 while we're trying to connect the account */
2296 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2297 modest_ui_actions_disk_operations_error_handler,
2299 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2301 /* Invoke the connect and perform */
2302 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2303 force_connection, info->account,
2304 do_send_receive_performer, info);
2309 modest_ui_actions_do_cancel_send (const gchar *account_name,
2312 TnyTransportAccount *transport_account;
2313 TnySendQueue *send_queue = NULL;
2314 GError *error = NULL;
2316 /* Get transport account */
2318 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2319 (modest_runtime_get_account_store(),
2321 TNY_ACCOUNT_TYPE_TRANSPORT));
2322 if (!transport_account) {
2323 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2328 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2329 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2330 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2331 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2332 "modest: could not find send queue for account\n");
2334 /* Cancel the current send */
2335 tny_account_cancel (TNY_ACCOUNT (transport_account));
2337 /* Suspend all pending messages */
2338 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2342 if (transport_account != NULL)
2343 g_object_unref (G_OBJECT (transport_account));
2347 modest_ui_actions_cancel_send_all (ModestWindow *win)
2349 GSList *account_names, *iter;
2351 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2354 iter = account_names;
2356 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2357 iter = g_slist_next (iter);
2360 modest_account_mgr_free_account_names (account_names);
2361 account_names = NULL;
2365 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2368 /* Check if accounts exist */
2369 gboolean accounts_exist =
2370 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2372 /* If not, allow the user to create an account before trying to send/receive. */
2373 if (!accounts_exist)
2374 modest_ui_actions_on_accounts (NULL, win);
2376 /* Cancel all sending operaitons */
2377 modest_ui_actions_cancel_send_all (win);
2381 * Refreshes all accounts. This function will be used by automatic
2385 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2386 gboolean force_connection,
2387 gboolean poke_status,
2388 gboolean interactive)
2390 GSList *account_names, *iter;
2392 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2395 iter = account_names;
2397 modest_ui_actions_do_send_receive ((const char*) iter->data,
2399 poke_status, interactive, win);
2400 iter = g_slist_next (iter);
2403 modest_account_mgr_free_account_names (account_names);
2404 account_names = NULL;
2408 * Handler of the click on Send&Receive button in the main toolbar
2411 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2413 /* Check if accounts exist */
2414 gboolean accounts_exist;
2417 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2419 /* If not, allow the user to create an account before trying to send/receive. */
2420 if (!accounts_exist)
2421 modest_ui_actions_on_accounts (NULL, win);
2423 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2424 if (MODEST_IS_MAIN_WINDOW (win)) {
2425 GtkWidget *folder_view;
2426 TnyFolderStore *folder_store;
2429 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2430 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2434 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2437 g_object_unref (folder_store);
2438 /* Refresh the active account. Force the connection if needed
2439 and poke the status of all folders */
2440 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2441 #ifdef MODEST_TOOLKIT_HILDON2
2442 } else if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2443 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2446 const gchar *active_account;
2447 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2449 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2456 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2459 GtkWidget *header_view;
2461 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2463 header_view = modest_main_window_get_child_widget (main_window,
2464 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2468 conf = modest_runtime_get_conf ();
2470 /* what is saved/restored is depending on the style; thus; we save with
2471 * old style, then update the style, and restore for this new style
2473 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2475 if (modest_header_view_get_style
2476 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2477 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2478 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2480 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2481 MODEST_HEADER_VIEW_STYLE_DETAILS);
2483 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2484 MODEST_CONF_HEADER_VIEW_KEY);
2489 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2491 ModestMainWindow *main_window)
2493 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2494 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2496 /* in the case the folder is empty, show the empty folder message and focus
2498 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2499 if (modest_header_view_is_empty (header_view)) {
2500 TnyFolder *folder = modest_header_view_get_folder (header_view);
2501 GtkWidget *folder_view =
2502 modest_main_window_get_child_widget (main_window,
2503 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2504 if (folder != NULL) {
2505 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2506 g_object_unref (folder);
2508 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2512 /* If no header has been selected then exit */
2517 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2518 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2520 /* Update toolbar dimming state */
2521 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2522 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2526 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2529 ModestWindow *window)
2531 GtkWidget *open_widget;
2532 GtkTreeRowReference *rowref;
2534 g_return_if_fail (MODEST_IS_WINDOW(window));
2535 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2536 g_return_if_fail (TNY_IS_HEADER (header));
2538 if (modest_header_view_count_selected_headers (header_view) > 1) {
2539 /* Don't allow activation if there are more than one message selected */
2540 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2544 /* we check for low-mem; in that case, show a warning, and don't allow
2545 * activating headers
2547 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2550 if (MODEST_IS_MAIN_WINDOW (window)) {
2551 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2552 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2553 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2557 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2558 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2559 gtk_tree_row_reference_free (rowref);
2563 set_active_account_from_tny_account (TnyAccount *account,
2564 ModestWindow *window)
2566 const gchar *server_acc_name = tny_account_get_id (account);
2568 /* We need the TnyAccount provided by the
2569 account store because that is the one that
2570 knows the name of the Modest account */
2571 TnyAccount *modest_server_account =
2572 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2573 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2575 if (!modest_server_account) {
2576 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2580 /* Update active account, but only if it's not a pseudo-account */
2581 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2582 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2583 const gchar *modest_acc_name =
2584 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2585 if (modest_acc_name)
2586 modest_window_set_active_account (window, modest_acc_name);
2589 g_object_unref (modest_server_account);
2594 folder_refreshed_cb (ModestMailOperation *mail_op,
2598 ModestMainWindow *win = NULL;
2599 GtkWidget *folder_view, *header_view;
2600 const GError *error;
2602 g_return_if_fail (TNY_IS_FOLDER (folder));
2604 win = MODEST_MAIN_WINDOW (user_data);
2606 /* Check if the operation failed due to memory low conditions */
2607 error = modest_mail_operation_get_error (mail_op);
2608 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2609 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2610 modest_platform_run_information_dialog (GTK_WINDOW (win),
2611 _KR("memr_ib_operation_disabled"),
2617 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2619 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2622 TnyFolderStore *current_folder;
2624 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2625 if (current_folder) {
2626 gboolean different = ((TnyFolderStore *) folder != current_folder);
2627 g_object_unref (current_folder);
2633 /* Check if folder is empty and set headers view contents style */
2634 if ((tny_folder_get_all_count (folder) == 0) ||
2635 modest_header_view_is_empty (MODEST_HEADER_VIEW (header_view)))
2636 modest_main_window_set_contents_style (win,
2637 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2641 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2642 TnyFolderStore *folder_store,
2644 ModestMainWindow *main_window)
2646 GtkWidget *header_view;
2648 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2650 header_view = modest_main_window_get_child_widget(main_window,
2651 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2656 if (TNY_IS_ACCOUNT (folder_store)) {
2658 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2660 /* Show account details */
2661 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2664 if (TNY_IS_FOLDER (folder_store) && selected) {
2665 TnyAccount *account;
2667 /* Update the active account */
2668 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2670 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2671 g_object_unref (account);
2675 /* Set the header style by default, it could
2676 be changed later by the refresh callback to
2678 modest_main_window_set_contents_style (main_window,
2679 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2681 /* Set folder on header view. This function
2682 will call tny_folder_refresh_async so we
2683 pass a callback that will be called when
2684 finished. We use that callback to set the
2685 empty view if there are no messages */
2686 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2687 TNY_FOLDER (folder_store),
2689 MODEST_WINDOW (main_window),
2690 folder_refreshed_cb,
2693 /* Restore configuration. We need to do this
2694 *after* the set_folder because the widget
2695 memory asks the header view about its
2697 modest_widget_memory_restore (modest_runtime_get_conf (),
2698 G_OBJECT(header_view),
2699 MODEST_CONF_HEADER_VIEW_KEY);
2701 /* No need to save the header view
2702 configuration for Maemo because it only
2703 saves the sorting stuff and that it's
2704 already being done by the sort
2705 dialog. Remove it when the GNOME version
2706 has the same behaviour */
2707 #ifdef MODEST_TOOLKIT_GTK
2708 if (modest_main_window_get_contents_style (main_window) ==
2709 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2710 modest_widget_memory_save (conf, G_OBJECT (header_view),
2711 MODEST_CONF_HEADER_VIEW_KEY);
2713 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2717 /* Update dimming state */
2718 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2719 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2723 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2730 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2732 online = tny_device_is_online (modest_runtime_get_device());
2735 /* already online -- the item is simply not there... */
2736 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2738 GTK_MESSAGE_WARNING,
2740 _("The %s you selected cannot be found"),
2742 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2743 gtk_dialog_run (GTK_DIALOG(dialog));
2745 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2748 _("mcen_bd_dialog_cancel"),
2749 GTK_RESPONSE_REJECT,
2750 _("mcen_bd_dialog_ok"),
2751 GTK_RESPONSE_ACCEPT,
2753 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2754 "Do you want to get online?"), item);
2755 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2756 gtk_label_new (txt), FALSE, FALSE, 0);
2757 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2760 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2761 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2762 /* TODO: Comment about why is this commented out: */
2763 /* modest_platform_connect_and_wait (); */
2766 gtk_widget_destroy (dialog);
2770 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2773 /* g_message ("%s %s", __FUNCTION__, link); */
2778 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2781 modest_platform_activate_uri (link);
2785 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2788 modest_platform_show_uri_popup (link);
2792 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2795 /* we check for low-mem; in that case, show a warning, and don't allow
2796 * viewing attachments
2798 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2801 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2805 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2806 const gchar *address,
2809 /* g_message ("%s %s", __FUNCTION__, address); */
2813 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2814 TnyMsg *saved_draft,
2817 ModestMsgEditWindow *edit_window;
2819 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2820 #ifndef MODEST_TOOLKIT_HILDON2
2821 ModestMainWindow *win;
2823 /* FIXME. Make the header view sensitive again. This is a
2824 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2826 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2827 modest_runtime_get_window_mgr(), FALSE));
2829 GtkWidget *hdrview = modest_main_window_get_child_widget(
2830 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2831 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2835 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2837 /* Set draft is there was no error */
2838 if (!modest_mail_operation_get_error (mail_op))
2839 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2841 g_object_unref(edit_window);
2845 enough_space_for_message (ModestMsgEditWindow *edit_window,
2848 guint64 available_disk, expected_size;
2853 available_disk = modest_utils_get_available_space (NULL);
2854 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2855 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2860 /* Double check: memory full condition or message too big */
2861 if (available_disk < MIN_FREE_SPACE ||
2862 expected_size > available_disk) {
2863 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
2864 modest_platform_information_banner (NULL, NULL, msg);
2871 * djcb: if we're in low-memory state, we only allow for
2872 * saving messages smaller than
2873 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2874 * should still allow for sending anything critical...
2876 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2877 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2881 * djcb: we also make sure that the attachments are smaller than the max size
2882 * this is for the case where we'd try to forward a message with attachments
2883 * bigger than our max allowed size, or sending an message from drafts which
2884 * somehow got past our checks when attaching.
2886 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2887 modest_platform_run_information_dialog (
2888 GTK_WINDOW(edit_window),
2889 _KR("memr_ib_operation_disabled"),
2898 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2900 TnyTransportAccount *transport_account;
2901 ModestMailOperation *mail_operation;
2903 gchar *account_name;
2904 ModestAccountMgr *account_mgr;
2905 gboolean had_error = FALSE;
2906 ModestMainWindow *win = NULL;
2908 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2910 data = modest_msg_edit_window_get_msg_data (edit_window);
2913 if (!enough_space_for_message (edit_window, data)) {
2914 modest_msg_edit_window_free_msg_data (edit_window, data);
2918 account_name = g_strdup (data->account_name);
2919 account_mgr = modest_runtime_get_account_mgr();
2921 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2923 account_name = modest_account_mgr_get_default_account (account_mgr);
2924 if (!account_name) {
2925 g_printerr ("modest: no account found\n");
2926 modest_msg_edit_window_free_msg_data (edit_window, data);
2930 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2931 account_name = g_strdup (data->account_name);
2935 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2936 (modest_runtime_get_account_store (),
2938 TNY_ACCOUNT_TYPE_TRANSPORT));
2939 if (!transport_account) {
2940 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2941 g_free (account_name);
2942 modest_msg_edit_window_free_msg_data (edit_window, data);
2946 /* Create the mail operation */
2947 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
2949 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2951 modest_mail_operation_save_to_drafts (mail_operation,
2963 data->priority_flags,
2966 on_save_to_drafts_cb,
2967 g_object_ref(edit_window));
2969 #ifdef MODEST_TOOLKIT_HILDON2
2970 /* In hildon2 we always show the information banner on saving to drafts.
2971 * It will be a system information banner in this case.
2973 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2974 modest_platform_information_banner (NULL, NULL, text);
2977 /* Use the main window as the parent of the banner, if the
2978 main window does not exist it won't be shown, if the parent
2979 window exists then it's properly shown. We don't use the
2980 editor window because it could be closed (save to drafts
2981 could happen after closing the window */
2982 win = (ModestMainWindow *)
2983 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
2985 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2986 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
2990 modest_msg_edit_window_set_modified (edit_window, FALSE);
2993 g_free (account_name);
2994 g_object_unref (G_OBJECT (transport_account));
2995 g_object_unref (G_OBJECT (mail_operation));
2997 modest_msg_edit_window_free_msg_data (edit_window, data);
3000 * If the drafts folder is selected then make the header view
3001 * insensitive while the message is being saved to drafts
3002 * (it'll be sensitive again in on_save_to_drafts_cb()). This
3003 * is not very clean but it avoids letting the drafts folder
3004 * in an inconsistent state: the user could edit the message
3005 * being saved and undesirable things would happen.
3006 * In the average case the user won't notice anything at
3007 * all. In the worst case (the user is editing a really big
3008 * file from Drafts) the header view will be insensitive
3009 * during the saving process (10 or 20 seconds, depending on
3010 * the message). Anyway this is just a quick workaround: once
3011 * we find a better solution it should be removed
3012 * See NB#65125 (commend #18) for details.
3014 if (!had_error && win != NULL) {
3015 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
3016 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
3018 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
3020 if (modest_tny_folder_is_local_folder(folder)) {
3021 TnyFolderType folder_type;
3022 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
3023 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
3024 GtkWidget *hdrview = modest_main_window_get_child_widget(
3025 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3026 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
3030 if (folder != NULL) g_object_unref(folder);
3037 /* For instance, when clicking the Send toolbar button when editing a message: */
3039 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
3041 TnyTransportAccount *transport_account = NULL;
3042 gboolean had_error = FALSE;
3044 ModestAccountMgr *account_mgr;
3045 gchar *account_name;
3046 ModestMailOperation *mail_operation;
3048 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
3050 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
3053 data = modest_msg_edit_window_get_msg_data (edit_window);
3056 if (!enough_space_for_message (edit_window, data)) {
3057 modest_msg_edit_window_free_msg_data (edit_window, data);
3061 account_mgr = modest_runtime_get_account_mgr();
3062 account_name = g_strdup (data->account_name);
3064 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
3067 account_name = modest_account_mgr_get_default_account (account_mgr);
3069 if (!account_name) {
3070 modest_msg_edit_window_free_msg_data (edit_window, data);
3071 /* Run account setup wizard */
3072 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
3077 /* Get the currently-active transport account for this modest account: */
3078 if (strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
3080 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3081 (modest_runtime_get_account_store (),
3082 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
3085 if (!transport_account) {
3086 modest_msg_edit_window_free_msg_data (edit_window, data);
3087 /* Run account setup wizard */
3088 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
3093 /* Create the mail operation */
3094 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
3095 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3097 modest_mail_operation_send_new_mail (mail_operation,
3111 data->priority_flags);
3113 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3114 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
3116 if (modest_mail_operation_get_error (mail_operation) != NULL) {
3117 const GError *error = modest_mail_operation_get_error (mail_operation);
3118 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3119 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3120 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3121 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3127 g_free (account_name);
3128 g_object_unref (G_OBJECT (transport_account));
3129 g_object_unref (G_OBJECT (mail_operation));
3131 modest_msg_edit_window_free_msg_data (edit_window, data);
3134 modest_msg_edit_window_set_sent (edit_window, TRUE);
3136 /* Save settings and close the window: */
3137 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3144 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3145 ModestMsgEditWindow *window)
3147 ModestMsgEditFormatState *format_state = NULL;
3149 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3150 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3152 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3155 format_state = modest_msg_edit_window_get_format_state (window);
3156 g_return_if_fail (format_state != NULL);
3158 format_state->bold = gtk_toggle_action_get_active (action);
3159 modest_msg_edit_window_set_format_state (window, format_state);
3160 g_free (format_state);
3165 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3166 ModestMsgEditWindow *window)
3168 ModestMsgEditFormatState *format_state = NULL;
3170 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3171 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3173 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3176 format_state = modest_msg_edit_window_get_format_state (window);
3177 g_return_if_fail (format_state != NULL);
3179 format_state->italics = gtk_toggle_action_get_active (action);
3180 modest_msg_edit_window_set_format_state (window, format_state);
3181 g_free (format_state);
3186 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3187 ModestMsgEditWindow *window)
3189 ModestMsgEditFormatState *format_state = NULL;
3191 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3192 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3194 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3197 format_state = modest_msg_edit_window_get_format_state (window);
3198 g_return_if_fail (format_state != NULL);
3200 format_state->bullet = gtk_toggle_action_get_active (action);
3201 modest_msg_edit_window_set_format_state (window, format_state);
3202 g_free (format_state);
3207 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3208 GtkRadioAction *selected,
3209 ModestMsgEditWindow *window)
3211 ModestMsgEditFormatState *format_state = NULL;
3212 GtkJustification value;
3214 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3216 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3219 value = gtk_radio_action_get_current_value (selected);
3221 format_state = modest_msg_edit_window_get_format_state (window);
3222 g_return_if_fail (format_state != NULL);
3224 format_state->justification = value;
3225 modest_msg_edit_window_set_format_state (window, format_state);
3226 g_free (format_state);
3230 modest_ui_actions_on_select_editor_color (GtkAction *action,
3231 ModestMsgEditWindow *window)
3233 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3234 g_return_if_fail (GTK_IS_ACTION (action));
3236 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3239 modest_msg_edit_window_select_color (window);
3243 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3244 ModestMsgEditWindow *window)
3246 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3247 g_return_if_fail (GTK_IS_ACTION (action));
3249 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3252 modest_msg_edit_window_select_background_color (window);
3256 modest_ui_actions_on_insert_image (GObject *object,
3257 ModestMsgEditWindow *window)
3259 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3262 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3265 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3268 modest_msg_edit_window_insert_image (window);
3272 modest_ui_actions_on_attach_file (GtkAction *action,
3273 ModestMsgEditWindow *window)
3275 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3276 g_return_if_fail (GTK_IS_ACTION (action));
3278 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3281 modest_msg_edit_window_offer_attach_file (window);
3285 modest_ui_actions_on_remove_attachments (GtkAction *action,
3286 ModestMsgEditWindow *window)
3288 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3290 modest_msg_edit_window_remove_attachments (window, NULL);
3294 do_create_folder_cb (ModestMailOperation *mail_op,
3295 TnyFolderStore *parent_folder,
3296 TnyFolder *new_folder,
3299 gchar *suggested_name = (gchar *) user_data;
3300 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3301 const GError *error;
3303 error = modest_mail_operation_get_error (mail_op);
3306 /* Show an error. If there was some problem writing to
3307 disk, show it, otherwise show the generic folder
3308 create error. We do it here and not in an error
3309 handler because the call to do_create_folder will
3310 stop the main loop in a gtk_dialog_run and then,
3311 the message won't be shown until that dialog is
3313 modest_ui_actions_disk_operations_error_handler (mail_op,
3314 _("mail_in_ui_folder_create_error"));
3316 if (!is_memory_full_error ((GError *) error, mail_op)) {
3317 /* Try again if there is no full memory condition */
3318 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3321 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3322 * FIXME: any other? */
3323 GtkWidget *folder_view;
3325 if (MODEST_IS_MAIN_WINDOW(source_win))
3327 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3328 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3330 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3331 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3333 /* Select the newly created folder. It could happen
3334 that the widget is no longer there (i.e. the window
3335 has been destroyed, so we need to check this */
3337 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3339 g_object_unref (new_folder);
3341 /* Free. Note that the first time it'll be NULL so noop */
3342 g_free (suggested_name);
3343 g_object_unref (source_win);
3348 TnyFolderStore *parent;
3349 } CreateFolderConnect;
3352 do_create_folder_performer (gboolean canceled,
3354 GtkWindow *parent_window,
3355 TnyAccount *account,
3358 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3359 ModestMailOperation *mail_op;
3361 if (canceled || err) {
3362 /* In memory full conditions we could get this error here */
3363 check_memory_full_error ((GtkWidget *) parent_window, err);
3367 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3368 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3370 modest_mail_operation_create_folder (mail_op,
3372 (const gchar *) helper->folder_name,
3373 do_create_folder_cb,
3374 g_strdup (helper->folder_name));
3375 g_object_unref (mail_op);
3379 g_object_unref (helper->parent);
3380 if (helper->folder_name)
3381 g_free (helper->folder_name);
3382 g_slice_free (CreateFolderConnect, helper);
3387 do_create_folder (GtkWindow *parent_window,
3388 TnyFolderStore *suggested_parent,
3389 const gchar *suggested_name)
3392 gchar *folder_name = NULL;
3393 TnyFolderStore *parent_folder = NULL;
3395 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3397 (gchar *) suggested_name,
3401 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3402 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3403 helper->folder_name = g_strdup (folder_name);
3404 helper->parent = g_object_ref (parent_folder);
3406 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3409 do_create_folder_performer,
3414 g_free (folder_name);
3416 g_object_unref (parent_folder);
3420 modest_ui_actions_create_folder(GtkWidget *parent_window,
3421 GtkWidget *folder_view,
3422 TnyFolderStore *parent_folder)
3424 if (!parent_folder) {
3425 #ifdef MODEST_TOOLKIT_HILDON2
3426 ModestTnyAccountStore *acc_store;
3428 acc_store = modest_runtime_get_account_store ();
3430 parent_folder = (TnyFolderStore *)
3431 modest_tny_account_store_get_local_folders_account (acc_store);
3433 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3437 if (parent_folder) {
3438 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3439 g_object_unref (parent_folder);
3444 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3447 g_return_if_fail (MODEST_IS_WINDOW(window));
3449 if (MODEST_IS_MAIN_WINDOW (window)) {
3450 GtkWidget *folder_view;
3452 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3453 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3457 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3458 #ifdef MODEST_TOOLKIT_HILDON2
3459 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3460 GtkWidget *folder_view;
3462 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3463 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view, NULL);
3466 g_assert_not_reached ();
3471 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3474 const GError *error = NULL;
3475 gchar *message = NULL;
3478 /* Get error message */
3479 error = modest_mail_operation_get_error (mail_op);
3481 g_return_if_reached ();
3483 mem_full = is_memory_full_error ((GError *) error, mail_op);
3485 message = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3486 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3487 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3488 message = _CS("ckdg_ib_folder_already_exists");
3489 } else if (error->domain == TNY_ERROR_DOMAIN &&
3490 error->code == TNY_SERVICE_ERROR_STATE) {
3491 /* This means that the folder is already in use (a
3492 message is opened for example */
3493 message = _("emev_ni_internal_error");
3495 message = _CS("ckdg_ib_unable_to_rename");
3498 /* We don't set a parent for the dialog because the dialog
3499 will be destroyed so the banner won't appear */
3500 modest_platform_information_banner (NULL, NULL, message);
3507 TnyFolderStore *folder;
3512 on_rename_folder_cb (ModestMailOperation *mail_op,
3513 TnyFolder *new_folder,
3516 ModestFolderView *folder_view;
3518 /* If the window was closed when renaming a folder, or if
3519 * it's not a main window this will happen */
3520 if (!MODEST_IS_FOLDER_VIEW (user_data))
3523 folder_view = MODEST_FOLDER_VIEW (user_data);
3524 /* Note that if the rename fails new_folder will be NULL */
3526 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3528 modest_folder_view_select_first_inbox_or_local (folder_view);
3530 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3534 on_rename_folder_performer (gboolean canceled,
3536 GtkWindow *parent_window,
3537 TnyAccount *account,
3540 ModestMailOperation *mail_op = NULL;
3541 GtkTreeSelection *sel = NULL;
3542 GtkWidget *folder_view = NULL;
3543 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3545 if (canceled || err) {
3546 /* In memory full conditions we could get this error here */
3547 check_memory_full_error ((GtkWidget *) parent_window, err);
3551 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3552 modest_ui_actions_rename_folder_error_handler,
3553 parent_window, NULL);
3555 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3558 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3560 folder_view = modest_main_window_get_child_widget (
3561 MODEST_MAIN_WINDOW (parent_window),
3562 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3564 #ifdef MODEST_TOOLKIT_HILDON2
3565 else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3566 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3567 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3571 /* Clear the folders view */
3572 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3573 gtk_tree_selection_unselect_all (sel);
3575 /* Actually rename the folder */
3576 modest_mail_operation_rename_folder (mail_op,
3577 TNY_FOLDER (data->folder),
3578 (const gchar *) (data->new_name),
3579 on_rename_folder_cb,
3581 g_object_unref (mail_op);
3584 g_object_unref (data->folder);
3585 g_free (data->new_name);
3590 modest_ui_actions_on_rename_folder (GtkAction *action,
3591 ModestWindow *window)
3593 modest_ui_actions_on_edit_mode_rename_folder (window);
3597 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3599 TnyFolderStore *folder;
3600 GtkWidget *folder_view;
3601 gboolean do_rename = TRUE;
3603 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3605 if (MODEST_IS_MAIN_WINDOW (window)) {
3606 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3607 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3611 #ifdef MODEST_TOOLKIT_HILDON2
3612 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3613 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3619 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3624 if (TNY_IS_FOLDER (folder)) {
3625 gchar *folder_name = NULL;
3627 const gchar *current_name;
3628 TnyFolderStore *parent;
3630 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3631 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3632 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
3633 parent, current_name,
3635 g_object_unref (parent);
3637 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3640 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3641 rename_folder_data->folder = g_object_ref (folder);
3642 rename_folder_data->new_name = folder_name;
3643 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
3644 folder, on_rename_folder_performer, rename_folder_data);
3647 g_object_unref (folder);
3652 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3655 GObject *win = modest_mail_operation_get_source (mail_op);
3657 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3658 _("mail_in_ui_folder_delete_error"),
3660 g_object_unref (win);
3664 TnyFolderStore *folder;
3665 gboolean move_to_trash;
3669 on_delete_folder_cb (gboolean canceled,
3671 GtkWindow *parent_window,
3672 TnyAccount *account,
3675 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3676 GtkWidget *folder_view;
3677 ModestMailOperation *mail_op;
3678 GtkTreeSelection *sel;
3680 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
3681 g_object_unref (G_OBJECT (info->folder));
3686 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
3687 folder_view = modest_main_window_get_child_widget (
3688 MODEST_MAIN_WINDOW (parent_window),
3689 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3690 #ifdef MODEST_TOOLKIT_HILDON2
3691 } else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3692 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
3695 g_object_unref (G_OBJECT (info->folder));
3700 /* Unselect the folder before deleting it to free the headers */
3701 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3702 gtk_tree_selection_unselect_all (sel);
3704 /* Create the mail operation */
3706 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3707 modest_ui_actions_delete_folder_error_handler,
3710 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3712 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3714 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3716 g_object_unref (G_OBJECT (mail_op));
3717 g_object_unref (G_OBJECT (info->folder));
3722 delete_folder (ModestWindow *window, gboolean move_to_trash)
3724 TnyFolderStore *folder;
3725 GtkWidget *folder_view;
3729 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3731 if (MODEST_IS_MAIN_WINDOW (window)) {
3733 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3734 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3735 #ifdef MODEST_TOOLKIT_HILDON2
3736 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3737 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3745 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3750 /* Show an error if it's an account */
3751 if (!TNY_IS_FOLDER (folder)) {
3752 modest_platform_run_information_dialog (GTK_WINDOW (window),
3753 _("mail_in_ui_folder_delete_error"),
3755 g_object_unref (G_OBJECT (folder));
3760 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3761 tny_folder_get_name (TNY_FOLDER (folder)));
3762 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
3763 (const gchar *) message);
3766 if (response == GTK_RESPONSE_OK) {
3767 DeleteFolderInfo *info;
3768 info = g_new0(DeleteFolderInfo, 1);
3769 info->folder = folder;
3770 info->move_to_trash = move_to_trash;
3771 g_object_ref (G_OBJECT (info->folder));
3772 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder));
3773 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
3775 TNY_FOLDER_STORE (account),
3776 on_delete_folder_cb, info);
3777 g_object_unref (account);
3782 g_object_unref (G_OBJECT (folder));
3786 modest_ui_actions_on_delete_folder (GtkAction *action,
3787 ModestWindow *window)
3789 modest_ui_actions_on_edit_mode_delete_folder (window);
3793 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
3795 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
3797 return delete_folder (window, FALSE);
3801 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3803 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3805 delete_folder (MODEST_WINDOW (main_window), TRUE);
3809 typedef struct _PasswordDialogFields {
3810 GtkWidget *username;
3811 GtkWidget *password;
3813 } PasswordDialogFields;
3816 password_dialog_check_field (GtkEditable *editable,
3817 PasswordDialogFields *fields)
3820 gboolean any_value_empty = FALSE;
3822 #ifdef MODEST_TOOLKIT_HILDON2
3823 value = hildon_entry_get_text (HILDON_ENTRY (fields->username));
3825 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
3827 if ((value == NULL) || value[0] == '\0') {
3828 any_value_empty = TRUE;
3830 #ifdef MODEST_TOOLKIT_HILDON2
3831 value = hildon_entry_get_text (HILDON_ENTRY (fields->password));
3833 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
3835 if ((value == NULL) || value[0] == '\0') {
3836 any_value_empty = TRUE;
3838 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3842 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3843 const gchar* server_account_name,
3848 ModestMainWindow *main_window)
3850 g_return_if_fail(server_account_name);
3851 gboolean completed = FALSE;
3852 PasswordDialogFields *fields = NULL;
3854 /* Initalize output parameters: */
3861 #ifndef MODEST_TOOLKIT_GTK
3862 /* Maemo uses a different (awkward) button order,
3863 * It should probably just use gtk_alternative_dialog_button_order ().
3865 #ifdef MODEST_TOOLKIT_HILDON2
3867 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3870 _HL("wdgt_bd_done"),
3871 GTK_RESPONSE_ACCEPT,
3873 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
3874 HILDON_MARGIN_DOUBLE);
3877 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3880 _("mcen_bd_dialog_ok"),
3881 GTK_RESPONSE_ACCEPT,
3882 _("mcen_bd_dialog_cancel"),
3883 GTK_RESPONSE_REJECT,
3885 #endif /* MODEST_TOOLKIT_HILDON2 */
3888 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3892 GTK_RESPONSE_REJECT,
3894 GTK_RESPONSE_ACCEPT,
3896 #endif /* MODEST_TOOLKIT_GTK */
3898 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3900 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3901 modest_runtime_get_account_mgr(), server_account_name);
3902 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3903 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3906 gtk_widget_destroy (dialog);
3910 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3911 GtkWidget *label = gtk_label_new (txt);
3912 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
3914 g_free (server_name);
3915 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
3920 gchar *initial_username = modest_account_mgr_get_server_account_username (
3921 modest_runtime_get_account_mgr(), server_account_name);
3923 #ifdef MODEST_TOOLKIT_HILDON2
3924 GtkWidget *entry_username = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
3925 if (initial_username)
3926 hildon_entry_set_text (HILDON_ENTRY (entry_username), initial_username);
3928 GtkWidget *entry_username = gtk_entry_new ();
3929 if (initial_username)
3930 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
3932 /* Dim this if a connection has ever succeeded with this username,
3933 * as per the UI spec: */
3934 /* const gboolean username_known = */
3935 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3936 /* modest_runtime_get_account_mgr(), server_account_name); */
3937 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3939 /* We drop the username sensitive code and disallow changing it here
3940 * as tinymail does not support really changing the username in the callback
3942 gtk_widget_set_sensitive (entry_username, FALSE);
3944 #ifndef MODEST_TOOLKIT_GTK
3945 /* Auto-capitalization is the default, so let's turn it off: */
3946 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3948 /* Create a size group to be used by all captions.
3949 * Note that HildonCaption does not create a default size group if we do not specify one.
3950 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3951 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3953 #ifdef MODEST_TOOLKIT_HILDON2
3954 GtkWidget *caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
3955 _("mail_fi_username"), FALSE,
3958 GtkWidget *caption = hildon_caption_new (sizegroup,
3959 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
3961 gtk_widget_show (entry_username);
3962 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3963 FALSE, FALSE, MODEST_MARGIN_HALF);
3964 gtk_widget_show (caption);
3966 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
3968 #endif /* !MODEST_TOOLKIT_GTK */
3971 #ifdef MODEST_TOOLKIT_HILDON2
3972 GtkWidget *entry_password = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
3974 GtkWidget *entry_password = gtk_entry_new ();
3976 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3977 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3979 #ifndef MODEST_TOOLKIT_GTK
3980 /* Auto-capitalization is the default, so let's turn it off: */
3981 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3982 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3984 #ifdef MODEST_TOOLKIT_HILDON2
3985 caption = modest_maemo_utils_create_captioned (sizegroup, NULL,
3986 _("mail_fi_password"), FALSE,
3989 caption = hildon_caption_new (sizegroup,
3990 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
3992 gtk_widget_show (entry_password);
3993 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3994 FALSE, FALSE, MODEST_MARGIN_HALF);
3995 gtk_widget_show (caption);
3996 g_object_unref (sizegroup);
3998 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
4000 #endif /* !MODEST_TOOLKIT_GTK */
4002 if (initial_username != NULL)
4003 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
4005 /* This is not in the Maemo UI spec:
4006 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
4007 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
4011 fields = g_slice_new0 (PasswordDialogFields);
4012 fields->username = entry_username;
4013 fields->password = entry_password;
4014 fields->dialog = dialog;
4016 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
4017 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
4018 password_dialog_check_field (NULL, fields);
4020 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4022 while (!completed) {
4024 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
4026 #ifdef MODEST_TOOLKIT_HILDON2
4027 *username = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_username)));
4029 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
4032 /* Note that an empty field becomes the "" string */
4033 if (*username && strlen (*username) > 0) {
4034 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
4035 server_account_name,
4039 const gboolean username_was_changed =
4040 (strcmp (*username, initial_username) != 0);
4041 if (username_was_changed) {
4042 g_warning ("%s: tinymail does not yet support changing the "
4043 "username in the get_password() callback.\n", __FUNCTION__);
4049 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
4050 _("mcen_ib_username_pw_incorrect"));
4056 #ifdef MODEST_TOOLKIT_HILDON2
4057 *password = g_strdup (hildon_entry_get_text (HILDON_ENTRY(entry_password)));
4059 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
4062 /* We do not save the password in the configuration,
4063 * because this function is only called for passwords that should
4064 * not be remembered:
4065 modest_server_account_set_password (
4066 modest_runtime_get_account_mgr(), server_account_name,
4073 #ifndef MODEST_TOOLKIT_HILDON2
4074 /* Set parent to NULL or the banner will disappear with its parent dialog */
4075 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
4087 /* This is not in the Maemo UI spec:
4088 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
4094 g_free (initial_username);
4095 gtk_widget_destroy (dialog);
4096 g_slice_free (PasswordDialogFields, fields);
4098 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
4102 modest_ui_actions_on_cut (GtkAction *action,
4103 ModestWindow *window)
4105 GtkWidget *focused_widget;
4106 GtkClipboard *clipboard;
4108 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4109 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4110 if (GTK_IS_EDITABLE (focused_widget)) {
4111 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
4112 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4113 gtk_clipboard_store (clipboard);
4114 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4115 GtkTextBuffer *buffer;
4117 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4118 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4119 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
4120 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4121 gtk_clipboard_store (clipboard);
4123 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4124 TnyList *header_list = modest_header_view_get_selected_headers (
4125 MODEST_HEADER_VIEW (focused_widget));
4126 gboolean continue_download = FALSE;
4127 gint num_of_unc_msgs;
4129 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4131 if (num_of_unc_msgs) {
4132 TnyAccount *account = get_account_from_header_list (header_list);
4134 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4135 g_object_unref (account);
4139 if (num_of_unc_msgs == 0 || continue_download) {
4140 /* modest_platform_information_banner (
4141 NULL, NULL, _CS("mcen_ib_getting_items"));*/
4142 modest_header_view_cut_selection (
4143 MODEST_HEADER_VIEW (focused_widget));
4146 g_object_unref (header_list);
4147 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4148 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4153 modest_ui_actions_on_copy (GtkAction *action,
4154 ModestWindow *window)
4156 GtkClipboard *clipboard;
4157 GtkWidget *focused_widget;
4158 gboolean copied = TRUE;
4160 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4161 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4163 if (GTK_IS_LABEL (focused_widget)) {
4165 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4166 gtk_clipboard_set_text (clipboard, selection, -1);
4168 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4169 gtk_clipboard_store (clipboard);
4170 } else if (GTK_IS_EDITABLE (focused_widget)) {
4171 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4172 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4173 gtk_clipboard_store (clipboard);
4174 } else if (GTK_IS_HTML (focused_widget)) {
4177 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4178 if ((sel == NULL) || (sel[0] == '\0')) {
4181 gtk_html_copy (GTK_HTML (focused_widget));
4182 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4183 gtk_clipboard_store (clipboard);
4185 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4186 GtkTextBuffer *buffer;
4187 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4188 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4189 gtk_text_buffer_copy_clipboard (buffer, clipboard);
4190 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4191 gtk_clipboard_store (clipboard);
4193 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4194 TnyList *header_list = modest_header_view_get_selected_headers (
4195 MODEST_HEADER_VIEW (focused_widget));
4196 gboolean continue_download = FALSE;
4197 gint num_of_unc_msgs;
4199 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4201 if (num_of_unc_msgs) {
4202 TnyAccount *account = get_account_from_header_list (header_list);
4204 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4205 g_object_unref (account);
4209 if (num_of_unc_msgs == 0 || continue_download) {
4210 modest_platform_information_banner (
4211 NULL, NULL, _CS("mcen_ib_getting_items"));
4212 modest_header_view_copy_selection (
4213 MODEST_HEADER_VIEW (focused_widget));
4217 g_object_unref (header_list);
4219 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4220 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4223 /* Show information banner if there was a copy to clipboard */
4225 modest_platform_information_banner (
4226 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4230 modest_ui_actions_on_undo (GtkAction *action,
4231 ModestWindow *window)
4233 ModestEmailClipboard *clipboard = NULL;
4235 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4236 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4237 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4238 /* Clear clipboard source */
4239 clipboard = modest_runtime_get_email_clipboard ();
4240 modest_email_clipboard_clear (clipboard);
4243 g_return_if_reached ();
4248 modest_ui_actions_on_redo (GtkAction *action,
4249 ModestWindow *window)
4251 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4252 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4255 g_return_if_reached ();
4261 destroy_information_note (ModestMailOperation *mail_op,
4264 /* destroy information note */
4265 gtk_widget_destroy (GTK_WIDGET(user_data));
4269 destroy_folder_information_note (ModestMailOperation *mail_op,
4270 TnyFolder *new_folder,
4273 /* destroy information note */
4274 gtk_widget_destroy (GTK_WIDGET(user_data));
4279 paste_as_attachment_free (gpointer data)
4281 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4283 if (helper->banner) {
4284 gtk_widget_destroy (helper->banner);
4285 g_object_unref (helper->banner);
4291 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4296 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4297 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4302 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4307 modest_ui_actions_on_paste (GtkAction *action,
4308 ModestWindow *window)
4310 GtkWidget *focused_widget = NULL;
4311 GtkWidget *inf_note = NULL;
4312 ModestMailOperation *mail_op = NULL;
4314 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4315 if (GTK_IS_EDITABLE (focused_widget)) {
4316 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4317 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4318 ModestEmailClipboard *e_clipboard = NULL;
4319 e_clipboard = modest_runtime_get_email_clipboard ();
4320 if (modest_email_clipboard_cleared (e_clipboard)) {
4321 GtkTextBuffer *buffer;
4322 GtkClipboard *clipboard;
4324 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4325 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4326 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4327 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4328 ModestMailOperation *mail_op;
4329 TnyFolder *src_folder = NULL;
4330 TnyList *data = NULL;
4332 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4333 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4334 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4335 _CS("ckct_nw_pasting"));
4336 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4337 mail_op = modest_mail_operation_new (G_OBJECT (window));
4338 if (helper->banner != NULL) {
4339 g_object_ref (G_OBJECT (helper->banner));
4340 gtk_widget_show (GTK_WIDGET (helper->banner));
4344 modest_mail_operation_get_msgs_full (mail_op,
4346 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4348 paste_as_attachment_free);
4352 g_object_unref (data);
4354 g_object_unref (src_folder);
4357 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4358 ModestEmailClipboard *clipboard = NULL;
4359 TnyFolder *src_folder = NULL;
4360 TnyFolderStore *folder_store = NULL;
4361 TnyList *data = NULL;
4362 gboolean delete = FALSE;
4364 /* Check clipboard source */
4365 clipboard = modest_runtime_get_email_clipboard ();
4366 if (modest_email_clipboard_cleared (clipboard))
4369 /* Get elements to paste */
4370 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4372 /* Create a new mail operation */
4373 mail_op = modest_mail_operation_new (G_OBJECT(window));
4375 /* Get destination folder */
4376 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4378 /* transfer messages */
4382 /* Ask for user confirmation */
4384 modest_ui_actions_msgs_move_to_confirmation (window,
4385 TNY_FOLDER (folder_store),
4389 if (response == GTK_RESPONSE_OK) {
4390 /* Launch notification */
4391 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4392 _CS("ckct_nw_pasting"));
4393 if (inf_note != NULL) {
4394 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4395 gtk_widget_show (GTK_WIDGET(inf_note));
4398 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4399 modest_mail_operation_xfer_msgs (mail_op,
4401 TNY_FOLDER (folder_store),
4403 destroy_information_note,
4406 g_object_unref (mail_op);
4409 } else if (src_folder != NULL) {
4410 /* Launch notification */
4411 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4412 _CS("ckct_nw_pasting"));
4413 if (inf_note != NULL) {
4414 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4415 gtk_widget_show (GTK_WIDGET(inf_note));
4418 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4419 modest_mail_operation_xfer_folder (mail_op,
4423 destroy_folder_information_note,
4429 g_object_unref (data);
4430 if (src_folder != NULL)
4431 g_object_unref (src_folder);
4432 if (folder_store != NULL)
4433 g_object_unref (folder_store);
4439 modest_ui_actions_on_select_all (GtkAction *action,
4440 ModestWindow *window)
4442 GtkWidget *focused_widget;
4444 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4445 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4446 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4447 } else if (GTK_IS_LABEL (focused_widget)) {
4448 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4449 } else if (GTK_IS_EDITABLE (focused_widget)) {
4450 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4451 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4452 GtkTextBuffer *buffer;
4453 GtkTextIter start, end;
4455 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4456 gtk_text_buffer_get_start_iter (buffer, &start);
4457 gtk_text_buffer_get_end_iter (buffer, &end);
4458 gtk_text_buffer_select_range (buffer, &start, &end);
4459 } else if (GTK_IS_HTML (focused_widget)) {
4460 gtk_html_select_all (GTK_HTML (focused_widget));
4461 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4462 GtkWidget *header_view = focused_widget;
4463 GtkTreeSelection *selection = NULL;
4465 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4466 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4467 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4470 /* Disable window dimming management */
4471 modest_window_disable_dimming (MODEST_WINDOW(window));
4473 /* Select all messages */
4474 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4475 gtk_tree_selection_select_all (selection);
4477 /* Set focuse on header view */
4478 gtk_widget_grab_focus (header_view);
4480 /* Enable window dimming management */
4481 modest_window_enable_dimming (MODEST_WINDOW(window));
4482 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4483 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4489 modest_ui_actions_on_mark_as_read (GtkAction *action,
4490 ModestWindow *window)
4492 g_return_if_fail (MODEST_IS_WINDOW(window));
4494 /* Mark each header as read */
4495 do_headers_action (window, headers_action_mark_as_read, NULL);
4499 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4500 ModestWindow *window)
4502 g_return_if_fail (MODEST_IS_WINDOW(window));
4504 /* Mark each header as read */
4505 do_headers_action (window, headers_action_mark_as_unread, NULL);
4509 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4510 GtkRadioAction *selected,
4511 ModestWindow *window)
4515 value = gtk_radio_action_get_current_value (selected);
4516 if (MODEST_IS_WINDOW (window)) {
4517 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4522 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4523 GtkRadioAction *selected,
4524 ModestWindow *window)
4526 TnyHeaderFlags flags;
4527 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4529 flags = gtk_radio_action_get_current_value (selected);
4530 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4534 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4535 GtkRadioAction *selected,
4536 ModestWindow *window)
4540 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4542 file_format = gtk_radio_action_get_current_value (selected);
4543 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4548 modest_ui_actions_on_zoom_plus (GtkAction *action,
4549 ModestWindow *window)
4551 g_return_if_fail (MODEST_IS_WINDOW (window));
4553 modest_window_zoom_plus (MODEST_WINDOW (window));
4557 modest_ui_actions_on_zoom_minus (GtkAction *action,
4558 ModestWindow *window)
4560 g_return_if_fail (MODEST_IS_WINDOW (window));
4562 modest_window_zoom_minus (MODEST_WINDOW (window));
4566 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4567 ModestWindow *window)
4569 ModestWindowMgr *mgr;
4570 gboolean fullscreen, active;
4571 g_return_if_fail (MODEST_IS_WINDOW (window));
4573 mgr = modest_runtime_get_window_mgr ();
4575 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4576 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4578 if (active != fullscreen) {
4579 modest_window_mgr_set_fullscreen_mode (mgr, active);
4580 #ifndef MODEST_TOOLKIT_HILDON2
4581 gtk_window_present (GTK_WINDOW (window));
4587 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4588 ModestWindow *window)
4590 ModestWindowMgr *mgr;
4591 gboolean fullscreen;
4593 g_return_if_fail (MODEST_IS_WINDOW (window));
4595 mgr = modest_runtime_get_window_mgr ();
4596 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4597 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4599 #ifndef MODEST_TOOLKIT_HILDON2
4600 gtk_window_present (GTK_WINDOW (window));
4605 * Used by modest_ui_actions_on_details to call do_headers_action
4608 headers_action_show_details (TnyHeader *header,
4609 ModestWindow *window,
4613 gboolean async_retrieval;
4616 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4617 async_retrieval = TRUE;
4618 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
4620 async_retrieval = FALSE;
4622 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header, async_retrieval, msg);
4624 g_object_unref (msg);
4628 * Show the header details in a ModestDetailsDialog widget
4631 modest_ui_actions_on_details (GtkAction *action,
4634 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4638 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4642 header = tny_msg_get_header (msg);
4644 headers_action_show_details (header, win, NULL);
4645 g_object_unref (header);
4647 g_object_unref (msg);
4649 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4650 GtkWidget *folder_view, *header_view;
4652 /* Check which widget has the focus */
4653 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4654 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4655 if (gtk_widget_is_focus (folder_view)) {
4656 TnyFolderStore *folder_store
4657 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4658 if (!folder_store) {
4659 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4662 /* Show only when it's a folder */
4663 /* This function should not be called for account items,
4664 * because we dim the menu item for them. */
4665 if (TNY_IS_FOLDER (folder_store)) {
4666 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4667 TNY_FOLDER (folder_store));
4670 g_object_unref (folder_store);
4673 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4674 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4675 /* Show details of each header */
4676 do_headers_action (win, headers_action_show_details, header_view);
4678 #ifdef MODEST_TOOLKIT_HILDON2
4679 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4681 GtkWidget *header_view;
4683 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4684 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4686 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4688 g_object_unref (folder);
4695 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4696 ModestMsgEditWindow *window)
4698 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4700 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4704 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4705 ModestMsgEditWindow *window)
4707 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4709 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4713 modest_ui_actions_toggle_folders_view (GtkAction *action,
4714 ModestMainWindow *main_window)
4716 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4718 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4719 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4721 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4725 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4726 ModestWindow *window)
4728 gboolean active, fullscreen = FALSE;
4729 ModestWindowMgr *mgr;
4731 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4733 /* Check if we want to toggle the toolbar view in fullscreen
4735 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4736 "ViewShowToolbarFullScreen")) {
4740 /* Toggle toolbar */
4741 mgr = modest_runtime_get_window_mgr ();
4742 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4746 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4747 ModestMsgEditWindow *window)
4749 modest_msg_edit_window_select_font (window);
4754 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4755 const gchar *display_name,
4758 /* don't update the display name if it was already set;
4759 * updating the display name apparently is expensive */
4760 const gchar* old_name = gtk_window_get_title (window);
4762 if (display_name == NULL)
4765 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4766 return; /* don't do anything */
4768 /* This is usually used to change the title of the main window, which
4769 * is the one that holds the folder view. Note that this change can
4770 * happen even when the widget doesn't have the focus. */
4771 gtk_window_set_title (window, display_name);
4776 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4778 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4779 modest_msg_edit_window_select_contacts (window);
4783 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4785 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4786 modest_msg_edit_window_check_names (window, FALSE);
4789 #ifndef MODEST_TOOLKIT_HILDON2
4791 * This function is used to track changes in the selection of the
4792 * folder view that is inside the "move to" dialog to enable/disable
4793 * the OK button because we do not want the user to select a disallowed
4794 * destination for a folder.
4795 * The user also not desired to be able to use NEW button on items where
4796 * folder creation is not possibel.
4799 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4800 TnyFolderStore *folder_store,
4804 GtkWidget *dialog = NULL;
4805 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4806 gboolean moving_folder = FALSE;
4807 gboolean is_local_account = TRUE;
4808 GtkWidget *folder_view = NULL;
4809 ModestTnyFolderRules rules;
4811 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
4816 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
4820 /* check if folder_store is an remote account */
4821 if (TNY_IS_ACCOUNT (folder_store)) {
4822 TnyAccount *local_account = NULL;
4823 TnyAccount *mmc_account = NULL;
4824 ModestTnyAccountStore *account_store = NULL;
4826 account_store = modest_runtime_get_account_store ();
4827 local_account = modest_tny_account_store_get_local_folders_account (account_store);
4828 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
4830 if ((gpointer) local_account != (gpointer) folder_store &&
4831 (gpointer) mmc_account != (gpointer) folder_store) {
4832 ModestProtocolType proto;
4833 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
4834 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
4835 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
4837 is_local_account = FALSE;
4838 /* New button should be dimmed on remote
4840 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4842 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
4844 g_object_unref (local_account);
4846 /* It could not exist */
4848 g_object_unref (mmc_account);
4851 /* Check the target folder rules */
4852 if (TNY_IS_FOLDER (folder_store)) {
4853 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
4854 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
4855 ok_sensitive = FALSE;
4856 new_sensitive = FALSE;
4861 /* Check if we're moving a folder */
4862 if (MODEST_IS_MAIN_WINDOW (user_data)) {
4863 /* Get the widgets */
4864 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
4865 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4866 if (gtk_widget_is_focus (folder_view))
4867 moving_folder = TRUE;
4870 if (moving_folder) {
4871 TnyFolderStore *moved_folder = NULL, *parent = NULL;
4873 /* Get the folder to move */
4874 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4876 /* Check that we're not moving to the same folder */
4877 if (TNY_IS_FOLDER (moved_folder)) {
4878 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
4879 if (parent == folder_store)
4880 ok_sensitive = FALSE;
4881 g_object_unref (parent);
4884 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
4885 /* Do not allow to move to an account unless it's the
4886 local folders account */
4887 if (!is_local_account)
4888 ok_sensitive = FALSE;
4891 if (ok_sensitive && (moved_folder == folder_store)) {
4892 /* Do not allow to move to itself */
4893 ok_sensitive = FALSE;
4895 g_object_unref (moved_folder);
4897 TnyFolder *src_folder = NULL;
4899 /* Moving a message */
4900 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
4902 TnyHeader *header = NULL;
4903 header = modest_msg_view_window_get_header
4904 (MODEST_MSG_VIEW_WINDOW (user_data));
4905 if (!TNY_IS_HEADER(header))
4906 g_warning ("%s: could not get source header", __FUNCTION__);
4908 src_folder = tny_header_get_folder (header);
4911 g_object_unref (header);
4914 TNY_FOLDER (modest_folder_view_get_selected
4915 (MODEST_FOLDER_VIEW (folder_view)));
4918 if (TNY_IS_FOLDER(src_folder)) {
4919 /* Do not allow to move the msg to the same folder */
4920 /* Do not allow to move the msg to an account */
4921 if ((gpointer) src_folder == (gpointer) folder_store ||
4922 TNY_IS_ACCOUNT (folder_store))
4923 ok_sensitive = FALSE;
4924 g_object_unref (src_folder);
4926 g_warning ("%s: could not get source folder", __FUNCTION__);
4930 /* Set sensitivity of the OK and NEW button */
4931 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
4932 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
4937 on_move_to_dialog_response (GtkDialog *dialog,
4941 GtkWidget *parent_win;
4942 MoveToInfo *helper = NULL;
4943 ModestFolderView *folder_view;
4945 helper = (MoveToInfo *) user_data;
4947 parent_win = (GtkWidget *) helper->win;
4948 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
4949 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4952 TnyFolderStore *dst_folder;
4953 TnyFolderStore *selected;
4955 case MODEST_GTK_RESPONSE_NEW_FOLDER:
4956 selected = modest_folder_view_get_selected (folder_view);
4957 modest_ui_actions_create_folder (GTK_WIDGET (dialog), GTK_WIDGET (folder_view), selected);
4958 g_object_unref (selected);
4960 case GTK_RESPONSE_NONE:
4961 case GTK_RESPONSE_CANCEL:
4962 case GTK_RESPONSE_DELETE_EVENT:
4964 case GTK_RESPONSE_OK:
4965 dst_folder = modest_folder_view_get_selected (folder_view);
4967 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
4968 /* Clean list to move used for filtering */
4969 modest_folder_view_set_list_to_move (folder_view, NULL);
4971 modest_ui_actions_on_main_window_move_to (NULL,
4972 GTK_WIDGET (folder_view),
4974 MODEST_MAIN_WINDOW (parent_win));
4975 #ifdef MODEST_TOOLKIT_HILDON2
4976 } else if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
4977 /* Clean list to move used for filtering */
4978 modest_folder_view_set_list_to_move (folder_view, NULL);
4980 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
4983 GTK_WINDOW (parent_win));
4986 /* if the user selected a root folder
4987 (account) then do not perform any action */
4988 if (TNY_IS_ACCOUNT (dst_folder)) {
4989 g_signal_stop_emission_by_name (dialog, "response");
4993 /* Clean list to move used for filtering */
4994 modest_folder_view_set_list_to_move (folder_view, NULL);
4996 /* Moving from headers window in edit mode */
4997 modest_ui_actions_on_window_move_to (NULL, helper->list,
4999 MODEST_WINDOW (parent_win));
5003 g_object_unref (dst_folder);
5007 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
5010 /* Free the helper and exit */
5012 g_object_unref (helper->list);
5013 g_slice_free (MoveToInfo, helper);
5014 gtk_widget_destroy (GTK_WIDGET (dialog));
5018 create_move_to_dialog (GtkWindow *win,
5019 GtkWidget *folder_view,
5020 TnyList *list_to_move)
5022 GtkWidget *dialog, *tree_view = NULL;
5024 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
5026 #ifndef MODEST_TOOLKIT_HILDON2
5027 /* Track changes in the selection to
5028 * disable the OK button whenever "Move to" is not possible
5029 * disbale NEW button whenever New is not possible */
5030 g_signal_connect (tree_view,
5031 "folder_selection_changed",
5032 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
5036 /* It could happen that we're trying to move a message from a
5037 window (msg window for example) after the main window was
5038 closed, so we can not just get the model of the folder
5040 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
5041 const gchar *visible_id = NULL;
5043 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5044 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5045 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
5046 MODEST_FOLDER_VIEW(tree_view));
5049 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
5051 /* Show the same account than the one that is shown in the main window */
5052 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
5055 const gchar *active_account_name = NULL;
5056 ModestAccountMgr *mgr = NULL;
5057 ModestAccountSettings *settings = NULL;
5058 ModestServerAccountSettings *store_settings = NULL;
5060 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
5061 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
5062 modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view),
5063 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
5065 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
5066 mgr = modest_runtime_get_account_mgr ();
5067 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
5070 const gchar *store_account_name;
5071 store_settings = modest_account_settings_get_store_settings (settings);
5072 store_account_name = modest_server_account_settings_get_account_name (store_settings);
5074 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
5075 store_account_name);
5076 g_object_unref (store_settings);
5077 g_object_unref (settings);
5081 /* we keep a pointer to the embedded folder view, so we can
5082 * retrieve it with get_folder_view_from_move_to_dialog (see
5083 * above) later (needed for focus handling)
5085 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
5087 /* Hide special folders */
5088 #ifndef MODEST_TOOLKIT_HILDON2
5089 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
5092 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
5093 #ifndef MODEST_TOOLKIT_HILDON2
5094 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5097 gtk_widget_show (GTK_WIDGET (tree_view));
5103 * Shows a confirmation dialog to the user when we're moving messages
5104 * from a remote server to the local storage. Returns the dialog
5105 * response. If it's other kind of movement then it always returns
5108 * This one is used by the next functions:
5109 * modest_ui_actions_on_paste - commented out
5110 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
5113 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
5114 TnyFolder *dest_folder,
5118 gint response = GTK_RESPONSE_OK;
5119 TnyAccount *account = NULL;
5120 TnyFolder *src_folder = NULL;
5121 TnyIterator *iter = NULL;
5122 TnyHeader *header = NULL;
5124 /* return with OK if the destination is a remote folder */
5125 if (modest_tny_folder_is_remote_folder (dest_folder))
5126 return GTK_RESPONSE_OK;
5128 /* Get source folder */
5129 iter = tny_list_create_iterator (headers);
5130 header = TNY_HEADER (tny_iterator_get_current (iter));
5132 src_folder = tny_header_get_folder (header);
5133 g_object_unref (header);
5135 g_object_unref (iter);
5137 /* if no src_folder, message may be an attahcment */
5138 if (src_folder == NULL)
5139 return GTK_RESPONSE_CANCEL;
5141 /* If the source is a local or MMC folder */
5142 if (!modest_tny_folder_is_remote_folder (src_folder)) {
5143 g_object_unref (src_folder);
5144 return GTK_RESPONSE_OK;
5147 /* Get the account */
5148 account = tny_folder_get_account (src_folder);
5150 /* now if offline we ask the user */
5151 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
5152 response = GTK_RESPONSE_OK;
5154 response = GTK_RESPONSE_CANCEL;
5157 g_object_unref (src_folder);
5158 g_object_unref (account);
5164 move_to_helper_destroyer (gpointer user_data)
5166 MoveToHelper *helper = (MoveToHelper *) user_data;
5168 /* Close the "Pasting" information banner */
5169 if (helper->banner) {
5170 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5171 g_object_unref (helper->banner);
5173 if (gtk_tree_row_reference_valid (helper->reference)) {
5174 gtk_tree_row_reference_free (helper->reference);
5175 helper->reference = NULL;
5181 move_to_cb (ModestMailOperation *mail_op,
5184 MoveToHelper *helper = (MoveToHelper *) user_data;
5185 GObject *object = modest_mail_operation_get_source (mail_op);
5187 /* Note that the operation could have failed, in that case do
5189 if (modest_mail_operation_get_status (mail_op) !=
5190 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5193 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5194 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5196 if (!modest_msg_view_window_select_next_message (self) &&
5197 !modest_msg_view_window_select_previous_message (self)) {
5198 /* No more messages to view, so close this window */
5199 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5201 } else if (MODEST_IS_MAIN_WINDOW (object) &&
5202 gtk_tree_row_reference_valid (helper->reference)) {
5203 GtkWidget *header_view;
5205 GtkTreeSelection *sel;
5207 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5208 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5209 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5210 path = gtk_tree_row_reference_get_path (helper->reference);
5211 /* We need to unselect the previous one
5212 because we could be copying instead of
5214 gtk_tree_selection_unselect_all (sel);
5215 gtk_tree_selection_select_path (sel, path);
5216 gtk_tree_path_free (path);
5218 g_object_unref (object);
5221 /* Destroy the helper */
5222 move_to_helper_destroyer (helper);
5226 folder_move_to_cb (ModestMailOperation *mail_op,
5227 TnyFolder *new_folder,
5230 GtkWidget *folder_view;
5233 object = modest_mail_operation_get_source (mail_op);
5234 if (MODEST_IS_MAIN_WINDOW (object)) {
5235 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5236 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5237 g_object_ref (folder_view);
5238 g_object_unref (object);
5239 move_to_cb (mail_op, user_data);
5240 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5241 g_object_unref (folder_view);
5243 move_to_cb (mail_op, user_data);
5248 msgs_move_to_cb (ModestMailOperation *mail_op,
5251 move_to_cb (mail_op, user_data);
5255 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5258 GObject *win = NULL;
5260 #ifndef MODEST_TOOLKIT_HILDON2
5261 ModestWindow *main_window = NULL;
5263 /* Disable next automatic folder selection */
5264 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5265 FALSE); /* don't create */
5267 GtkWidget *folder_view = NULL;
5269 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5270 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5271 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5273 if (user_data && TNY_IS_FOLDER (user_data)) {
5274 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5275 TNY_FOLDER (user_data), FALSE);
5279 /* Show notification dialog only if the main window exists */
5280 win = modest_mail_operation_get_source (mail_op);
5281 modest_platform_run_information_dialog ((GtkWindow *) win,
5282 _("mail_in_ui_folder_move_target_error"),
5285 g_object_unref (win);
5289 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5298 gint pending_purges = 0;
5299 gboolean some_purged = FALSE;
5300 ModestWindow *win = MODEST_WINDOW (user_data);
5301 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5303 /* If there was any error */
5304 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5305 modest_window_mgr_unregister_header (mgr, header);
5309 /* Once the message has been retrieved for purging, we check if
5310 * it's all ok for purging */
5312 parts = tny_simple_list_new ();
5313 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5314 iter = tny_list_create_iterator (parts);
5316 while (!tny_iterator_is_done (iter)) {
5318 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5319 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5320 if (tny_mime_part_is_purged (part))
5327 g_object_unref (part);
5329 tny_iterator_next (iter);
5331 g_object_unref (iter);
5334 if (pending_purges>0) {
5336 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5338 if (response == GTK_RESPONSE_OK) {
5341 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5342 iter = tny_list_create_iterator (parts);
5343 while (!tny_iterator_is_done (iter)) {
5346 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5347 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5348 tny_mime_part_set_purged (part);
5351 g_object_unref (part);
5353 tny_iterator_next (iter);
5355 g_object_unref (iter);
5357 tny_msg_rewrite_cache (msg);
5359 gtk_widget_destroy (info);
5363 modest_window_mgr_unregister_header (mgr, header);
5365 g_object_unref (parts);
5369 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5370 ModestMainWindow *win)
5372 GtkWidget *header_view;
5373 TnyList *header_list;
5375 TnyHeaderFlags flags;
5376 ModestWindow *msg_view_window = NULL;
5379 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5381 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5382 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5384 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5386 g_warning ("%s: no header selected", __FUNCTION__);
5390 if (tny_list_get_length (header_list) == 1) {
5391 TnyIterator *iter = tny_list_create_iterator (header_list);
5392 header = TNY_HEADER (tny_iterator_get_current (iter));
5393 g_object_unref (iter);
5397 if (!header || !TNY_IS_HEADER(header)) {
5398 g_warning ("%s: header is not valid", __FUNCTION__);
5402 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5403 header, &msg_view_window);
5404 flags = tny_header_get_flags (header);
5405 if (!(flags & TNY_HEADER_FLAG_CACHED))
5408 if (msg_view_window != NULL)
5409 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5411 /* do nothing; uid was registered before, so window is probably on it's way */
5412 g_warning ("debug: header %p has already been registered", header);
5415 ModestMailOperation *mail_op = NULL;
5416 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5417 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5418 modest_ui_actions_disk_operations_error_handler,
5420 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5421 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5423 g_object_unref (mail_op);
5426 g_object_unref (header);
5428 g_object_unref (header_list);
5432 * Checks if we need a connection to do the transfer and if the user
5433 * wants to connect to complete it
5436 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5437 TnyFolderStore *src_folder,
5439 TnyFolder *dst_folder,
5440 gboolean delete_originals,
5441 gboolean *need_connection,
5444 TnyAccount *src_account;
5445 gint uncached_msgs = 0;
5447 /* We don't need any further check if
5449 * 1- the source folder is local OR
5450 * 2- the device is already online
5452 if (!modest_tny_folder_store_is_remote (src_folder) ||
5453 tny_device_is_online (modest_runtime_get_device())) {
5454 *need_connection = FALSE;
5459 /* We must ask for a connection when
5461 * - the message(s) is not already cached OR
5462 * - the message(s) is cached but the leave_on_server setting
5463 * is FALSE (because we need to sync the source folder to
5464 * delete the message from the server (for IMAP we could do it
5465 * offline, it'll take place the next time we get a
5468 uncached_msgs = header_list_count_uncached_msgs (headers);
5469 src_account = get_account_from_folder_store (src_folder);
5470 if (uncached_msgs > 0) {
5474 *need_connection = TRUE;
5475 num_headers = tny_list_get_length (headers);
5476 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5478 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5479 GTK_RESPONSE_CANCEL) {
5485 /* The transfer is possible and the user wants to */
5488 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5489 const gchar *account_name;
5490 gboolean leave_on_server;
5492 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5493 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5496 if (leave_on_server == TRUE) {
5497 *need_connection = FALSE;
5499 *need_connection = TRUE;
5502 *need_connection = FALSE;
5507 g_object_unref (src_account);
5511 xfer_messages_error_handler (ModestMailOperation *mail_op,
5515 const GError *error;
5517 win = modest_mail_operation_get_source (mail_op);
5518 error = modest_mail_operation_get_error (mail_op);
5520 if (error && is_memory_full_error ((GError *) error, mail_op)) {
5521 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
5522 modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
5525 modest_platform_run_information_dialog ((GtkWindow *) win,
5526 _("mail_in_ui_folder_move_target_error"),
5530 g_object_unref (win);
5534 TnyFolderStore *dst_folder;
5539 * Utility function that transfer messages from both the main window
5540 * and the msg view window when using the "Move to" dialog
5543 xfer_messages_performer (gboolean canceled,
5545 GtkWindow *parent_window,
5546 TnyAccount *account,
5549 ModestWindow *win = MODEST_WINDOW (parent_window);
5550 TnyAccount *dst_account = NULL;
5551 gboolean dst_forbids_message_add = FALSE;
5552 XferMsgsHelper *helper;
5553 MoveToHelper *movehelper;
5554 ModestMailOperation *mail_op;
5556 helper = (XferMsgsHelper *) user_data;
5558 if (canceled || err) {
5559 if (!check_memory_full_error ((GtkWidget *) parent_window, err)) {
5560 /* Show the proper error message */
5561 modest_ui_actions_on_account_connection_error (parent_window, account);
5566 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5568 /* tinymail will return NULL for local folders it seems */
5569 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5570 modest_tny_account_get_protocol_type (dst_account),
5571 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_MESSAGE_ADD);
5572 g_object_unref (dst_account);
5574 if (dst_forbids_message_add) {
5575 modest_platform_information_banner (GTK_WIDGET (win),
5577 ngettext("mail_in_ui_folder_move_target_error",
5578 "mail_in_ui_folder_move_targets_error",
5579 tny_list_get_length (helper->headers)));
5583 movehelper = g_new0 (MoveToHelper, 1);
5585 #ifndef MODEST_TOOLKIT_HILDON2
5586 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5587 _CS("ckct_nw_pasting"));
5588 if (movehelper->banner != NULL) {
5589 g_object_ref (movehelper->banner);
5590 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5594 if (MODEST_IS_MAIN_WINDOW (win)) {
5595 GtkWidget *header_view =
5596 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5597 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5598 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5601 /* Perform the mail operation */
5602 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5603 xfer_messages_error_handler,
5605 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5608 modest_mail_operation_xfer_msgs (mail_op,
5610 TNY_FOLDER (helper->dst_folder),
5615 g_object_unref (G_OBJECT (mail_op));
5617 g_object_unref (helper->dst_folder);
5618 g_object_unref (helper->headers);
5619 g_slice_free (XferMsgsHelper, helper);
5623 TnyFolder *src_folder;
5624 TnyFolderStore *dst_folder;
5625 gboolean delete_original;
5626 GtkWidget *folder_view;
5630 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
5631 TnyAccount *account, gpointer user_data)
5633 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5634 GtkTreeSelection *sel;
5635 ModestMailOperation *mail_op = NULL;
5637 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
5638 g_object_unref (G_OBJECT (info->src_folder));
5639 g_object_unref (G_OBJECT (info->dst_folder));
5644 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5645 #ifndef MODEST_TOOLKIT_HILDON2
5646 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5647 _CS("ckct_nw_pasting"));
5648 if (helper->banner != NULL) {
5649 g_object_ref (helper->banner);
5650 gtk_widget_show (GTK_WIDGET(helper->banner));
5653 /* Clean folder on header view before moving it */
5654 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5655 gtk_tree_selection_unselect_all (sel);
5657 /* Let gtk events run. We need that the folder
5658 view frees its reference to the source
5659 folder *before* issuing the mail operation
5660 so we need the signal handler of selection
5661 changed to happen before the mail
5663 while (gtk_events_pending ())
5664 gtk_main_iteration (); */
5667 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5668 modest_ui_actions_move_folder_error_handler,
5669 info->src_folder, NULL);
5670 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5673 /* Select *after* the changes */
5674 /* TODO: this function hangs UI after transfer */
5675 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
5676 /* TNY_FOLDER (src_folder), TRUE); */
5678 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
5679 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5680 TNY_FOLDER (info->dst_folder), TRUE);
5682 modest_mail_operation_xfer_folder (mail_op,
5683 TNY_FOLDER (info->src_folder),
5685 info->delete_original,
5688 g_object_unref (G_OBJECT (info->src_folder));
5690 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5693 /* Unref mail operation */
5694 g_object_unref (G_OBJECT (mail_op));
5695 g_object_unref (G_OBJECT (info->dst_folder));
5700 get_account_from_folder_store (TnyFolderStore *folder_store)
5702 if (TNY_IS_ACCOUNT (folder_store))
5703 return g_object_ref (folder_store);
5705 return tny_folder_get_account (TNY_FOLDER (folder_store));
5709 * UI handler for the "Move to" action when invoked from the
5713 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5714 GtkWidget *folder_view,
5715 TnyFolderStore *dst_folder,
5716 ModestMainWindow *win)
5718 ModestHeaderView *header_view = NULL;
5719 TnyFolderStore *src_folder = NULL;
5721 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5723 /* Get the source folder */
5724 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5726 /* Get header view */
5727 header_view = (ModestHeaderView *)
5728 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5730 /* Get folder or messages to transfer */
5731 if (gtk_widget_is_focus (folder_view)) {
5732 gboolean do_xfer = TRUE;
5734 /* Allow only to transfer folders to the local root folder */
5735 if (TNY_IS_ACCOUNT (dst_folder) &&
5736 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5737 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5739 } else if (!TNY_IS_FOLDER (src_folder)) {
5740 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5745 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5746 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5748 info->src_folder = g_object_ref (src_folder);
5749 info->dst_folder = g_object_ref (dst_folder);
5750 info->delete_original = TRUE;
5751 info->folder_view = folder_view;
5753 connect_info->callback = on_move_folder_cb;
5754 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5755 connect_info->data = info;
5757 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5758 TNY_FOLDER_STORE (src_folder),
5761 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5764 headers = modest_header_view_get_selected_headers(header_view);
5766 /* Transfer the messages */
5767 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
5768 headers, TNY_FOLDER (dst_folder));
5770 g_object_unref (headers);
5774 g_object_unref (src_folder);
5777 #ifdef MODEST_TOOLKIT_HILDON2
5779 * UI handler for the "Move to" action when invoked from the
5780 * ModestFolderWindow
5783 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
5784 TnyFolderStore *dst_folder,
5788 TnyFolderStore *src_folder = NULL;
5789 TnyIterator *iterator;
5791 if (tny_list_get_length (selection) != 1)
5794 iterator = tny_list_create_iterator (selection);
5795 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
5796 g_object_unref (iterator);
5799 gboolean do_xfer = TRUE;
5801 /* Allow only to transfer folders to the local root folder */
5802 if (TNY_IS_ACCOUNT (dst_folder) &&
5803 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5804 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5807 modest_platform_run_information_dialog (win,
5808 _("mail_in_ui_folder_move_target_error"),
5810 } else if (!TNY_IS_FOLDER (src_folder)) {
5811 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5816 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5817 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5819 info->src_folder = g_object_ref (src_folder);
5820 info->dst_folder = g_object_ref (dst_folder);
5821 info->delete_original = TRUE;
5822 info->folder_view = folder_view;
5824 connect_info->callback = on_move_folder_cb;
5825 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5826 connect_info->data = info;
5828 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5829 TNY_FOLDER_STORE (src_folder),
5834 g_object_unref (src_folder);
5840 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
5841 TnyFolder *src_folder,
5843 TnyFolder *dst_folder)
5845 gboolean need_connection = TRUE;
5846 gboolean do_xfer = TRUE;
5847 XferMsgsHelper *helper;
5849 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5850 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5851 g_return_if_fail (TNY_IS_LIST (headers));
5853 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5854 headers, TNY_FOLDER (dst_folder),
5855 TRUE, &need_connection,
5858 /* If we don't want to transfer just return */
5862 /* Create the helper */
5863 helper = g_slice_new (XferMsgsHelper);
5864 helper->dst_folder = g_object_ref (dst_folder);
5865 helper->headers = g_object_ref (headers);
5867 if (need_connection) {
5868 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5869 connect_info->callback = xfer_messages_performer;
5870 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5871 connect_info->data = helper;
5873 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5874 TNY_FOLDER_STORE (src_folder),
5877 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5878 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
5879 src_account, helper);
5880 g_object_unref (src_account);
5885 * UI handler for the "Move to" action when invoked from the
5886 * ModestMsgViewWindow
5889 modest_ui_actions_on_window_move_to (GtkAction *action,
5891 TnyFolderStore *dst_folder,
5894 TnyFolder *src_folder = NULL;
5896 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5899 TnyHeader *header = NULL;
5902 iter = tny_list_create_iterator (headers);
5903 header = (TnyHeader *) tny_iterator_get_current (iter);
5904 src_folder = tny_header_get_folder (header);
5906 /* Transfer the messages */
5907 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
5909 TNY_FOLDER (dst_folder));
5912 g_object_unref (header);
5913 g_object_unref (iter);
5914 g_object_unref (src_folder);
5919 modest_ui_actions_on_move_to (GtkAction *action,
5922 modest_ui_actions_on_edit_mode_move_to (win);
5926 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
5928 GtkWidget *dialog = NULL;
5929 MoveToInfo *helper = NULL;
5930 TnyList *list_to_move;
5932 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
5934 #ifndef MODEST_TOOLKIT_HILDON2
5935 /* Get the main window if exists */
5936 ModestMainWindow *main_window;
5937 if (MODEST_IS_MAIN_WINDOW (win))
5938 main_window = MODEST_MAIN_WINDOW (win);
5941 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5942 FALSE)); /* don't create */
5945 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
5950 if (tny_list_get_length (list_to_move) < 1) {
5951 g_object_unref (list_to_move);
5955 /* Create and run the dialog */
5956 dialog = create_move_to_dialog (GTK_WINDOW (win), NULL, list_to_move);
5957 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
5958 GTK_WINDOW (dialog),
5962 helper = g_slice_new0 (MoveToInfo);
5963 helper->list = list_to_move;
5966 /* Listen to response signal */
5967 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
5969 /* Show the dialog */
5970 gtk_widget_show (dialog);
5976 * Calls #HeadersFunc for each header already selected in the main
5977 * window or the message currently being shown in the msg view window
5980 do_headers_action (ModestWindow *win,
5984 TnyList *headers_list = NULL;
5985 TnyIterator *iter = NULL;
5986 TnyHeader *header = NULL;
5987 TnyFolder *folder = NULL;
5990 headers_list = get_selected_headers (win);
5994 /* Get the folder */
5995 iter = tny_list_create_iterator (headers_list);
5996 header = TNY_HEADER (tny_iterator_get_current (iter));
5998 folder = tny_header_get_folder (header);
5999 g_object_unref (header);
6002 /* Call the function for each header */
6003 while (!tny_iterator_is_done (iter)) {
6004 header = TNY_HEADER (tny_iterator_get_current (iter));
6005 func (header, win, user_data);
6006 g_object_unref (header);
6007 tny_iterator_next (iter);
6010 /* Trick: do a poke status in order to speed up the signaling
6013 tny_folder_poke_status (folder);
6014 g_object_unref (folder);
6018 g_object_unref (iter);
6019 g_object_unref (headers_list);
6023 modest_ui_actions_view_attachment (GtkAction *action,
6024 ModestWindow *window)
6026 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6027 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
6029 /* not supported window for this action */
6030 g_return_if_reached ();
6035 modest_ui_actions_save_attachments (GtkAction *action,
6036 ModestWindow *window)
6038 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6040 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
6043 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
6045 /* not supported window for this action */
6046 g_return_if_reached ();
6051 modest_ui_actions_remove_attachments (GtkAction *action,
6052 ModestWindow *window)
6054 if (MODEST_IS_MAIN_WINDOW (window)) {
6055 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
6056 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
6057 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
6059 /* not supported window for this action */
6060 g_return_if_reached ();
6065 modest_ui_actions_on_settings (GtkAction *action,
6070 dialog = modest_platform_get_global_settings_dialog ();
6071 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
6072 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
6073 gtk_widget_show_all (dialog);
6075 gtk_dialog_run (GTK_DIALOG (dialog));
6077 gtk_widget_destroy (dialog);
6081 modest_ui_actions_on_help (GtkAction *action,
6084 /* Help app is not available at all in fremantle */
6085 #ifndef MODEST_TOOLKIT_HILDON2
6086 const gchar *help_id;
6088 g_return_if_fail (win && GTK_IS_WINDOW(win));
6090 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
6093 modest_platform_show_help (GTK_WINDOW (win), help_id);
6098 modest_ui_actions_on_csm_help (GtkAction *action,
6101 /* Help app is not available at all in fremantle */
6102 #ifndef MODEST_TOOLKIT_HILDON2
6104 const gchar* help_id = NULL;
6105 GtkWidget *folder_view;
6106 TnyFolderStore *folder_store;
6108 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
6110 /* Get selected folder */
6111 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
6112 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6113 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6115 /* Switch help_id */
6116 if (folder_store && TNY_IS_FOLDER (folder_store))
6117 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
6120 g_object_unref (folder_store);
6123 modest_platform_show_help (GTK_WINDOW (win), help_id);
6125 modest_ui_actions_on_help (action, win);
6130 retrieve_contents_cb (ModestMailOperation *mail_op,
6137 /* We only need this callback to show an error in case of
6138 memory low condition */
6139 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
6140 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
6145 retrieve_msg_contents_performer (gboolean canceled,
6147 GtkWindow *parent_window,
6148 TnyAccount *account,
6151 ModestMailOperation *mail_op;
6152 TnyList *headers = TNY_LIST (user_data);
6154 if (err || canceled) {
6155 check_memory_full_error ((GtkWidget *) parent_window, err);
6159 /* Create mail operation */
6160 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
6161 modest_ui_actions_disk_operations_error_handler,
6163 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
6164 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
6167 g_object_unref (mail_op);
6169 g_object_unref (headers);
6170 g_object_unref (account);
6174 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
6175 ModestWindow *window)
6177 TnyList *headers = NULL;
6178 TnyAccount *account = NULL;
6179 TnyIterator *iter = NULL;
6180 TnyHeader *header = NULL;
6181 TnyFolder *folder = NULL;
6184 headers = get_selected_headers (window);
6188 /* Pick the account */
6189 iter = tny_list_create_iterator (headers);
6190 header = TNY_HEADER (tny_iterator_get_current (iter));
6191 folder = tny_header_get_folder (header);
6192 account = tny_folder_get_account (folder);
6193 g_object_unref (folder);
6194 g_object_unref (header);
6195 g_object_unref (iter);
6197 /* Connect and perform the message retrieval */
6198 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6199 g_object_ref (account),
6200 retrieve_msg_contents_performer,
6201 g_object_ref (headers));
6204 g_object_unref (account);
6205 g_object_unref (headers);
6209 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6211 g_return_if_fail (MODEST_IS_WINDOW (window));
6214 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6218 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6220 g_return_if_fail (MODEST_IS_WINDOW (window));
6223 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6227 modest_ui_actions_on_email_menu_activated (GtkAction *action,
6228 ModestWindow *window)
6230 g_return_if_fail (MODEST_IS_WINDOW (window));
6233 modest_ui_actions_check_menu_dimming_rules (window);
6237 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
6238 ModestWindow *window)
6240 g_return_if_fail (MODEST_IS_WINDOW (window));
6243 modest_ui_actions_check_menu_dimming_rules (window);
6247 modest_ui_actions_on_view_menu_activated (GtkAction *action,
6248 ModestWindow *window)
6250 g_return_if_fail (MODEST_IS_WINDOW (window));
6253 modest_ui_actions_check_menu_dimming_rules (window);
6257 modest_ui_actions_on_format_menu_activated (GtkAction *action,
6258 ModestWindow *window)
6260 g_return_if_fail (MODEST_IS_WINDOW (window));
6263 modest_ui_actions_check_menu_dimming_rules (window);
6267 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
6268 ModestWindow *window)
6270 g_return_if_fail (MODEST_IS_WINDOW (window));
6273 modest_ui_actions_check_menu_dimming_rules (window);
6277 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
6278 ModestWindow *window)
6280 g_return_if_fail (MODEST_IS_WINDOW (window));
6283 modest_ui_actions_check_menu_dimming_rules (window);
6287 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
6288 ModestWindow *window)
6290 g_return_if_fail (MODEST_IS_WINDOW (window));
6293 modest_ui_actions_check_menu_dimming_rules (window);
6297 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
6298 ModestWindow *window)
6300 g_return_if_fail (MODEST_IS_WINDOW (window));
6303 modest_ui_actions_check_menu_dimming_rules (window);
6307 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
6308 ModestWindow *window)
6310 g_return_if_fail (MODEST_IS_WINDOW (window));
6313 modest_ui_actions_check_menu_dimming_rules (window);
6317 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6319 g_return_if_fail (MODEST_IS_WINDOW (window));
6321 /* we check for low-mem; in that case, show a warning, and don't allow
6324 if (modest_platform_check_memory_low (window, TRUE))
6327 modest_platform_show_search_messages (GTK_WINDOW (window));
6331 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6333 g_return_if_fail (MODEST_IS_WINDOW (win));
6336 /* we check for low-mem; in that case, show a warning, and don't allow
6337 * for the addressbook
6339 if (modest_platform_check_memory_low (win, TRUE))
6343 modest_platform_show_addressbook (GTK_WINDOW (win));
6348 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6349 ModestWindow *window)
6352 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6354 if (GTK_IS_TOGGLE_ACTION (action))
6355 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6359 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window),
6364 on_send_receive_finished (ModestMailOperation *mail_op,
6367 GtkWidget *header_view, *folder_view;
6368 TnyFolderStore *folder_store;
6369 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6371 /* Set send/receive operation finished */
6372 modest_main_window_notify_send_receive_completed (main_win);
6374 /* Don't refresh the current folder if there were any errors */
6375 if (modest_mail_operation_get_status (mail_op) !=
6376 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6379 /* Refresh the current folder if we're viewing a window. We do
6380 this because the user won't be able to see the new mails in
6381 the selected folder after a Send&Receive because it only
6382 performs a poke_status, i.e, only the number of read/unread
6383 messages is updated, but the new headers are not
6385 folder_view = modest_main_window_get_child_widget (main_win,
6386 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6390 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6392 /* Do not need to refresh INBOX again because the
6393 update_account does it always automatically */
6394 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6395 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6396 ModestMailOperation *refresh_op;
6398 header_view = modest_main_window_get_child_widget (main_win,
6399 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6401 /* We do not need to set the contents style
6402 because it hasn't changed. We also do not
6403 need to save the widget status. Just force
6405 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6406 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6407 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6408 folder_refreshed_cb, main_win);
6409 g_object_unref (refresh_op);
6413 g_object_unref (folder_store);
6418 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6424 const gchar* server_name = NULL;
6425 TnyTransportAccount *transport;
6426 gchar *message = NULL;
6427 ModestProtocol *protocol;
6429 /* Don't show anything if the user cancelled something or the
6430 * send receive request is not interactive. Authentication
6431 * errors are managed by the account store so no need to show
6432 * a dialog here again */
6433 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6434 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6435 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6439 /* Get the server name. Note that we could be using a
6440 connection specific transport account */
6441 transport = (TnyTransportAccount *)
6442 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
6444 ModestTnyAccountStore *acc_store;
6445 const gchar *acc_name;
6446 TnyTransportAccount *conn_specific;
6448 acc_store = modest_runtime_get_account_store();
6449 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
6450 conn_specific = (TnyTransportAccount *)
6451 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
6452 if (conn_specific) {
6453 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
6454 g_object_unref (conn_specific);
6456 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
6458 g_object_unref (transport);
6462 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
6463 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
6464 tny_account_get_proto (TNY_ACCOUNT (transport)));
6466 g_warning ("%s: Account with no proto", __FUNCTION__);
6470 /* Show the appropriate message text for the GError: */
6471 switch (err->code) {
6472 case TNY_SERVICE_ERROR_CONNECT:
6473 message = modest_protocol_get_translation (protocol,
6474 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
6477 case TNY_SERVICE_ERROR_SEND:
6478 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6480 case TNY_SERVICE_ERROR_UNAVAILABLE:
6481 message = modest_protocol_get_translation (protocol,
6482 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
6486 g_warning ("%s: unexpected ERROR %d",
6487 __FUNCTION__, err->code);
6488 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6492 modest_platform_run_information_dialog (NULL, message, FALSE);
6497 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6502 ModestWindow *top_window = NULL;
6503 ModestWindowMgr *mgr = NULL;
6504 GtkWidget *header_view = NULL;
6505 TnyFolder *selected_folder = NULL;
6506 TnyFolderType folder_type;
6508 mgr = modest_runtime_get_window_mgr ();
6509 top_window = modest_window_mgr_get_current_top (mgr);
6514 #ifndef MODEST_TOOLKIT_HILDON2
6515 if (MODEST_IS_MAIN_WINDOW (top_window)) {
6516 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (top_window),
6517 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6520 if (MODEST_IS_HEADER_WINDOW (top_window)) {
6521 header_view = (GtkWidget *)
6522 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
6526 /* Get selected folder */
6528 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
6529 if (!selected_folder)
6532 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6533 #if GTK_CHECK_VERSION(2, 8, 0)
6534 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
6535 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6536 GtkTreeViewColumn *tree_column;
6538 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6539 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6541 gtk_tree_view_column_queue_resize (tree_column);
6543 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
6544 gtk_widget_queue_draw (header_view);
6547 #ifndef MODEST_TOOLKIT_HILDON2
6548 /* Rerun dimming rules, because the message could become deletable for example */
6549 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6550 MODEST_DIMMING_RULES_TOOLBAR);
6551 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
6552 MODEST_DIMMING_RULES_MENU);
6556 g_object_unref (selected_folder);
6560 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6561 TnyAccount *account)
6563 ModestProtocolType protocol_type;
6564 ModestProtocol *protocol;
6565 gchar *error_note = NULL;
6567 protocol_type = modest_tny_account_get_protocol_type (account);
6568 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6571 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6572 if (error_note == NULL) {
6573 g_warning ("%s: This should not be reached", __FUNCTION__);
6575 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6576 g_free (error_note);
6581 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6585 TnyFolderStore *folder = NULL;
6586 TnyAccount *account = NULL;
6587 ModestProtocolType proto;
6588 ModestProtocol *protocol;
6589 TnyHeader *header = NULL;
6591 if (MODEST_IS_MAIN_WINDOW (win)) {
6592 GtkWidget *header_view;
6593 TnyList* headers = NULL;
6595 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6596 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6597 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6598 if (!headers || tny_list_get_length (headers) == 0) {
6600 g_object_unref (headers);
6603 iter = tny_list_create_iterator (headers);
6604 header = TNY_HEADER (tny_iterator_get_current (iter));
6605 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6606 g_object_unref (iter);
6607 g_object_unref (headers);
6608 #ifdef MODEST_TOOLKIT_HILDON2
6609 } else if (MODEST_IS_HEADER_WINDOW (win)) {
6610 GtkWidget *header_view;
6611 TnyList* headers = NULL;
6613 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
6614 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6615 if (!headers || tny_list_get_length (headers) == 0) {
6617 g_object_unref (headers);
6620 iter = tny_list_create_iterator (headers);
6621 header = TNY_HEADER (tny_iterator_get_current (iter));
6623 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6625 g_warning ("List should contain headers");
6627 g_object_unref (iter);
6628 g_object_unref (headers);
6630 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6631 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6633 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6636 if (!header || !folder)
6639 /* Get the account type */
6640 account = tny_folder_get_account (TNY_FOLDER (folder));
6641 proto = modest_tny_account_get_protocol_type (account);
6642 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6645 subject = tny_header_dup_subject (header);
6646 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6650 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6656 g_object_unref (account);
6658 g_object_unref (folder);
6660 g_object_unref (header);
6666 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6667 const gchar *account_name,
6668 const gchar *account_title)
6670 ModestAccountMgr *account_mgr;
6673 ModestProtocol *protocol;
6674 gboolean removed = FALSE;
6676 g_return_val_if_fail (account_name, FALSE);
6677 g_return_val_if_fail (account_title, FALSE);
6679 account_mgr = modest_runtime_get_account_mgr();
6681 /* The warning text depends on the account type: */
6682 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6683 modest_account_mgr_get_store_protocol (account_mgr,
6685 txt = modest_protocol_get_translation (protocol,
6686 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6689 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6691 response = modest_platform_run_confirmation_dialog (parent_window, txt);
6695 if (response == GTK_RESPONSE_OK) {
6696 /* Remove account. If it succeeds then it also removes
6697 the account from the ModestAccountView: */
6698 gboolean is_default = FALSE;
6699 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6700 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6702 g_free (default_account_name);
6704 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6706 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
6712 modest_ui_actions_on_fetch_images (GtkAction *action,
6713 ModestWindow *window)
6715 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
6717 modest_msg_view_window_fetch_images (MODEST_MSG_VIEW_WINDOW (window));
6722 modest_ui_actions_on_reload_message (const gchar *msg_id)
6724 ModestWindow *window = NULL;
6726 g_return_if_fail (msg_id && msg_id[0] != '\0');
6727 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
6733 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
6736 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));