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-tny-folder.h>
39 #include <modest-tny-msg.h>
40 #include <modest-tny-account.h>
41 #include <modest-address-book.h>
42 #include "modest-error.h"
43 #include "modest-ui-actions.h"
44 #include "modest-tny-platform-factory.h"
45 #include "modest-platform.h"
46 #include "modest-debug.h"
47 #include <tny-mime-part.h>
48 #include <tny-camel-folder.h>
49 #include <tny-camel-imap-folder.h>
50 #include <tny-camel-pop-folder.h>
51 #ifdef MODEST_TOOLKIT_HILDON2
52 #include <hildon/hildon-pannable-area.h>
55 #ifdef MODEST_PLATFORM_MAEMO
56 #include "maemo/modest-osso-state-saving.h"
57 #endif /* MODEST_PLATFORM_MAEMO */
58 #ifndef MODEST_TOOLKIT_GTK
59 #include "maemo/modest-hildon-includes.h"
60 #include "maemo/modest-connection-specific-smtp-window.h"
61 #endif /* !MODEST_TOOLKIT_GTK */
62 #include <modest-utils.h>
64 #include "widgets/modest-ui-constants.h"
65 #include <widgets/modest-main-window.h>
66 #include <widgets/modest-msg-view-window.h>
67 #include <widgets/modest-account-view-window.h>
68 #include <widgets/modest-details-dialog.h>
69 #include <widgets/modest-attachments-view.h>
70 #include "widgets/modest-folder-view.h"
71 #include "widgets/modest-global-settings-dialog.h"
72 #include "modest-account-mgr-helpers.h"
73 #include "modest-mail-operation.h"
74 #include "modest-text-utils.h"
76 #ifdef MODEST_HAVE_EASYSETUP
77 #ifdef MODEST_TOOLKIT_HILDON2
78 #include "modest-easysetup-wizard-dialog.h"
80 #include "easysetup/modest-easysetup-wizard-dialog.h"
82 #endif /* MODEST_HAVE_EASYSETUP */
84 #include <modest-widget-memory.h>
85 #include <tny-error.h>
86 #include <tny-simple-list.h>
87 #include <tny-msg-view.h>
88 #include <tny-device.h>
89 #include <tny-merge-folder.h>
91 #include <gtkhtml/gtkhtml.h>
93 #define MIN_FREE_SPACE 5 * 1024 * 1024
94 #define MOVE_FOLDER_OK_BUTTON "ok-button"
95 #define MOVE_FOLDER_NEW_BUTTON "new-button"
97 typedef struct _GetMsgAsyncHelper {
99 ModestMailOperation *mail_op;
106 typedef enum _ReplyForwardAction {
110 } ReplyForwardAction;
112 typedef struct _ReplyForwardHelper {
113 guint reply_forward_type;
114 ReplyForwardAction action;
116 GtkWidget *parent_window;
118 } ReplyForwardHelper;
120 typedef struct _MoveToHelper {
121 GtkTreeRowReference *reference;
125 typedef struct _PasteAsAttachmentHelper {
126 ModestMsgEditWindow *window;
128 } PasteAsAttachmentHelper;
132 * The do_headers_action uses this kind of functions to perform some
133 * action to each member of a list of headers
135 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
137 static void do_headers_action (ModestWindow *win,
141 static void open_msg_cb (ModestMailOperation *mail_op,
148 static void reply_forward_cb (ModestMailOperation *mail_op,
155 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
157 static void folder_refreshed_cb (ModestMailOperation *mail_op,
161 static void on_send_receive_finished (ModestMailOperation *mail_op,
164 static gint header_list_count_uncached_msgs (TnyList *header_list);
166 static gboolean connect_to_get_msg (ModestWindow *win,
167 gint num_of_uncached_msgs,
168 TnyAccount *account);
170 static gboolean remote_folder_has_leave_on_server (TnyFolderStore *folder);
172 static void do_create_folder (GtkWindow *window,
173 TnyFolderStore *parent_folder,
174 const gchar *suggested_name);
176 static GtkWidget* get_folder_view_from_move_to_dialog (GtkWidget *move_to_dialog);
178 static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store);
181 * This function checks whether a TnyFolderStore is a pop account
184 remote_folder_has_leave_on_server (TnyFolderStore *folder)
189 g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
191 account = get_account_from_folder_store (folder);
192 result = (modest_protocol_registry_protocol_type_has_leave_on_server (modest_runtime_get_protocol_registry (),
193 modest_tny_account_get_protocol_type (account)));
194 g_object_unref (account);
199 /* FIXME: this should be merged with the similar code in modest-account-view-window */
200 /* Show the account creation wizard dialog.
201 * returns: TRUE if an account was created. FALSE if the user cancelled.
204 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
206 gboolean result = FALSE;
208 gint dialog_response;
210 /* there is no such wizard yet */
211 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
212 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (wizard), (GtkWindow *) win);
214 /* always present a main window in the background
215 * we do it here, so we cannot end up with two wizards (as this
216 * function might be called in modest_window_mgr_get_main_window as well */
218 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
219 TRUE); /* create if not existent */
221 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
223 /* make sure the mainwindow is visible. We need to present the
224 wizard again to give it the focus back. show_all are needed
225 in order to get the widgets properly drawn (MainWindow main
226 paned won't be in its right position and the dialog will be
228 #ifndef MODEST_TOOLKIT_HILDON2
229 gtk_widget_show_all (GTK_WIDGET (win));
230 gtk_widget_show_all (GTK_WIDGET (wizard));
231 gtk_window_present (GTK_WINDOW (win));
232 gtk_window_present (GTK_WINDOW (wizard));
235 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
236 gtk_widget_destroy (GTK_WIDGET (wizard));
237 if (gtk_events_pending ())
238 gtk_main_iteration ();
240 if (dialog_response == GTK_RESPONSE_CANCEL) {
243 /* Check whether an account was created: */
244 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
251 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
254 const gchar *authors[] = {
255 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
258 about = gtk_about_dialog_new ();
259 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
260 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
261 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
262 _("Copyright (c) 2006, Nokia Corporation\n"
263 "All rights reserved."));
264 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
265 _("a modest e-mail client\n\n"
266 "design and implementation: Dirk-Jan C. Binnema\n"
267 "contributions from the fine people at KC and Ig\n"
268 "uses the tinymail email framework written by Philip van Hoof"));
269 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
270 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
271 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
272 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
274 gtk_dialog_run (GTK_DIALOG (about));
275 gtk_widget_destroy(about);
279 * Gets the list of currently selected messages. If the win is the
280 * main window, then it returns a newly allocated list of the headers
281 * selected in the header view. If win is the msg view window, then
282 * the value returned is a list with just a single header.
284 * The caller of this funcion must free the list.
287 get_selected_headers (ModestWindow *win)
289 if (MODEST_IS_MAIN_WINDOW(win)) {
290 GtkWidget *header_view;
292 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
293 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
294 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
296 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
297 /* for MsgViewWindows, we simply return a list with one element */
299 TnyList *list = NULL;
301 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
302 if (header != NULL) {
303 list = tny_simple_list_new ();
304 tny_list_prepend (list, G_OBJECT(header));
305 g_object_unref (G_OBJECT(header));
314 static GtkTreeRowReference *
315 get_next_after_selected_headers (ModestHeaderView *header_view)
317 GtkTreeSelection *sel;
318 GList *selected_rows, *node;
320 GtkTreeRowReference *result;
323 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
324 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
325 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
327 if (selected_rows == NULL)
330 node = g_list_last (selected_rows);
331 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
332 gtk_tree_path_next (path);
334 result = gtk_tree_row_reference_new (model, path);
336 gtk_tree_path_free (path);
337 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
338 g_list_free (selected_rows);
344 headers_action_mark_as_read (TnyHeader *header,
348 TnyHeaderFlags flags;
350 g_return_if_fail (TNY_IS_HEADER(header));
352 flags = tny_header_get_flags (header);
353 if (flags & TNY_HEADER_FLAG_SEEN) return;
354 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
358 headers_action_mark_as_unread (TnyHeader *header,
362 TnyHeaderFlags flags;
364 g_return_if_fail (TNY_IS_HEADER(header));
366 flags = tny_header_get_flags (header);
367 if (flags & TNY_HEADER_FLAG_SEEN) {
368 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
372 /** After deleing a message that is currently visible in a window,
373 * show the next message from the list, or close the window if there are no more messages.
376 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
378 /* Close msg view window or select next */
379 if (!modest_msg_view_window_select_next_message (win) &&
380 !modest_msg_view_window_select_previous_message (win)) {
382 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
388 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
390 TnyList *header_list = NULL;
391 TnyIterator *iter = NULL;
392 TnyHeader *header = NULL;
393 gchar *message = NULL;
396 ModestWindowMgr *mgr;
397 GtkWidget *header_view = NULL;
399 g_return_if_fail (MODEST_IS_WINDOW(win));
401 /* Check first if the header view has the focus */
402 if (MODEST_IS_MAIN_WINDOW (win)) {
404 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
405 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
406 if (!gtk_widget_is_focus (header_view))
410 /* Get the headers, either from the header view (if win is the main window),
411 * or from the message view window: */
412 header_list = get_selected_headers (win);
413 if (!header_list) return;
415 /* Check if any of the headers are already opened, or in the process of being opened */
416 if (MODEST_IS_MAIN_WINDOW (win)) {
417 gint opened_headers = 0;
419 iter = tny_list_create_iterator (header_list);
420 mgr = modest_runtime_get_window_mgr ();
421 while (!tny_iterator_is_done (iter)) {
422 header = TNY_HEADER (tny_iterator_get_current (iter));
424 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
426 g_object_unref (header);
428 tny_iterator_next (iter);
430 g_object_unref (iter);
432 if (opened_headers > 0) {
435 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
438 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg, FALSE);
441 g_object_unref (header_list);
447 if (tny_list_get_length(header_list) == 1) {
448 iter = tny_list_create_iterator (header_list);
449 header = TNY_HEADER (tny_iterator_get_current (iter));
452 subject = tny_header_dup_subject (header);
454 subject = g_strdup (_("mail_va_no_subject"));
455 desc = g_strdup_printf ("%s", subject);
457 g_object_unref (header);
460 g_object_unref (iter);
462 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
463 tny_list_get_length(header_list)), desc);
465 /* Confirmation dialog */
466 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
470 if (response == GTK_RESPONSE_OK) {
471 ModestWindow *main_window = NULL;
472 ModestWindowMgr *mgr = NULL;
473 GtkTreeModel *model = NULL;
474 GtkTreeSelection *sel = NULL;
475 GList *sel_list = NULL, *tmp = NULL;
476 GtkTreeRowReference *next_row_reference = NULL;
477 GtkTreeRowReference *prev_row_reference = NULL;
478 GtkTreePath *next_path = NULL;
479 GtkTreePath *prev_path = NULL;
480 ModestMailOperation *mail_op = NULL;
482 /* Find last selected row */
483 if (MODEST_IS_MAIN_WINDOW (win)) {
484 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
485 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
486 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
487 for (tmp=sel_list; tmp; tmp=tmp->next) {
488 if (tmp->next == NULL) {
489 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
490 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
492 gtk_tree_path_prev (prev_path);
493 gtk_tree_path_next (next_path);
495 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
496 next_row_reference = gtk_tree_row_reference_new (model, next_path);
501 /* Disable window dimming management */
502 modest_window_disable_dimming (MODEST_WINDOW(win));
504 /* Remove each header. If it's a view window header_view == NULL */
505 mail_op = modest_mail_operation_new ((GObject *) win);
506 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
508 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
509 g_object_unref (mail_op);
511 /* Enable window dimming management */
513 gtk_tree_selection_unselect_all (sel);
515 modest_window_enable_dimming (MODEST_WINDOW(win));
517 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
518 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
520 /* Get main window */
521 mgr = modest_runtime_get_window_mgr ();
522 main_window = modest_window_mgr_get_main_window (mgr, FALSE); /* don't create */
524 /* Move cursor to next row */
527 /* Select next or previous row */
528 if (gtk_tree_row_reference_valid (next_row_reference)) {
529 gtk_tree_selection_select_path (sel, next_path);
531 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
532 gtk_tree_selection_select_path (sel, prev_path);
536 if (gtk_tree_row_reference_valid (next_row_reference))
537 gtk_tree_row_reference_free (next_row_reference);
538 if (next_path != NULL)
539 gtk_tree_path_free (next_path);
540 if (gtk_tree_row_reference_valid (prev_row_reference))
541 gtk_tree_row_reference_free (prev_row_reference);
542 if (prev_path != NULL)
543 gtk_tree_path_free (prev_path);
546 /* Update toolbar dimming state */
548 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
549 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
553 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
554 g_list_free (sel_list);
560 g_object_unref (header_list);
566 /* delete either message or folder, based on where we are */
568 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
570 g_return_if_fail (MODEST_IS_WINDOW(win));
572 /* Check first if the header view has the focus */
573 if (MODEST_IS_MAIN_WINDOW (win)) {
575 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
576 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
577 if (gtk_widget_is_focus (w)) {
578 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
582 modest_ui_actions_on_delete_message (action, win);
586 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
588 ModestWindowMgr *mgr = NULL;
590 #ifdef MODEST_PLATFORM_MAEMO
591 modest_osso_save_state();
592 #endif /* MODEST_PLATFORM_MAEMO */
594 g_debug ("closing down, clearing %d item(s) from operation queue",
595 modest_mail_operation_queue_num_elements
596 (modest_runtime_get_mail_operation_queue()));
598 /* cancel all outstanding operations */
599 modest_mail_operation_queue_cancel_all
600 (modest_runtime_get_mail_operation_queue());
602 g_debug ("queue has been cleared");
605 /* Check if there are opened editing windows */
606 mgr = modest_runtime_get_window_mgr ();
607 modest_window_mgr_close_all_windows (mgr);
609 /* note: when modest-tny-account-store is finalized,
610 it will automatically set all network connections
613 /* gtk_main_quit (); */
617 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
621 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
623 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
624 /* gtk_widget_destroy (GTK_WIDGET (win)); */
625 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
626 /* gboolean ret_value; */
627 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
628 /* } else if (MODEST_IS_WINDOW (win)) { */
629 /* gtk_widget_destroy (GTK_WIDGET (win)); */
631 /* g_return_if_reached (); */
636 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
638 GtkClipboard *clipboard = NULL;
639 gchar *selection = NULL;
641 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
642 selection = gtk_clipboard_wait_for_text (clipboard);
644 /* Question: why is the clipboard being used here?
645 * It doesn't really make a lot of sense. */
649 modest_address_book_add_address (selection);
655 modest_ui_actions_on_accounts (GtkAction *action,
658 /* This is currently only implemented for Maemo */
659 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
660 if (!modest_ui_actions_run_account_setup_wizard (win))
661 g_debug ("%s: wizard was already running", __FUNCTION__);
665 /* Show the list of accounts */
666 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
668 /* The accounts dialog must be modal */
669 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
670 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
675 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
677 /* This is currently only implemented for Maemo,
678 * because it requires an API (libconic) to detect different connection
681 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
683 /* Create the window if necessary: */
684 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
685 modest_connection_specific_smtp_window_fill_with_connections (
686 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
687 modest_runtime_get_account_mgr());
689 /* Show the window: */
690 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
691 GTK_WINDOW (specific_window), (GtkWindow *) win);
692 gtk_widget_show (specific_window);
693 #endif /* !MODEST_TOOLKIT_GTK */
697 modest_ui_actions_compose_msg(ModestWindow *win,
700 const gchar *bcc_str,
701 const gchar *subject_str,
702 const gchar *body_str,
704 gboolean set_as_modified)
706 gchar *account_name = NULL;
708 TnyAccount *account = NULL;
709 TnyFolder *folder = NULL;
710 gchar *from_str = NULL, *signature = NULL, *body = NULL;
711 gboolean use_signature = FALSE;
712 ModestWindow *msg_win = NULL;
713 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
714 ModestTnyAccountStore *store = modest_runtime_get_account_store();
715 GnomeVFSFileSize total_size, allowed_size;
717 /* we check for low-mem */
718 if (modest_platform_check_memory_low (win, TRUE))
721 #ifdef MODEST_TOOLKIT_HILDON2
722 account_name = g_strdup (modest_window_get_active_account(win));
725 account_name = modest_account_mgr_get_default_account(mgr);
728 g_printerr ("modest: no account found\n");
731 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
733 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
736 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
738 g_printerr ("modest: failed to find Drafts folder\n");
741 from_str = modest_account_mgr_get_from_string (mgr, account_name);
743 g_printerr ("modest: failed get from string for '%s'\n", account_name);
747 signature = modest_account_mgr_get_signature (mgr, account_name, &use_signature);
748 if (body_str != NULL) {
749 body = use_signature ? g_strconcat(body_str, "\n--\n", signature, NULL) : g_strdup(body_str);
751 body = use_signature ? g_strconcat("\n--\n", signature, NULL) : g_strdup("");
754 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, body, NULL, NULL, NULL);
756 g_printerr ("modest: failed to create new msg\n");
760 /* Create and register edit window */
761 /* This is destroyed by TODO. */
763 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
764 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
766 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, NULL)) {
767 gtk_widget_destroy (GTK_WIDGET (msg_win));
770 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
771 gtk_widget_show_all (GTK_WIDGET (msg_win));
773 while (attachments) {
775 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
776 attachments->data, allowed_size);
778 if (total_size > allowed_size) {
779 g_warning ("%s: total size: %u",
780 __FUNCTION__, (unsigned int)total_size);
783 allowed_size -= total_size;
785 attachments = g_slist_next(attachments);
792 g_free (account_name);
794 g_object_unref (G_OBJECT(account));
796 g_object_unref (G_OBJECT(folder));
798 g_object_unref (G_OBJECT(msg));
802 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
804 /* if there are no accounts yet, just show the wizard */
805 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
806 if (!modest_ui_actions_run_account_setup_wizard (win))
809 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
814 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
818 ModestMailOperationStatus status;
820 /* If there is no message or the operation was not successful */
821 status = modest_mail_operation_get_status (mail_op);
822 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
825 /* If it's a memory low issue, then show a banner */
826 error = modest_mail_operation_get_error (mail_op);
827 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
828 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
829 GObject *source = modest_mail_operation_get_source (mail_op);
830 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
831 dgettext("ke-recv","memr_ib_operation_disabled"),
833 g_object_unref (source);
836 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
837 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
838 gchar *subject, *msg;
839 subject = tny_header_dup_subject (header);
841 subject = g_strdup (_("mail_va_no_subject"));;
842 msg = g_strdup_printf (_("emev_ni_ui_imap_message_not_available_in_server"),
844 modest_platform_run_information_dialog (NULL, msg, FALSE);
849 /* Remove the header from the preregistered uids */
850 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
868 OpenMsgBannerInfo *banner_info;
869 GHashTable *row_refs_per_header;
873 open_msg_banner_idle (gpointer userdata)
875 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
877 gdk_threads_enter ();
878 banner_info->idle_handler = 0;
879 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
881 g_object_ref (banner_info->banner);
883 gdk_threads_leave ();
890 open_msg_cb (ModestMailOperation *mail_op,
897 ModestWindowMgr *mgr = NULL;
898 ModestWindow *parent_win = NULL;
899 ModestWindow *win = NULL;
900 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
901 gchar *account = NULL;
903 gboolean open_in_editor = FALSE;
904 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
906 /* Do nothing if there was any problem with the mail
907 operation. The error will be shown by the error_handler of
908 the mail operation */
909 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
912 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
913 folder = tny_header_get_folder (header);
915 /* Mark header as read */
916 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
918 /* Gets folder type (OUTBOX headers will be opened in edit window */
919 if (modest_tny_folder_is_local_folder (folder)) {
920 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
921 if (folder_type == TNY_FOLDER_TYPE_INVALID)
922 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
926 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
927 TnyTransportAccount *traccount = NULL;
928 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
929 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
931 ModestTnySendQueue *send_queue = NULL;
932 ModestTnySendQueueStatus status;
934 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
935 TNY_ACCOUNT(traccount)));
936 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
937 if (TNY_IS_SEND_QUEUE (send_queue)) {
938 msg_id = modest_tny_send_queue_get_msg_id (header);
939 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
942 /* Only open messages in outbox with the editor if they are in Failed state */
943 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
944 open_in_editor = TRUE;
946 #ifdef MODEST_TOOLKIT_HILDON2
948 /* In Fremantle we can not
949 open any message from
950 outbox which is not in
952 g_object_unref(traccount);
957 g_object_unref(traccount);
959 g_warning("Cannot get transport account for message in outbox!!");
961 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
962 open_in_editor = TRUE; /* Open in editor if the message is in the Drafts folder */
967 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
969 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
971 if (open_in_editor) {
972 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
973 gchar *from_header = NULL, *acc_name;
975 from_header = tny_header_dup_from (header);
977 /* we cannot edit without a valid account... */
978 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
979 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
980 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
982 g_free (from_header);
987 acc_name = modest_utils_get_account_name_from_recipient (from_header);
988 g_free (from_header);
994 win = modest_msg_edit_window_new (msg, account, TRUE);
996 gchar *uid = modest_tny_folder_get_header_unique_id (header);
998 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
999 GtkTreeRowReference *row_reference;
1001 row_reference = (GtkTreeRowReference *) g_hash_table_lookup (helper->row_refs_per_header, header);
1003 win = modest_msg_view_window_new_with_header_model (msg, account, (const gchar*) uid,
1004 helper->model, row_reference);
1006 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
1011 /* Register and show new window */
1013 mgr = modest_runtime_get_window_mgr ();
1014 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1015 gtk_widget_destroy (GTK_WIDGET (win));
1018 gtk_widget_show_all (GTK_WIDGET(win));
1021 /* Update toolbar dimming state */
1022 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1023 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1029 g_object_unref (parent_win);
1030 g_object_unref (folder);
1034 is_memory_full_error (GError *error)
1036 gboolean enough_free_space = TRUE;
1037 GnomeVFSURI *cache_dir_uri;
1038 const gchar *cache_dir;
1039 GnomeVFSFileSize free_space;
1041 cache_dir = tny_account_store_get_cache_dir (TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
1042 cache_dir_uri = gnome_vfs_uri_new (cache_dir);
1043 if (gnome_vfs_get_volume_free_space (cache_dir_uri, &free_space) == GNOME_VFS_OK) {
1044 if (free_space < MIN_FREE_SPACE)
1045 enough_free_space = FALSE;
1047 gnome_vfs_uri_unref (cache_dir_uri);
1049 if ((error->code == TNY_SYSTEM_ERROR_MEMORY ||
1050 /* When asking for a mail and no space left on device
1051 tinymail returns this error */
1052 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE ||
1053 /* When the folder summary could not be read or
1055 error->code == TNY_IO_ERROR_WRITE ||
1056 error->code == TNY_IO_ERROR_READ) &&
1057 !enough_free_space) {
1065 check_memory_full_error (GtkWidget *parent_window, GError *err)
1070 if (is_memory_full_error (err))
1071 modest_platform_information_banner (parent_window,
1072 NULL, dgettext("ke-recv",
1073 "cerm_device_memory_full"));
1074 else if (err->code == TNY_SYSTEM_ERROR_MEMORY)
1075 /* If the account was created in memory full
1076 conditions then tinymail won't be able to
1077 connect so it'll return this error code */
1078 modest_platform_information_banner (parent_window,
1079 NULL, _("emev_ui_imap_inbox_select_error"));
1087 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1090 const GError *error;
1091 GObject *win = NULL;
1092 ModestMailOperationStatus status;
1094 win = modest_mail_operation_get_source (mail_op);
1095 error = modest_mail_operation_get_error (mail_op);
1096 status = modest_mail_operation_get_status (mail_op);
1098 /* If the mail op has been cancelled then it's not an error:
1099 don't show any message */
1100 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1101 if (is_memory_full_error ((GError *) error)) {
1102 modest_platform_information_banner ((GtkWidget *) win,
1103 NULL, dgettext("ke-recv",
1104 "cerm_device_memory_full"));
1105 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1106 modest_platform_information_banner ((GtkWidget *) win,
1107 NULL, _("emev_ui_imap_inbox_select_error"));
1108 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1109 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1110 modest_platform_information_banner ((GtkWidget *) win,
1111 NULL, dgettext ("hildon-common-strings", "sfil_ni_unable_to_open_file_not_found"));
1112 } else if (user_data) {
1113 modest_platform_information_banner ((GtkWidget *) win,
1119 g_object_unref (win);
1123 * Returns the account a list of headers belongs to. It returns a
1124 * *new* reference so don't forget to unref it
1127 get_account_from_header_list (TnyList *headers)
1129 TnyAccount *account = NULL;
1131 if (tny_list_get_length (headers) > 0) {
1132 TnyIterator *iter = tny_list_create_iterator (headers);
1133 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1134 TnyFolder *folder = tny_header_get_folder (header);
1137 g_object_unref (header);
1139 while (!tny_iterator_is_done (iter)) {
1140 header = TNY_HEADER (tny_iterator_get_current (iter));
1141 folder = tny_header_get_folder (header);
1144 g_object_unref (header);
1146 tny_iterator_next (iter);
1151 account = tny_folder_get_account (folder);
1152 g_object_unref (folder);
1156 g_object_unref (header);
1158 g_object_unref (iter);
1164 foreach_unregister_headers (gpointer data,
1167 ModestWindowMgr *mgr = (ModestWindowMgr *) user_data;
1168 TnyHeader *header = TNY_HEADER (data);
1170 modest_window_mgr_unregister_header (mgr, header);
1174 open_msgs_helper_destroyer (gpointer user_data)
1176 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1178 if (helper->banner_info) {
1179 g_free (helper->banner_info->message);
1180 if (helper->banner_info->idle_handler > 0) {
1181 g_source_remove (helper->banner_info->idle_handler);
1182 helper->banner_info->idle_handler = 0;
1184 if (helper->banner_info->banner != NULL) {
1185 gtk_widget_destroy (helper->banner_info->banner);
1186 g_object_unref (helper->banner_info->banner);
1187 helper->banner_info->banner = NULL;
1189 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1190 helper->banner_info = NULL;
1192 g_object_unref (helper->model);
1193 g_object_unref (helper->headers);
1194 g_hash_table_destroy (helper->row_refs_per_header);
1195 g_slice_free (OpenMsgHelper, helper);
1199 open_msgs_performer(gboolean canceled,
1201 GtkWindow *parent_window,
1202 TnyAccount *account,
1205 ModestMailOperation *mail_op = NULL;
1207 ModestProtocolType proto;
1208 TnyList *not_opened_headers;
1209 TnyConnectionStatus status;
1210 gboolean show_open_draft = FALSE;
1211 OpenMsgHelper *helper = NULL;
1213 helper = (OpenMsgHelper *) user_data;
1214 not_opened_headers = helper->headers;
1216 status = tny_account_get_connection_status (account);
1217 if (err || canceled) {
1218 /* Unregister the already registered headers */
1219 tny_list_foreach (not_opened_headers, foreach_unregister_headers,
1220 modest_runtime_get_window_mgr ());
1221 /* Free the helper */
1222 open_msgs_helper_destroyer (helper);
1224 /* In memory full conditions we could get this error here */
1225 check_memory_full_error ((GtkWidget *) parent_window, err);
1230 /* Get the error message depending on the protocol */
1231 proto = modest_tny_account_get_protocol_type (account);
1232 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1233 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1236 /* Create the error messages */
1237 if (tny_list_get_length (not_opened_headers) == 1) {
1238 ModestProtocol *protocol;
1239 ModestProtocolRegistry *protocol_registry;
1244 protocol_registry = modest_runtime_get_protocol_registry ();
1245 iter = tny_list_create_iterator (not_opened_headers);
1246 header = TNY_HEADER (tny_iterator_get_current (iter));
1247 subject = tny_header_dup_subject (header);
1249 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1250 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1253 g_object_unref (header);
1254 g_object_unref (iter);
1256 if (error_msg == NULL) {
1257 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1260 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1262 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1266 TnyFolderType folder_type;
1268 iter = tny_list_create_iterator (not_opened_headers);
1269 header = TNY_HEADER (tny_iterator_get_current (iter));
1270 folder = tny_header_get_folder (header);
1271 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1272 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1273 g_object_unref (folder);
1274 g_object_unref (header);
1275 g_object_unref (iter);
1278 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1281 /* Create the mail operation */
1283 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1284 modest_ui_actions_disk_operations_error_handler,
1286 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1289 if (show_open_draft) {
1290 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1291 #ifdef MODEST_TOOLKIT_HILDON2
1292 helper->banner_info->message = g_strdup (_("mail_me_opening"));
1294 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1296 helper->banner_info->banner = NULL;
1297 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1298 helper->banner_info);
1301 modest_mail_operation_get_msgs_full (mail_op,
1305 open_msgs_helper_destroyer);
1310 g_object_unref (mail_op);
1311 g_object_unref (account);
1315 * This function is used by both modest_ui_actions_on_open and
1316 * modest_ui_actions_on_header_activated. This way we always do the
1317 * same when trying to open messages.
1320 open_msgs_from_headers (TnyList *headers, ModestWindow *win)
1322 ModestWindowMgr *mgr = NULL;
1323 TnyIterator *iter = NULL, *iter_not_opened = NULL;
1324 TnyList *not_opened_headers = NULL;
1325 TnyHeaderFlags flags = 0;
1326 TnyAccount *account;
1327 gint uncached_msgs = 0;
1328 GtkWidget *header_view;
1329 GtkTreeModel *model;
1330 GHashTable *refs_for_headers;
1331 OpenMsgHelper *helper;
1332 GtkTreeSelection *sel;
1333 GList *sel_list = NULL, *sel_list_iter = NULL;
1335 g_return_if_fail (headers != NULL);
1337 /* Check that only one message is selected for opening */
1338 if (tny_list_get_length (headers) != 1) {
1339 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1340 NULL, _("mcen_ib_select_one_message"));
1344 mgr = modest_runtime_get_window_mgr ();
1345 iter = tny_list_create_iterator (headers);
1347 /* Get the account */
1348 account = get_account_from_header_list (headers);
1353 /* Get the selections, we need to get the references to the
1354 rows here because the treeview/model could dissapear (the
1355 user might want to select another folder)*/
1356 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1357 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1358 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
1359 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
1360 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
1361 refs_for_headers = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
1362 (GDestroyNotify) gtk_tree_row_reference_free);
1364 /* Look if we already have a message view for each header. If
1365 true, then remove the header from the list of headers to
1367 sel_list_iter = sel_list;
1368 not_opened_headers = tny_simple_list_new ();
1369 while (!tny_iterator_is_done (iter) && sel_list_iter) {
1371 ModestWindow *window = NULL;
1372 TnyHeader *header = NULL;
1373 gboolean found = FALSE;
1375 header = TNY_HEADER (tny_iterator_get_current (iter));
1377 flags = tny_header_get_flags (header);
1380 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1382 /* Do not open again the message and present the
1383 window to the user */
1386 #ifndef MODEST_TOOLKIT_HILDON2
1387 gtk_window_present (GTK_WINDOW (window));
1390 /* the header has been registered already, we don't do
1391 * anything but wait for the window to come up*/
1392 g_debug ("header %p already registered, waiting for window", header);
1395 GtkTreeRowReference *row_reference;
1397 tny_list_append (not_opened_headers, G_OBJECT (header));
1398 /* Create a new row reference and add it to the hash table */
1399 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list_iter->data);
1400 g_hash_table_insert (refs_for_headers, header, row_reference);
1404 g_object_unref (header);
1407 tny_iterator_next (iter);
1408 sel_list_iter = g_list_next (sel_list_iter);
1410 g_object_unref (iter);
1412 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
1413 g_list_free (sel_list);
1415 /* Open each message */
1416 if (tny_list_get_length (not_opened_headers) == 0) {
1417 g_hash_table_destroy (refs_for_headers);
1421 /* If some messages would have to be downloaded, ask the user to
1422 * make a connection. It's generally easier to do this here (in the mainloop)
1423 * than later in a thread:
1425 if (tny_list_get_length (not_opened_headers) > 0) {
1426 uncached_msgs = header_list_count_uncached_msgs (not_opened_headers);
1428 if (uncached_msgs > 0) {
1429 /* Allways download if we are online. */
1430 if (!tny_device_is_online (modest_runtime_get_device ())) {
1433 /* If ask for user permission to download the messages */
1434 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1435 ngettext("mcen_nc_get_msg",
1439 /* End if the user does not want to continue */
1440 if (response == GTK_RESPONSE_CANCEL) {
1441 g_hash_table_destroy (refs_for_headers);
1448 /* Register the headers before actually creating the windows: */
1449 iter_not_opened = tny_list_create_iterator (not_opened_headers);
1450 while (!tny_iterator_is_done (iter_not_opened)) {
1451 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1453 modest_window_mgr_register_header (mgr, header, NULL);
1454 g_object_unref (header);
1456 tny_iterator_next (iter_not_opened);
1458 g_object_unref (iter_not_opened);
1459 iter_not_opened = NULL;
1461 /* Create the helper. We need to get a reference to the model
1462 here because it could change while the message is readed
1463 (the user could switch between folders) */
1464 helper = g_slice_new (OpenMsgHelper);
1465 helper->model = g_object_ref (model);
1466 helper->headers = g_object_ref (not_opened_headers);
1467 helper->row_refs_per_header = refs_for_headers;
1468 helper->banner_info = NULL;
1470 /* Connect to the account and perform */
1471 if (uncached_msgs > 0) {
1472 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1473 open_msgs_performer, helper);
1475 /* Call directly the performer, do not need to connect */
1476 open_msgs_performer (FALSE, NULL, (GtkWindow *) win,
1477 g_object_ref (account), helper);
1482 g_object_unref (account);
1483 if (not_opened_headers)
1484 g_object_unref (not_opened_headers);
1488 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1492 /* we check for low-mem; in that case, show a warning, and don't allow
1495 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1499 headers = get_selected_headers (win);
1504 open_msgs_from_headers (headers, win);
1506 g_object_unref(headers);
1509 static ReplyForwardHelper*
1510 create_reply_forward_helper (ReplyForwardAction action,
1512 guint reply_forward_type,
1515 ReplyForwardHelper *rf_helper = NULL;
1516 const gchar *active_acc = modest_window_get_active_account (win);
1518 rf_helper = g_slice_new0 (ReplyForwardHelper);
1519 rf_helper->reply_forward_type = reply_forward_type;
1520 rf_helper->action = action;
1521 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1522 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1523 rf_helper->account_name = (active_acc) ?
1524 g_strdup (active_acc) :
1525 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1531 free_reply_forward_helper (gpointer data)
1533 ReplyForwardHelper *helper;
1535 helper = (ReplyForwardHelper *) data;
1536 g_free (helper->account_name);
1538 g_object_unref (helper->header);
1539 g_slice_free (ReplyForwardHelper, helper);
1543 reply_forward_cb (ModestMailOperation *mail_op,
1550 TnyMsg *new_msg = NULL;
1551 ReplyForwardHelper *rf_helper;
1552 ModestWindow *msg_win = NULL;
1553 ModestEditType edit_type;
1555 TnyAccount *account = NULL;
1556 ModestWindowMgr *mgr = NULL;
1557 gchar *signature = NULL;
1558 gboolean use_signature;
1560 /* If there was any error. The mail operation could be NULL,
1561 this means that we already have the message downloaded and
1562 that we didn't do a mail operation to retrieve it */
1563 rf_helper = (ReplyForwardHelper *) user_data;
1564 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1567 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1568 rf_helper->account_name);
1569 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr(),
1570 rf_helper->account_name,
1573 /* Create reply mail */
1574 switch (rf_helper->action) {
1577 modest_tny_msg_create_reply_msg (msg, header, from,
1578 (use_signature) ? signature : NULL,
1579 rf_helper->reply_forward_type,
1580 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1582 case ACTION_REPLY_TO_ALL:
1584 modest_tny_msg_create_reply_msg (msg, header, from,
1585 (use_signature) ? signature : NULL,
1586 rf_helper->reply_forward_type,
1587 MODEST_TNY_MSG_REPLY_MODE_ALL);
1588 edit_type = MODEST_EDIT_TYPE_REPLY;
1590 case ACTION_FORWARD:
1592 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1593 rf_helper->reply_forward_type);
1594 edit_type = MODEST_EDIT_TYPE_FORWARD;
1597 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1599 g_return_if_reached ();
1607 g_warning ("%s: failed to create message\n", __FUNCTION__);
1611 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1612 rf_helper->account_name,
1613 TNY_ACCOUNT_TYPE_STORE);
1615 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1619 /* Create and register the windows */
1620 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1621 mgr = modest_runtime_get_window_mgr ();
1622 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1624 if (rf_helper->parent_window != NULL) {
1625 gdouble parent_zoom;
1627 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1628 modest_window_set_zoom (msg_win, parent_zoom);
1631 /* Show edit window */
1632 gtk_widget_show_all (GTK_WIDGET (msg_win));
1635 /* We always unregister the header because the message is
1636 forwarded or replied so the original one is no longer
1638 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1641 g_object_unref (G_OBJECT (new_msg));
1643 g_object_unref (G_OBJECT (account));
1644 free_reply_forward_helper (rf_helper);
1647 /* Checks a list of headers. If any of them are not currently
1648 * downloaded (CACHED) then returns TRUE else returns FALSE.
1651 header_list_count_uncached_msgs (TnyList *header_list)
1654 gint uncached_messages = 0;
1656 iter = tny_list_create_iterator (header_list);
1657 while (!tny_iterator_is_done (iter)) {
1660 header = TNY_HEADER (tny_iterator_get_current (iter));
1662 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1663 uncached_messages ++;
1664 g_object_unref (header);
1667 tny_iterator_next (iter);
1669 g_object_unref (iter);
1671 return uncached_messages;
1674 /* Returns FALSE if the user does not want to download the
1675 * messages. Returns TRUE if the user allowed the download.
1678 connect_to_get_msg (ModestWindow *win,
1679 gint num_of_uncached_msgs,
1680 TnyAccount *account)
1682 GtkResponseType response;
1684 /* Allways download if we are online. */
1685 if (tny_device_is_online (modest_runtime_get_device ()))
1688 /* If offline, then ask for user permission to download the messages */
1689 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1690 ngettext("mcen_nc_get_msg",
1692 num_of_uncached_msgs));
1694 if (response == GTK_RESPONSE_CANCEL)
1697 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1701 reply_forward_performer (gboolean canceled,
1703 GtkWindow *parent_window,
1704 TnyAccount *account,
1707 ReplyForwardHelper *rf_helper = NULL;
1708 ModestMailOperation *mail_op;
1710 rf_helper = (ReplyForwardHelper *) user_data;
1712 if (canceled || err) {
1713 free_reply_forward_helper (rf_helper);
1717 /* Retrieve the message */
1718 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1719 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1720 modest_ui_actions_disk_operations_error_handler,
1722 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1723 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1726 g_object_unref(mail_op);
1730 * Common code for the reply and forward actions
1733 reply_forward (ReplyForwardAction action, ModestWindow *win)
1735 ReplyForwardHelper *rf_helper = NULL;
1736 guint reply_forward_type;
1738 g_return_if_fail (MODEST_IS_WINDOW(win));
1740 /* we check for low-mem; in that case, show a warning, and don't allow
1741 * reply/forward (because it could potentially require a lot of memory */
1742 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1746 /* we need an account when editing */
1747 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1748 if (!modest_ui_actions_run_account_setup_wizard (win))
1752 reply_forward_type =
1753 modest_conf_get_int (modest_runtime_get_conf (),
1754 (action == ACTION_FORWARD) ?
1755 MODEST_CONF_FORWARD_TYPE :
1756 MODEST_CONF_REPLY_TYPE,
1759 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1761 TnyHeader *header = NULL;
1762 /* Get header and message. Do not free them here, the
1763 reply_forward_cb must do it */
1764 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1765 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1767 if (msg && header) {
1769 rf_helper = create_reply_forward_helper (action, win,
1770 reply_forward_type, header);
1771 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1773 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1777 g_object_unref (msg);
1779 g_object_unref (header);
1781 TnyHeader *header = NULL;
1783 gboolean do_retrieve = TRUE;
1784 TnyList *header_list = NULL;
1786 header_list = get_selected_headers (win);
1789 /* Check that only one message is selected for replying */
1790 if (tny_list_get_length (header_list) != 1) {
1791 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1792 NULL, _("mcen_ib_select_one_message"));
1793 g_object_unref (header_list);
1797 /* Only reply/forward to one message */
1798 iter = tny_list_create_iterator (header_list);
1799 header = TNY_HEADER (tny_iterator_get_current (iter));
1800 g_object_unref (iter);
1802 /* Retrieve messages */
1803 do_retrieve = (action == ACTION_FORWARD) ||
1804 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1807 TnyAccount *account = NULL;
1808 TnyFolder *folder = NULL;
1809 gdouble download = TRUE;
1810 guint uncached_msgs = 0;
1812 folder = tny_header_get_folder (header);
1814 goto do_retrieve_frees;
1815 account = tny_folder_get_account (folder);
1817 goto do_retrieve_frees;
1819 uncached_msgs = header_list_count_uncached_msgs (header_list);
1821 if (uncached_msgs > 0) {
1822 /* Allways download if we are online. */
1823 if (!tny_device_is_online (modest_runtime_get_device ())) {
1826 /* If ask for user permission to download the messages */
1827 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1828 ngettext("mcen_nc_get_msg",
1832 /* End if the user does not want to continue */
1833 if (response == GTK_RESPONSE_CANCEL)
1840 rf_helper = create_reply_forward_helper (action, win,
1841 reply_forward_type, header);
1842 if (uncached_msgs > 0) {
1843 modest_platform_connect_and_perform (GTK_WINDOW (win),
1845 reply_forward_performer,
1848 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
1849 account, rf_helper);
1854 g_object_unref (account);
1856 g_object_unref (folder);
1858 reply_forward_cb (NULL, header, FALSE, NULL, NULL, rf_helper);
1861 g_object_unref (header_list);
1862 g_object_unref (header);
1867 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1869 g_return_if_fail (MODEST_IS_WINDOW(win));
1871 reply_forward (ACTION_REPLY, win);
1875 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1877 g_return_if_fail (MODEST_IS_WINDOW(win));
1879 reply_forward (ACTION_FORWARD, win);
1883 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1885 g_return_if_fail (MODEST_IS_WINDOW(win));
1887 reply_forward (ACTION_REPLY_TO_ALL, win);
1891 modest_ui_actions_on_next (GtkAction *action,
1892 ModestWindow *window)
1894 if (MODEST_IS_MAIN_WINDOW (window)) {
1895 GtkWidget *header_view;
1897 header_view = modest_main_window_get_child_widget (
1898 MODEST_MAIN_WINDOW(window),
1899 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1903 modest_header_view_select_next (
1904 MODEST_HEADER_VIEW(header_view));
1905 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1906 modest_msg_view_window_select_next_message (
1907 MODEST_MSG_VIEW_WINDOW (window));
1909 g_return_if_reached ();
1914 modest_ui_actions_on_prev (GtkAction *action,
1915 ModestWindow *window)
1917 g_return_if_fail (MODEST_IS_WINDOW(window));
1919 if (MODEST_IS_MAIN_WINDOW (window)) {
1920 GtkWidget *header_view;
1921 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1922 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1926 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1927 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1928 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1930 g_return_if_reached ();
1935 modest_ui_actions_on_sort (GtkAction *action,
1936 ModestWindow *window)
1938 g_return_if_fail (MODEST_IS_WINDOW(window));
1940 if (MODEST_IS_MAIN_WINDOW (window)) {
1941 GtkWidget *header_view;
1942 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1943 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1945 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1950 /* Show sorting dialog */
1951 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1956 new_messages_arrived (ModestMailOperation *self,
1957 TnyList *new_headers,
1961 gboolean show_visual_notifications;
1963 source = modest_mail_operation_get_source (self);
1964 show_visual_notifications = (source) ? FALSE : TRUE;
1966 g_object_unref (source);
1968 /* Notify new messages have been downloaded. If the
1969 send&receive was invoked by the user then do not show any
1970 visual notification, only play a sound and activate the LED
1971 (for the Maemo version) */
1972 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0)
1973 modest_platform_on_new_headers_received (new_headers,
1974 show_visual_notifications);
1979 retrieve_all_messages_cb (GObject *source,
1981 guint retrieve_limit)
1987 window = GTK_WINDOW (source);
1988 msg = g_strdup_printf (_("mail_nc_msg_count_limit_exceeded"),
1989 num_msgs, retrieve_limit);
1991 /* Ask the user if they want to retrieve all the messages */
1993 modest_platform_run_confirmation_dialog_with_buttons (window, msg,
1994 _("mcen_bd_get_all"),
1995 _("mcen_bd_newest_only"));
1996 /* Free and return */
1998 return (response == GTK_RESPONSE_ACCEPT) ? TRUE : FALSE;
2002 TnyAccount *account;
2004 gchar *account_name;
2005 gboolean poke_status;
2006 gboolean interactive;
2007 ModestMailOperation *mail_op;
2011 do_send_receive_performer (gboolean canceled,
2013 GtkWindow *parent_window,
2014 TnyAccount *account,
2017 SendReceiveInfo *info;
2019 info = (SendReceiveInfo *) user_data;
2021 if (err || canceled) {
2022 /* In memory full conditions we could get this error here */
2023 check_memory_full_error ((GtkWidget *) parent_window, err);
2025 if (info->mail_op) {
2026 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2032 /* Set send/receive operation in progress */
2033 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2034 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2037 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2038 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2039 G_CALLBACK (on_send_receive_finished),
2042 /* Send & receive. */
2043 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2044 (info->win) ? retrieve_all_messages_cb : NULL,
2045 new_messages_arrived, info->win);
2050 g_object_unref (G_OBJECT (info->mail_op));
2051 if (info->account_name)
2052 g_free (info->account_name);
2054 g_object_unref (info->win);
2056 g_object_unref (info->account);
2057 g_slice_free (SendReceiveInfo, info);
2061 * This function performs the send & receive required actions. The
2062 * window is used to create the mail operation. Typically it should
2063 * always be the main window, but we pass it as argument in order to
2067 modest_ui_actions_do_send_receive (const gchar *account_name,
2068 gboolean force_connection,
2069 gboolean poke_status,
2070 gboolean interactive,
2073 gchar *acc_name = NULL;
2074 SendReceiveInfo *info;
2075 ModestTnyAccountStore *acc_store;
2077 /* If no account name was provided then get the current account, and if
2078 there is no current account then pick the default one: */
2079 if (!account_name) {
2081 acc_name = g_strdup (modest_window_get_active_account (win));
2083 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2085 g_printerr ("modest: cannot get default account\n");
2089 acc_name = g_strdup (account_name);
2092 acc_store = modest_runtime_get_account_store ();
2094 /* Create the info for the connect and perform */
2095 info = g_slice_new (SendReceiveInfo);
2096 info->account_name = acc_name;
2097 info->win = (win) ? g_object_ref (win) : NULL;
2098 info->poke_status = poke_status;
2099 info->interactive = interactive;
2100 info->account = modest_tny_account_store_get_server_account (acc_store, acc_name,
2101 TNY_ACCOUNT_TYPE_STORE);
2102 /* We need to create the operation here, because otherwise it
2103 could happen that the queue emits the queue-empty signal
2104 while we're trying to connect the account */
2105 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2106 modest_ui_actions_disk_operations_error_handler,
2108 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2110 /* Invoke the connect and perform */
2111 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2112 force_connection, info->account,
2113 do_send_receive_performer, info);
2118 modest_ui_actions_do_cancel_send (const gchar *account_name,
2121 TnyTransportAccount *transport_account;
2122 TnySendQueue *send_queue = NULL;
2123 GError *error = NULL;
2125 /* Get transport account */
2127 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2128 (modest_runtime_get_account_store(),
2130 TNY_ACCOUNT_TYPE_TRANSPORT));
2131 if (!transport_account) {
2132 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2137 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2138 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2139 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2140 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2141 "modest: could not find send queue for account\n");
2143 /* Cancel the current send */
2144 tny_account_cancel (TNY_ACCOUNT (transport_account));
2146 /* Suspend all pending messages */
2147 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2151 if (transport_account != NULL)
2152 g_object_unref (G_OBJECT (transport_account));
2156 modest_ui_actions_cancel_send_all (ModestWindow *win)
2158 GSList *account_names, *iter;
2160 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2163 iter = account_names;
2165 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2166 iter = g_slist_next (iter);
2169 modest_account_mgr_free_account_names (account_names);
2170 account_names = NULL;
2174 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2177 /* Check if accounts exist */
2178 gboolean accounts_exist =
2179 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2181 /* If not, allow the user to create an account before trying to send/receive. */
2182 if (!accounts_exist)
2183 modest_ui_actions_on_accounts (NULL, win);
2185 /* Cancel all sending operaitons */
2186 modest_ui_actions_cancel_send_all (win);
2190 * Refreshes all accounts. This function will be used by automatic
2194 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2195 gboolean force_connection,
2196 gboolean poke_status,
2197 gboolean interactive)
2199 GSList *account_names, *iter;
2201 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2204 iter = account_names;
2206 modest_ui_actions_do_send_receive ((const char*) iter->data,
2208 poke_status, interactive, win);
2209 iter = g_slist_next (iter);
2212 modest_account_mgr_free_account_names (account_names);
2213 account_names = NULL;
2217 * Handler of the click on Send&Receive button in the main toolbar
2220 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2222 /* Check if accounts exist */
2223 gboolean accounts_exist;
2226 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2228 /* If not, allow the user to create an account before trying to send/receive. */
2229 if (!accounts_exist)
2230 modest_ui_actions_on_accounts (NULL, win);
2232 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2233 if (MODEST_IS_MAIN_WINDOW (win)) {
2234 GtkWidget *folder_view;
2235 TnyFolderStore *folder_store;
2238 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2239 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2243 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2246 g_object_unref (folder_store);
2249 /* Refresh the active account. Force the connection if needed
2250 and poke the status of all folders */
2251 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2256 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2259 GtkWidget *header_view;
2261 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2263 header_view = modest_main_window_get_child_widget (main_window,
2264 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2268 conf = modest_runtime_get_conf ();
2270 /* what is saved/restored is depending on the style; thus; we save with
2271 * old style, then update the style, and restore for this new style
2273 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2275 if (modest_header_view_get_style
2276 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2277 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2278 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2280 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2281 MODEST_HEADER_VIEW_STYLE_DETAILS);
2283 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2284 MODEST_CONF_HEADER_VIEW_KEY);
2289 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2291 ModestMainWindow *main_window)
2293 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2294 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2296 /* in the case the folder is empty, show the empty folder message and focus
2298 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2299 if (modest_header_view_is_empty (header_view)) {
2300 TnyFolder *folder = modest_header_view_get_folder (header_view);
2301 GtkWidget *folder_view =
2302 modest_main_window_get_child_widget (main_window,
2303 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2304 if (folder != NULL) {
2305 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2306 g_object_unref (folder);
2308 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2312 /* If no header has been selected then exit */
2317 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2318 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2320 /* Update toolbar dimming state */
2321 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2322 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2326 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2328 ModestMainWindow *main_window)
2332 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2337 if (modest_header_view_count_selected_headers (header_view) > 1) {
2338 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2342 /* we check for low-mem; in that case, show a warning, and don't allow
2343 * activating headers
2345 if (modest_platform_check_memory_low (MODEST_WINDOW(main_window), TRUE))
2348 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2350 headers = modest_header_view_get_selected_headers (header_view);
2352 open_msgs_from_headers (headers, MODEST_WINDOW (main_window));
2354 g_object_unref (headers);
2358 set_active_account_from_tny_account (TnyAccount *account,
2359 ModestWindow *window)
2361 const gchar *server_acc_name = tny_account_get_id (account);
2363 /* We need the TnyAccount provided by the
2364 account store because that is the one that
2365 knows the name of the Modest account */
2366 TnyAccount *modest_server_account = modest_server_account =
2367 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2368 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2370 if (!modest_server_account) {
2371 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2375 /* Update active account, but only if it's not a pseudo-account */
2376 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2377 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2378 const gchar *modest_acc_name =
2379 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2380 if (modest_acc_name)
2381 modest_window_set_active_account (window, modest_acc_name);
2384 g_object_unref (modest_server_account);
2389 folder_refreshed_cb (ModestMailOperation *mail_op,
2393 ModestMainWindow *win = NULL;
2394 GtkWidget *folder_view;
2395 const GError *error;
2397 g_return_if_fail (TNY_IS_FOLDER (folder));
2399 win = MODEST_MAIN_WINDOW (user_data);
2401 /* Check if the operation failed due to memory low conditions */
2402 error = modest_mail_operation_get_error (mail_op);
2403 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2404 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2405 modest_platform_run_information_dialog (GTK_WINDOW (win),
2406 dgettext("ke-recv","memr_ib_operation_disabled"),
2412 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2415 TnyFolderStore *current_folder;
2417 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2418 if (current_folder) {
2419 gboolean different = ((TnyFolderStore *) folder != current_folder);
2420 g_object_unref (current_folder);
2426 /* Check if folder is empty and set headers view contents style */
2427 if (tny_folder_get_all_count (folder) == 0)
2428 modest_main_window_set_contents_style (win,
2429 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2434 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2435 TnyFolderStore *folder_store,
2437 ModestMainWindow *main_window)
2440 GtkWidget *header_view;
2442 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2444 header_view = modest_main_window_get_child_widget(main_window,
2445 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2449 conf = modest_runtime_get_conf ();
2451 if (TNY_IS_ACCOUNT (folder_store)) {
2453 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2455 /* Show account details */
2456 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2459 if (TNY_IS_FOLDER (folder_store) && selected) {
2460 TnyAccount *account;
2461 const gchar *account_name = NULL;
2463 /* Update the active account */
2464 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2466 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2468 modest_tny_account_get_parent_modest_account_name_for_server_account (account);
2469 g_object_unref (account);
2473 /* Set the header style by default, it could
2474 be changed later by the refresh callback to
2476 modest_main_window_set_contents_style (main_window,
2477 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2479 /* Set folder on header view. This function
2480 will call tny_folder_refresh_async so we
2481 pass a callback that will be called when
2482 finished. We use that callback to set the
2483 empty view if there are no messages */
2484 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2485 TNY_FOLDER (folder_store),
2487 folder_refreshed_cb,
2490 /* Restore configuration. We need to do this
2491 *after* the set_folder because the widget
2492 memory asks the header view about its
2494 modest_widget_memory_restore (modest_runtime_get_conf (),
2495 G_OBJECT(header_view),
2496 MODEST_CONF_HEADER_VIEW_KEY);
2498 /* No need to save the header view
2499 configuration for Maemo because it only
2500 saves the sorting stuff and that it's
2501 already being done by the sort
2502 dialog. Remove it when the GNOME version
2503 has the same behaviour */
2504 #ifdef MODEST_TOOLKIT_GTK
2505 if (modest_main_window_get_contents_style (main_window) ==
2506 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2507 modest_widget_memory_save (conf, G_OBJECT (header_view),
2508 MODEST_CONF_HEADER_VIEW_KEY);
2510 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2514 /* Update dimming state */
2515 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2516 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2520 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2527 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2529 online = tny_device_is_online (modest_runtime_get_device());
2532 /* already online -- the item is simply not there... */
2533 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2535 GTK_MESSAGE_WARNING,
2537 _("The %s you selected cannot be found"),
2539 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2540 gtk_dialog_run (GTK_DIALOG(dialog));
2542 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2545 _("mcen_bd_dialog_cancel"),
2546 GTK_RESPONSE_REJECT,
2547 _("mcen_bd_dialog_ok"),
2548 GTK_RESPONSE_ACCEPT,
2550 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2551 "Do you want to get online?"), item);
2552 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2553 gtk_label_new (txt), FALSE, FALSE, 0);
2554 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2557 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2558 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2559 /* TODO: Comment about why is this commented out: */
2560 /* modest_platform_connect_and_wait (); */
2563 gtk_widget_destroy (dialog);
2567 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2570 /* g_message ("%s %s", __FUNCTION__, link); */
2575 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2578 modest_platform_activate_uri (link);
2582 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2585 modest_platform_show_uri_popup (link);
2589 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2592 /* we check for low-mem; in that case, show a warning, and don't allow
2593 * viewing attachments
2595 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2598 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2602 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2603 const gchar *address,
2606 /* g_message ("%s %s", __FUNCTION__, address); */
2610 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2611 TnyMsg *saved_draft,
2614 ModestMsgEditWindow *edit_window;
2615 ModestMainWindow *win;
2617 /* FIXME. Make the header view sensitive again. This is a
2618 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2620 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2621 modest_runtime_get_window_mgr(), FALSE));
2623 GtkWidget *hdrview = modest_main_window_get_child_widget(
2624 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2625 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2628 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2630 /* Set draft is there was no error */
2631 if (!modest_mail_operation_get_error (mail_op))
2632 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2634 g_object_unref(edit_window);
2638 enough_space_for_message (ModestMsgEditWindow *edit_window,
2641 TnyAccountStore *acc_store;
2642 guint64 available_disk, expected_size;
2647 acc_store = TNY_ACCOUNT_STORE (modest_runtime_get_account_store());
2648 available_disk = modest_utils_get_available_space (NULL);
2649 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2650 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2655 /* Double check: memory full condition or message too big */
2656 if (available_disk < MIN_FREE_SPACE ||
2657 expected_size > available_disk) {
2659 modest_platform_information_banner (NULL, NULL,
2661 "cerm_device_memory_full"));
2666 * djcb: if we're in low-memory state, we only allow for
2667 * saving messages smaller than
2668 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2669 * should still allow for sending anything critical...
2671 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2672 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2676 * djcb: we also make sure that the attachments are smaller than the max size
2677 * this is for the case where we'd try to forward a message with attachments
2678 * bigger than our max allowed size, or sending an message from drafts which
2679 * somehow got past our checks when attaching.
2681 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2682 modest_platform_run_information_dialog (
2683 GTK_WINDOW(edit_window),
2684 dgettext("ke-recv","memr_ib_operation_disabled"),
2693 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2695 TnyTransportAccount *transport_account;
2696 ModestMailOperation *mail_operation;
2698 gchar *account_name, *from;
2699 ModestAccountMgr *account_mgr;
2700 gboolean had_error = FALSE;
2701 ModestMainWindow *win = NULL;
2703 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2705 data = modest_msg_edit_window_get_msg_data (edit_window);
2708 if (!enough_space_for_message (edit_window, data)) {
2709 modest_msg_edit_window_free_msg_data (edit_window, data);
2713 account_name = g_strdup (data->account_name);
2714 account_mgr = modest_runtime_get_account_mgr();
2716 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2718 account_name = modest_account_mgr_get_default_account (account_mgr);
2719 if (!account_name) {
2720 g_printerr ("modest: no account found\n");
2721 modest_msg_edit_window_free_msg_data (edit_window, data);
2725 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2726 account_name = g_strdup (data->account_name);
2730 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2731 (modest_runtime_get_account_store (),
2733 TNY_ACCOUNT_TYPE_TRANSPORT));
2734 if (!transport_account) {
2735 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2736 g_free (account_name);
2737 modest_msg_edit_window_free_msg_data (edit_window, data);
2740 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2742 /* Create the mail operation */
2743 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
2745 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2747 modest_mail_operation_save_to_drafts (mail_operation,
2759 data->priority_flags,
2760 on_save_to_drafts_cb,
2761 g_object_ref(edit_window));
2763 #ifdef MODEST_TOOLKIT_HILDON2
2764 /* In hildon2 we always show the information banner on saving to drafts.
2765 * It will be a system information banner in this case.
2767 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2768 modest_platform_information_banner (NULL, NULL, text);
2771 /* Use the main window as the parent of the banner, if the
2772 main window does not exist it won't be shown, if the parent
2773 window exists then it's properly shown. We don't use the
2774 editor window because it could be closed (save to drafts
2775 could happen after closing the window */
2776 win = (ModestMainWindow *)
2777 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
2779 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2780 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
2784 modest_msg_edit_window_set_modified (edit_window, FALSE);
2788 g_free (account_name);
2789 g_object_unref (G_OBJECT (transport_account));
2790 g_object_unref (G_OBJECT (mail_operation));
2792 modest_msg_edit_window_free_msg_data (edit_window, data);
2795 * If the drafts folder is selected then make the header view
2796 * insensitive while the message is being saved to drafts
2797 * (it'll be sensitive again in on_save_to_drafts_cb()). This
2798 * is not very clean but it avoids letting the drafts folder
2799 * in an inconsistent state: the user could edit the message
2800 * being saved and undesirable things would happen.
2801 * In the average case the user won't notice anything at
2802 * all. In the worst case (the user is editing a really big
2803 * file from Drafts) the header view will be insensitive
2804 * during the saving process (10 or 20 seconds, depending on
2805 * the message). Anyway this is just a quick workaround: once
2806 * we find a better solution it should be removed
2807 * See NB#65125 (commend #18) for details.
2809 if (!had_error && win != NULL) {
2810 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
2811 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
2813 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
2815 if (modest_tny_folder_is_local_folder(folder)) {
2816 TnyFolderType folder_type;
2817 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
2818 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
2819 GtkWidget *hdrview = modest_main_window_get_child_widget(
2820 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2821 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
2825 if (folder != NULL) g_object_unref(folder);
2832 /* For instance, when clicking the Send toolbar button when editing a message: */
2834 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2836 TnyTransportAccount *transport_account = NULL;
2837 gboolean had_error = FALSE;
2839 ModestAccountMgr *account_mgr;
2840 gchar *account_name;
2842 ModestMailOperation *mail_operation;
2844 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
2846 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2849 data = modest_msg_edit_window_get_msg_data (edit_window);
2852 if (!enough_space_for_message (edit_window, data)) {
2853 modest_msg_edit_window_free_msg_data (edit_window, data);
2857 account_mgr = modest_runtime_get_account_mgr();
2858 account_name = g_strdup (data->account_name);
2860 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2863 account_name = modest_account_mgr_get_default_account (account_mgr);
2865 if (!account_name) {
2866 modest_msg_edit_window_free_msg_data (edit_window, data);
2867 /* Run account setup wizard */
2868 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
2873 /* Get the currently-active transport account for this modest account: */
2874 if (strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
2876 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2877 (modest_runtime_get_account_store (),
2878 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
2881 if (!transport_account) {
2882 modest_msg_edit_window_free_msg_data (edit_window, data);
2883 /* Run account setup wizard */
2884 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2889 /* Create the mail operation */
2890 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2891 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
2892 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2894 modest_mail_operation_send_new_mail (mail_operation,
2906 data->priority_flags);
2908 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
2909 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2912 if (modest_mail_operation_get_error (mail_operation) != NULL) {
2913 const GError *error = modest_mail_operation_get_error (mail_operation);
2914 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
2915 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
2916 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
2917 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
2924 g_free (account_name);
2925 g_object_unref (G_OBJECT (transport_account));
2926 g_object_unref (G_OBJECT (mail_operation));
2928 modest_msg_edit_window_free_msg_data (edit_window, data);
2931 modest_msg_edit_window_set_sent (edit_window, TRUE);
2933 /* Save settings and close the window: */
2934 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2941 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2942 ModestMsgEditWindow *window)
2944 ModestMsgEditFormatState *format_state = NULL;
2946 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2947 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2949 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2952 format_state = modest_msg_edit_window_get_format_state (window);
2953 g_return_if_fail (format_state != NULL);
2955 format_state->bold = gtk_toggle_action_get_active (action);
2956 modest_msg_edit_window_set_format_state (window, format_state);
2957 g_free (format_state);
2962 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2963 ModestMsgEditWindow *window)
2965 ModestMsgEditFormatState *format_state = NULL;
2967 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2968 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2970 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2973 format_state = modest_msg_edit_window_get_format_state (window);
2974 g_return_if_fail (format_state != NULL);
2976 format_state->italics = gtk_toggle_action_get_active (action);
2977 modest_msg_edit_window_set_format_state (window, format_state);
2978 g_free (format_state);
2983 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2984 ModestMsgEditWindow *window)
2986 ModestMsgEditFormatState *format_state = NULL;
2988 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2989 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2991 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2994 format_state = modest_msg_edit_window_get_format_state (window);
2995 g_return_if_fail (format_state != NULL);
2997 format_state->bullet = gtk_toggle_action_get_active (action);
2998 modest_msg_edit_window_set_format_state (window, format_state);
2999 g_free (format_state);
3004 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3005 GtkRadioAction *selected,
3006 ModestMsgEditWindow *window)
3008 ModestMsgEditFormatState *format_state = NULL;
3009 GtkJustification value;
3011 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3013 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3016 value = gtk_radio_action_get_current_value (selected);
3018 format_state = modest_msg_edit_window_get_format_state (window);
3019 g_return_if_fail (format_state != NULL);
3021 format_state->justification = value;
3022 modest_msg_edit_window_set_format_state (window, format_state);
3023 g_free (format_state);
3027 modest_ui_actions_on_select_editor_color (GtkAction *action,
3028 ModestMsgEditWindow *window)
3030 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3031 g_return_if_fail (GTK_IS_ACTION (action));
3033 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3036 modest_msg_edit_window_select_color (window);
3040 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3041 ModestMsgEditWindow *window)
3043 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3044 g_return_if_fail (GTK_IS_ACTION (action));
3046 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3049 modest_msg_edit_window_select_background_color (window);
3053 modest_ui_actions_on_insert_image (GtkAction *action,
3054 ModestMsgEditWindow *window)
3056 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3057 g_return_if_fail (GTK_IS_ACTION (action));
3060 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3063 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3066 modest_msg_edit_window_insert_image (window);
3070 modest_ui_actions_on_attach_file (GtkAction *action,
3071 ModestMsgEditWindow *window)
3073 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3074 g_return_if_fail (GTK_IS_ACTION (action));
3076 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3079 modest_msg_edit_window_offer_attach_file (window);
3083 modest_ui_actions_on_remove_attachments (GtkAction *action,
3084 ModestMsgEditWindow *window)
3086 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3087 g_return_if_fail (GTK_IS_ACTION (action));
3089 modest_msg_edit_window_remove_attachments (window, NULL);
3093 #ifndef MODEST_TOOLKIT_GTK
3098 TnyFolderStore *folder;
3099 } CreateFolderHelper;
3102 show_create_folder_in_timeout (gpointer data)
3104 CreateFolderHelper *helper = (CreateFolderHelper *) data;
3106 /* Remove the timeout ASAP, we can not wait until the dialog
3107 is shown because it could take a lot of time and so the
3108 timeout could be called twice or more times */
3109 g_source_remove (helper->handler);
3111 gdk_threads_enter ();
3112 do_create_folder (helper->win, helper->folder, helper->name);
3113 gdk_threads_leave ();
3115 g_object_unref (helper->win);
3116 g_object_unref (helper->folder);
3117 g_free (helper->name);
3118 g_slice_free (CreateFolderHelper, helper);
3125 do_create_folder_cb (ModestMailOperation *mail_op,
3126 TnyFolderStore *parent_folder,
3127 TnyFolder *new_folder,
3130 gchar *suggested_name = (gchar *) user_data;
3131 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3133 if (modest_mail_operation_get_error (mail_op)) {
3135 /* Show an error. If there was some problem writing to
3136 disk, show it, otherwise show the generic folder
3137 create error. We do it here and not in an error
3138 handler because the call to do_create_folder will
3139 stop the main loop in a gtk_dialog_run and then,
3140 the message won't be shown until that dialog is
3142 modest_ui_actions_disk_operations_error_handler (mail_op,
3143 _("mail_in_ui_folder_create_error"));
3145 /* Try again. Do *NOT* show any error because the mail
3146 operations system will do it for us because we
3147 created the mail_op with new_with_error_handler */
3148 #ifndef MODEST_TOOLKIT_GTK
3149 CreateFolderHelper *helper;
3150 helper = g_slice_new0 (CreateFolderHelper);
3151 helper->name = g_strdup (suggested_name);
3152 helper->folder = g_object_ref (parent_folder);
3153 helper->win = g_object_ref (source_win);
3155 /* Ugly but neccesary stuff. The problem is that the
3156 dialog when is shown calls a function that destroys
3157 all the temporary windows, so the banner is
3159 helper->handler = g_timeout_add (2000, show_create_folder_in_timeout, helper);
3161 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3164 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3165 * FIXME: any other? */
3166 GtkWidget *folder_view;
3168 if (MODEST_IS_MAIN_WINDOW(source_win))
3170 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3171 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3174 get_folder_view_from_move_to_dialog (GTK_WIDGET(source_win));
3176 /* Select the newly created folder. It could happen
3177 that the widget is no longer there (i.e. the window
3178 has been destroyed, so we need to check this */
3180 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3182 g_object_unref (new_folder);
3184 /* Free. Note that the first time it'll be NULL so noop */
3185 g_free (suggested_name);
3186 g_object_unref (source_win);
3190 do_create_folder (GtkWindow *parent_window,
3191 TnyFolderStore *parent_folder,
3192 const gchar *suggested_name)
3195 gchar *folder_name = NULL;
3197 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3199 (gchar *) suggested_name,
3202 if (result == GTK_RESPONSE_ACCEPT) {
3203 ModestMailOperation *mail_op;
3205 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3206 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3208 modest_mail_operation_create_folder (mail_op,
3210 (const gchar *) folder_name,
3211 do_create_folder_cb,
3213 g_object_unref (mail_op);
3218 create_folder_performer (gboolean canceled,
3220 GtkWindow *parent_window,
3221 TnyAccount *account,
3224 TnyFolderStore *parent_folder = TNY_FOLDER_STORE (user_data);
3226 if (canceled || err) {
3227 /* In memory full conditions we could get this error here */
3228 check_memory_full_error ((GtkWidget *) parent_window, err);
3232 /* Run the new folder dialog */
3233 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3236 g_object_unref (parent_folder);
3240 modest_ui_actions_create_folder(GtkWidget *parent_window,
3241 GtkWidget *folder_view)
3243 TnyFolderStore *parent_folder;
3245 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3247 if (parent_folder) {
3248 /* The parent folder will be freed in the callback */
3249 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3252 create_folder_performer,
3258 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
3260 GtkWidget *folder_view;
3262 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3264 folder_view = modest_main_window_get_child_widget (main_window,
3265 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3269 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
3273 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3276 const GError *error = NULL;
3277 const gchar *message = NULL;
3279 /* Get error message */
3280 error = modest_mail_operation_get_error (mail_op);
3282 g_return_if_reached ();
3284 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3285 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3286 message = _CS("ckdg_ib_folder_already_exists");
3287 } else if (error->domain == TNY_ERROR_DOMAIN &&
3288 error->code == TNY_SERVICE_ERROR_STATE) {
3289 /* This means that the folder is already in use (a
3290 message is opened for example */
3291 message = _("emev_ni_internal_error");
3293 message = _("emev_ib_ui_imap_unable_to_rename");
3296 /* We don't set a parent for the dialog because the dialog
3297 will be destroyed so the banner won't appear */
3298 modest_platform_information_banner (NULL, NULL, message);
3302 TnyFolderStore *folder;
3307 on_rename_folder_cb (ModestMailOperation *mail_op,
3308 TnyFolder *new_folder,
3311 ModestFolderView *folder_view;
3313 /* If the window was closed when renaming a folder this could
3315 if (!MODEST_IS_FOLDER_VIEW (user_data))
3318 folder_view = MODEST_FOLDER_VIEW (user_data);
3319 /* Note that if the rename fails new_folder will be NULL */
3321 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3323 modest_folder_view_select_first_inbox_or_local (folder_view);
3325 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3329 on_rename_folder_performer (gboolean canceled,
3331 GtkWindow *parent_window,
3332 TnyAccount *account,
3335 ModestMailOperation *mail_op = NULL;
3336 GtkTreeSelection *sel = NULL;
3337 GtkWidget *folder_view = NULL;
3338 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3340 if (canceled || err) {
3341 /* In memory full conditions we could get this error here */
3342 check_memory_full_error ((GtkWidget *) parent_window, err);
3343 } else if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3345 folder_view = modest_main_window_get_child_widget (
3346 MODEST_MAIN_WINDOW (parent_window),
3347 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3350 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3351 modest_ui_actions_rename_folder_error_handler,
3352 parent_window, NULL);
3354 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3357 /* Clear the headers view */
3358 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3359 gtk_tree_selection_unselect_all (sel);
3361 /* Actually rename the folder */
3362 modest_mail_operation_rename_folder (mail_op,
3363 TNY_FOLDER (data->folder),
3364 (const gchar *) (data->new_name),
3365 on_rename_folder_cb,
3367 g_object_unref (data->folder);
3368 g_object_unref (mail_op);
3371 g_free (data->new_name);
3376 modest_ui_actions_on_rename_folder (GtkAction *action,
3377 ModestMainWindow *main_window)
3379 TnyFolderStore *folder;
3380 GtkWidget *folder_view;
3381 GtkWidget *header_view;
3383 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3385 folder_view = modest_main_window_get_child_widget (main_window,
3386 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3390 header_view = modest_main_window_get_child_widget (main_window,
3391 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3396 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3401 if (TNY_IS_FOLDER (folder)) {
3402 gchar *folder_name = NULL;
3404 const gchar *current_name;
3405 TnyFolderStore *parent;
3406 gboolean do_rename = TRUE;
3408 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3409 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3410 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
3411 parent, current_name,
3413 g_object_unref (parent);
3415 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3418 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3419 rename_folder_data->folder = g_object_ref (folder);
3420 rename_folder_data->new_name = folder_name;
3421 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(main_window), TRUE,
3422 folder, on_rename_folder_performer, rename_folder_data);
3425 g_object_unref (folder);
3429 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3432 GObject *win = modest_mail_operation_get_source (mail_op);
3434 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3435 _("mail_in_ui_folder_delete_error"),
3437 g_object_unref (win);
3441 TnyFolderStore *folder;
3442 gboolean move_to_trash;
3446 on_delete_folder_cb (gboolean canceled,
3448 GtkWindow *parent_window,
3449 TnyAccount *account,
3452 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3453 GtkWidget *folder_view;
3454 ModestMailOperation *mail_op;
3455 GtkTreeSelection *sel;
3457 if (!MODEST_IS_MAIN_WINDOW(parent_window) || canceled || (err!=NULL)) {
3458 g_object_unref (G_OBJECT (info->folder));
3463 folder_view = modest_main_window_get_child_widget (
3464 MODEST_MAIN_WINDOW (parent_window),
3465 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3467 /* Unselect the folder before deleting it to free the headers */
3468 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3469 gtk_tree_selection_unselect_all (sel);
3471 /* Create the mail operation */
3473 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3474 modest_ui_actions_delete_folder_error_handler,
3477 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3479 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3481 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3483 g_object_unref (G_OBJECT (mail_op));
3484 g_object_unref (G_OBJECT (info->folder));
3489 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
3491 TnyFolderStore *folder;
3492 GtkWidget *folder_view;
3496 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3498 folder_view = modest_main_window_get_child_widget (main_window,
3499 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3503 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3505 /* Show an error if it's an account */
3506 if (!TNY_IS_FOLDER (folder)) {
3507 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
3508 _("mail_in_ui_folder_delete_error"),
3510 g_object_unref (G_OBJECT (folder));
3515 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3516 tny_folder_get_name (TNY_FOLDER (folder)));
3517 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
3518 (const gchar *) message);
3521 if (response == GTK_RESPONSE_OK) {
3522 DeleteFolderInfo *info;
3523 info = g_new0(DeleteFolderInfo, 1);
3524 info->folder = folder;
3525 info->move_to_trash = move_to_trash;
3526 g_object_ref (G_OBJECT (info->folder));
3527 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder));
3528 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (main_window),
3530 TNY_FOLDER_STORE (account),
3531 on_delete_folder_cb, info);
3532 g_object_unref (account);
3534 g_object_unref (G_OBJECT (folder));
3538 modest_ui_actions_on_delete_folder (GtkAction *action,
3539 ModestMainWindow *main_window)
3541 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3543 delete_folder (main_window, FALSE);
3547 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3549 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3551 delete_folder (main_window, TRUE);
3555 typedef struct _PasswordDialogFields {
3556 GtkWidget *username;
3557 GtkWidget *password;
3559 } PasswordDialogFields;
3562 password_dialog_check_field (GtkEditable *editable,
3563 PasswordDialogFields *fields)
3566 gboolean any_value_empty = FALSE;
3568 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
3569 if ((value == NULL) || value[0] == '\0') {
3570 any_value_empty = TRUE;
3572 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
3573 if ((value == NULL) || value[0] == '\0') {
3574 any_value_empty = TRUE;
3576 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3580 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3581 const gchar* server_account_name,
3586 ModestMainWindow *main_window)
3588 g_return_if_fail(server_account_name);
3589 gboolean completed = FALSE;
3590 PasswordDialogFields *fields = NULL;
3592 /* Initalize output parameters: */
3599 #ifndef MODEST_TOOLKIT_GTK
3600 /* Maemo uses a different (awkward) button order,
3601 * It should probably just use gtk_alternative_dialog_button_order ().
3603 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3606 _("mcen_bd_dialog_ok"),
3607 GTK_RESPONSE_ACCEPT,
3608 _("mcen_bd_dialog_cancel"),
3609 GTK_RESPONSE_REJECT,
3612 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3616 GTK_RESPONSE_REJECT,
3618 GTK_RESPONSE_ACCEPT,
3620 #endif /* !MODEST_TOOLKIT_GTK */
3622 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3624 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3625 modest_runtime_get_account_mgr(), server_account_name);
3626 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3627 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3630 gtk_widget_destroy (dialog);
3634 /* This causes a warning because the logical ID has no %s in it,
3635 * though the translation does, but there is not much we can do about that: */
3636 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3637 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
3640 g_free (server_name);
3644 gchar *initial_username = modest_account_mgr_get_server_account_username (
3645 modest_runtime_get_account_mgr(), server_account_name);
3647 GtkWidget *entry_username = gtk_entry_new ();
3648 if (initial_username)
3649 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
3650 /* Dim this if a connection has ever succeeded with this username,
3651 * as per the UI spec: */
3652 /* const gboolean username_known = */
3653 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3654 /* modest_runtime_get_account_mgr(), server_account_name); */
3655 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3657 /* We drop the username sensitive code and disallow changing it here
3658 * as tinymail does not support really changing the username in the callback
3660 gtk_widget_set_sensitive (entry_username, FALSE);
3662 #ifndef MODEST_TOOLKIT_GTK
3663 /* Auto-capitalization is the default, so let's turn it off: */
3664 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3666 /* Create a size group to be used by all captions.
3667 * Note that HildonCaption does not create a default size group if we do not specify one.
3668 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3669 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3671 GtkWidget *caption = hildon_caption_new (sizegroup,
3672 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
3673 gtk_widget_show (entry_username);
3674 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3675 FALSE, FALSE, MODEST_MARGIN_HALF);
3676 gtk_widget_show (caption);
3678 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
3680 #endif /* !MODEST_TOOLKIT_GTK */
3683 GtkWidget *entry_password = gtk_entry_new ();
3684 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3685 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3687 #ifndef MODEST_TOOLKIT_GTK
3688 /* Auto-capitalization is the default, so let's turn it off: */
3689 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3690 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3692 caption = hildon_caption_new (sizegroup,
3693 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
3694 gtk_widget_show (entry_password);
3695 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3696 FALSE, FALSE, MODEST_MARGIN_HALF);
3697 gtk_widget_show (caption);
3698 g_object_unref (sizegroup);
3700 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
3702 #endif /* !MODEST_TOOLKIT_GTK */
3704 if (initial_username != NULL)
3705 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3707 /* This is not in the Maemo UI spec:
3708 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3709 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3713 fields = g_slice_new0 (PasswordDialogFields);
3714 fields->username = entry_username;
3715 fields->password = entry_password;
3716 fields->dialog = dialog;
3718 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3719 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3720 password_dialog_check_field (NULL, fields);
3722 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3724 while (!completed) {
3726 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3728 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
3730 /* Note that an empty field becomes the "" string */
3731 if (*username && strlen (*username) > 0) {
3732 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
3733 server_account_name,
3737 const gboolean username_was_changed =
3738 (strcmp (*username, initial_username) != 0);
3739 if (username_was_changed) {
3740 g_warning ("%s: tinymail does not yet support changing the "
3741 "username in the get_password() callback.\n", __FUNCTION__);
3747 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
3748 _("mcen_ib_username_pw_incorrect"));
3754 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
3756 /* We do not save the password in the configuration,
3757 * because this function is only called for passwords that should
3758 * not be remembered:
3759 modest_server_account_set_password (
3760 modest_runtime_get_account_mgr(), server_account_name,
3767 /* Set parent to NULL or the banner will disappear with its parent dialog */
3768 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
3779 /* This is not in the Maemo UI spec:
3780 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3786 g_free (initial_username);
3787 gtk_widget_destroy (dialog);
3788 g_slice_free (PasswordDialogFields, fields);
3790 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3794 modest_ui_actions_on_cut (GtkAction *action,
3795 ModestWindow *window)
3797 GtkWidget *focused_widget;
3798 GtkClipboard *clipboard;
3800 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3801 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3802 if (GTK_IS_EDITABLE (focused_widget)) {
3803 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3804 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3805 gtk_clipboard_store (clipboard);
3806 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3807 GtkTextBuffer *buffer;
3809 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3810 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3811 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3812 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3813 gtk_clipboard_store (clipboard);
3815 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3816 TnyList *header_list = modest_header_view_get_selected_headers (
3817 MODEST_HEADER_VIEW (focused_widget));
3818 gboolean continue_download = FALSE;
3819 gint num_of_unc_msgs;
3821 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3823 if (num_of_unc_msgs) {
3824 TnyAccount *account = get_account_from_header_list (header_list);
3826 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3827 g_object_unref (account);
3831 if (num_of_unc_msgs == 0 || continue_download) {
3832 /* modest_platform_information_banner (
3833 NULL, NULL, _CS("mcen_ib_getting_items"));*/
3834 modest_header_view_cut_selection (
3835 MODEST_HEADER_VIEW (focused_widget));
3838 g_object_unref (header_list);
3839 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3840 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3845 modest_ui_actions_on_copy (GtkAction *action,
3846 ModestWindow *window)
3848 GtkClipboard *clipboard;
3849 GtkWidget *focused_widget;
3850 gboolean copied = TRUE;
3852 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3853 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3855 if (GTK_IS_LABEL (focused_widget)) {
3857 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
3858 gtk_clipboard_set_text (clipboard, selection, -1);
3860 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3861 gtk_clipboard_store (clipboard);
3862 } else if (GTK_IS_EDITABLE (focused_widget)) {
3863 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3864 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3865 gtk_clipboard_store (clipboard);
3866 } else if (GTK_IS_HTML (focused_widget)) {
3869 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
3870 if ((sel == NULL) || (sel[0] == '\0')) {
3873 gtk_html_copy (GTK_HTML (focused_widget));
3874 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3875 gtk_clipboard_store (clipboard);
3877 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3878 GtkTextBuffer *buffer;
3879 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3880 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3881 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3882 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3883 gtk_clipboard_store (clipboard);
3885 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3886 TnyList *header_list = modest_header_view_get_selected_headers (
3887 MODEST_HEADER_VIEW (focused_widget));
3888 gboolean continue_download = FALSE;
3889 gint num_of_unc_msgs;
3891 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3893 if (num_of_unc_msgs) {
3894 TnyAccount *account = get_account_from_header_list (header_list);
3896 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3897 g_object_unref (account);
3901 if (num_of_unc_msgs == 0 || continue_download) {
3902 modest_platform_information_banner (
3903 NULL, NULL, _CS("mcen_ib_getting_items"));
3904 modest_header_view_copy_selection (
3905 MODEST_HEADER_VIEW (focused_widget));
3909 g_object_unref (header_list);
3911 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3912 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3915 /* Show information banner if there was a copy to clipboard */
3917 modest_platform_information_banner (
3918 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3922 modest_ui_actions_on_undo (GtkAction *action,
3923 ModestWindow *window)
3925 ModestEmailClipboard *clipboard = NULL;
3927 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3928 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3929 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3930 /* Clear clipboard source */
3931 clipboard = modest_runtime_get_email_clipboard ();
3932 modest_email_clipboard_clear (clipboard);
3935 g_return_if_reached ();
3940 modest_ui_actions_on_redo (GtkAction *action,
3941 ModestWindow *window)
3943 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3944 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3947 g_return_if_reached ();
3953 destroy_information_note (ModestMailOperation *mail_op,
3956 /* destroy information note */
3957 gtk_widget_destroy (GTK_WIDGET(user_data));
3961 destroy_folder_information_note (ModestMailOperation *mail_op,
3962 TnyFolder *new_folder,
3965 /* destroy information note */
3966 gtk_widget_destroy (GTK_WIDGET(user_data));
3971 paste_as_attachment_free (gpointer data)
3973 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3975 if (helper->banner) {
3976 gtk_widget_destroy (helper->banner);
3977 g_object_unref (helper->banner);
3983 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3988 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3989 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3994 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3999 modest_ui_actions_on_paste (GtkAction *action,
4000 ModestWindow *window)
4002 GtkWidget *focused_widget = NULL;
4003 GtkWidget *inf_note = NULL;
4004 ModestMailOperation *mail_op = NULL;
4006 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4007 if (GTK_IS_EDITABLE (focused_widget)) {
4008 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4009 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4010 ModestEmailClipboard *e_clipboard = NULL;
4011 e_clipboard = modest_runtime_get_email_clipboard ();
4012 if (modest_email_clipboard_cleared (e_clipboard)) {
4013 GtkTextBuffer *buffer;
4014 GtkClipboard *clipboard;
4016 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4017 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4018 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4019 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4020 ModestMailOperation *mail_op;
4021 TnyFolder *src_folder = NULL;
4022 TnyList *data = NULL;
4024 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4025 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4026 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4027 _CS("ckct_nw_pasting"));
4028 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4029 mail_op = modest_mail_operation_new (G_OBJECT (window));
4030 if (helper->banner != NULL) {
4031 g_object_ref (G_OBJECT (helper->banner));
4032 gtk_widget_show (GTK_WIDGET (helper->banner));
4036 modest_mail_operation_get_msgs_full (mail_op,
4038 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4040 paste_as_attachment_free);
4044 g_object_unref (data);
4046 g_object_unref (src_folder);
4049 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4050 ModestEmailClipboard *clipboard = NULL;
4051 TnyFolder *src_folder = NULL;
4052 TnyFolderStore *folder_store = NULL;
4053 TnyList *data = NULL;
4054 gboolean delete = FALSE;
4056 /* Check clipboard source */
4057 clipboard = modest_runtime_get_email_clipboard ();
4058 if (modest_email_clipboard_cleared (clipboard))
4061 /* Get elements to paste */
4062 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4064 /* Create a new mail operation */
4065 mail_op = modest_mail_operation_new (G_OBJECT(window));
4067 /* Get destination folder */
4068 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4070 /* transfer messages */
4074 /* Ask for user confirmation */
4076 modest_ui_actions_msgs_move_to_confirmation (window,
4077 TNY_FOLDER (folder_store),
4081 if (response == GTK_RESPONSE_OK) {
4082 /* Launch notification */
4083 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4084 _CS("ckct_nw_pasting"));
4085 if (inf_note != NULL) {
4086 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4087 gtk_widget_show (GTK_WIDGET(inf_note));
4090 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4091 modest_mail_operation_xfer_msgs (mail_op,
4093 TNY_FOLDER (folder_store),
4095 destroy_information_note,
4098 g_object_unref (mail_op);
4101 } else if (src_folder != NULL) {
4102 /* Launch notification */
4103 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4104 _CS("ckct_nw_pasting"));
4105 if (inf_note != NULL) {
4106 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4107 gtk_widget_show (GTK_WIDGET(inf_note));
4110 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4111 modest_mail_operation_xfer_folder (mail_op,
4115 destroy_folder_information_note,
4121 g_object_unref (data);
4122 if (src_folder != NULL)
4123 g_object_unref (src_folder);
4124 if (folder_store != NULL)
4125 g_object_unref (folder_store);
4131 modest_ui_actions_on_select_all (GtkAction *action,
4132 ModestWindow *window)
4134 GtkWidget *focused_widget;
4136 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4137 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4138 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4139 } else if (GTK_IS_LABEL (focused_widget)) {
4140 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4141 } else if (GTK_IS_EDITABLE (focused_widget)) {
4142 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4143 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4144 GtkTextBuffer *buffer;
4145 GtkTextIter start, end;
4147 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4148 gtk_text_buffer_get_start_iter (buffer, &start);
4149 gtk_text_buffer_get_end_iter (buffer, &end);
4150 gtk_text_buffer_select_range (buffer, &start, &end);
4151 } else if (GTK_IS_HTML (focused_widget)) {
4152 gtk_html_select_all (GTK_HTML (focused_widget));
4153 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4154 GtkWidget *header_view = focused_widget;
4155 GtkTreeSelection *selection = NULL;
4157 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4158 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4159 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4162 /* Disable window dimming management */
4163 modest_window_disable_dimming (MODEST_WINDOW(window));
4165 /* Select all messages */
4166 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4167 gtk_tree_selection_select_all (selection);
4169 /* Set focuse on header view */
4170 gtk_widget_grab_focus (header_view);
4172 /* Enable window dimming management */
4173 modest_window_enable_dimming (MODEST_WINDOW(window));
4174 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4175 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4181 modest_ui_actions_on_mark_as_read (GtkAction *action,
4182 ModestWindow *window)
4184 g_return_if_fail (MODEST_IS_WINDOW(window));
4186 /* Mark each header as read */
4187 do_headers_action (window, headers_action_mark_as_read, NULL);
4191 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4192 ModestWindow *window)
4194 g_return_if_fail (MODEST_IS_WINDOW(window));
4196 /* Mark each header as read */
4197 do_headers_action (window, headers_action_mark_as_unread, NULL);
4201 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4202 GtkRadioAction *selected,
4203 ModestWindow *window)
4207 value = gtk_radio_action_get_current_value (selected);
4208 if (MODEST_IS_WINDOW (window)) {
4209 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4214 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4215 GtkRadioAction *selected,
4216 ModestWindow *window)
4218 TnyHeaderFlags flags;
4219 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4221 flags = gtk_radio_action_get_current_value (selected);
4222 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4226 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4227 GtkRadioAction *selected,
4228 ModestWindow *window)
4232 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4234 file_format = gtk_radio_action_get_current_value (selected);
4235 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4240 modest_ui_actions_on_zoom_plus (GtkAction *action,
4241 ModestWindow *window)
4243 g_return_if_fail (MODEST_IS_WINDOW (window));
4245 modest_window_zoom_plus (MODEST_WINDOW (window));
4249 modest_ui_actions_on_zoom_minus (GtkAction *action,
4250 ModestWindow *window)
4252 g_return_if_fail (MODEST_IS_WINDOW (window));
4254 modest_window_zoom_minus (MODEST_WINDOW (window));
4258 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4259 ModestWindow *window)
4261 ModestWindowMgr *mgr;
4262 gboolean fullscreen, active;
4263 g_return_if_fail (MODEST_IS_WINDOW (window));
4265 mgr = modest_runtime_get_window_mgr ();
4267 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4268 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4270 if (active != fullscreen) {
4271 modest_window_mgr_set_fullscreen_mode (mgr, active);
4272 #ifndef MODEST_TOOLKIT_HILDON2
4273 gtk_window_present (GTK_WINDOW (window));
4279 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4280 ModestWindow *window)
4282 ModestWindowMgr *mgr;
4283 gboolean fullscreen;
4285 g_return_if_fail (MODEST_IS_WINDOW (window));
4287 mgr = modest_runtime_get_window_mgr ();
4288 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4289 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4291 #ifndef MODEST_TOOLKIT_HILDON2
4292 gtk_window_present (GTK_WINDOW (window));
4297 * Used by modest_ui_actions_on_details to call do_headers_action
4300 headers_action_show_details (TnyHeader *header,
4301 ModestWindow *window,
4305 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header);
4309 * Show the header details in a ModestDetailsDialog widget
4312 modest_ui_actions_on_details (GtkAction *action,
4315 TnyList * headers_list;
4319 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4322 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4325 g_object_unref (msg);
4327 headers_list = get_selected_headers (win);
4331 iter = tny_list_create_iterator (headers_list);
4333 header = TNY_HEADER (tny_iterator_get_current (iter));
4335 headers_action_show_details (header, win, NULL);
4336 g_object_unref (header);
4339 g_object_unref (iter);
4340 g_object_unref (headers_list);
4342 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4343 GtkWidget *folder_view, *header_view;
4345 /* Check which widget has the focus */
4346 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4347 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4348 if (gtk_widget_is_focus (folder_view)) {
4349 TnyFolderStore *folder_store
4350 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4351 if (!folder_store) {
4352 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4355 /* Show only when it's a folder */
4356 /* This function should not be called for account items,
4357 * because we dim the menu item for them. */
4358 if (TNY_IS_FOLDER (folder_store)) {
4359 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4360 TNY_FOLDER (folder_store));
4363 g_object_unref (folder_store);
4366 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4367 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4368 /* Show details of each header */
4369 do_headers_action (win, headers_action_show_details, header_view);
4375 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4376 ModestMsgEditWindow *window)
4378 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4380 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4384 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4385 ModestMsgEditWindow *window)
4387 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4389 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4393 modest_ui_actions_toggle_folders_view (GtkAction *action,
4394 ModestMainWindow *main_window)
4396 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4398 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4399 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4401 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4405 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4406 ModestWindow *window)
4408 gboolean active, fullscreen = FALSE;
4409 ModestWindowMgr *mgr;
4411 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4413 /* Check if we want to toggle the toolbar view in fullscreen
4415 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4416 "ViewShowToolbarFullScreen")) {
4420 /* Toggle toolbar */
4421 mgr = modest_runtime_get_window_mgr ();
4422 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4426 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4427 ModestMsgEditWindow *window)
4429 modest_msg_edit_window_select_font (window);
4434 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4435 const gchar *display_name,
4438 /* don't update the display name if it was already set;
4439 * updating the display name apparently is expensive */
4440 const gchar* old_name = gtk_window_get_title (window);
4442 if (display_name == NULL)
4445 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4446 return; /* don't do anything */
4448 /* This is usually used to change the title of the main window, which
4449 * is the one that holds the folder view. Note that this change can
4450 * happen even when the widget doesn't have the focus. */
4451 gtk_window_set_title (window, display_name);
4456 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4458 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4459 modest_msg_edit_window_select_contacts (window);
4463 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4465 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4466 modest_msg_edit_window_check_names (window, FALSE);
4470 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
4472 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
4473 GTK_WIDGET (user_data));
4477 * This function is used to track changes in the selection of the
4478 * folder view that is inside the "move to" dialog to enable/disable
4479 * the OK button because we do not want the user to select a disallowed
4480 * destination for a folder.
4481 * The user also not desired to be able to use NEW button on items where
4482 * folder creation is not possibel.
4485 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4486 TnyFolderStore *folder_store,
4490 GtkWidget *dialog = NULL;
4491 GtkWidget *ok_button = NULL, *new_button = NULL;
4492 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4493 gboolean moving_folder = FALSE;
4494 gboolean is_local_account = TRUE;
4495 GtkWidget *folder_view = NULL;
4496 ModestTnyFolderRules rules;
4498 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
4503 /* Get the OK button */
4504 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
4508 ok_button = g_object_get_data (G_OBJECT (dialog), MOVE_FOLDER_OK_BUTTON);
4509 new_button = g_object_get_data (G_OBJECT (dialog), MOVE_FOLDER_NEW_BUTTON);
4511 /* check if folder_store is an remote account */
4512 if (TNY_IS_ACCOUNT (folder_store)) {
4513 TnyAccount *local_account = NULL;
4514 TnyAccount *mmc_account = NULL;
4515 ModestTnyAccountStore *account_store = NULL;
4517 account_store = modest_runtime_get_account_store ();
4518 local_account = modest_tny_account_store_get_local_folders_account (account_store);
4519 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
4521 if ((gpointer) local_account != (gpointer) folder_store &&
4522 (gpointer) mmc_account != (gpointer) folder_store) {
4523 ModestProtocolType proto;
4524 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
4525 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
4526 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
4528 is_local_account = FALSE;
4529 /* New button should be dimmed on remote
4531 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4533 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
4535 g_object_unref (local_account);
4537 /* It could not exist */
4539 g_object_unref (mmc_account);
4542 /* Check the target folder rules */
4543 if (TNY_IS_FOLDER (folder_store)) {
4544 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
4545 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
4546 ok_sensitive = FALSE;
4547 new_sensitive = FALSE;
4552 /* Check if we're moving a folder */
4553 if (MODEST_IS_MAIN_WINDOW (user_data)) {
4554 /* Get the widgets */
4555 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
4556 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4557 if (gtk_widget_is_focus (folder_view))
4558 moving_folder = TRUE;
4561 if (moving_folder) {
4562 TnyFolderStore *moved_folder = NULL, *parent = NULL;
4564 /* Get the folder to move */
4565 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4567 /* Check that we're not moving to the same folder */
4568 if (TNY_IS_FOLDER (moved_folder)) {
4569 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
4570 if (parent == folder_store)
4571 ok_sensitive = FALSE;
4572 g_object_unref (parent);
4575 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
4576 /* Do not allow to move to an account unless it's the
4577 local folders account */
4578 if (!is_local_account)
4579 ok_sensitive = FALSE;
4582 if (ok_sensitive && (moved_folder == folder_store)) {
4583 /* Do not allow to move to itself */
4584 ok_sensitive = FALSE;
4586 g_object_unref (moved_folder);
4588 TnyFolder *src_folder = NULL;
4590 /* Moving a message */
4591 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
4593 TnyHeader *header = NULL;
4594 header = modest_msg_view_window_get_header
4595 (MODEST_MSG_VIEW_WINDOW (user_data));
4596 if (!TNY_IS_HEADER(header))
4597 g_warning ("%s: could not get source header", __FUNCTION__);
4599 src_folder = tny_header_get_folder (header);
4602 g_object_unref (header);
4605 TNY_FOLDER (modest_folder_view_get_selected
4606 (MODEST_FOLDER_VIEW (folder_view)));
4609 if (TNY_IS_FOLDER(src_folder)) {
4610 /* Do not allow to move the msg to the same folder */
4611 /* Do not allow to move the msg to an account */
4612 if ((gpointer) src_folder == (gpointer) folder_store ||
4613 TNY_IS_ACCOUNT (folder_store))
4614 ok_sensitive = FALSE;
4615 g_object_unref (src_folder);
4617 g_warning ("%s: could not get source folder", __FUNCTION__);
4621 /* Set sensitivity of the OK button */
4622 gtk_widget_set_sensitive (ok_button, ok_sensitive);
4623 /* Set sensitivity of the NEW button */
4624 gtk_widget_set_sensitive (new_button, new_sensitive);
4628 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
4631 get_folder_view_from_move_to_dialog (GtkWidget *move_to_dialog)
4633 return GTK_WIDGET(g_object_get_data (G_OBJECT(move_to_dialog),
4634 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4638 create_move_to_dialog (GtkWindow *win,
4639 GtkWidget *folder_view,
4640 GtkWidget **tree_view)
4643 #ifdef MODEST_TOOLKIT_HILDON2
4644 GtkWidget *pannable;
4648 GtkWidget *new_button, *ok_button;
4650 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
4652 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
4655 #ifndef MODEST_TOOLKIT_GTK
4656 ok_button = gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
4657 /* We do this manually so GTK+ does not associate a response ID for
4659 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
4660 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
4661 gtk_widget_show (new_button);
4662 #ifndef MODEST_TOOLKIT_HILDON2
4663 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
4666 /* We do this manually so GTK+ does not associate a response ID for
4668 new_button = gtk_button_new_with_label (_("mcen_ti_new_folder"));
4669 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
4670 gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (GTK_DIALOG (dialog)->action_area), new_button, TRUE);
4671 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
4672 ok_button = gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
4673 gtk_container_set_border_width (GTK_CONTAINER (dialog), 12);
4674 gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 24);
4676 g_object_set_data (G_OBJECT (dialog), MOVE_FOLDER_OK_BUTTON, ok_button);
4677 g_object_set_data (G_OBJECT (dialog), MOVE_FOLDER_NEW_BUTTON, new_button);
4679 /* Create scrolled window */
4680 #ifdef MODEST_TOOLKIT_HILDON2
4681 pannable = hildon_pannable_area_new ();
4683 scroll = gtk_scrolled_window_new (NULL, NULL);
4684 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
4685 GTK_POLICY_AUTOMATIC,
4686 GTK_POLICY_AUTOMATIC);
4689 #ifdef MODEST_TOOLKIT_GTK
4690 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN);
4693 /* Create folder view */
4694 *tree_view = modest_platform_create_folder_view (NULL);
4696 /* Track changes in the selection to
4697 * disable the OK button whenever "Move to" is not possible
4698 * disbale NEW button whenever New is not possible */
4699 g_signal_connect (*tree_view,
4700 "folder_selection_changed",
4701 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
4704 /* Listen to clicks on New button */
4705 g_signal_connect (G_OBJECT (new_button),
4707 G_CALLBACK(create_move_to_dialog_on_new_folder),
4710 /* It could happen that we're trying to move a message from a
4711 window (msg window for example) after the main window was
4712 closed, so we can not just get the model of the folder
4714 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4715 const gchar *visible_id = NULL;
4717 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4718 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4719 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4720 MODEST_FOLDER_VIEW(*tree_view));
4723 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4725 /* Show the same account than the one that is shown in the main window */
4726 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
4729 const gchar *active_account_name = NULL;
4730 ModestAccountMgr *mgr = NULL;
4731 ModestAccountSettings *settings = NULL;
4732 ModestServerAccountSettings *store_settings = NULL;
4734 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4735 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4736 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
4737 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
4739 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4740 mgr = modest_runtime_get_account_mgr ();
4741 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4744 const gchar *store_account_name;
4745 store_settings = modest_account_settings_get_store_settings (settings);
4746 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4748 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
4749 store_account_name);
4750 g_object_unref (store_settings);
4751 g_object_unref (settings);
4755 /* we keep a pointer to the embedded folder view, so we can retrieve it with
4756 * get_folder_view_from_move_to_dialog
4757 * (see above) later (needed for focus handling)
4759 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, *tree_view);
4762 /* Hide special folders */
4763 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
4765 #ifdef MODEST_TOOLKIT_HILDON2
4766 gtk_container_add (GTK_CONTAINER (pannable), *tree_view);
4767 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
4768 pannable, TRUE, TRUE, 0);
4770 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
4771 /* Add scroll to dialog */
4772 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
4773 scroll, TRUE, TRUE, 0);
4777 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4778 #ifndef MODEST_TOOLKIT_GTK
4779 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
4781 gtk_window_set_default_size (GTK_WINDOW (dialog), 600, 400);
4790 * Shows a confirmation dialog to the user when we're moving messages
4791 * from a remote server to the local storage. Returns the dialog
4792 * response. If it's other kind of movement then it always returns
4795 * This one is used by the next functions:
4796 * modest_ui_actions_on_paste - commented out
4797 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4800 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4801 TnyFolder *dest_folder,
4805 gint response = GTK_RESPONSE_OK;
4806 TnyAccount *account = NULL;
4807 TnyFolder *src_folder = NULL;
4808 TnyIterator *iter = NULL;
4809 TnyHeader *header = NULL;
4811 /* return with OK if the destination is a remote folder */
4812 if (modest_tny_folder_is_remote_folder (dest_folder))
4813 return GTK_RESPONSE_OK;
4815 /* Get source folder */
4816 iter = tny_list_create_iterator (headers);
4817 header = TNY_HEADER (tny_iterator_get_current (iter));
4819 src_folder = tny_header_get_folder (header);
4820 g_object_unref (header);
4822 g_object_unref (iter);
4824 /* if no src_folder, message may be an attahcment */
4825 if (src_folder == NULL)
4826 return GTK_RESPONSE_CANCEL;
4828 /* If the source is a local or MMC folder */
4829 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4830 g_object_unref (src_folder);
4831 return GTK_RESPONSE_OK;
4834 /* Get the account */
4835 account = tny_folder_get_account (src_folder);
4837 /* now if offline we ask the user */
4838 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4839 response = GTK_RESPONSE_OK;
4841 response = GTK_RESPONSE_CANCEL;
4844 g_object_unref (src_folder);
4845 g_object_unref (account);
4851 move_to_helper_destroyer (gpointer user_data)
4853 MoveToHelper *helper = (MoveToHelper *) user_data;
4855 /* Close the "Pasting" information banner */
4856 if (helper->banner) {
4857 gtk_widget_destroy (GTK_WIDGET (helper->banner));
4858 g_object_unref (helper->banner);
4860 if (gtk_tree_row_reference_valid (helper->reference)) {
4861 gtk_tree_row_reference_free (helper->reference);
4862 helper->reference = NULL;
4868 move_to_cb (ModestMailOperation *mail_op,
4871 MoveToHelper *helper = (MoveToHelper *) user_data;
4873 /* Note that the operation could have failed, in that case do
4875 if (modest_mail_operation_get_status (mail_op) ==
4876 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
4878 GObject *object = modest_mail_operation_get_source (mail_op);
4879 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4880 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4882 if (!modest_msg_view_window_select_next_message (self) &&
4883 !modest_msg_view_window_select_previous_message (self)) {
4884 /* No more messages to view, so close this window */
4885 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4887 } else if (MODEST_IS_MAIN_WINDOW (object) &&
4888 gtk_tree_row_reference_valid (helper->reference)) {
4889 GtkWidget *header_view;
4891 GtkTreeSelection *sel;
4893 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4894 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4895 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
4896 path = gtk_tree_row_reference_get_path (helper->reference);
4897 /* We need to unselect the previous one
4898 because we could be copying instead of
4900 gtk_tree_selection_unselect_all (sel);
4901 gtk_tree_selection_select_path (sel, path);
4902 gtk_tree_path_free (path);
4904 g_object_unref (object);
4906 /* Destroy the helper */
4907 move_to_helper_destroyer (helper);
4911 folder_move_to_cb (ModestMailOperation *mail_op,
4912 TnyFolder *new_folder,
4915 GtkWidget *folder_view;
4918 object = modest_mail_operation_get_source (mail_op);
4919 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4920 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4921 g_object_ref (folder_view);
4922 g_object_unref (object);
4923 move_to_cb (mail_op, user_data);
4924 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
4925 g_object_unref (folder_view);
4929 msgs_move_to_cb (ModestMailOperation *mail_op,
4932 move_to_cb (mail_op, user_data);
4936 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
4939 ModestWindow *main_window = NULL;
4941 /* Disable next automatic folder selection */
4942 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
4943 FALSE); /* don't create */
4945 GObject *win = NULL;
4946 GtkWidget *folder_view = NULL;
4948 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
4949 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4950 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
4952 if (user_data && TNY_IS_FOLDER (user_data)) {
4953 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
4954 TNY_FOLDER (user_data), FALSE);
4957 /* Show notification dialog only if the main window exists */
4958 win = modest_mail_operation_get_source (mail_op);
4959 modest_platform_run_information_dialog ((GtkWindow *) win,
4960 _("mail_in_ui_folder_move_target_error"),
4963 g_object_unref (win);
4968 open_msg_for_purge_cb (ModestMailOperation *mail_op,
4977 gint pending_purges = 0;
4978 gboolean some_purged = FALSE;
4979 ModestWindow *win = MODEST_WINDOW (user_data);
4980 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
4982 /* If there was any error */
4983 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
4984 modest_window_mgr_unregister_header (mgr, header);
4988 /* Once the message has been retrieved for purging, we check if
4989 * it's all ok for purging */
4991 parts = tny_simple_list_new ();
4992 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
4993 iter = tny_list_create_iterator (parts);
4995 while (!tny_iterator_is_done (iter)) {
4997 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4998 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
4999 if (tny_mime_part_is_purged (part))
5006 g_object_unref (part);
5008 tny_iterator_next (iter);
5010 g_object_unref (iter);
5013 if (pending_purges>0) {
5015 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5017 if (response == GTK_RESPONSE_OK) {
5020 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5021 iter = tny_list_create_iterator (parts);
5022 while (!tny_iterator_is_done (iter)) {
5025 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5026 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5027 tny_mime_part_set_purged (part);
5030 g_object_unref (part);
5032 tny_iterator_next (iter);
5034 g_object_unref (iter);
5036 tny_msg_rewrite_cache (msg);
5038 gtk_widget_destroy (info);
5042 modest_window_mgr_unregister_header (mgr, header);
5044 g_object_unref (parts);
5048 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5049 ModestMainWindow *win)
5051 GtkWidget *header_view;
5052 TnyList *header_list;
5054 TnyHeaderFlags flags;
5055 ModestWindow *msg_view_window = NULL;
5058 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5060 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5061 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5063 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5065 g_warning ("%s: no header selected", __FUNCTION__);
5069 if (tny_list_get_length (header_list) == 1) {
5070 TnyIterator *iter = tny_list_create_iterator (header_list);
5071 header = TNY_HEADER (tny_iterator_get_current (iter));
5072 g_object_unref (iter);
5076 if (!header || !TNY_IS_HEADER(header)) {
5077 g_warning ("%s: header is not valid", __FUNCTION__);
5081 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5082 header, &msg_view_window);
5083 flags = tny_header_get_flags (header);
5084 if (!(flags & TNY_HEADER_FLAG_CACHED))
5087 if (msg_view_window != NULL)
5088 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5090 /* do nothing; uid was registered before, so window is probably on it's way */
5091 g_warning ("debug: header %p has already been registered", header);
5094 ModestMailOperation *mail_op = NULL;
5095 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5096 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5097 modest_ui_actions_disk_operations_error_handler,
5099 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5100 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5102 g_object_unref (mail_op);
5105 g_object_unref (header);
5107 g_object_unref (header_list);
5111 * Checks if we need a connection to do the transfer and if the user
5112 * wants to connect to complete it
5115 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5116 TnyFolderStore *src_folder,
5118 TnyFolder *dst_folder,
5119 gboolean delete_originals,
5120 gboolean *need_connection,
5123 TnyAccount *src_account;
5124 gint uncached_msgs = 0;
5126 uncached_msgs = header_list_count_uncached_msgs (headers);
5128 /* We don't need any further check if
5130 * 1- the source folder is local OR
5131 * 2- the device is already online
5133 if (!modest_tny_folder_store_is_remote (src_folder) ||
5134 tny_device_is_online (modest_runtime_get_device())) {
5135 *need_connection = FALSE;
5140 /* We must ask for a connection when
5142 * - the message(s) is not already cached OR
5143 * - the message(s) is cached but the leave_on_server setting
5144 * is FALSE (because we need to sync the source folder to
5145 * delete the message from the server (for IMAP we could do it
5146 * offline, it'll take place the next time we get a
5149 src_account = get_account_from_folder_store (src_folder);
5150 if (uncached_msgs > 0) {
5154 *need_connection = TRUE;
5155 num_headers = tny_list_get_length (headers);
5156 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5158 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5159 GTK_RESPONSE_CANCEL) {
5165 /* The transfer is possible and the user wants to */
5168 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5169 const gchar *account_name;
5170 gboolean leave_on_server;
5172 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5173 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5176 if (leave_on_server == TRUE) {
5177 *need_connection = FALSE;
5179 *need_connection = TRUE;
5182 *need_connection = FALSE;
5187 g_object_unref (src_account);
5191 xfer_messages_error_handler (ModestMailOperation *mail_op,
5194 ModestWindow *main_window = NULL;
5196 /* Disable next automatic folder selection */
5197 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5198 FALSE); /* don't create */
5200 GObject *win = modest_mail_operation_get_source (mail_op);
5201 modest_platform_run_information_dialog ((GtkWindow *) win,
5202 _("mail_in_ui_folder_move_target_error"),
5205 g_object_unref (win);
5207 move_to_helper_destroyer (user_data);
5211 TnyFolderStore *dst_folder;
5216 * Utility function that transfer messages from both the main window
5217 * and the msg view window when using the "Move to" dialog
5220 xfer_messages_performer (gboolean canceled,
5222 GtkWindow *parent_window,
5223 TnyAccount *account,
5226 ModestWindow *win = MODEST_WINDOW (parent_window);
5227 TnyAccount *dst_account = NULL;
5228 gboolean dst_forbids_message_add = FALSE;
5229 XferMsgsHelper *helper;
5230 MoveToHelper *movehelper;
5231 ModestMailOperation *mail_op;
5233 helper = (XferMsgsHelper *) user_data;
5235 if (canceled || err) {
5236 if (!check_memory_full_error ((GtkWidget *) parent_window, err)) {
5237 /* Show the proper error message */
5238 modest_ui_actions_on_account_connection_error (parent_window, account);
5243 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5245 /* tinymail will return NULL for local folders it seems */
5246 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5247 modest_tny_account_get_protocol_type (dst_account),
5248 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_MESSAGE_ADD);
5249 g_object_unref (dst_account);
5251 if (dst_forbids_message_add) {
5252 modest_platform_information_banner (GTK_WIDGET (win),
5254 ngettext("mail_in_ui_folder_move_target_error",
5255 "mail_in_ui_folder_move_targets_error",
5256 tny_list_get_length (helper->headers)));
5260 movehelper = g_new0 (MoveToHelper, 1);
5261 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5262 _CS("ckct_nw_pasting"));
5263 if (movehelper->banner != NULL) {
5264 g_object_ref (movehelper->banner);
5265 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5268 if (MODEST_IS_MAIN_WINDOW (win)) {
5269 GtkWidget *header_view =
5270 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5271 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5272 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5275 /* Perform the mail operation */
5276 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5277 xfer_messages_error_handler,
5279 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5282 modest_mail_operation_xfer_msgs (mail_op,
5284 TNY_FOLDER (helper->dst_folder),
5289 g_object_unref (G_OBJECT (mail_op));
5291 g_object_unref (helper->dst_folder);
5292 g_object_unref (helper->headers);
5293 g_slice_free (XferMsgsHelper, helper);
5297 TnyFolder *src_folder;
5298 TnyFolderStore *dst_folder;
5299 gboolean delete_original;
5300 GtkWidget *folder_view;
5304 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
5305 TnyAccount *account, gpointer user_data)
5307 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5308 GtkTreeSelection *sel;
5309 ModestMailOperation *mail_op = NULL;
5311 if (canceled || err || !MODEST_IS_MAIN_WINDOW (parent_window)) {
5312 g_object_unref (G_OBJECT (info->src_folder));
5313 g_object_unref (G_OBJECT (info->dst_folder));
5318 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5319 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5320 _CS("ckct_nw_pasting"));
5321 if (helper->banner != NULL) {
5322 g_object_ref (helper->banner);
5323 gtk_widget_show (GTK_WIDGET(helper->banner));
5325 /* Clean folder on header view before moving it */
5326 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5327 gtk_tree_selection_unselect_all (sel);
5329 /* Let gtk events run. We need that the folder
5330 view frees its reference to the source
5331 folder *before* issuing the mail operation
5332 so we need the signal handler of selection
5333 changed to happen before the mail
5335 while (gtk_events_pending ())
5336 gtk_main_iteration (); */
5339 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5340 modest_ui_actions_move_folder_error_handler,
5341 info->src_folder, NULL);
5342 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5345 /* Select *after* the changes */
5346 /* TODO: this function hangs UI after transfer */
5347 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
5348 /* TNY_FOLDER (src_folder), TRUE); */
5350 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5351 TNY_FOLDER (info->dst_folder), TRUE);
5352 modest_mail_operation_xfer_folder (mail_op,
5353 TNY_FOLDER (info->src_folder),
5355 info->delete_original,
5358 g_object_unref (G_OBJECT (info->src_folder));
5360 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5363 /* Unref mail operation */
5364 g_object_unref (G_OBJECT (mail_op));
5365 g_object_unref (G_OBJECT (info->dst_folder));
5370 get_account_from_folder_store (TnyFolderStore *folder_store)
5372 if (TNY_IS_ACCOUNT (folder_store))
5373 return g_object_ref (folder_store);
5375 return tny_folder_get_account (TNY_FOLDER (folder_store));
5379 * UI handler for the "Move to" action when invoked from the
5383 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5384 GtkWidget *folder_view,
5385 TnyFolderStore *dst_folder,
5386 ModestMainWindow *win)
5388 ModestHeaderView *header_view = NULL;
5389 TnyFolderStore *src_folder = NULL;
5391 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5393 /* Get the source folder */
5394 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5396 /* Get header view */
5397 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
5399 /* Get folder or messages to transfer */
5400 if (gtk_widget_is_focus (folder_view)) {
5401 gboolean do_xfer = TRUE;
5403 /* Allow only to transfer folders to the local root folder */
5404 if (TNY_IS_ACCOUNT (dst_folder) &&
5405 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5406 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5408 } else if (!TNY_IS_FOLDER (src_folder)) {
5409 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5414 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5415 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5417 info->src_folder = g_object_ref (src_folder);
5418 info->dst_folder = g_object_ref (dst_folder);
5419 info->delete_original = TRUE;
5420 info->folder_view = folder_view;
5422 connect_info->callback = on_move_folder_cb;
5423 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5424 connect_info->data = info;
5426 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5427 TNY_FOLDER_STORE (src_folder),
5430 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5433 headers = modest_header_view_get_selected_headers(header_view);
5435 /* Transfer the messages */
5436 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
5437 headers, TNY_FOLDER (dst_folder));
5439 g_object_unref (headers);
5443 g_object_unref (src_folder);
5448 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
5449 TnyFolder *src_folder,
5451 TnyFolder *dst_folder)
5453 gboolean need_connection = TRUE;
5454 gboolean do_xfer = TRUE;
5455 XferMsgsHelper *helper;
5457 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5458 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5459 g_return_if_fail (TNY_IS_LIST (headers));
5461 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5462 headers, TNY_FOLDER (dst_folder),
5463 TRUE, &need_connection,
5466 /* If we don't want to transfer just return */
5470 /* Create the helper */
5471 helper = g_slice_new (XferMsgsHelper);
5472 helper->dst_folder = g_object_ref (dst_folder);
5473 helper->headers = g_object_ref (headers);
5475 if (need_connection) {
5476 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5477 connect_info->callback = xfer_messages_performer;
5478 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5479 connect_info->data = helper;
5481 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5482 TNY_FOLDER_STORE (src_folder),
5485 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5486 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
5487 src_account, helper);
5488 g_object_unref (src_account);
5493 * UI handler for the "Move to" action when invoked from the
5494 * ModestMsgViewWindow
5497 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
5498 TnyFolderStore *dst_folder,
5499 ModestMsgViewWindow *win)
5501 TnyList *headers = NULL;
5502 TnyHeader *header = NULL;
5503 TnyFolder *src_folder = NULL;
5505 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5507 /* Create header list */
5508 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
5509 src_folder = TNY_FOLDER (tny_header_get_folder(header));
5510 headers = tny_simple_list_new ();
5511 tny_list_append (headers, G_OBJECT (header));
5513 /* Transfer the messages */
5514 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder, headers,
5515 TNY_FOLDER (dst_folder));
5518 g_object_unref (src_folder);
5519 g_object_unref (header);
5520 g_object_unref (headers);
5524 modest_ui_actions_on_move_to (GtkAction *action,
5527 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
5529 TnyFolderStore *dst_folder = NULL;
5530 ModestMainWindow *main_window;
5532 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
5533 MODEST_IS_MSG_VIEW_WINDOW (win));
5535 /* Get the main window if exists */
5536 if (MODEST_IS_MAIN_WINDOW (win))
5537 main_window = MODEST_MAIN_WINDOW (win);
5540 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5541 FALSE)); /* don't create */
5543 /* Get the folder view widget if exists */
5545 folder_view = modest_main_window_get_child_widget (main_window,
5546 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5550 /* Create and run the dialog */
5551 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
5552 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5553 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog), (GtkWindow *) win);
5554 result = gtk_dialog_run (GTK_DIALOG(dialog));
5555 g_object_ref (tree_view);
5556 gtk_widget_destroy (dialog);
5558 if (result != GTK_RESPONSE_ACCEPT)
5561 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
5562 /* Do window specific stuff */
5563 if (MODEST_IS_MAIN_WINDOW (win)) {
5564 modest_ui_actions_on_main_window_move_to (action,
5567 MODEST_MAIN_WINDOW (win));
5569 modest_ui_actions_on_msg_view_window_move_to (action,
5571 MODEST_MSG_VIEW_WINDOW (win));
5575 g_object_unref (dst_folder);
5579 * Calls #HeadersFunc for each header already selected in the main
5580 * window or the message currently being shown in the msg view window
5583 do_headers_action (ModestWindow *win,
5587 TnyList *headers_list = NULL;
5588 TnyIterator *iter = NULL;
5589 TnyHeader *header = NULL;
5590 TnyFolder *folder = NULL;
5593 headers_list = get_selected_headers (win);
5597 /* Get the folder */
5598 iter = tny_list_create_iterator (headers_list);
5599 header = TNY_HEADER (tny_iterator_get_current (iter));
5601 folder = tny_header_get_folder (header);
5602 g_object_unref (header);
5605 /* Call the function for each header */
5606 while (!tny_iterator_is_done (iter)) {
5607 header = TNY_HEADER (tny_iterator_get_current (iter));
5608 func (header, win, user_data);
5609 g_object_unref (header);
5610 tny_iterator_next (iter);
5613 /* Trick: do a poke status in order to speed up the signaling
5615 tny_folder_poke_status (folder);
5618 g_object_unref (folder);
5619 g_object_unref (iter);
5620 g_object_unref (headers_list);
5624 modest_ui_actions_view_attachment (GtkAction *action,
5625 ModestWindow *window)
5627 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5628 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5630 /* not supported window for this action */
5631 g_return_if_reached ();
5636 modest_ui_actions_save_attachments (GtkAction *action,
5637 ModestWindow *window)
5639 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5641 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5644 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5646 /* not supported window for this action */
5647 g_return_if_reached ();
5652 modest_ui_actions_remove_attachments (GtkAction *action,
5653 ModestWindow *window)
5655 if (MODEST_IS_MAIN_WINDOW (window)) {
5656 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
5657 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5658 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5660 /* not supported window for this action */
5661 g_return_if_reached ();
5666 modest_ui_actions_on_settings (GtkAction *action,
5671 dialog = modest_platform_get_global_settings_dialog ();
5672 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
5673 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5674 gtk_widget_show_all (dialog);
5676 gtk_dialog_run (GTK_DIALOG (dialog));
5678 gtk_widget_destroy (dialog);
5682 modest_ui_actions_on_help (GtkAction *action,
5685 /* Help app is not available at all in fremantle */
5686 #ifndef MODEST_TOOLKIT_HILDON2
5687 const gchar *help_id;
5689 g_return_if_fail (win && GTK_IS_WINDOW(win));
5691 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5694 modest_platform_show_help (GTK_WINDOW (win), help_id);
5699 modest_ui_actions_on_csm_help (GtkAction *action,
5702 /* Help app is not available at all in fremantle */
5703 #ifndef MODEST_TOOLKIT_HILDON2
5705 const gchar* help_id = NULL;
5706 GtkWidget *folder_view;
5707 TnyFolderStore *folder_store;
5709 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
5711 /* Get selected folder */
5712 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5713 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5714 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5716 /* Switch help_id */
5717 if (folder_store && TNY_IS_FOLDER (folder_store))
5718 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
5721 g_object_unref (folder_store);
5724 modest_platform_show_help (GTK_WINDOW (win), help_id);
5726 modest_ui_actions_on_help (action, win);
5731 retrieve_contents_cb (ModestMailOperation *mail_op,
5738 /* We only need this callback to show an error in case of
5739 memory low condition */
5740 modest_ui_actions_msg_retrieval_check (mail_op, header, msg);
5744 retrieve_msg_contents_performer (gboolean canceled,
5746 GtkWindow *parent_window,
5747 TnyAccount *account,
5750 ModestMailOperation *mail_op;
5751 TnyList *headers = TNY_LIST (user_data);
5753 if (err || canceled) {
5754 check_memory_full_error ((GtkWidget *) parent_window, err);
5758 /* Create mail operation */
5759 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5760 modest_ui_actions_disk_operations_error_handler,
5762 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5763 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
5766 g_object_unref (mail_op);
5768 g_object_unref (headers);
5769 g_object_unref (account);
5773 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5774 ModestWindow *window)
5776 TnyList *headers = NULL;
5777 TnyAccount *account = NULL;
5778 TnyIterator *iter = NULL;
5779 TnyHeader *header = NULL;
5780 TnyFolder *folder = NULL;
5783 headers = get_selected_headers (window);
5787 /* Pick the account */
5788 iter = tny_list_create_iterator (headers);
5789 header = TNY_HEADER (tny_iterator_get_current (iter));
5790 folder = tny_header_get_folder (header);
5791 account = tny_folder_get_account (folder);
5792 g_object_unref (folder);
5793 g_object_unref (header);
5794 g_object_unref (iter);
5796 /* Connect and perform the message retrieval */
5797 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
5798 g_object_ref (account),
5799 retrieve_msg_contents_performer,
5800 g_object_ref (headers));
5803 g_object_unref (account);
5804 g_object_unref (headers);
5808 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
5810 g_return_if_fail (MODEST_IS_WINDOW (window));
5813 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
5817 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
5819 g_return_if_fail (MODEST_IS_WINDOW (window));
5822 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
5826 modest_ui_actions_on_email_menu_activated (GtkAction *action,
5827 ModestWindow *window)
5829 g_return_if_fail (MODEST_IS_WINDOW (window));
5832 modest_ui_actions_check_menu_dimming_rules (window);
5836 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
5837 ModestWindow *window)
5839 g_return_if_fail (MODEST_IS_WINDOW (window));
5842 modest_ui_actions_check_menu_dimming_rules (window);
5846 modest_ui_actions_on_view_menu_activated (GtkAction *action,
5847 ModestWindow *window)
5849 g_return_if_fail (MODEST_IS_WINDOW (window));
5852 modest_ui_actions_check_menu_dimming_rules (window);
5856 modest_ui_actions_on_format_menu_activated (GtkAction *action,
5857 ModestWindow *window)
5859 g_return_if_fail (MODEST_IS_WINDOW (window));
5862 modest_ui_actions_check_menu_dimming_rules (window);
5866 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
5867 ModestWindow *window)
5869 g_return_if_fail (MODEST_IS_WINDOW (window));
5872 modest_ui_actions_check_menu_dimming_rules (window);
5876 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
5877 ModestWindow *window)
5879 g_return_if_fail (MODEST_IS_WINDOW (window));
5882 modest_ui_actions_check_menu_dimming_rules (window);
5886 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
5887 ModestWindow *window)
5889 g_return_if_fail (MODEST_IS_WINDOW (window));
5892 modest_ui_actions_check_menu_dimming_rules (window);
5896 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
5897 ModestWindow *window)
5899 g_return_if_fail (MODEST_IS_WINDOW (window));
5902 modest_ui_actions_check_menu_dimming_rules (window);
5906 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
5907 ModestWindow *window)
5909 g_return_if_fail (MODEST_IS_WINDOW (window));
5912 modest_ui_actions_check_menu_dimming_rules (window);
5916 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
5918 g_return_if_fail (MODEST_IS_WINDOW (window));
5920 /* we check for low-mem; in that case, show a warning, and don't allow
5923 if (modest_platform_check_memory_low (window, TRUE))
5926 modest_platform_show_search_messages (GTK_WINDOW (window));
5930 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
5932 g_return_if_fail (MODEST_IS_WINDOW (win));
5935 /* we check for low-mem; in that case, show a warning, and don't allow
5936 * for the addressbook
5938 if (modest_platform_check_memory_low (win, TRUE))
5942 modest_platform_show_addressbook (GTK_WINDOW (win));
5947 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
5948 ModestWindow *window)
5950 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5952 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
5956 on_send_receive_finished (ModestMailOperation *mail_op,
5959 GtkWidget *header_view, *folder_view;
5960 TnyFolderStore *folder_store;
5961 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
5963 /* Set send/receive operation finished */
5964 modest_main_window_notify_send_receive_completed (main_win);
5966 /* Don't refresh the current folder if there were any errors */
5967 if (modest_mail_operation_get_status (mail_op) !=
5968 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5971 /* Refresh the current folder if we're viewing a window. We do
5972 this because the user won't be able to see the new mails in
5973 the selected folder after a Send&Receive because it only
5974 performs a poke_status, i.e, only the number of read/unread
5975 messages is updated, but the new headers are not
5977 folder_view = modest_main_window_get_child_widget (main_win,
5978 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5982 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5984 /* Do not need to refresh INBOX again because the
5985 update_account does it always automatically */
5986 if (folder_store && TNY_IS_FOLDER (folder_store) &&
5987 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
5988 ModestMailOperation *refresh_op;
5990 header_view = modest_main_window_get_child_widget (main_win,
5991 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5993 /* We do not need to set the contents style
5994 because it hasn't changed. We also do not
5995 need to save the widget status. Just force
5997 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
5998 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
5999 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6000 folder_refreshed_cb, main_win);
6001 g_object_unref (refresh_op);
6005 g_object_unref (folder_store);
6010 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6016 const gchar* server_name = NULL;
6017 TnyTransportAccount *server_account;
6018 gchar *message = NULL;
6020 /* Don't show anything if the user cancelled something or the
6021 * send receive request is not interactive. Authentication
6022 * errors are managed by the account store so no need to show
6023 * a dialog here again */
6024 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6025 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6026 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6030 /* Get the server name: */
6032 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
6034 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
6036 g_return_if_reached ();
6038 /* Show the appropriate message text for the GError: */
6039 switch (err->code) {
6040 case TNY_SERVICE_ERROR_CONNECT:
6041 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6043 case TNY_SERVICE_ERROR_SEND:
6044 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
6046 case TNY_SERVICE_ERROR_UNAVAILABLE:
6047 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6050 g_warning ("%s: unexpected ERROR %d",
6051 __FUNCTION__, err->code);
6052 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
6056 modest_platform_run_information_dialog (NULL, message, FALSE);
6058 g_object_unref (server_account);
6062 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6067 ModestMainWindow *main_window = NULL;
6068 ModestWindowMgr *mgr = NULL;
6069 GtkWidget *folder_view = NULL, *header_view = NULL;
6070 TnyFolderStore *selected_folder = NULL;
6071 TnyFolderType folder_type;
6073 mgr = modest_runtime_get_window_mgr ();
6074 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr,
6075 FALSE));/* don't create */
6079 /* Check if selected folder is OUTBOX */
6080 folder_view = modest_main_window_get_child_widget (main_window,
6081 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6082 header_view = modest_main_window_get_child_widget (main_window,
6083 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6085 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6086 if (!TNY_IS_FOLDER (selected_folder))
6089 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6090 #if GTK_CHECK_VERSION(2, 8, 0)
6091 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
6092 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6093 GtkTreeViewColumn *tree_column;
6095 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6096 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6098 gtk_tree_view_column_queue_resize (tree_column);
6101 gtk_widget_queue_draw (header_view);
6104 /* Rerun dimming rules, because the message could become deletable for example */
6105 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6106 MODEST_DIMMING_RULES_TOOLBAR);
6107 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6108 MODEST_DIMMING_RULES_MENU);
6112 if (selected_folder != NULL)
6113 g_object_unref (selected_folder);
6117 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6118 TnyAccount *account)
6120 ModestProtocolType protocol_type;
6121 ModestProtocol *protocol;
6122 gchar *error_note = NULL;
6124 protocol_type = modest_tny_account_get_protocol_type (account);
6125 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6128 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6129 if (error_note == NULL) {
6130 g_warning ("%s: This should not be reached", __FUNCTION__);
6132 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6133 g_free (error_note);
6138 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6142 TnyFolderStore *folder = NULL;
6143 TnyAccount *account = NULL;
6144 ModestProtocolType proto;
6145 ModestProtocol *protocol;
6146 TnyHeader *header = NULL;
6148 if (MODEST_IS_MAIN_WINDOW (win)) {
6149 GtkWidget *header_view;
6150 TnyList* headers = NULL;
6152 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6153 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6154 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6155 if (!headers || tny_list_get_length (headers) == 0) {
6157 g_object_unref (headers);
6160 iter = tny_list_create_iterator (headers);
6161 header = TNY_HEADER (tny_iterator_get_current (iter));
6162 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6163 g_object_unref (iter);
6164 g_object_unref (headers);
6165 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6166 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6167 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6170 /* Get the account type */
6171 account = tny_folder_get_account (TNY_FOLDER (folder));
6172 proto = modest_tny_account_get_protocol_type (account);
6173 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6176 subject = tny_header_dup_subject (header);
6177 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6181 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6185 g_object_unref (account);
6186 g_object_unref (folder);
6187 g_object_unref (header);
6193 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6194 const gchar *account_name,
6195 const gchar *account_title)
6197 ModestAccountMgr *account_mgr;
6200 ModestProtocol *protocol;
6201 gboolean removed = FALSE;
6203 g_return_val_if_fail (account_name, FALSE);
6204 g_return_val_if_fail (account_title, FALSE);
6206 account_mgr = modest_runtime_get_account_mgr();
6208 /* The warning text depends on the account type: */
6209 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6210 modest_account_mgr_get_store_protocol (account_mgr,
6212 txt = modest_protocol_get_translation (protocol,
6213 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6216 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6218 response = modest_platform_run_confirmation_dialog (parent_window, txt);
6222 if (response == GTK_RESPONSE_OK) {
6223 /* Remove account. If it succeeds then it also removes
6224 the account from the ModestAccountView: */
6225 gboolean is_default = FALSE;
6226 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6227 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6229 g_free (default_account_name);
6231 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6233 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);