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 /* Set parent to NULL or the banner will disappear with its parent dialog */
3777 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
3788 /* This is not in the Maemo UI spec:
3789 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3795 g_free (initial_username);
3796 gtk_widget_destroy (dialog);
3797 g_slice_free (PasswordDialogFields, fields);
3799 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3803 modest_ui_actions_on_cut (GtkAction *action,
3804 ModestWindow *window)
3806 GtkWidget *focused_widget;
3807 GtkClipboard *clipboard;
3809 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3810 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3811 if (GTK_IS_EDITABLE (focused_widget)) {
3812 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3813 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3814 gtk_clipboard_store (clipboard);
3815 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3816 GtkTextBuffer *buffer;
3818 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3819 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3820 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3821 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3822 gtk_clipboard_store (clipboard);
3824 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3825 TnyList *header_list = modest_header_view_get_selected_headers (
3826 MODEST_HEADER_VIEW (focused_widget));
3827 gboolean continue_download = FALSE;
3828 gint num_of_unc_msgs;
3830 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3832 if (num_of_unc_msgs) {
3833 TnyAccount *account = get_account_from_header_list (header_list);
3835 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3836 g_object_unref (account);
3840 if (num_of_unc_msgs == 0 || continue_download) {
3841 /* modest_platform_information_banner (
3842 NULL, NULL, _CS("mcen_ib_getting_items"));*/
3843 modest_header_view_cut_selection (
3844 MODEST_HEADER_VIEW (focused_widget));
3847 g_object_unref (header_list);
3848 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3849 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3854 modest_ui_actions_on_copy (GtkAction *action,
3855 ModestWindow *window)
3857 GtkClipboard *clipboard;
3858 GtkWidget *focused_widget;
3859 gboolean copied = TRUE;
3861 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3862 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3864 if (GTK_IS_LABEL (focused_widget)) {
3866 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
3867 gtk_clipboard_set_text (clipboard, selection, -1);
3869 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3870 gtk_clipboard_store (clipboard);
3871 } else if (GTK_IS_EDITABLE (focused_widget)) {
3872 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3873 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3874 gtk_clipboard_store (clipboard);
3875 } else if (GTK_IS_HTML (focused_widget)) {
3878 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
3879 if ((sel == NULL) || (sel[0] == '\0')) {
3882 gtk_html_copy (GTK_HTML (focused_widget));
3883 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3884 gtk_clipboard_store (clipboard);
3886 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3887 GtkTextBuffer *buffer;
3888 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3889 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3890 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3891 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3892 gtk_clipboard_store (clipboard);
3894 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3895 TnyList *header_list = modest_header_view_get_selected_headers (
3896 MODEST_HEADER_VIEW (focused_widget));
3897 gboolean continue_download = FALSE;
3898 gint num_of_unc_msgs;
3900 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3902 if (num_of_unc_msgs) {
3903 TnyAccount *account = get_account_from_header_list (header_list);
3905 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3906 g_object_unref (account);
3910 if (num_of_unc_msgs == 0 || continue_download) {
3911 modest_platform_information_banner (
3912 NULL, NULL, _CS("mcen_ib_getting_items"));
3913 modest_header_view_copy_selection (
3914 MODEST_HEADER_VIEW (focused_widget));
3918 g_object_unref (header_list);
3920 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3921 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3924 /* Show information banner if there was a copy to clipboard */
3926 modest_platform_information_banner (
3927 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3931 modest_ui_actions_on_undo (GtkAction *action,
3932 ModestWindow *window)
3934 ModestEmailClipboard *clipboard = NULL;
3936 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3937 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3938 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3939 /* Clear clipboard source */
3940 clipboard = modest_runtime_get_email_clipboard ();
3941 modest_email_clipboard_clear (clipboard);
3944 g_return_if_reached ();
3949 modest_ui_actions_on_redo (GtkAction *action,
3950 ModestWindow *window)
3952 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3953 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3956 g_return_if_reached ();
3962 destroy_information_note (ModestMailOperation *mail_op,
3965 /* destroy information note */
3966 gtk_widget_destroy (GTK_WIDGET(user_data));
3970 destroy_folder_information_note (ModestMailOperation *mail_op,
3971 TnyFolder *new_folder,
3974 /* destroy information note */
3975 gtk_widget_destroy (GTK_WIDGET(user_data));
3980 paste_as_attachment_free (gpointer data)
3982 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3984 if (helper->banner) {
3985 gtk_widget_destroy (helper->banner);
3986 g_object_unref (helper->banner);
3992 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3997 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3998 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4003 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4008 modest_ui_actions_on_paste (GtkAction *action,
4009 ModestWindow *window)
4011 GtkWidget *focused_widget = NULL;
4012 GtkWidget *inf_note = NULL;
4013 ModestMailOperation *mail_op = NULL;
4015 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4016 if (GTK_IS_EDITABLE (focused_widget)) {
4017 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4018 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4019 ModestEmailClipboard *e_clipboard = NULL;
4020 e_clipboard = modest_runtime_get_email_clipboard ();
4021 if (modest_email_clipboard_cleared (e_clipboard)) {
4022 GtkTextBuffer *buffer;
4023 GtkClipboard *clipboard;
4025 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4026 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4027 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4028 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4029 ModestMailOperation *mail_op;
4030 TnyFolder *src_folder = NULL;
4031 TnyList *data = NULL;
4033 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4034 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4035 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4036 _CS("ckct_nw_pasting"));
4037 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4038 mail_op = modest_mail_operation_new (G_OBJECT (window));
4039 if (helper->banner != NULL) {
4040 g_object_ref (G_OBJECT (helper->banner));
4041 gtk_widget_show (GTK_WIDGET (helper->banner));
4045 modest_mail_operation_get_msgs_full (mail_op,
4047 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4049 paste_as_attachment_free);
4053 g_object_unref (data);
4055 g_object_unref (src_folder);
4058 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4059 ModestEmailClipboard *clipboard = NULL;
4060 TnyFolder *src_folder = NULL;
4061 TnyFolderStore *folder_store = NULL;
4062 TnyList *data = NULL;
4063 gboolean delete = FALSE;
4065 /* Check clipboard source */
4066 clipboard = modest_runtime_get_email_clipboard ();
4067 if (modest_email_clipboard_cleared (clipboard))
4070 /* Get elements to paste */
4071 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4073 /* Create a new mail operation */
4074 mail_op = modest_mail_operation_new (G_OBJECT(window));
4076 /* Get destination folder */
4077 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4079 /* transfer messages */
4083 /* Ask for user confirmation */
4085 modest_ui_actions_msgs_move_to_confirmation (window,
4086 TNY_FOLDER (folder_store),
4090 if (response == GTK_RESPONSE_OK) {
4091 /* Launch notification */
4092 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4093 _CS("ckct_nw_pasting"));
4094 if (inf_note != NULL) {
4095 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4096 gtk_widget_show (GTK_WIDGET(inf_note));
4099 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4100 modest_mail_operation_xfer_msgs (mail_op,
4102 TNY_FOLDER (folder_store),
4104 destroy_information_note,
4107 g_object_unref (mail_op);
4110 } else if (src_folder != NULL) {
4111 /* Launch notification */
4112 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4113 _CS("ckct_nw_pasting"));
4114 if (inf_note != NULL) {
4115 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4116 gtk_widget_show (GTK_WIDGET(inf_note));
4119 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4120 modest_mail_operation_xfer_folder (mail_op,
4124 destroy_folder_information_note,
4130 g_object_unref (data);
4131 if (src_folder != NULL)
4132 g_object_unref (src_folder);
4133 if (folder_store != NULL)
4134 g_object_unref (folder_store);
4140 modest_ui_actions_on_select_all (GtkAction *action,
4141 ModestWindow *window)
4143 GtkWidget *focused_widget;
4145 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4146 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4147 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4148 } else if (GTK_IS_LABEL (focused_widget)) {
4149 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4150 } else if (GTK_IS_EDITABLE (focused_widget)) {
4151 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4152 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4153 GtkTextBuffer *buffer;
4154 GtkTextIter start, end;
4156 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4157 gtk_text_buffer_get_start_iter (buffer, &start);
4158 gtk_text_buffer_get_end_iter (buffer, &end);
4159 gtk_text_buffer_select_range (buffer, &start, &end);
4160 } else if (GTK_IS_HTML (focused_widget)) {
4161 gtk_html_select_all (GTK_HTML (focused_widget));
4162 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4163 GtkWidget *header_view = focused_widget;
4164 GtkTreeSelection *selection = NULL;
4166 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4167 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4168 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4171 /* Disable window dimming management */
4172 modest_window_disable_dimming (MODEST_WINDOW(window));
4174 /* Select all messages */
4175 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4176 gtk_tree_selection_select_all (selection);
4178 /* Set focuse on header view */
4179 gtk_widget_grab_focus (header_view);
4181 /* Enable window dimming management */
4182 modest_window_enable_dimming (MODEST_WINDOW(window));
4183 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4184 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4190 modest_ui_actions_on_mark_as_read (GtkAction *action,
4191 ModestWindow *window)
4193 g_return_if_fail (MODEST_IS_WINDOW(window));
4195 /* Mark each header as read */
4196 do_headers_action (window, headers_action_mark_as_read, NULL);
4200 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4201 ModestWindow *window)
4203 g_return_if_fail (MODEST_IS_WINDOW(window));
4205 /* Mark each header as read */
4206 do_headers_action (window, headers_action_mark_as_unread, NULL);
4210 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4211 GtkRadioAction *selected,
4212 ModestWindow *window)
4216 value = gtk_radio_action_get_current_value (selected);
4217 if (MODEST_IS_WINDOW (window)) {
4218 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4223 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4224 GtkRadioAction *selected,
4225 ModestWindow *window)
4227 TnyHeaderFlags flags;
4228 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4230 flags = gtk_radio_action_get_current_value (selected);
4231 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4235 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4236 GtkRadioAction *selected,
4237 ModestWindow *window)
4241 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4243 file_format = gtk_radio_action_get_current_value (selected);
4244 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4249 modest_ui_actions_on_zoom_plus (GtkAction *action,
4250 ModestWindow *window)
4252 g_return_if_fail (MODEST_IS_WINDOW (window));
4254 modest_window_zoom_plus (MODEST_WINDOW (window));
4258 modest_ui_actions_on_zoom_minus (GtkAction *action,
4259 ModestWindow *window)
4261 g_return_if_fail (MODEST_IS_WINDOW (window));
4263 modest_window_zoom_minus (MODEST_WINDOW (window));
4267 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4268 ModestWindow *window)
4270 ModestWindowMgr *mgr;
4271 gboolean fullscreen, active;
4272 g_return_if_fail (MODEST_IS_WINDOW (window));
4274 mgr = modest_runtime_get_window_mgr ();
4276 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4277 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4279 if (active != fullscreen) {
4280 modest_window_mgr_set_fullscreen_mode (mgr, active);
4281 #ifndef MODEST_TOOLKIT_HILDON2
4282 gtk_window_present (GTK_WINDOW (window));
4288 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4289 ModestWindow *window)
4291 ModestWindowMgr *mgr;
4292 gboolean fullscreen;
4294 g_return_if_fail (MODEST_IS_WINDOW (window));
4296 mgr = modest_runtime_get_window_mgr ();
4297 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4298 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4300 #ifndef MODEST_TOOLKIT_HILDON2
4301 gtk_window_present (GTK_WINDOW (window));
4306 * Used by modest_ui_actions_on_details to call do_headers_action
4309 headers_action_show_details (TnyHeader *header,
4310 ModestWindow *window,
4314 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header);
4318 * Show the header details in a ModestDetailsDialog widget
4321 modest_ui_actions_on_details (GtkAction *action,
4324 TnyList * headers_list;
4328 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4331 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4334 g_object_unref (msg);
4336 headers_list = get_selected_headers (win);
4340 iter = tny_list_create_iterator (headers_list);
4342 header = TNY_HEADER (tny_iterator_get_current (iter));
4344 headers_action_show_details (header, win, NULL);
4345 g_object_unref (header);
4348 g_object_unref (iter);
4349 g_object_unref (headers_list);
4351 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4352 GtkWidget *folder_view, *header_view;
4354 /* Check which widget has the focus */
4355 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4356 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4357 if (gtk_widget_is_focus (folder_view)) {
4358 TnyFolderStore *folder_store
4359 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4360 if (!folder_store) {
4361 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4364 /* Show only when it's a folder */
4365 /* This function should not be called for account items,
4366 * because we dim the menu item for them. */
4367 if (TNY_IS_FOLDER (folder_store)) {
4368 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4369 TNY_FOLDER (folder_store));
4372 g_object_unref (folder_store);
4375 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4376 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4377 /* Show details of each header */
4378 do_headers_action (win, headers_action_show_details, header_view);
4384 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4385 ModestMsgEditWindow *window)
4387 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4389 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4393 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4394 ModestMsgEditWindow *window)
4396 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4398 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4402 modest_ui_actions_toggle_folders_view (GtkAction *action,
4403 ModestMainWindow *main_window)
4405 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4407 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4408 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4410 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4414 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4415 ModestWindow *window)
4417 gboolean active, fullscreen = FALSE;
4418 ModestWindowMgr *mgr;
4420 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4422 /* Check if we want to toggle the toolbar view in fullscreen
4424 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4425 "ViewShowToolbarFullScreen")) {
4429 /* Toggle toolbar */
4430 mgr = modest_runtime_get_window_mgr ();
4431 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4435 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4436 ModestMsgEditWindow *window)
4438 modest_msg_edit_window_select_font (window);
4443 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4444 const gchar *display_name,
4447 /* don't update the display name if it was already set;
4448 * updating the display name apparently is expensive */
4449 const gchar* old_name = gtk_window_get_title (window);
4451 if (display_name == NULL)
4454 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4455 return; /* don't do anything */
4457 /* This is usually used to change the title of the main window, which
4458 * is the one that holds the folder view. Note that this change can
4459 * happen even when the widget doesn't have the focus. */
4460 gtk_window_set_title (window, display_name);
4465 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4467 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4468 modest_msg_edit_window_select_contacts (window);
4472 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4474 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4475 modest_msg_edit_window_check_names (window, FALSE);
4479 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
4481 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
4482 GTK_WIDGET (user_data));
4486 * This function is used to track changes in the selection of the
4487 * folder view that is inside the "move to" dialog to enable/disable
4488 * the OK button because we do not want the user to select a disallowed
4489 * destination for a folder.
4490 * The user also not desired to be able to use NEW button on items where
4491 * folder creation is not possibel.
4494 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4495 TnyFolderStore *folder_store,
4499 GtkWidget *dialog = NULL;
4500 GtkWidget *ok_button = NULL, *new_button = NULL;
4501 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4502 gboolean moving_folder = FALSE;
4503 gboolean is_local_account = TRUE;
4504 GtkWidget *folder_view = NULL;
4505 ModestTnyFolderRules rules;
4507 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
4512 /* Get the OK button */
4513 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
4517 ok_button = g_object_get_data (G_OBJECT (dialog), MOVE_FOLDER_OK_BUTTON);
4518 new_button = g_object_get_data (G_OBJECT (dialog), MOVE_FOLDER_NEW_BUTTON);
4520 /* check if folder_store is an remote account */
4521 if (TNY_IS_ACCOUNT (folder_store)) {
4522 TnyAccount *local_account = NULL;
4523 TnyAccount *mmc_account = NULL;
4524 ModestTnyAccountStore *account_store = NULL;
4526 account_store = modest_runtime_get_account_store ();
4527 local_account = modest_tny_account_store_get_local_folders_account (account_store);
4528 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
4530 if ((gpointer) local_account != (gpointer) folder_store &&
4531 (gpointer) mmc_account != (gpointer) folder_store) {
4532 ModestProtocolType proto;
4533 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
4534 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
4535 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
4537 is_local_account = FALSE;
4538 /* New button should be dimmed on remote
4540 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4542 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
4544 g_object_unref (local_account);
4546 /* It could not exist */
4548 g_object_unref (mmc_account);
4551 /* Check the target folder rules */
4552 if (TNY_IS_FOLDER (folder_store)) {
4553 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
4554 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
4555 ok_sensitive = FALSE;
4556 new_sensitive = FALSE;
4561 /* Check if we're moving a folder */
4562 if (MODEST_IS_MAIN_WINDOW (user_data)) {
4563 /* Get the widgets */
4564 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
4565 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4566 if (gtk_widget_is_focus (folder_view))
4567 moving_folder = TRUE;
4570 if (moving_folder) {
4571 TnyFolderStore *moved_folder = NULL, *parent = NULL;
4573 /* Get the folder to move */
4574 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4576 /* Check that we're not moving to the same folder */
4577 if (TNY_IS_FOLDER (moved_folder)) {
4578 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
4579 if (parent == folder_store)
4580 ok_sensitive = FALSE;
4581 g_object_unref (parent);
4584 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
4585 /* Do not allow to move to an account unless it's the
4586 local folders account */
4587 if (!is_local_account)
4588 ok_sensitive = FALSE;
4591 if (ok_sensitive && (moved_folder == folder_store)) {
4592 /* Do not allow to move to itself */
4593 ok_sensitive = FALSE;
4595 g_object_unref (moved_folder);
4597 TnyFolder *src_folder = NULL;
4599 /* Moving a message */
4600 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
4602 TnyHeader *header = NULL;
4603 header = modest_msg_view_window_get_header
4604 (MODEST_MSG_VIEW_WINDOW (user_data));
4605 if (!TNY_IS_HEADER(header))
4606 g_warning ("%s: could not get source header", __FUNCTION__);
4608 src_folder = tny_header_get_folder (header);
4611 g_object_unref (header);
4614 TNY_FOLDER (modest_folder_view_get_selected
4615 (MODEST_FOLDER_VIEW (folder_view)));
4618 if (TNY_IS_FOLDER(src_folder)) {
4619 /* Do not allow to move the msg to the same folder */
4620 /* Do not allow to move the msg to an account */
4621 if ((gpointer) src_folder == (gpointer) folder_store ||
4622 TNY_IS_ACCOUNT (folder_store))
4623 ok_sensitive = FALSE;
4624 g_object_unref (src_folder);
4626 g_warning ("%s: could not get source folder", __FUNCTION__);
4630 /* Set sensitivity of the OK button */
4631 gtk_widget_set_sensitive (ok_button, ok_sensitive);
4632 /* Set sensitivity of the NEW button */
4633 gtk_widget_set_sensitive (new_button, new_sensitive);
4637 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
4640 get_folder_view_from_move_to_dialog (GtkWidget *move_to_dialog)
4642 return GTK_WIDGET(g_object_get_data (G_OBJECT(move_to_dialog),
4643 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4647 create_move_to_dialog (GtkWindow *win,
4648 GtkWidget *folder_view,
4649 GtkWidget **tree_view)
4652 #ifdef MODEST_TOOLKIT_HILDON2
4653 GtkWidget *pannable;
4657 GtkWidget *new_button, *ok_button;
4659 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
4661 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
4664 #ifndef MODEST_TOOLKIT_GTK
4665 ok_button = gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
4666 /* We do this manually so GTK+ does not associate a response ID for
4668 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
4669 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
4670 gtk_widget_show (new_button);
4671 #ifndef MODEST_TOOLKIT_HILDON2
4672 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
4675 /* We do this manually so GTK+ does not associate a response ID for
4677 new_button = gtk_button_new_with_label (_("mcen_ti_new_folder"));
4678 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
4679 gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (GTK_DIALOG (dialog)->action_area), new_button, TRUE);
4680 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
4681 ok_button = gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
4682 gtk_container_set_border_width (GTK_CONTAINER (dialog), 12);
4683 gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 24);
4685 g_object_set_data (G_OBJECT (dialog), MOVE_FOLDER_OK_BUTTON, ok_button);
4686 g_object_set_data (G_OBJECT (dialog), MOVE_FOLDER_NEW_BUTTON, new_button);
4688 /* Create scrolled window */
4689 #ifdef MODEST_TOOLKIT_HILDON2
4690 pannable = hildon_pannable_area_new ();
4692 scroll = gtk_scrolled_window_new (NULL, NULL);
4693 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
4694 GTK_POLICY_AUTOMATIC,
4695 GTK_POLICY_AUTOMATIC);
4698 #ifdef MODEST_TOOLKIT_GTK
4699 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN);
4702 /* Create folder view */
4703 *tree_view = modest_platform_create_folder_view (NULL);
4705 /* Track changes in the selection to
4706 * disable the OK button whenever "Move to" is not possible
4707 * disbale NEW button whenever New is not possible */
4708 g_signal_connect (*tree_view,
4709 "folder_selection_changed",
4710 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
4713 /* Listen to clicks on New button */
4714 g_signal_connect (G_OBJECT (new_button),
4716 G_CALLBACK(create_move_to_dialog_on_new_folder),
4719 /* It could happen that we're trying to move a message from a
4720 window (msg window for example) after the main window was
4721 closed, so we can not just get the model of the folder
4723 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4724 const gchar *visible_id = NULL;
4726 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4727 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4728 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4729 MODEST_FOLDER_VIEW(*tree_view));
4732 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4734 /* Show the same account than the one that is shown in the main window */
4735 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
4738 const gchar *active_account_name = NULL;
4739 ModestAccountMgr *mgr = NULL;
4740 ModestAccountSettings *settings = NULL;
4741 ModestServerAccountSettings *store_settings = NULL;
4743 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4744 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4745 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
4746 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
4748 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4749 mgr = modest_runtime_get_account_mgr ();
4750 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4753 const gchar *store_account_name;
4754 store_settings = modest_account_settings_get_store_settings (settings);
4755 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4757 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
4758 store_account_name);
4759 g_object_unref (store_settings);
4760 g_object_unref (settings);
4764 /* we keep a pointer to the embedded folder view, so we can retrieve it with
4765 * get_folder_view_from_move_to_dialog
4766 * (see above) later (needed for focus handling)
4768 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, *tree_view);
4771 /* Hide special folders */
4772 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
4774 #ifdef MODEST_TOOLKIT_HILDON2
4775 gtk_container_add (GTK_CONTAINER (pannable), *tree_view);
4776 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
4777 pannable, TRUE, TRUE, 0);
4779 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
4780 /* Add scroll to dialog */
4781 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
4782 scroll, TRUE, TRUE, 0);
4786 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4787 #ifndef MODEST_TOOLKIT_GTK
4788 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
4790 gtk_window_set_default_size (GTK_WINDOW (dialog), 600, 400);
4799 * Shows a confirmation dialog to the user when we're moving messages
4800 * from a remote server to the local storage. Returns the dialog
4801 * response. If it's other kind of movement then it always returns
4804 * This one is used by the next functions:
4805 * modest_ui_actions_on_paste - commented out
4806 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4809 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4810 TnyFolder *dest_folder,
4814 gint response = GTK_RESPONSE_OK;
4815 TnyAccount *account = NULL;
4816 TnyFolder *src_folder = NULL;
4817 TnyIterator *iter = NULL;
4818 TnyHeader *header = NULL;
4820 /* return with OK if the destination is a remote folder */
4821 if (modest_tny_folder_is_remote_folder (dest_folder))
4822 return GTK_RESPONSE_OK;
4824 /* Get source folder */
4825 iter = tny_list_create_iterator (headers);
4826 header = TNY_HEADER (tny_iterator_get_current (iter));
4828 src_folder = tny_header_get_folder (header);
4829 g_object_unref (header);
4831 g_object_unref (iter);
4833 /* if no src_folder, message may be an attahcment */
4834 if (src_folder == NULL)
4835 return GTK_RESPONSE_CANCEL;
4837 /* If the source is a local or MMC folder */
4838 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4839 g_object_unref (src_folder);
4840 return GTK_RESPONSE_OK;
4843 /* Get the account */
4844 account = tny_folder_get_account (src_folder);
4846 /* now if offline we ask the user */
4847 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4848 response = GTK_RESPONSE_OK;
4850 response = GTK_RESPONSE_CANCEL;
4853 g_object_unref (src_folder);
4854 g_object_unref (account);
4860 move_to_helper_destroyer (gpointer user_data)
4862 MoveToHelper *helper = (MoveToHelper *) user_data;
4864 /* Close the "Pasting" information banner */
4865 if (helper->banner) {
4866 gtk_widget_destroy (GTK_WIDGET (helper->banner));
4867 g_object_unref (helper->banner);
4869 if (gtk_tree_row_reference_valid (helper->reference)) {
4870 gtk_tree_row_reference_free (helper->reference);
4871 helper->reference = NULL;
4877 move_to_cb (ModestMailOperation *mail_op,
4880 MoveToHelper *helper = (MoveToHelper *) user_data;
4882 /* Note that the operation could have failed, in that case do
4884 if (modest_mail_operation_get_status (mail_op) ==
4885 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
4887 GObject *object = modest_mail_operation_get_source (mail_op);
4888 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4889 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4891 if (!modest_msg_view_window_select_next_message (self) &&
4892 !modest_msg_view_window_select_previous_message (self)) {
4893 /* No more messages to view, so close this window */
4894 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4896 } else if (MODEST_IS_MAIN_WINDOW (object) &&
4897 gtk_tree_row_reference_valid (helper->reference)) {
4898 GtkWidget *header_view;
4900 GtkTreeSelection *sel;
4902 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4903 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4904 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
4905 path = gtk_tree_row_reference_get_path (helper->reference);
4906 /* We need to unselect the previous one
4907 because we could be copying instead of
4909 gtk_tree_selection_unselect_all (sel);
4910 gtk_tree_selection_select_path (sel, path);
4911 gtk_tree_path_free (path);
4913 g_object_unref (object);
4915 /* Destroy the helper */
4916 move_to_helper_destroyer (helper);
4920 folder_move_to_cb (ModestMailOperation *mail_op,
4921 TnyFolder *new_folder,
4924 GtkWidget *folder_view;
4927 object = modest_mail_operation_get_source (mail_op);
4928 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4929 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4930 g_object_ref (folder_view);
4931 g_object_unref (object);
4932 move_to_cb (mail_op, user_data);
4933 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
4934 g_object_unref (folder_view);
4938 msgs_move_to_cb (ModestMailOperation *mail_op,
4941 move_to_cb (mail_op, user_data);
4945 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
4948 ModestWindow *main_window = NULL;
4950 /* Disable next automatic folder selection */
4951 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
4952 FALSE); /* don't create */
4954 GObject *win = NULL;
4955 GtkWidget *folder_view = NULL;
4957 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
4958 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4959 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
4961 if (user_data && TNY_IS_FOLDER (user_data)) {
4962 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
4963 TNY_FOLDER (user_data), FALSE);
4966 /* Show notification dialog only if the main window exists */
4967 win = modest_mail_operation_get_source (mail_op);
4968 modest_platform_run_information_dialog ((GtkWindow *) win,
4969 _("mail_in_ui_folder_move_target_error"),
4972 g_object_unref (win);
4977 open_msg_for_purge_cb (ModestMailOperation *mail_op,
4986 gint pending_purges = 0;
4987 gboolean some_purged = FALSE;
4988 ModestWindow *win = MODEST_WINDOW (user_data);
4989 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
4991 /* If there was any error */
4992 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
4993 modest_window_mgr_unregister_header (mgr, header);
4997 /* Once the message has been retrieved for purging, we check if
4998 * it's all ok for purging */
5000 parts = tny_simple_list_new ();
5001 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5002 iter = tny_list_create_iterator (parts);
5004 while (!tny_iterator_is_done (iter)) {
5006 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5007 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5008 if (tny_mime_part_is_purged (part))
5015 g_object_unref (part);
5017 tny_iterator_next (iter);
5019 g_object_unref (iter);
5022 if (pending_purges>0) {
5024 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5026 if (response == GTK_RESPONSE_OK) {
5029 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5030 iter = tny_list_create_iterator (parts);
5031 while (!tny_iterator_is_done (iter)) {
5034 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5035 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5036 tny_mime_part_set_purged (part);
5039 g_object_unref (part);
5041 tny_iterator_next (iter);
5043 g_object_unref (iter);
5045 tny_msg_rewrite_cache (msg);
5047 gtk_widget_destroy (info);
5051 modest_window_mgr_unregister_header (mgr, header);
5053 g_object_unref (parts);
5057 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5058 ModestMainWindow *win)
5060 GtkWidget *header_view;
5061 TnyList *header_list;
5063 TnyHeaderFlags flags;
5064 ModestWindow *msg_view_window = NULL;
5067 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5069 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5070 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5072 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5074 g_warning ("%s: no header selected", __FUNCTION__);
5078 if (tny_list_get_length (header_list) == 1) {
5079 TnyIterator *iter = tny_list_create_iterator (header_list);
5080 header = TNY_HEADER (tny_iterator_get_current (iter));
5081 g_object_unref (iter);
5085 if (!header || !TNY_IS_HEADER(header)) {
5086 g_warning ("%s: header is not valid", __FUNCTION__);
5090 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5091 header, &msg_view_window);
5092 flags = tny_header_get_flags (header);
5093 if (!(flags & TNY_HEADER_FLAG_CACHED))
5096 if (msg_view_window != NULL)
5097 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5099 /* do nothing; uid was registered before, so window is probably on it's way */
5100 g_warning ("debug: header %p has already been registered", header);
5103 ModestMailOperation *mail_op = NULL;
5104 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5105 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5106 modest_ui_actions_disk_operations_error_handler,
5108 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5109 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5111 g_object_unref (mail_op);
5114 g_object_unref (header);
5116 g_object_unref (header_list);
5120 * Checks if we need a connection to do the transfer and if the user
5121 * wants to connect to complete it
5124 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5125 TnyFolderStore *src_folder,
5127 TnyFolder *dst_folder,
5128 gboolean delete_originals,
5129 gboolean *need_connection,
5132 TnyAccount *src_account;
5133 gint uncached_msgs = 0;
5135 uncached_msgs = header_list_count_uncached_msgs (headers);
5137 /* We don't need any further check if
5139 * 1- the source folder is local OR
5140 * 2- the device is already online
5142 if (!modest_tny_folder_store_is_remote (src_folder) ||
5143 tny_device_is_online (modest_runtime_get_device())) {
5144 *need_connection = FALSE;
5149 /* We must ask for a connection when
5151 * - the message(s) is not already cached OR
5152 * - the message(s) is cached but the leave_on_server setting
5153 * is FALSE (because we need to sync the source folder to
5154 * delete the message from the server (for IMAP we could do it
5155 * offline, it'll take place the next time we get a
5158 src_account = get_account_from_folder_store (src_folder);
5159 if (uncached_msgs > 0) {
5163 *need_connection = TRUE;
5164 num_headers = tny_list_get_length (headers);
5165 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5167 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5168 GTK_RESPONSE_CANCEL) {
5174 /* The transfer is possible and the user wants to */
5177 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5178 const gchar *account_name;
5179 gboolean leave_on_server;
5181 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5182 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5185 if (leave_on_server == TRUE) {
5186 *need_connection = FALSE;
5188 *need_connection = TRUE;
5191 *need_connection = FALSE;
5196 g_object_unref (src_account);
5200 xfer_messages_error_handler (ModestMailOperation *mail_op,
5203 ModestWindow *main_window = NULL;
5205 /* Disable next automatic folder selection */
5206 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5207 FALSE); /* don't create */
5209 GObject *win = modest_mail_operation_get_source (mail_op);
5210 modest_platform_run_information_dialog ((GtkWindow *) win,
5211 _("mail_in_ui_folder_move_target_error"),
5214 g_object_unref (win);
5216 move_to_helper_destroyer (user_data);
5220 TnyFolderStore *dst_folder;
5225 * Utility function that transfer messages from both the main window
5226 * and the msg view window when using the "Move to" dialog
5229 xfer_messages_performer (gboolean canceled,
5231 GtkWindow *parent_window,
5232 TnyAccount *account,
5235 ModestWindow *win = MODEST_WINDOW (parent_window);
5236 TnyAccount *dst_account = NULL;
5237 gboolean dst_forbids_message_add = FALSE;
5238 XferMsgsHelper *helper;
5239 MoveToHelper *movehelper;
5240 ModestMailOperation *mail_op;
5242 helper = (XferMsgsHelper *) user_data;
5244 if (canceled || err) {
5245 if (!check_memory_full_error ((GtkWidget *) parent_window, err)) {
5246 /* Show the proper error message */
5247 modest_ui_actions_on_account_connection_error (parent_window, account);
5252 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5254 /* tinymail will return NULL for local folders it seems */
5255 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5256 modest_tny_account_get_protocol_type (dst_account),
5257 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_MESSAGE_ADD);
5258 g_object_unref (dst_account);
5260 if (dst_forbids_message_add) {
5261 modest_platform_information_banner (GTK_WIDGET (win),
5263 ngettext("mail_in_ui_folder_move_target_error",
5264 "mail_in_ui_folder_move_targets_error",
5265 tny_list_get_length (helper->headers)));
5269 movehelper = g_new0 (MoveToHelper, 1);
5270 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5271 _CS("ckct_nw_pasting"));
5272 if (movehelper->banner != NULL) {
5273 g_object_ref (movehelper->banner);
5274 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5277 if (MODEST_IS_MAIN_WINDOW (win)) {
5278 GtkWidget *header_view =
5279 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5280 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5281 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5284 /* Perform the mail operation */
5285 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5286 xfer_messages_error_handler,
5288 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5291 modest_mail_operation_xfer_msgs (mail_op,
5293 TNY_FOLDER (helper->dst_folder),
5298 g_object_unref (G_OBJECT (mail_op));
5300 g_object_unref (helper->dst_folder);
5301 g_object_unref (helper->headers);
5302 g_slice_free (XferMsgsHelper, helper);
5306 TnyFolder *src_folder;
5307 TnyFolderStore *dst_folder;
5308 gboolean delete_original;
5309 GtkWidget *folder_view;
5313 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
5314 TnyAccount *account, gpointer user_data)
5316 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5317 GtkTreeSelection *sel;
5318 ModestMailOperation *mail_op = NULL;
5320 if (canceled || err || !MODEST_IS_MAIN_WINDOW (parent_window)) {
5321 g_object_unref (G_OBJECT (info->src_folder));
5322 g_object_unref (G_OBJECT (info->dst_folder));
5327 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5328 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5329 _CS("ckct_nw_pasting"));
5330 if (helper->banner != NULL) {
5331 g_object_ref (helper->banner);
5332 gtk_widget_show (GTK_WIDGET(helper->banner));
5334 /* Clean folder on header view before moving it */
5335 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5336 gtk_tree_selection_unselect_all (sel);
5338 /* Let gtk events run. We need that the folder
5339 view frees its reference to the source
5340 folder *before* issuing the mail operation
5341 so we need the signal handler of selection
5342 changed to happen before the mail
5344 while (gtk_events_pending ())
5345 gtk_main_iteration (); */
5348 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5349 modest_ui_actions_move_folder_error_handler,
5350 info->src_folder, NULL);
5351 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5354 /* Select *after* the changes */
5355 /* TODO: this function hangs UI after transfer */
5356 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
5357 /* TNY_FOLDER (src_folder), TRUE); */
5359 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5360 TNY_FOLDER (info->dst_folder), TRUE);
5361 modest_mail_operation_xfer_folder (mail_op,
5362 TNY_FOLDER (info->src_folder),
5364 info->delete_original,
5367 g_object_unref (G_OBJECT (info->src_folder));
5369 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5372 /* Unref mail operation */
5373 g_object_unref (G_OBJECT (mail_op));
5374 g_object_unref (G_OBJECT (info->dst_folder));
5379 get_account_from_folder_store (TnyFolderStore *folder_store)
5381 if (TNY_IS_ACCOUNT (folder_store))
5382 return g_object_ref (folder_store);
5384 return tny_folder_get_account (TNY_FOLDER (folder_store));
5388 * UI handler for the "Move to" action when invoked from the
5392 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5393 GtkWidget *folder_view,
5394 TnyFolderStore *dst_folder,
5395 ModestMainWindow *win)
5397 ModestHeaderView *header_view = NULL;
5398 TnyFolderStore *src_folder = NULL;
5400 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5402 /* Get the source folder */
5403 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5405 /* Get header view */
5406 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
5408 /* Get folder or messages to transfer */
5409 if (gtk_widget_is_focus (folder_view)) {
5410 gboolean do_xfer = TRUE;
5412 /* Allow only to transfer folders to the local root folder */
5413 if (TNY_IS_ACCOUNT (dst_folder) &&
5414 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5415 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5417 } else if (!TNY_IS_FOLDER (src_folder)) {
5418 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5423 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5424 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5426 info->src_folder = g_object_ref (src_folder);
5427 info->dst_folder = g_object_ref (dst_folder);
5428 info->delete_original = TRUE;
5429 info->folder_view = folder_view;
5431 connect_info->callback = on_move_folder_cb;
5432 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5433 connect_info->data = info;
5435 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5436 TNY_FOLDER_STORE (src_folder),
5439 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5442 headers = modest_header_view_get_selected_headers(header_view);
5444 /* Transfer the messages */
5445 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
5446 headers, TNY_FOLDER (dst_folder));
5448 g_object_unref (headers);
5452 g_object_unref (src_folder);
5457 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
5458 TnyFolder *src_folder,
5460 TnyFolder *dst_folder)
5462 gboolean need_connection = TRUE;
5463 gboolean do_xfer = TRUE;
5464 XferMsgsHelper *helper;
5466 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5467 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5468 g_return_if_fail (TNY_IS_LIST (headers));
5470 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5471 headers, TNY_FOLDER (dst_folder),
5472 TRUE, &need_connection,
5475 /* If we don't want to transfer just return */
5479 /* Create the helper */
5480 helper = g_slice_new (XferMsgsHelper);
5481 helper->dst_folder = g_object_ref (dst_folder);
5482 helper->headers = g_object_ref (headers);
5484 if (need_connection) {
5485 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5486 connect_info->callback = xfer_messages_performer;
5487 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5488 connect_info->data = helper;
5490 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5491 TNY_FOLDER_STORE (src_folder),
5494 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5495 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
5496 src_account, helper);
5497 g_object_unref (src_account);
5502 * UI handler for the "Move to" action when invoked from the
5503 * ModestMsgViewWindow
5506 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
5507 TnyFolderStore *dst_folder,
5508 ModestMsgViewWindow *win)
5510 TnyList *headers = NULL;
5511 TnyHeader *header = NULL;
5512 TnyFolder *src_folder = NULL;
5514 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5516 /* Create header list */
5517 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
5518 src_folder = TNY_FOLDER (tny_header_get_folder(header));
5519 headers = tny_simple_list_new ();
5520 tny_list_append (headers, G_OBJECT (header));
5522 /* Transfer the messages */
5523 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder, headers,
5524 TNY_FOLDER (dst_folder));
5527 g_object_unref (src_folder);
5528 g_object_unref (header);
5529 g_object_unref (headers);
5533 modest_ui_actions_on_move_to (GtkAction *action,
5536 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
5538 TnyFolderStore *dst_folder = NULL;
5539 ModestMainWindow *main_window;
5541 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
5542 MODEST_IS_MSG_VIEW_WINDOW (win));
5544 /* Get the main window if exists */
5545 if (MODEST_IS_MAIN_WINDOW (win))
5546 main_window = MODEST_MAIN_WINDOW (win);
5549 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5550 FALSE)); /* don't create */
5552 /* Get the folder view widget if exists */
5554 folder_view = modest_main_window_get_child_widget (main_window,
5555 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5559 /* Create and run the dialog */
5560 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
5561 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5562 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog), (GtkWindow *) win);
5563 result = gtk_dialog_run (GTK_DIALOG(dialog));
5564 g_object_ref (tree_view);
5565 gtk_widget_destroy (dialog);
5567 if (result != GTK_RESPONSE_ACCEPT)
5570 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
5571 /* Do window specific stuff */
5572 if (MODEST_IS_MAIN_WINDOW (win)) {
5573 modest_ui_actions_on_main_window_move_to (action,
5576 MODEST_MAIN_WINDOW (win));
5578 modest_ui_actions_on_msg_view_window_move_to (action,
5580 MODEST_MSG_VIEW_WINDOW (win));
5584 g_object_unref (dst_folder);
5588 * Calls #HeadersFunc for each header already selected in the main
5589 * window or the message currently being shown in the msg view window
5592 do_headers_action (ModestWindow *win,
5596 TnyList *headers_list = NULL;
5597 TnyIterator *iter = NULL;
5598 TnyHeader *header = NULL;
5599 TnyFolder *folder = NULL;
5602 headers_list = get_selected_headers (win);
5606 /* Get the folder */
5607 iter = tny_list_create_iterator (headers_list);
5608 header = TNY_HEADER (tny_iterator_get_current (iter));
5610 folder = tny_header_get_folder (header);
5611 g_object_unref (header);
5614 /* Call the function for each header */
5615 while (!tny_iterator_is_done (iter)) {
5616 header = TNY_HEADER (tny_iterator_get_current (iter));
5617 func (header, win, user_data);
5618 g_object_unref (header);
5619 tny_iterator_next (iter);
5622 /* Trick: do a poke status in order to speed up the signaling
5624 tny_folder_poke_status (folder);
5627 g_object_unref (folder);
5628 g_object_unref (iter);
5629 g_object_unref (headers_list);
5633 modest_ui_actions_view_attachment (GtkAction *action,
5634 ModestWindow *window)
5636 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5637 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5639 /* not supported window for this action */
5640 g_return_if_reached ();
5645 modest_ui_actions_save_attachments (GtkAction *action,
5646 ModestWindow *window)
5648 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5650 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5653 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5655 /* not supported window for this action */
5656 g_return_if_reached ();
5661 modest_ui_actions_remove_attachments (GtkAction *action,
5662 ModestWindow *window)
5664 if (MODEST_IS_MAIN_WINDOW (window)) {
5665 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
5666 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5667 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5669 /* not supported window for this action */
5670 g_return_if_reached ();
5675 modest_ui_actions_on_settings (GtkAction *action,
5680 dialog = modest_platform_get_global_settings_dialog ();
5681 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
5682 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5683 gtk_widget_show_all (dialog);
5685 gtk_dialog_run (GTK_DIALOG (dialog));
5687 gtk_widget_destroy (dialog);
5691 modest_ui_actions_on_help (GtkAction *action,
5694 /* Help app is not available at all in fremantle */
5695 #ifndef MODEST_TOOLKIT_HILDON2
5696 const gchar *help_id;
5698 g_return_if_fail (win && GTK_IS_WINDOW(win));
5700 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5703 modest_platform_show_help (GTK_WINDOW (win), help_id);
5708 modest_ui_actions_on_csm_help (GtkAction *action,
5711 /* Help app is not available at all in fremantle */
5712 #ifndef MODEST_TOOLKIT_HILDON2
5714 const gchar* help_id = NULL;
5715 GtkWidget *folder_view;
5716 TnyFolderStore *folder_store;
5718 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
5720 /* Get selected folder */
5721 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5722 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5723 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5725 /* Switch help_id */
5726 if (folder_store && TNY_IS_FOLDER (folder_store))
5727 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
5730 g_object_unref (folder_store);
5733 modest_platform_show_help (GTK_WINDOW (win), help_id);
5735 modest_ui_actions_on_help (action, win);
5740 retrieve_contents_cb (ModestMailOperation *mail_op,
5747 /* We only need this callback to show an error in case of
5748 memory low condition */
5749 modest_ui_actions_msg_retrieval_check (mail_op, header, msg);
5753 retrieve_msg_contents_performer (gboolean canceled,
5755 GtkWindow *parent_window,
5756 TnyAccount *account,
5759 ModestMailOperation *mail_op;
5760 TnyList *headers = TNY_LIST (user_data);
5762 if (err || canceled) {
5763 check_memory_full_error ((GtkWidget *) parent_window, err);
5767 /* Create mail operation */
5768 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5769 modest_ui_actions_disk_operations_error_handler,
5771 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5772 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
5775 g_object_unref (mail_op);
5777 g_object_unref (headers);
5778 g_object_unref (account);
5782 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5783 ModestWindow *window)
5785 TnyList *headers = NULL;
5786 TnyAccount *account = NULL;
5787 TnyIterator *iter = NULL;
5788 TnyHeader *header = NULL;
5789 TnyFolder *folder = NULL;
5792 headers = get_selected_headers (window);
5796 /* Pick the account */
5797 iter = tny_list_create_iterator (headers);
5798 header = TNY_HEADER (tny_iterator_get_current (iter));
5799 folder = tny_header_get_folder (header);
5800 account = tny_folder_get_account (folder);
5801 g_object_unref (folder);
5802 g_object_unref (header);
5803 g_object_unref (iter);
5805 /* Connect and perform the message retrieval */
5806 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
5807 g_object_ref (account),
5808 retrieve_msg_contents_performer,
5809 g_object_ref (headers));
5812 g_object_unref (account);
5813 g_object_unref (headers);
5817 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
5819 g_return_if_fail (MODEST_IS_WINDOW (window));
5822 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
5826 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
5828 g_return_if_fail (MODEST_IS_WINDOW (window));
5831 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
5835 modest_ui_actions_on_email_menu_activated (GtkAction *action,
5836 ModestWindow *window)
5838 g_return_if_fail (MODEST_IS_WINDOW (window));
5841 modest_ui_actions_check_menu_dimming_rules (window);
5845 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
5846 ModestWindow *window)
5848 g_return_if_fail (MODEST_IS_WINDOW (window));
5851 modest_ui_actions_check_menu_dimming_rules (window);
5855 modest_ui_actions_on_view_menu_activated (GtkAction *action,
5856 ModestWindow *window)
5858 g_return_if_fail (MODEST_IS_WINDOW (window));
5861 modest_ui_actions_check_menu_dimming_rules (window);
5865 modest_ui_actions_on_format_menu_activated (GtkAction *action,
5866 ModestWindow *window)
5868 g_return_if_fail (MODEST_IS_WINDOW (window));
5871 modest_ui_actions_check_menu_dimming_rules (window);
5875 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
5876 ModestWindow *window)
5878 g_return_if_fail (MODEST_IS_WINDOW (window));
5881 modest_ui_actions_check_menu_dimming_rules (window);
5885 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
5886 ModestWindow *window)
5888 g_return_if_fail (MODEST_IS_WINDOW (window));
5891 modest_ui_actions_check_menu_dimming_rules (window);
5895 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
5896 ModestWindow *window)
5898 g_return_if_fail (MODEST_IS_WINDOW (window));
5901 modest_ui_actions_check_menu_dimming_rules (window);
5905 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
5906 ModestWindow *window)
5908 g_return_if_fail (MODEST_IS_WINDOW (window));
5911 modest_ui_actions_check_menu_dimming_rules (window);
5915 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
5916 ModestWindow *window)
5918 g_return_if_fail (MODEST_IS_WINDOW (window));
5921 modest_ui_actions_check_menu_dimming_rules (window);
5925 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
5927 g_return_if_fail (MODEST_IS_WINDOW (window));
5929 /* we check for low-mem; in that case, show a warning, and don't allow
5932 if (modest_platform_check_memory_low (window, TRUE))
5935 modest_platform_show_search_messages (GTK_WINDOW (window));
5939 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
5941 g_return_if_fail (MODEST_IS_WINDOW (win));
5944 /* we check for low-mem; in that case, show a warning, and don't allow
5945 * for the addressbook
5947 if (modest_platform_check_memory_low (win, TRUE))
5951 modest_platform_show_addressbook (GTK_WINDOW (win));
5956 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
5957 ModestWindow *window)
5959 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5961 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
5965 on_send_receive_finished (ModestMailOperation *mail_op,
5968 GtkWidget *header_view, *folder_view;
5969 TnyFolderStore *folder_store;
5970 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
5972 /* Set send/receive operation finished */
5973 modest_main_window_notify_send_receive_completed (main_win);
5975 /* Don't refresh the current folder if there were any errors */
5976 if (modest_mail_operation_get_status (mail_op) !=
5977 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5980 /* Refresh the current folder if we're viewing a window. We do
5981 this because the user won't be able to see the new mails in
5982 the selected folder after a Send&Receive because it only
5983 performs a poke_status, i.e, only the number of read/unread
5984 messages is updated, but the new headers are not
5986 folder_view = modest_main_window_get_child_widget (main_win,
5987 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5991 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5993 /* Do not need to refresh INBOX again because the
5994 update_account does it always automatically */
5995 if (folder_store && TNY_IS_FOLDER (folder_store) &&
5996 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
5997 ModestMailOperation *refresh_op;
5999 header_view = modest_main_window_get_child_widget (main_win,
6000 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6002 /* We do not need to set the contents style
6003 because it hasn't changed. We also do not
6004 need to save the widget status. Just force
6006 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6007 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6008 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6009 folder_refreshed_cb, main_win);
6010 g_object_unref (refresh_op);
6014 g_object_unref (folder_store);
6019 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6025 const gchar* server_name = NULL;
6026 TnyTransportAccount *server_account;
6027 gchar *message = NULL;
6029 /* Don't show anything if the user cancelled something or the
6030 * send receive request is not interactive. Authentication
6031 * errors are managed by the account store so no need to show
6032 * a dialog here again */
6033 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6034 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6035 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6039 /* Get the server name: */
6041 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
6043 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
6045 g_return_if_reached ();
6047 /* Show the appropriate message text for the GError: */
6048 switch (err->code) {
6049 case TNY_SERVICE_ERROR_CONNECT:
6050 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6052 case TNY_SERVICE_ERROR_SEND:
6053 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
6055 case TNY_SERVICE_ERROR_UNAVAILABLE:
6056 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6059 g_warning ("%s: unexpected ERROR %d",
6060 __FUNCTION__, err->code);
6061 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
6065 modest_platform_run_information_dialog (NULL, message, FALSE);
6067 g_object_unref (server_account);
6071 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6076 ModestMainWindow *main_window = NULL;
6077 ModestWindowMgr *mgr = NULL;
6078 GtkWidget *folder_view = NULL, *header_view = NULL;
6079 TnyFolderStore *selected_folder = NULL;
6080 TnyFolderType folder_type;
6082 mgr = modest_runtime_get_window_mgr ();
6083 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr,
6084 FALSE));/* don't create */
6088 /* Check if selected folder is OUTBOX */
6089 folder_view = modest_main_window_get_child_widget (main_window,
6090 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6091 header_view = modest_main_window_get_child_widget (main_window,
6092 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6094 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6095 if (!TNY_IS_FOLDER (selected_folder))
6098 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6099 #if GTK_CHECK_VERSION(2, 8, 0)
6100 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
6101 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6102 GtkTreeViewColumn *tree_column;
6104 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6105 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6107 gtk_tree_view_column_queue_resize (tree_column);
6110 gtk_widget_queue_draw (header_view);
6113 /* Rerun dimming rules, because the message could become deletable for example */
6114 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6115 MODEST_DIMMING_RULES_TOOLBAR);
6116 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6117 MODEST_DIMMING_RULES_MENU);
6121 if (selected_folder != NULL)
6122 g_object_unref (selected_folder);
6126 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6127 TnyAccount *account)
6129 ModestProtocolType protocol_type;
6130 ModestProtocol *protocol;
6131 gchar *error_note = NULL;
6133 protocol_type = modest_tny_account_get_protocol_type (account);
6134 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6137 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6138 if (error_note == NULL) {
6139 g_warning ("%s: This should not be reached", __FUNCTION__);
6141 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6142 g_free (error_note);
6147 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6151 TnyFolderStore *folder = NULL;
6152 TnyAccount *account = NULL;
6153 ModestProtocolType proto;
6154 ModestProtocol *protocol;
6155 TnyHeader *header = NULL;
6157 if (MODEST_IS_MAIN_WINDOW (win)) {
6158 GtkWidget *header_view;
6159 TnyList* headers = NULL;
6161 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6162 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6163 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6164 if (!headers || tny_list_get_length (headers) == 0) {
6166 g_object_unref (headers);
6169 iter = tny_list_create_iterator (headers);
6170 header = TNY_HEADER (tny_iterator_get_current (iter));
6171 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6172 g_object_unref (iter);
6173 g_object_unref (headers);
6174 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6175 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6176 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6179 /* Get the account type */
6180 account = tny_folder_get_account (TNY_FOLDER (folder));
6181 proto = modest_tny_account_get_protocol_type (account);
6182 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6185 subject = tny_header_dup_subject (header);
6186 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6190 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6194 g_object_unref (account);
6195 g_object_unref (folder);
6196 g_object_unref (header);
6202 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6203 const gchar *account_name,
6204 const gchar *account_title)
6206 ModestAccountMgr *account_mgr;
6209 ModestProtocol *protocol;
6210 gboolean removed = FALSE;
6212 g_return_val_if_fail (account_name, FALSE);
6213 g_return_val_if_fail (account_title, FALSE);
6215 account_mgr = modest_runtime_get_account_mgr();
6217 /* The warning text depends on the account type: */
6218 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6219 modest_account_mgr_get_store_protocol (account_mgr,
6221 txt = modest_protocol_get_translation (protocol,
6222 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6225 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6227 response = modest_platform_run_confirmation_dialog (parent_window, txt);
6231 if (response == GTK_RESPONSE_OK) {
6232 /* Remove account. If it succeeds then it also removes
6233 the account from the ModestAccountView: */
6234 gboolean is_default = FALSE;
6235 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6236 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6238 g_free (default_account_name);
6240 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6242 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);