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 #ifdef MODEST_TOOLKIT_HILDON2
3605 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3608 _HL("wdgt_bd_done"),
3609 GTK_RESPONSE_ACCEPT,
3613 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3615 _("mcen_bd_dialog_ok"),
3616 GTK_RESPONSE_ACCEPT,
3617 _("mcen_bd_dialog_cancel"),
3618 GTK_RESPONSE_REJECT,
3620 #endif /* MODEST_TOOLKIT_HILDON2 */
3623 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3627 GTK_RESPONSE_REJECT,
3629 GTK_RESPONSE_ACCEPT,
3631 #endif /* MODEST_TOOLKIT_GTK */
3633 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3635 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3636 modest_runtime_get_account_mgr(), server_account_name);
3637 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3638 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3641 gtk_widget_destroy (dialog);
3645 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3646 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
3649 g_free (server_name);
3653 gchar *initial_username = modest_account_mgr_get_server_account_username (
3654 modest_runtime_get_account_mgr(), server_account_name);
3656 GtkWidget *entry_username = gtk_entry_new ();
3657 if (initial_username)
3658 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
3659 /* Dim this if a connection has ever succeeded with this username,
3660 * as per the UI spec: */
3661 /* const gboolean username_known = */
3662 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3663 /* modest_runtime_get_account_mgr(), server_account_name); */
3664 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3666 /* We drop the username sensitive code and disallow changing it here
3667 * as tinymail does not support really changing the username in the callback
3669 gtk_widget_set_sensitive (entry_username, FALSE);
3671 #ifndef MODEST_TOOLKIT_GTK
3672 /* Auto-capitalization is the default, so let's turn it off: */
3673 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3675 /* Create a size group to be used by all captions.
3676 * Note that HildonCaption does not create a default size group if we do not specify one.
3677 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3678 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3680 GtkWidget *caption = hildon_caption_new (sizegroup,
3681 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
3682 gtk_widget_show (entry_username);
3683 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3684 FALSE, FALSE, MODEST_MARGIN_HALF);
3685 gtk_widget_show (caption);
3687 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
3689 #endif /* !MODEST_TOOLKIT_GTK */
3692 GtkWidget *entry_password = gtk_entry_new ();
3693 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3694 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3696 #ifndef MODEST_TOOLKIT_GTK
3697 /* Auto-capitalization is the default, so let's turn it off: */
3698 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3699 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3701 caption = hildon_caption_new (sizegroup,
3702 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
3703 gtk_widget_show (entry_password);
3704 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3705 FALSE, FALSE, MODEST_MARGIN_HALF);
3706 gtk_widget_show (caption);
3707 g_object_unref (sizegroup);
3709 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
3711 #endif /* !MODEST_TOOLKIT_GTK */
3713 if (initial_username != NULL)
3714 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3716 /* This is not in the Maemo UI spec:
3717 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3718 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3722 fields = g_slice_new0 (PasswordDialogFields);
3723 fields->username = entry_username;
3724 fields->password = entry_password;
3725 fields->dialog = dialog;
3727 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3728 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3729 password_dialog_check_field (NULL, fields);
3731 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3733 while (!completed) {
3735 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3737 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
3739 /* Note that an empty field becomes the "" string */
3740 if (*username && strlen (*username) > 0) {
3741 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
3742 server_account_name,
3746 const gboolean username_was_changed =
3747 (strcmp (*username, initial_username) != 0);
3748 if (username_was_changed) {
3749 g_warning ("%s: tinymail does not yet support changing the "
3750 "username in the get_password() callback.\n", __FUNCTION__);
3756 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
3757 _("mcen_ib_username_pw_incorrect"));
3763 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
3765 /* We do not save the password in the configuration,
3766 * because this function is only called for passwords that should
3767 * not be remembered:
3768 modest_server_account_set_password (
3769 modest_runtime_get_account_mgr(), server_account_name,
3776 #ifndef MODEST_TOOLKIT_HILDON2
3777 /* Set parent to NULL or the banner will disappear with its parent dialog */
3778 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
3790 /* This is not in the Maemo UI spec:
3791 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3797 g_free (initial_username);
3798 gtk_widget_destroy (dialog);
3799 g_slice_free (PasswordDialogFields, fields);
3801 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3805 modest_ui_actions_on_cut (GtkAction *action,
3806 ModestWindow *window)
3808 GtkWidget *focused_widget;
3809 GtkClipboard *clipboard;
3811 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3812 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3813 if (GTK_IS_EDITABLE (focused_widget)) {
3814 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3815 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3816 gtk_clipboard_store (clipboard);
3817 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3818 GtkTextBuffer *buffer;
3820 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3821 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3822 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3823 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3824 gtk_clipboard_store (clipboard);
3826 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3827 TnyList *header_list = modest_header_view_get_selected_headers (
3828 MODEST_HEADER_VIEW (focused_widget));
3829 gboolean continue_download = FALSE;
3830 gint num_of_unc_msgs;
3832 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3834 if (num_of_unc_msgs) {
3835 TnyAccount *account = get_account_from_header_list (header_list);
3837 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3838 g_object_unref (account);
3842 if (num_of_unc_msgs == 0 || continue_download) {
3843 /* modest_platform_information_banner (
3844 NULL, NULL, _CS("mcen_ib_getting_items"));*/
3845 modest_header_view_cut_selection (
3846 MODEST_HEADER_VIEW (focused_widget));
3849 g_object_unref (header_list);
3850 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3851 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3856 modest_ui_actions_on_copy (GtkAction *action,
3857 ModestWindow *window)
3859 GtkClipboard *clipboard;
3860 GtkWidget *focused_widget;
3861 gboolean copied = TRUE;
3863 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3864 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3866 if (GTK_IS_LABEL (focused_widget)) {
3868 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
3869 gtk_clipboard_set_text (clipboard, selection, -1);
3871 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3872 gtk_clipboard_store (clipboard);
3873 } else if (GTK_IS_EDITABLE (focused_widget)) {
3874 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3875 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3876 gtk_clipboard_store (clipboard);
3877 } else if (GTK_IS_HTML (focused_widget)) {
3880 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
3881 if ((sel == NULL) || (sel[0] == '\0')) {
3884 gtk_html_copy (GTK_HTML (focused_widget));
3885 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3886 gtk_clipboard_store (clipboard);
3888 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3889 GtkTextBuffer *buffer;
3890 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3891 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3892 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3893 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3894 gtk_clipboard_store (clipboard);
3896 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3897 TnyList *header_list = modest_header_view_get_selected_headers (
3898 MODEST_HEADER_VIEW (focused_widget));
3899 gboolean continue_download = FALSE;
3900 gint num_of_unc_msgs;
3902 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3904 if (num_of_unc_msgs) {
3905 TnyAccount *account = get_account_from_header_list (header_list);
3907 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3908 g_object_unref (account);
3912 if (num_of_unc_msgs == 0 || continue_download) {
3913 modest_platform_information_banner (
3914 NULL, NULL, _CS("mcen_ib_getting_items"));
3915 modest_header_view_copy_selection (
3916 MODEST_HEADER_VIEW (focused_widget));
3920 g_object_unref (header_list);
3922 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3923 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3926 /* Show information banner if there was a copy to clipboard */
3928 modest_platform_information_banner (
3929 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3933 modest_ui_actions_on_undo (GtkAction *action,
3934 ModestWindow *window)
3936 ModestEmailClipboard *clipboard = NULL;
3938 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3939 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3940 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3941 /* Clear clipboard source */
3942 clipboard = modest_runtime_get_email_clipboard ();
3943 modest_email_clipboard_clear (clipboard);
3946 g_return_if_reached ();
3951 modest_ui_actions_on_redo (GtkAction *action,
3952 ModestWindow *window)
3954 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3955 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3958 g_return_if_reached ();
3964 destroy_information_note (ModestMailOperation *mail_op,
3967 /* destroy information note */
3968 gtk_widget_destroy (GTK_WIDGET(user_data));
3972 destroy_folder_information_note (ModestMailOperation *mail_op,
3973 TnyFolder *new_folder,
3976 /* destroy information note */
3977 gtk_widget_destroy (GTK_WIDGET(user_data));
3982 paste_as_attachment_free (gpointer data)
3984 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3986 if (helper->banner) {
3987 gtk_widget_destroy (helper->banner);
3988 g_object_unref (helper->banner);
3994 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3999 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4000 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4005 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4010 modest_ui_actions_on_paste (GtkAction *action,
4011 ModestWindow *window)
4013 GtkWidget *focused_widget = NULL;
4014 GtkWidget *inf_note = NULL;
4015 ModestMailOperation *mail_op = NULL;
4017 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4018 if (GTK_IS_EDITABLE (focused_widget)) {
4019 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4020 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4021 ModestEmailClipboard *e_clipboard = NULL;
4022 e_clipboard = modest_runtime_get_email_clipboard ();
4023 if (modest_email_clipboard_cleared (e_clipboard)) {
4024 GtkTextBuffer *buffer;
4025 GtkClipboard *clipboard;
4027 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4028 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4029 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4030 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4031 ModestMailOperation *mail_op;
4032 TnyFolder *src_folder = NULL;
4033 TnyList *data = NULL;
4035 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4036 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4037 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4038 _CS("ckct_nw_pasting"));
4039 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4040 mail_op = modest_mail_operation_new (G_OBJECT (window));
4041 if (helper->banner != NULL) {
4042 g_object_ref (G_OBJECT (helper->banner));
4043 gtk_widget_show (GTK_WIDGET (helper->banner));
4047 modest_mail_operation_get_msgs_full (mail_op,
4049 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4051 paste_as_attachment_free);
4055 g_object_unref (data);
4057 g_object_unref (src_folder);
4060 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4061 ModestEmailClipboard *clipboard = NULL;
4062 TnyFolder *src_folder = NULL;
4063 TnyFolderStore *folder_store = NULL;
4064 TnyList *data = NULL;
4065 gboolean delete = FALSE;
4067 /* Check clipboard source */
4068 clipboard = modest_runtime_get_email_clipboard ();
4069 if (modest_email_clipboard_cleared (clipboard))
4072 /* Get elements to paste */
4073 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4075 /* Create a new mail operation */
4076 mail_op = modest_mail_operation_new (G_OBJECT(window));
4078 /* Get destination folder */
4079 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4081 /* transfer messages */
4085 /* Ask for user confirmation */
4087 modest_ui_actions_msgs_move_to_confirmation (window,
4088 TNY_FOLDER (folder_store),
4092 if (response == GTK_RESPONSE_OK) {
4093 /* Launch notification */
4094 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4095 _CS("ckct_nw_pasting"));
4096 if (inf_note != NULL) {
4097 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4098 gtk_widget_show (GTK_WIDGET(inf_note));
4101 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4102 modest_mail_operation_xfer_msgs (mail_op,
4104 TNY_FOLDER (folder_store),
4106 destroy_information_note,
4109 g_object_unref (mail_op);
4112 } else if (src_folder != NULL) {
4113 /* Launch notification */
4114 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4115 _CS("ckct_nw_pasting"));
4116 if (inf_note != NULL) {
4117 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4118 gtk_widget_show (GTK_WIDGET(inf_note));
4121 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4122 modest_mail_operation_xfer_folder (mail_op,
4126 destroy_folder_information_note,
4132 g_object_unref (data);
4133 if (src_folder != NULL)
4134 g_object_unref (src_folder);
4135 if (folder_store != NULL)
4136 g_object_unref (folder_store);
4142 modest_ui_actions_on_select_all (GtkAction *action,
4143 ModestWindow *window)
4145 GtkWidget *focused_widget;
4147 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4148 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4149 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4150 } else if (GTK_IS_LABEL (focused_widget)) {
4151 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4152 } else if (GTK_IS_EDITABLE (focused_widget)) {
4153 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4154 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4155 GtkTextBuffer *buffer;
4156 GtkTextIter start, end;
4158 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4159 gtk_text_buffer_get_start_iter (buffer, &start);
4160 gtk_text_buffer_get_end_iter (buffer, &end);
4161 gtk_text_buffer_select_range (buffer, &start, &end);
4162 } else if (GTK_IS_HTML (focused_widget)) {
4163 gtk_html_select_all (GTK_HTML (focused_widget));
4164 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4165 GtkWidget *header_view = focused_widget;
4166 GtkTreeSelection *selection = NULL;
4168 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4169 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4170 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4173 /* Disable window dimming management */
4174 modest_window_disable_dimming (MODEST_WINDOW(window));
4176 /* Select all messages */
4177 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4178 gtk_tree_selection_select_all (selection);
4180 /* Set focuse on header view */
4181 gtk_widget_grab_focus (header_view);
4183 /* Enable window dimming management */
4184 modest_window_enable_dimming (MODEST_WINDOW(window));
4185 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4186 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4192 modest_ui_actions_on_mark_as_read (GtkAction *action,
4193 ModestWindow *window)
4195 g_return_if_fail (MODEST_IS_WINDOW(window));
4197 /* Mark each header as read */
4198 do_headers_action (window, headers_action_mark_as_read, NULL);
4202 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4203 ModestWindow *window)
4205 g_return_if_fail (MODEST_IS_WINDOW(window));
4207 /* Mark each header as read */
4208 do_headers_action (window, headers_action_mark_as_unread, NULL);
4212 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4213 GtkRadioAction *selected,
4214 ModestWindow *window)
4218 value = gtk_radio_action_get_current_value (selected);
4219 if (MODEST_IS_WINDOW (window)) {
4220 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4225 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4226 GtkRadioAction *selected,
4227 ModestWindow *window)
4229 TnyHeaderFlags flags;
4230 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4232 flags = gtk_radio_action_get_current_value (selected);
4233 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4237 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4238 GtkRadioAction *selected,
4239 ModestWindow *window)
4243 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4245 file_format = gtk_radio_action_get_current_value (selected);
4246 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4251 modest_ui_actions_on_zoom_plus (GtkAction *action,
4252 ModestWindow *window)
4254 g_return_if_fail (MODEST_IS_WINDOW (window));
4256 modest_window_zoom_plus (MODEST_WINDOW (window));
4260 modest_ui_actions_on_zoom_minus (GtkAction *action,
4261 ModestWindow *window)
4263 g_return_if_fail (MODEST_IS_WINDOW (window));
4265 modest_window_zoom_minus (MODEST_WINDOW (window));
4269 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4270 ModestWindow *window)
4272 ModestWindowMgr *mgr;
4273 gboolean fullscreen, active;
4274 g_return_if_fail (MODEST_IS_WINDOW (window));
4276 mgr = modest_runtime_get_window_mgr ();
4278 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4279 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4281 if (active != fullscreen) {
4282 modest_window_mgr_set_fullscreen_mode (mgr, active);
4283 #ifndef MODEST_TOOLKIT_HILDON2
4284 gtk_window_present (GTK_WINDOW (window));
4290 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4291 ModestWindow *window)
4293 ModestWindowMgr *mgr;
4294 gboolean fullscreen;
4296 g_return_if_fail (MODEST_IS_WINDOW (window));
4298 mgr = modest_runtime_get_window_mgr ();
4299 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4300 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4302 #ifndef MODEST_TOOLKIT_HILDON2
4303 gtk_window_present (GTK_WINDOW (window));
4308 * Used by modest_ui_actions_on_details to call do_headers_action
4311 headers_action_show_details (TnyHeader *header,
4312 ModestWindow *window,
4316 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header);
4320 * Show the header details in a ModestDetailsDialog widget
4323 modest_ui_actions_on_details (GtkAction *action,
4326 TnyList * headers_list;
4330 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4333 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4336 g_object_unref (msg);
4338 headers_list = get_selected_headers (win);
4342 iter = tny_list_create_iterator (headers_list);
4344 header = TNY_HEADER (tny_iterator_get_current (iter));
4346 headers_action_show_details (header, win, NULL);
4347 g_object_unref (header);
4350 g_object_unref (iter);
4351 g_object_unref (headers_list);
4353 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4354 GtkWidget *folder_view, *header_view;
4356 /* Check which widget has the focus */
4357 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4358 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4359 if (gtk_widget_is_focus (folder_view)) {
4360 TnyFolderStore *folder_store
4361 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4362 if (!folder_store) {
4363 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4366 /* Show only when it's a folder */
4367 /* This function should not be called for account items,
4368 * because we dim the menu item for them. */
4369 if (TNY_IS_FOLDER (folder_store)) {
4370 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4371 TNY_FOLDER (folder_store));
4374 g_object_unref (folder_store);
4377 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4378 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4379 /* Show details of each header */
4380 do_headers_action (win, headers_action_show_details, header_view);
4386 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4387 ModestMsgEditWindow *window)
4389 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4391 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4395 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4396 ModestMsgEditWindow *window)
4398 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4400 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4404 modest_ui_actions_toggle_folders_view (GtkAction *action,
4405 ModestMainWindow *main_window)
4407 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4409 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4410 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4412 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4416 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4417 ModestWindow *window)
4419 gboolean active, fullscreen = FALSE;
4420 ModestWindowMgr *mgr;
4422 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4424 /* Check if we want to toggle the toolbar view in fullscreen
4426 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4427 "ViewShowToolbarFullScreen")) {
4431 /* Toggle toolbar */
4432 mgr = modest_runtime_get_window_mgr ();
4433 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4437 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4438 ModestMsgEditWindow *window)
4440 modest_msg_edit_window_select_font (window);
4445 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4446 const gchar *display_name,
4449 /* don't update the display name if it was already set;
4450 * updating the display name apparently is expensive */
4451 const gchar* old_name = gtk_window_get_title (window);
4453 if (display_name == NULL)
4456 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4457 return; /* don't do anything */
4459 /* This is usually used to change the title of the main window, which
4460 * is the one that holds the folder view. Note that this change can
4461 * happen even when the widget doesn't have the focus. */
4462 gtk_window_set_title (window, display_name);
4467 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4469 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4470 modest_msg_edit_window_select_contacts (window);
4474 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4476 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4477 modest_msg_edit_window_check_names (window, FALSE);
4481 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
4483 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
4484 GTK_WIDGET (user_data));
4488 * This function is used to track changes in the selection of the
4489 * folder view that is inside the "move to" dialog to enable/disable
4490 * the OK button because we do not want the user to select a disallowed
4491 * destination for a folder.
4492 * The user also not desired to be able to use NEW button on items where
4493 * folder creation is not possibel.
4496 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4497 TnyFolderStore *folder_store,
4501 GtkWidget *dialog = NULL;
4502 GtkWidget *ok_button = NULL, *new_button = NULL;
4503 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4504 gboolean moving_folder = FALSE;
4505 gboolean is_local_account = TRUE;
4506 GtkWidget *folder_view = NULL;
4507 ModestTnyFolderRules rules;
4509 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
4514 /* Get the OK button */
4515 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
4519 ok_button = g_object_get_data (G_OBJECT (dialog), MOVE_FOLDER_OK_BUTTON);
4520 new_button = g_object_get_data (G_OBJECT (dialog), MOVE_FOLDER_NEW_BUTTON);
4522 /* check if folder_store is an remote account */
4523 if (TNY_IS_ACCOUNT (folder_store)) {
4524 TnyAccount *local_account = NULL;
4525 TnyAccount *mmc_account = NULL;
4526 ModestTnyAccountStore *account_store = NULL;
4528 account_store = modest_runtime_get_account_store ();
4529 local_account = modest_tny_account_store_get_local_folders_account (account_store);
4530 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
4532 if ((gpointer) local_account != (gpointer) folder_store &&
4533 (gpointer) mmc_account != (gpointer) folder_store) {
4534 ModestProtocolType proto;
4535 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
4536 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
4537 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
4539 is_local_account = FALSE;
4540 /* New button should be dimmed on remote
4542 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4544 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
4546 g_object_unref (local_account);
4548 /* It could not exist */
4550 g_object_unref (mmc_account);
4553 /* Check the target folder rules */
4554 if (TNY_IS_FOLDER (folder_store)) {
4555 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
4556 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
4557 ok_sensitive = FALSE;
4558 new_sensitive = FALSE;
4563 /* Check if we're moving a folder */
4564 if (MODEST_IS_MAIN_WINDOW (user_data)) {
4565 /* Get the widgets */
4566 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
4567 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4568 if (gtk_widget_is_focus (folder_view))
4569 moving_folder = TRUE;
4572 if (moving_folder) {
4573 TnyFolderStore *moved_folder = NULL, *parent = NULL;
4575 /* Get the folder to move */
4576 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4578 /* Check that we're not moving to the same folder */
4579 if (TNY_IS_FOLDER (moved_folder)) {
4580 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
4581 if (parent == folder_store)
4582 ok_sensitive = FALSE;
4583 g_object_unref (parent);
4586 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
4587 /* Do not allow to move to an account unless it's the
4588 local folders account */
4589 if (!is_local_account)
4590 ok_sensitive = FALSE;
4593 if (ok_sensitive && (moved_folder == folder_store)) {
4594 /* Do not allow to move to itself */
4595 ok_sensitive = FALSE;
4597 g_object_unref (moved_folder);
4599 TnyFolder *src_folder = NULL;
4601 /* Moving a message */
4602 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
4604 TnyHeader *header = NULL;
4605 header = modest_msg_view_window_get_header
4606 (MODEST_MSG_VIEW_WINDOW (user_data));
4607 if (!TNY_IS_HEADER(header))
4608 g_warning ("%s: could not get source header", __FUNCTION__);
4610 src_folder = tny_header_get_folder (header);
4613 g_object_unref (header);
4616 TNY_FOLDER (modest_folder_view_get_selected
4617 (MODEST_FOLDER_VIEW (folder_view)));
4620 if (TNY_IS_FOLDER(src_folder)) {
4621 /* Do not allow to move the msg to the same folder */
4622 /* Do not allow to move the msg to an account */
4623 if ((gpointer) src_folder == (gpointer) folder_store ||
4624 TNY_IS_ACCOUNT (folder_store))
4625 ok_sensitive = FALSE;
4626 g_object_unref (src_folder);
4628 g_warning ("%s: could not get source folder", __FUNCTION__);
4632 /* Set sensitivity of the OK button */
4633 gtk_widget_set_sensitive (ok_button, ok_sensitive);
4634 /* Set sensitivity of the NEW button */
4635 gtk_widget_set_sensitive (new_button, new_sensitive);
4639 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
4642 get_folder_view_from_move_to_dialog (GtkWidget *move_to_dialog)
4644 return GTK_WIDGET(g_object_get_data (G_OBJECT(move_to_dialog),
4645 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4649 create_move_to_dialog (GtkWindow *win,
4650 GtkWidget *folder_view,
4651 GtkWidget **tree_view)
4654 #ifdef MODEST_TOOLKIT_HILDON2
4655 GtkWidget *pannable;
4659 GtkWidget *new_button, *ok_button;
4661 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
4663 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
4666 #ifndef MODEST_TOOLKIT_GTK
4667 ok_button = gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
4668 /* We do this manually so GTK+ does not associate a response ID for
4670 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
4671 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
4672 gtk_widget_show (new_button);
4673 #ifndef MODEST_TOOLKIT_HILDON2
4674 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
4677 /* We do this manually so GTK+ does not associate a response ID for
4679 new_button = gtk_button_new_with_label (_("mcen_ti_new_folder"));
4680 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
4681 gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (GTK_DIALOG (dialog)->action_area), new_button, TRUE);
4682 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
4683 ok_button = gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
4684 gtk_container_set_border_width (GTK_CONTAINER (dialog), 12);
4685 gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 24);
4687 g_object_set_data (G_OBJECT (dialog), MOVE_FOLDER_OK_BUTTON, ok_button);
4688 g_object_set_data (G_OBJECT (dialog), MOVE_FOLDER_NEW_BUTTON, new_button);
4690 /* Create scrolled window */
4691 #ifdef MODEST_TOOLKIT_HILDON2
4692 pannable = hildon_pannable_area_new ();
4694 scroll = gtk_scrolled_window_new (NULL, NULL);
4695 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
4696 GTK_POLICY_AUTOMATIC,
4697 GTK_POLICY_AUTOMATIC);
4700 #ifdef MODEST_TOOLKIT_GTK
4701 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN);
4704 /* Create folder view */
4705 *tree_view = modest_platform_create_folder_view (NULL);
4707 /* Track changes in the selection to
4708 * disable the OK button whenever "Move to" is not possible
4709 * disbale NEW button whenever New is not possible */
4710 g_signal_connect (*tree_view,
4711 "folder_selection_changed",
4712 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
4715 /* Listen to clicks on New button */
4716 g_signal_connect (G_OBJECT (new_button),
4718 G_CALLBACK(create_move_to_dialog_on_new_folder),
4721 /* It could happen that we're trying to move a message from a
4722 window (msg window for example) after the main window was
4723 closed, so we can not just get the model of the folder
4725 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4726 const gchar *visible_id = NULL;
4728 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4729 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4730 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4731 MODEST_FOLDER_VIEW(*tree_view));
4734 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4736 /* Show the same account than the one that is shown in the main window */
4737 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
4740 const gchar *active_account_name = NULL;
4741 ModestAccountMgr *mgr = NULL;
4742 ModestAccountSettings *settings = NULL;
4743 ModestServerAccountSettings *store_settings = NULL;
4745 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4746 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4747 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
4748 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
4750 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4751 mgr = modest_runtime_get_account_mgr ();
4752 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4755 const gchar *store_account_name;
4756 store_settings = modest_account_settings_get_store_settings (settings);
4757 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4759 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
4760 store_account_name);
4761 g_object_unref (store_settings);
4762 g_object_unref (settings);
4766 /* we keep a pointer to the embedded folder view, so we can retrieve it with
4767 * get_folder_view_from_move_to_dialog
4768 * (see above) later (needed for focus handling)
4770 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, *tree_view);
4773 /* Hide special folders */
4774 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
4776 #ifdef MODEST_TOOLKIT_HILDON2
4777 gtk_container_add (GTK_CONTAINER (pannable), *tree_view);
4778 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
4779 pannable, TRUE, TRUE, 0);
4781 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
4782 /* Add scroll to dialog */
4783 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
4784 scroll, TRUE, TRUE, 0);
4788 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4789 #ifndef MODEST_TOOLKIT_GTK
4790 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
4792 gtk_window_set_default_size (GTK_WINDOW (dialog), 600, 400);
4801 * Shows a confirmation dialog to the user when we're moving messages
4802 * from a remote server to the local storage. Returns the dialog
4803 * response. If it's other kind of movement then it always returns
4806 * This one is used by the next functions:
4807 * modest_ui_actions_on_paste - commented out
4808 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4811 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4812 TnyFolder *dest_folder,
4816 gint response = GTK_RESPONSE_OK;
4817 TnyAccount *account = NULL;
4818 TnyFolder *src_folder = NULL;
4819 TnyIterator *iter = NULL;
4820 TnyHeader *header = NULL;
4822 /* return with OK if the destination is a remote folder */
4823 if (modest_tny_folder_is_remote_folder (dest_folder))
4824 return GTK_RESPONSE_OK;
4826 /* Get source folder */
4827 iter = tny_list_create_iterator (headers);
4828 header = TNY_HEADER (tny_iterator_get_current (iter));
4830 src_folder = tny_header_get_folder (header);
4831 g_object_unref (header);
4833 g_object_unref (iter);
4835 /* if no src_folder, message may be an attahcment */
4836 if (src_folder == NULL)
4837 return GTK_RESPONSE_CANCEL;
4839 /* If the source is a local or MMC folder */
4840 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4841 g_object_unref (src_folder);
4842 return GTK_RESPONSE_OK;
4845 /* Get the account */
4846 account = tny_folder_get_account (src_folder);
4848 /* now if offline we ask the user */
4849 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4850 response = GTK_RESPONSE_OK;
4852 response = GTK_RESPONSE_CANCEL;
4855 g_object_unref (src_folder);
4856 g_object_unref (account);
4862 move_to_helper_destroyer (gpointer user_data)
4864 MoveToHelper *helper = (MoveToHelper *) user_data;
4866 /* Close the "Pasting" information banner */
4867 if (helper->banner) {
4868 gtk_widget_destroy (GTK_WIDGET (helper->banner));
4869 g_object_unref (helper->banner);
4871 if (gtk_tree_row_reference_valid (helper->reference)) {
4872 gtk_tree_row_reference_free (helper->reference);
4873 helper->reference = NULL;
4879 move_to_cb (ModestMailOperation *mail_op,
4882 MoveToHelper *helper = (MoveToHelper *) user_data;
4884 /* Note that the operation could have failed, in that case do
4886 if (modest_mail_operation_get_status (mail_op) ==
4887 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
4889 GObject *object = modest_mail_operation_get_source (mail_op);
4890 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4891 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4893 if (!modest_msg_view_window_select_next_message (self) &&
4894 !modest_msg_view_window_select_previous_message (self)) {
4895 /* No more messages to view, so close this window */
4896 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4898 } else if (MODEST_IS_MAIN_WINDOW (object) &&
4899 gtk_tree_row_reference_valid (helper->reference)) {
4900 GtkWidget *header_view;
4902 GtkTreeSelection *sel;
4904 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4905 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4906 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
4907 path = gtk_tree_row_reference_get_path (helper->reference);
4908 /* We need to unselect the previous one
4909 because we could be copying instead of
4911 gtk_tree_selection_unselect_all (sel);
4912 gtk_tree_selection_select_path (sel, path);
4913 gtk_tree_path_free (path);
4915 g_object_unref (object);
4917 /* Destroy the helper */
4918 move_to_helper_destroyer (helper);
4922 folder_move_to_cb (ModestMailOperation *mail_op,
4923 TnyFolder *new_folder,
4926 GtkWidget *folder_view;
4929 object = modest_mail_operation_get_source (mail_op);
4930 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4931 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4932 g_object_ref (folder_view);
4933 g_object_unref (object);
4934 move_to_cb (mail_op, user_data);
4935 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
4936 g_object_unref (folder_view);
4940 msgs_move_to_cb (ModestMailOperation *mail_op,
4943 move_to_cb (mail_op, user_data);
4947 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
4950 ModestWindow *main_window = NULL;
4952 /* Disable next automatic folder selection */
4953 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
4954 FALSE); /* don't create */
4956 GObject *win = NULL;
4957 GtkWidget *folder_view = NULL;
4959 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
4960 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4961 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
4963 if (user_data && TNY_IS_FOLDER (user_data)) {
4964 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
4965 TNY_FOLDER (user_data), FALSE);
4968 /* Show notification dialog only if the main window exists */
4969 win = modest_mail_operation_get_source (mail_op);
4970 modest_platform_run_information_dialog ((GtkWindow *) win,
4971 _("mail_in_ui_folder_move_target_error"),
4974 g_object_unref (win);
4979 open_msg_for_purge_cb (ModestMailOperation *mail_op,
4988 gint pending_purges = 0;
4989 gboolean some_purged = FALSE;
4990 ModestWindow *win = MODEST_WINDOW (user_data);
4991 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
4993 /* If there was any error */
4994 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
4995 modest_window_mgr_unregister_header (mgr, header);
4999 /* Once the message has been retrieved for purging, we check if
5000 * it's all ok for purging */
5002 parts = tny_simple_list_new ();
5003 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5004 iter = tny_list_create_iterator (parts);
5006 while (!tny_iterator_is_done (iter)) {
5008 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5009 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5010 if (tny_mime_part_is_purged (part))
5017 g_object_unref (part);
5019 tny_iterator_next (iter);
5021 g_object_unref (iter);
5024 if (pending_purges>0) {
5026 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5028 if (response == GTK_RESPONSE_OK) {
5031 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5032 iter = tny_list_create_iterator (parts);
5033 while (!tny_iterator_is_done (iter)) {
5036 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5037 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5038 tny_mime_part_set_purged (part);
5041 g_object_unref (part);
5043 tny_iterator_next (iter);
5045 g_object_unref (iter);
5047 tny_msg_rewrite_cache (msg);
5049 gtk_widget_destroy (info);
5053 modest_window_mgr_unregister_header (mgr, header);
5055 g_object_unref (parts);
5059 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5060 ModestMainWindow *win)
5062 GtkWidget *header_view;
5063 TnyList *header_list;
5065 TnyHeaderFlags flags;
5066 ModestWindow *msg_view_window = NULL;
5069 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5071 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5072 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5074 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5076 g_warning ("%s: no header selected", __FUNCTION__);
5080 if (tny_list_get_length (header_list) == 1) {
5081 TnyIterator *iter = tny_list_create_iterator (header_list);
5082 header = TNY_HEADER (tny_iterator_get_current (iter));
5083 g_object_unref (iter);
5087 if (!header || !TNY_IS_HEADER(header)) {
5088 g_warning ("%s: header is not valid", __FUNCTION__);
5092 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5093 header, &msg_view_window);
5094 flags = tny_header_get_flags (header);
5095 if (!(flags & TNY_HEADER_FLAG_CACHED))
5098 if (msg_view_window != NULL)
5099 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5101 /* do nothing; uid was registered before, so window is probably on it's way */
5102 g_warning ("debug: header %p has already been registered", header);
5105 ModestMailOperation *mail_op = NULL;
5106 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5107 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5108 modest_ui_actions_disk_operations_error_handler,
5110 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5111 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5113 g_object_unref (mail_op);
5116 g_object_unref (header);
5118 g_object_unref (header_list);
5122 * Checks if we need a connection to do the transfer and if the user
5123 * wants to connect to complete it
5126 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5127 TnyFolderStore *src_folder,
5129 TnyFolder *dst_folder,
5130 gboolean delete_originals,
5131 gboolean *need_connection,
5134 TnyAccount *src_account;
5135 gint uncached_msgs = 0;
5137 uncached_msgs = header_list_count_uncached_msgs (headers);
5139 /* We don't need any further check if
5141 * 1- the source folder is local OR
5142 * 2- the device is already online
5144 if (!modest_tny_folder_store_is_remote (src_folder) ||
5145 tny_device_is_online (modest_runtime_get_device())) {
5146 *need_connection = FALSE;
5151 /* We must ask for a connection when
5153 * - the message(s) is not already cached OR
5154 * - the message(s) is cached but the leave_on_server setting
5155 * is FALSE (because we need to sync the source folder to
5156 * delete the message from the server (for IMAP we could do it
5157 * offline, it'll take place the next time we get a
5160 src_account = get_account_from_folder_store (src_folder);
5161 if (uncached_msgs > 0) {
5165 *need_connection = TRUE;
5166 num_headers = tny_list_get_length (headers);
5167 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5169 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5170 GTK_RESPONSE_CANCEL) {
5176 /* The transfer is possible and the user wants to */
5179 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5180 const gchar *account_name;
5181 gboolean leave_on_server;
5183 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5184 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5187 if (leave_on_server == TRUE) {
5188 *need_connection = FALSE;
5190 *need_connection = TRUE;
5193 *need_connection = FALSE;
5198 g_object_unref (src_account);
5202 xfer_messages_error_handler (ModestMailOperation *mail_op,
5205 ModestWindow *main_window = NULL;
5207 /* Disable next automatic folder selection */
5208 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5209 FALSE); /* don't create */
5211 GObject *win = modest_mail_operation_get_source (mail_op);
5212 modest_platform_run_information_dialog ((GtkWindow *) win,
5213 _("mail_in_ui_folder_move_target_error"),
5216 g_object_unref (win);
5218 move_to_helper_destroyer (user_data);
5222 TnyFolderStore *dst_folder;
5227 * Utility function that transfer messages from both the main window
5228 * and the msg view window when using the "Move to" dialog
5231 xfer_messages_performer (gboolean canceled,
5233 GtkWindow *parent_window,
5234 TnyAccount *account,
5237 ModestWindow *win = MODEST_WINDOW (parent_window);
5238 TnyAccount *dst_account = NULL;
5239 gboolean dst_forbids_message_add = FALSE;
5240 XferMsgsHelper *helper;
5241 MoveToHelper *movehelper;
5242 ModestMailOperation *mail_op;
5244 helper = (XferMsgsHelper *) user_data;
5246 if (canceled || err) {
5247 if (!check_memory_full_error ((GtkWidget *) parent_window, err)) {
5248 /* Show the proper error message */
5249 modest_ui_actions_on_account_connection_error (parent_window, account);
5254 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5256 /* tinymail will return NULL for local folders it seems */
5257 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5258 modest_tny_account_get_protocol_type (dst_account),
5259 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_MESSAGE_ADD);
5260 g_object_unref (dst_account);
5262 if (dst_forbids_message_add) {
5263 modest_platform_information_banner (GTK_WIDGET (win),
5265 ngettext("mail_in_ui_folder_move_target_error",
5266 "mail_in_ui_folder_move_targets_error",
5267 tny_list_get_length (helper->headers)));
5271 movehelper = g_new0 (MoveToHelper, 1);
5272 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5273 _CS("ckct_nw_pasting"));
5274 if (movehelper->banner != NULL) {
5275 g_object_ref (movehelper->banner);
5276 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5279 if (MODEST_IS_MAIN_WINDOW (win)) {
5280 GtkWidget *header_view =
5281 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5282 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5283 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5286 /* Perform the mail operation */
5287 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5288 xfer_messages_error_handler,
5290 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5293 modest_mail_operation_xfer_msgs (mail_op,
5295 TNY_FOLDER (helper->dst_folder),
5300 g_object_unref (G_OBJECT (mail_op));
5302 g_object_unref (helper->dst_folder);
5303 g_object_unref (helper->headers);
5304 g_slice_free (XferMsgsHelper, helper);
5308 TnyFolder *src_folder;
5309 TnyFolderStore *dst_folder;
5310 gboolean delete_original;
5311 GtkWidget *folder_view;
5315 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
5316 TnyAccount *account, gpointer user_data)
5318 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5319 GtkTreeSelection *sel;
5320 ModestMailOperation *mail_op = NULL;
5322 if (canceled || err || !MODEST_IS_MAIN_WINDOW (parent_window)) {
5323 g_object_unref (G_OBJECT (info->src_folder));
5324 g_object_unref (G_OBJECT (info->dst_folder));
5329 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5330 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5331 _CS("ckct_nw_pasting"));
5332 if (helper->banner != NULL) {
5333 g_object_ref (helper->banner);
5334 gtk_widget_show (GTK_WIDGET(helper->banner));
5336 /* Clean folder on header view before moving it */
5337 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5338 gtk_tree_selection_unselect_all (sel);
5340 /* Let gtk events run. We need that the folder
5341 view frees its reference to the source
5342 folder *before* issuing the mail operation
5343 so we need the signal handler of selection
5344 changed to happen before the mail
5346 while (gtk_events_pending ())
5347 gtk_main_iteration (); */
5350 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5351 modest_ui_actions_move_folder_error_handler,
5352 info->src_folder, NULL);
5353 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5356 /* Select *after* the changes */
5357 /* TODO: this function hangs UI after transfer */
5358 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
5359 /* TNY_FOLDER (src_folder), TRUE); */
5361 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5362 TNY_FOLDER (info->dst_folder), TRUE);
5363 modest_mail_operation_xfer_folder (mail_op,
5364 TNY_FOLDER (info->src_folder),
5366 info->delete_original,
5369 g_object_unref (G_OBJECT (info->src_folder));
5371 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5374 /* Unref mail operation */
5375 g_object_unref (G_OBJECT (mail_op));
5376 g_object_unref (G_OBJECT (info->dst_folder));
5381 get_account_from_folder_store (TnyFolderStore *folder_store)
5383 if (TNY_IS_ACCOUNT (folder_store))
5384 return g_object_ref (folder_store);
5386 return tny_folder_get_account (TNY_FOLDER (folder_store));
5390 * UI handler for the "Move to" action when invoked from the
5394 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5395 GtkWidget *folder_view,
5396 TnyFolderStore *dst_folder,
5397 ModestMainWindow *win)
5399 ModestHeaderView *header_view = NULL;
5400 TnyFolderStore *src_folder = NULL;
5402 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5404 /* Get the source folder */
5405 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5407 /* Get header view */
5408 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
5410 /* Get folder or messages to transfer */
5411 if (gtk_widget_is_focus (folder_view)) {
5412 gboolean do_xfer = TRUE;
5414 /* Allow only to transfer folders to the local root folder */
5415 if (TNY_IS_ACCOUNT (dst_folder) &&
5416 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5417 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5419 } else if (!TNY_IS_FOLDER (src_folder)) {
5420 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5425 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5426 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5428 info->src_folder = g_object_ref (src_folder);
5429 info->dst_folder = g_object_ref (dst_folder);
5430 info->delete_original = TRUE;
5431 info->folder_view = folder_view;
5433 connect_info->callback = on_move_folder_cb;
5434 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5435 connect_info->data = info;
5437 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5438 TNY_FOLDER_STORE (src_folder),
5441 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5444 headers = modest_header_view_get_selected_headers(header_view);
5446 /* Transfer the messages */
5447 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
5448 headers, TNY_FOLDER (dst_folder));
5450 g_object_unref (headers);
5454 g_object_unref (src_folder);
5459 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
5460 TnyFolder *src_folder,
5462 TnyFolder *dst_folder)
5464 gboolean need_connection = TRUE;
5465 gboolean do_xfer = TRUE;
5466 XferMsgsHelper *helper;
5468 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5469 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5470 g_return_if_fail (TNY_IS_LIST (headers));
5472 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5473 headers, TNY_FOLDER (dst_folder),
5474 TRUE, &need_connection,
5477 /* If we don't want to transfer just return */
5481 /* Create the helper */
5482 helper = g_slice_new (XferMsgsHelper);
5483 helper->dst_folder = g_object_ref (dst_folder);
5484 helper->headers = g_object_ref (headers);
5486 if (need_connection) {
5487 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5488 connect_info->callback = xfer_messages_performer;
5489 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5490 connect_info->data = helper;
5492 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5493 TNY_FOLDER_STORE (src_folder),
5496 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5497 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
5498 src_account, helper);
5499 g_object_unref (src_account);
5504 * UI handler for the "Move to" action when invoked from the
5505 * ModestMsgViewWindow
5508 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
5509 TnyFolderStore *dst_folder,
5510 ModestMsgViewWindow *win)
5512 TnyList *headers = NULL;
5513 TnyHeader *header = NULL;
5514 TnyFolder *src_folder = NULL;
5516 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5518 /* Create header list */
5519 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
5520 src_folder = TNY_FOLDER (tny_header_get_folder(header));
5521 headers = tny_simple_list_new ();
5522 tny_list_append (headers, G_OBJECT (header));
5524 /* Transfer the messages */
5525 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder, headers,
5526 TNY_FOLDER (dst_folder));
5529 g_object_unref (src_folder);
5530 g_object_unref (header);
5531 g_object_unref (headers);
5535 modest_ui_actions_on_move_to (GtkAction *action,
5538 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
5540 TnyFolderStore *dst_folder = NULL;
5541 ModestMainWindow *main_window;
5543 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
5544 MODEST_IS_MSG_VIEW_WINDOW (win));
5546 /* Get the main window if exists */
5547 if (MODEST_IS_MAIN_WINDOW (win))
5548 main_window = MODEST_MAIN_WINDOW (win);
5551 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5552 FALSE)); /* don't create */
5554 /* Get the folder view widget if exists */
5556 folder_view = modest_main_window_get_child_widget (main_window,
5557 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5561 /* Create and run the dialog */
5562 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
5563 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5564 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog), (GtkWindow *) win);
5565 result = gtk_dialog_run (GTK_DIALOG(dialog));
5566 g_object_ref (tree_view);
5567 gtk_widget_destroy (dialog);
5569 if (result != GTK_RESPONSE_ACCEPT)
5572 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
5573 /* Do window specific stuff */
5574 if (MODEST_IS_MAIN_WINDOW (win)) {
5575 modest_ui_actions_on_main_window_move_to (action,
5578 MODEST_MAIN_WINDOW (win));
5580 modest_ui_actions_on_msg_view_window_move_to (action,
5582 MODEST_MSG_VIEW_WINDOW (win));
5586 g_object_unref (dst_folder);
5590 * Calls #HeadersFunc for each header already selected in the main
5591 * window or the message currently being shown in the msg view window
5594 do_headers_action (ModestWindow *win,
5598 TnyList *headers_list = NULL;
5599 TnyIterator *iter = NULL;
5600 TnyHeader *header = NULL;
5601 TnyFolder *folder = NULL;
5604 headers_list = get_selected_headers (win);
5608 /* Get the folder */
5609 iter = tny_list_create_iterator (headers_list);
5610 header = TNY_HEADER (tny_iterator_get_current (iter));
5612 folder = tny_header_get_folder (header);
5613 g_object_unref (header);
5616 /* Call the function for each header */
5617 while (!tny_iterator_is_done (iter)) {
5618 header = TNY_HEADER (tny_iterator_get_current (iter));
5619 func (header, win, user_data);
5620 g_object_unref (header);
5621 tny_iterator_next (iter);
5624 /* Trick: do a poke status in order to speed up the signaling
5626 tny_folder_poke_status (folder);
5629 g_object_unref (folder);
5630 g_object_unref (iter);
5631 g_object_unref (headers_list);
5635 modest_ui_actions_view_attachment (GtkAction *action,
5636 ModestWindow *window)
5638 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5639 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5641 /* not supported window for this action */
5642 g_return_if_reached ();
5647 modest_ui_actions_save_attachments (GtkAction *action,
5648 ModestWindow *window)
5650 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5652 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5655 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5657 /* not supported window for this action */
5658 g_return_if_reached ();
5663 modest_ui_actions_remove_attachments (GtkAction *action,
5664 ModestWindow *window)
5666 if (MODEST_IS_MAIN_WINDOW (window)) {
5667 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
5668 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5669 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5671 /* not supported window for this action */
5672 g_return_if_reached ();
5677 modest_ui_actions_on_settings (GtkAction *action,
5682 dialog = modest_platform_get_global_settings_dialog ();
5683 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
5684 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5685 gtk_widget_show_all (dialog);
5687 gtk_dialog_run (GTK_DIALOG (dialog));
5689 gtk_widget_destroy (dialog);
5693 modest_ui_actions_on_help (GtkAction *action,
5696 /* Help app is not available at all in fremantle */
5697 #ifndef MODEST_TOOLKIT_HILDON2
5698 const gchar *help_id;
5700 g_return_if_fail (win && GTK_IS_WINDOW(win));
5702 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5705 modest_platform_show_help (GTK_WINDOW (win), help_id);
5710 modest_ui_actions_on_csm_help (GtkAction *action,
5713 /* Help app is not available at all in fremantle */
5714 #ifndef MODEST_TOOLKIT_HILDON2
5716 const gchar* help_id = NULL;
5717 GtkWidget *folder_view;
5718 TnyFolderStore *folder_store;
5720 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
5722 /* Get selected folder */
5723 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5724 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5725 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5727 /* Switch help_id */
5728 if (folder_store && TNY_IS_FOLDER (folder_store))
5729 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
5732 g_object_unref (folder_store);
5735 modest_platform_show_help (GTK_WINDOW (win), help_id);
5737 modest_ui_actions_on_help (action, win);
5742 retrieve_contents_cb (ModestMailOperation *mail_op,
5749 /* We only need this callback to show an error in case of
5750 memory low condition */
5751 modest_ui_actions_msg_retrieval_check (mail_op, header, msg);
5755 retrieve_msg_contents_performer (gboolean canceled,
5757 GtkWindow *parent_window,
5758 TnyAccount *account,
5761 ModestMailOperation *mail_op;
5762 TnyList *headers = TNY_LIST (user_data);
5764 if (err || canceled) {
5765 check_memory_full_error ((GtkWidget *) parent_window, err);
5769 /* Create mail operation */
5770 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5771 modest_ui_actions_disk_operations_error_handler,
5773 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5774 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
5777 g_object_unref (mail_op);
5779 g_object_unref (headers);
5780 g_object_unref (account);
5784 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5785 ModestWindow *window)
5787 TnyList *headers = NULL;
5788 TnyAccount *account = NULL;
5789 TnyIterator *iter = NULL;
5790 TnyHeader *header = NULL;
5791 TnyFolder *folder = NULL;
5794 headers = get_selected_headers (window);
5798 /* Pick the account */
5799 iter = tny_list_create_iterator (headers);
5800 header = TNY_HEADER (tny_iterator_get_current (iter));
5801 folder = tny_header_get_folder (header);
5802 account = tny_folder_get_account (folder);
5803 g_object_unref (folder);
5804 g_object_unref (header);
5805 g_object_unref (iter);
5807 /* Connect and perform the message retrieval */
5808 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
5809 g_object_ref (account),
5810 retrieve_msg_contents_performer,
5811 g_object_ref (headers));
5814 g_object_unref (account);
5815 g_object_unref (headers);
5819 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
5821 g_return_if_fail (MODEST_IS_WINDOW (window));
5824 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
5828 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
5830 g_return_if_fail (MODEST_IS_WINDOW (window));
5833 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
5837 modest_ui_actions_on_email_menu_activated (GtkAction *action,
5838 ModestWindow *window)
5840 g_return_if_fail (MODEST_IS_WINDOW (window));
5843 modest_ui_actions_check_menu_dimming_rules (window);
5847 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
5848 ModestWindow *window)
5850 g_return_if_fail (MODEST_IS_WINDOW (window));
5853 modest_ui_actions_check_menu_dimming_rules (window);
5857 modest_ui_actions_on_view_menu_activated (GtkAction *action,
5858 ModestWindow *window)
5860 g_return_if_fail (MODEST_IS_WINDOW (window));
5863 modest_ui_actions_check_menu_dimming_rules (window);
5867 modest_ui_actions_on_format_menu_activated (GtkAction *action,
5868 ModestWindow *window)
5870 g_return_if_fail (MODEST_IS_WINDOW (window));
5873 modest_ui_actions_check_menu_dimming_rules (window);
5877 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
5878 ModestWindow *window)
5880 g_return_if_fail (MODEST_IS_WINDOW (window));
5883 modest_ui_actions_check_menu_dimming_rules (window);
5887 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
5888 ModestWindow *window)
5890 g_return_if_fail (MODEST_IS_WINDOW (window));
5893 modest_ui_actions_check_menu_dimming_rules (window);
5897 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
5898 ModestWindow *window)
5900 g_return_if_fail (MODEST_IS_WINDOW (window));
5903 modest_ui_actions_check_menu_dimming_rules (window);
5907 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
5908 ModestWindow *window)
5910 g_return_if_fail (MODEST_IS_WINDOW (window));
5913 modest_ui_actions_check_menu_dimming_rules (window);
5917 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
5918 ModestWindow *window)
5920 g_return_if_fail (MODEST_IS_WINDOW (window));
5923 modest_ui_actions_check_menu_dimming_rules (window);
5927 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
5929 g_return_if_fail (MODEST_IS_WINDOW (window));
5931 /* we check for low-mem; in that case, show a warning, and don't allow
5934 if (modest_platform_check_memory_low (window, TRUE))
5937 modest_platform_show_search_messages (GTK_WINDOW (window));
5941 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
5943 g_return_if_fail (MODEST_IS_WINDOW (win));
5946 /* we check for low-mem; in that case, show a warning, and don't allow
5947 * for the addressbook
5949 if (modest_platform_check_memory_low (win, TRUE))
5953 modest_platform_show_addressbook (GTK_WINDOW (win));
5958 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
5959 ModestWindow *window)
5961 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5963 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
5967 on_send_receive_finished (ModestMailOperation *mail_op,
5970 GtkWidget *header_view, *folder_view;
5971 TnyFolderStore *folder_store;
5972 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
5974 /* Set send/receive operation finished */
5975 modest_main_window_notify_send_receive_completed (main_win);
5977 /* Don't refresh the current folder if there were any errors */
5978 if (modest_mail_operation_get_status (mail_op) !=
5979 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5982 /* Refresh the current folder if we're viewing a window. We do
5983 this because the user won't be able to see the new mails in
5984 the selected folder after a Send&Receive because it only
5985 performs a poke_status, i.e, only the number of read/unread
5986 messages is updated, but the new headers are not
5988 folder_view = modest_main_window_get_child_widget (main_win,
5989 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5993 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5995 /* Do not need to refresh INBOX again because the
5996 update_account does it always automatically */
5997 if (folder_store && TNY_IS_FOLDER (folder_store) &&
5998 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
5999 ModestMailOperation *refresh_op;
6001 header_view = modest_main_window_get_child_widget (main_win,
6002 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6004 /* We do not need to set the contents style
6005 because it hasn't changed. We also do not
6006 need to save the widget status. Just force
6008 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6009 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6010 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6011 folder_refreshed_cb, main_win);
6012 g_object_unref (refresh_op);
6016 g_object_unref (folder_store);
6021 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6027 const gchar* server_name = NULL;
6028 TnyTransportAccount *server_account;
6029 gchar *message = NULL;
6031 /* Don't show anything if the user cancelled something or the
6032 * send receive request is not interactive. Authentication
6033 * errors are managed by the account store so no need to show
6034 * a dialog here again */
6035 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6036 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6037 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6041 /* Get the server name: */
6043 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
6045 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
6047 g_return_if_reached ();
6049 /* Show the appropriate message text for the GError: */
6050 switch (err->code) {
6051 case TNY_SERVICE_ERROR_CONNECT:
6052 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6054 case TNY_SERVICE_ERROR_SEND:
6055 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
6057 case TNY_SERVICE_ERROR_UNAVAILABLE:
6058 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6061 g_warning ("%s: unexpected ERROR %d",
6062 __FUNCTION__, err->code);
6063 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
6067 modest_platform_run_information_dialog (NULL, message, FALSE);
6069 g_object_unref (server_account);
6073 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6078 ModestMainWindow *main_window = NULL;
6079 ModestWindowMgr *mgr = NULL;
6080 GtkWidget *folder_view = NULL, *header_view = NULL;
6081 TnyFolderStore *selected_folder = NULL;
6082 TnyFolderType folder_type;
6084 mgr = modest_runtime_get_window_mgr ();
6085 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr,
6086 FALSE));/* don't create */
6090 /* Check if selected folder is OUTBOX */
6091 folder_view = modest_main_window_get_child_widget (main_window,
6092 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6093 header_view = modest_main_window_get_child_widget (main_window,
6094 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6096 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6097 if (!TNY_IS_FOLDER (selected_folder))
6100 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6101 #if GTK_CHECK_VERSION(2, 8, 0)
6102 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
6103 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6104 GtkTreeViewColumn *tree_column;
6106 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6107 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6109 gtk_tree_view_column_queue_resize (tree_column);
6112 gtk_widget_queue_draw (header_view);
6115 /* Rerun dimming rules, because the message could become deletable for example */
6116 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6117 MODEST_DIMMING_RULES_TOOLBAR);
6118 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6119 MODEST_DIMMING_RULES_MENU);
6123 if (selected_folder != NULL)
6124 g_object_unref (selected_folder);
6128 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6129 TnyAccount *account)
6131 ModestProtocolType protocol_type;
6132 ModestProtocol *protocol;
6133 gchar *error_note = NULL;
6135 protocol_type = modest_tny_account_get_protocol_type (account);
6136 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6139 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6140 if (error_note == NULL) {
6141 g_warning ("%s: This should not be reached", __FUNCTION__);
6143 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6144 g_free (error_note);
6149 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6153 TnyFolderStore *folder = NULL;
6154 TnyAccount *account = NULL;
6155 ModestProtocolType proto;
6156 ModestProtocol *protocol;
6157 TnyHeader *header = NULL;
6159 if (MODEST_IS_MAIN_WINDOW (win)) {
6160 GtkWidget *header_view;
6161 TnyList* headers = NULL;
6163 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6164 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6165 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6166 if (!headers || tny_list_get_length (headers) == 0) {
6168 g_object_unref (headers);
6171 iter = tny_list_create_iterator (headers);
6172 header = TNY_HEADER (tny_iterator_get_current (iter));
6173 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6174 g_object_unref (iter);
6175 g_object_unref (headers);
6176 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6177 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6178 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6181 /* Get the account type */
6182 account = tny_folder_get_account (TNY_FOLDER (folder));
6183 proto = modest_tny_account_get_protocol_type (account);
6184 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6187 subject = tny_header_dup_subject (header);
6188 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6192 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6196 g_object_unref (account);
6197 g_object_unref (folder);
6198 g_object_unref (header);
6204 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6205 const gchar *account_name,
6206 const gchar *account_title)
6208 ModestAccountMgr *account_mgr;
6211 ModestProtocol *protocol;
6212 gboolean removed = FALSE;
6214 g_return_val_if_fail (account_name, FALSE);
6215 g_return_val_if_fail (account_title, FALSE);
6217 account_mgr = modest_runtime_get_account_mgr();
6219 /* The warning text depends on the account type: */
6220 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6221 modest_account_mgr_get_store_protocol (account_mgr,
6223 txt = modest_protocol_get_translation (protocol,
6224 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6227 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6229 response = modest_platform_run_confirmation_dialog (parent_window, txt);
6233 if (response == GTK_RESPONSE_OK) {
6234 /* Remove account. If it succeeds then it also removes
6235 the account from the ModestAccountView: */
6236 gboolean is_default = FALSE;
6237 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6238 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6240 g_free (default_account_name);
6242 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6244 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);