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_add_to_contacts (GtkAction *action, ModestWindow *win)
638 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
640 modest_msg_view_window_add_to_contacts (MODEST_MSG_VIEW_WINDOW (win));
644 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
646 GtkClipboard *clipboard = NULL;
647 gchar *selection = NULL;
649 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
650 selection = gtk_clipboard_wait_for_text (clipboard);
652 /* Question: why is the clipboard being used here?
653 * It doesn't really make a lot of sense. */
657 modest_address_book_add_address (selection);
663 modest_ui_actions_on_accounts (GtkAction *action,
666 /* This is currently only implemented for Maemo */
667 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
668 if (!modest_ui_actions_run_account_setup_wizard (win))
669 g_debug ("%s: wizard was already running", __FUNCTION__);
673 /* Show the list of accounts */
674 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
676 /* The accounts dialog must be modal */
677 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
678 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
683 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
685 /* This is currently only implemented for Maemo,
686 * because it requires an API (libconic) to detect different connection
689 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
691 /* Create the window if necessary: */
692 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
693 modest_connection_specific_smtp_window_fill_with_connections (
694 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
695 modest_runtime_get_account_mgr());
697 /* Show the window: */
698 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
699 GTK_WINDOW (specific_window), (GtkWindow *) win);
700 gtk_widget_show (specific_window);
701 #endif /* !MODEST_TOOLKIT_GTK */
705 modest_ui_actions_compose_msg(ModestWindow *win,
708 const gchar *bcc_str,
709 const gchar *subject_str,
710 const gchar *body_str,
712 gboolean set_as_modified)
714 gchar *account_name = NULL;
716 TnyAccount *account = NULL;
717 TnyFolder *folder = NULL;
718 gchar *from_str = NULL, *signature = NULL, *body = NULL;
719 gboolean use_signature = FALSE;
720 ModestWindow *msg_win = NULL;
721 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
722 ModestTnyAccountStore *store = modest_runtime_get_account_store();
723 GnomeVFSFileSize total_size, allowed_size;
725 /* we check for low-mem */
726 if (modest_platform_check_memory_low (win, TRUE))
729 #ifdef MODEST_TOOLKIT_HILDON2
730 account_name = g_strdup (modest_window_get_active_account(win));
733 account_name = modest_account_mgr_get_default_account(mgr);
736 g_printerr ("modest: no account found\n");
739 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
741 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
744 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
746 g_printerr ("modest: failed to find Drafts folder\n");
749 from_str = modest_account_mgr_get_from_string (mgr, account_name);
751 g_printerr ("modest: failed get from string for '%s'\n", account_name);
755 signature = modest_account_mgr_get_signature (mgr, account_name, &use_signature);
756 if (body_str != NULL) {
757 body = use_signature ? g_strconcat(body_str, "\n--\n", signature, NULL) : g_strdup(body_str);
759 body = use_signature ? g_strconcat("\n--\n", signature, NULL) : g_strdup("");
762 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, body, NULL, NULL, NULL);
764 g_printerr ("modest: failed to create new msg\n");
768 /* Create and register edit window */
769 /* This is destroyed by TODO. */
771 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
772 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
774 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, NULL)) {
775 gtk_widget_destroy (GTK_WIDGET (msg_win));
778 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
779 gtk_widget_show_all (GTK_WIDGET (msg_win));
781 while (attachments) {
783 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
784 attachments->data, allowed_size);
786 if (total_size > allowed_size) {
787 g_warning ("%s: total size: %u",
788 __FUNCTION__, (unsigned int)total_size);
791 allowed_size -= total_size;
793 attachments = g_slist_next(attachments);
800 g_free (account_name);
802 g_object_unref (G_OBJECT(account));
804 g_object_unref (G_OBJECT(folder));
806 g_object_unref (G_OBJECT(msg));
810 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
812 /* if there are no accounts yet, just show the wizard */
813 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
814 if (!modest_ui_actions_run_account_setup_wizard (win))
817 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
822 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
826 ModestMailOperationStatus status;
828 /* If there is no message or the operation was not successful */
829 status = modest_mail_operation_get_status (mail_op);
830 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
833 /* If it's a memory low issue, then show a banner */
834 error = modest_mail_operation_get_error (mail_op);
835 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
836 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
837 GObject *source = modest_mail_operation_get_source (mail_op);
838 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
839 dgettext("ke-recv","memr_ib_operation_disabled"),
841 g_object_unref (source);
844 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
845 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
846 gchar *subject, *msg;
847 subject = tny_header_dup_subject (header);
849 subject = g_strdup (_("mail_va_no_subject"));;
850 msg = g_strdup_printf (_("emev_ni_ui_imap_message_not_available_in_server"),
852 modest_platform_run_information_dialog (NULL, msg, FALSE);
857 /* Remove the header from the preregistered uids */
858 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
876 OpenMsgBannerInfo *banner_info;
877 GHashTable *row_refs_per_header;
881 open_msg_banner_idle (gpointer userdata)
883 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
885 gdk_threads_enter ();
886 banner_info->idle_handler = 0;
887 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
889 g_object_ref (banner_info->banner);
891 gdk_threads_leave ();
898 open_msg_cb (ModestMailOperation *mail_op,
905 ModestWindowMgr *mgr = NULL;
906 ModestWindow *parent_win = NULL;
907 ModestWindow *win = NULL;
908 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
909 gchar *account = NULL;
911 gboolean open_in_editor = FALSE;
912 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
914 /* Do nothing if there was any problem with the mail
915 operation. The error will be shown by the error_handler of
916 the mail operation */
917 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
920 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
921 folder = tny_header_get_folder (header);
923 /* Mark header as read */
924 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
926 /* Gets folder type (OUTBOX headers will be opened in edit window */
927 if (modest_tny_folder_is_local_folder (folder)) {
928 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
929 if (folder_type == TNY_FOLDER_TYPE_INVALID)
930 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
934 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
935 TnyTransportAccount *traccount = NULL;
936 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
937 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
939 ModestTnySendQueue *send_queue = NULL;
940 ModestTnySendQueueStatus status;
942 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
943 TNY_ACCOUNT(traccount)));
944 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
945 if (TNY_IS_SEND_QUEUE (send_queue)) {
946 msg_id = modest_tny_send_queue_get_msg_id (header);
947 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
950 /* Only open messages in outbox with the editor if they are in Failed state */
951 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
952 open_in_editor = TRUE;
954 #ifdef MODEST_TOOLKIT_HILDON2
956 /* In Fremantle we can not
957 open any message from
958 outbox which is not in
960 g_object_unref(traccount);
965 g_object_unref(traccount);
967 g_warning("Cannot get transport account for message in outbox!!");
969 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
970 open_in_editor = TRUE; /* Open in editor if the message is in the Drafts folder */
975 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
977 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
979 if (open_in_editor) {
980 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
981 gchar *from_header = NULL, *acc_name;
983 from_header = tny_header_dup_from (header);
985 /* we cannot edit without a valid account... */
986 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
987 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
988 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
990 g_free (from_header);
995 acc_name = modest_utils_get_account_name_from_recipient (from_header);
996 g_free (from_header);
1002 win = modest_msg_edit_window_new (msg, account, TRUE);
1004 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1006 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1007 GtkTreeRowReference *row_reference;
1009 row_reference = (GtkTreeRowReference *) g_hash_table_lookup (helper->row_refs_per_header, header);
1011 win = modest_msg_view_window_new_with_header_model (msg, account, (const gchar*) uid,
1012 helper->model, row_reference);
1014 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
1019 /* Register and show new window */
1021 mgr = modest_runtime_get_window_mgr ();
1022 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1023 gtk_widget_destroy (GTK_WIDGET (win));
1026 gtk_widget_show_all (GTK_WIDGET(win));
1029 /* Update toolbar dimming state */
1030 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1031 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1037 g_object_unref (parent_win);
1038 g_object_unref (folder);
1042 is_memory_full_error (GError *error)
1044 gboolean enough_free_space = TRUE;
1045 GnomeVFSURI *cache_dir_uri;
1046 const gchar *cache_dir;
1047 GnomeVFSFileSize free_space;
1049 cache_dir = tny_account_store_get_cache_dir (TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
1050 cache_dir_uri = gnome_vfs_uri_new (cache_dir);
1051 if (gnome_vfs_get_volume_free_space (cache_dir_uri, &free_space) == GNOME_VFS_OK) {
1052 if (free_space < MIN_FREE_SPACE)
1053 enough_free_space = FALSE;
1055 gnome_vfs_uri_unref (cache_dir_uri);
1057 if ((error->code == TNY_SYSTEM_ERROR_MEMORY ||
1058 /* When asking for a mail and no space left on device
1059 tinymail returns this error */
1060 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE ||
1061 /* When the folder summary could not be read or
1063 error->code == TNY_IO_ERROR_WRITE ||
1064 error->code == TNY_IO_ERROR_READ) &&
1065 !enough_free_space) {
1073 check_memory_full_error (GtkWidget *parent_window, GError *err)
1078 if (is_memory_full_error (err))
1079 modest_platform_information_banner (parent_window,
1080 NULL, dgettext("ke-recv",
1081 "cerm_device_memory_full"));
1082 else if (err->code == TNY_SYSTEM_ERROR_MEMORY)
1083 /* If the account was created in memory full
1084 conditions then tinymail won't be able to
1085 connect so it'll return this error code */
1086 modest_platform_information_banner (parent_window,
1087 NULL, _("emev_ui_imap_inbox_select_error"));
1095 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1098 const GError *error;
1099 GObject *win = NULL;
1100 ModestMailOperationStatus status;
1102 win = modest_mail_operation_get_source (mail_op);
1103 error = modest_mail_operation_get_error (mail_op);
1104 status = modest_mail_operation_get_status (mail_op);
1106 /* If the mail op has been cancelled then it's not an error:
1107 don't show any message */
1108 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1109 if (is_memory_full_error ((GError *) error)) {
1110 modest_platform_information_banner ((GtkWidget *) win,
1111 NULL, dgettext("ke-recv",
1112 "cerm_device_memory_full"));
1113 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1114 modest_platform_information_banner ((GtkWidget *) win,
1115 NULL, _("emev_ui_imap_inbox_select_error"));
1116 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1117 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1118 modest_platform_information_banner ((GtkWidget *) win,
1119 NULL, dgettext ("hildon-common-strings", "sfil_ni_unable_to_open_file_not_found"));
1120 } else if (user_data) {
1121 modest_platform_information_banner ((GtkWidget *) win,
1127 g_object_unref (win);
1131 * Returns the account a list of headers belongs to. It returns a
1132 * *new* reference so don't forget to unref it
1135 get_account_from_header_list (TnyList *headers)
1137 TnyAccount *account = NULL;
1139 if (tny_list_get_length (headers) > 0) {
1140 TnyIterator *iter = tny_list_create_iterator (headers);
1141 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1142 TnyFolder *folder = tny_header_get_folder (header);
1145 g_object_unref (header);
1147 while (!tny_iterator_is_done (iter)) {
1148 header = TNY_HEADER (tny_iterator_get_current (iter));
1149 folder = tny_header_get_folder (header);
1152 g_object_unref (header);
1154 tny_iterator_next (iter);
1159 account = tny_folder_get_account (folder);
1160 g_object_unref (folder);
1164 g_object_unref (header);
1166 g_object_unref (iter);
1172 foreach_unregister_headers (gpointer data,
1175 ModestWindowMgr *mgr = (ModestWindowMgr *) user_data;
1176 TnyHeader *header = TNY_HEADER (data);
1178 modest_window_mgr_unregister_header (mgr, header);
1182 open_msgs_helper_destroyer (gpointer user_data)
1184 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1186 if (helper->banner_info) {
1187 g_free (helper->banner_info->message);
1188 if (helper->banner_info->idle_handler > 0) {
1189 g_source_remove (helper->banner_info->idle_handler);
1190 helper->banner_info->idle_handler = 0;
1192 if (helper->banner_info->banner != NULL) {
1193 gtk_widget_destroy (helper->banner_info->banner);
1194 g_object_unref (helper->banner_info->banner);
1195 helper->banner_info->banner = NULL;
1197 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1198 helper->banner_info = NULL;
1200 g_object_unref (helper->model);
1201 g_object_unref (helper->headers);
1202 g_hash_table_destroy (helper->row_refs_per_header);
1203 g_slice_free (OpenMsgHelper, helper);
1207 open_msgs_performer(gboolean canceled,
1209 GtkWindow *parent_window,
1210 TnyAccount *account,
1213 ModestMailOperation *mail_op = NULL;
1215 ModestProtocolType proto;
1216 TnyList *not_opened_headers;
1217 TnyConnectionStatus status;
1218 gboolean show_open_draft = FALSE;
1219 OpenMsgHelper *helper = NULL;
1221 helper = (OpenMsgHelper *) user_data;
1222 not_opened_headers = helper->headers;
1224 status = tny_account_get_connection_status (account);
1225 if (err || canceled) {
1226 /* Unregister the already registered headers */
1227 tny_list_foreach (not_opened_headers, foreach_unregister_headers,
1228 modest_runtime_get_window_mgr ());
1229 /* Free the helper */
1230 open_msgs_helper_destroyer (helper);
1232 /* In memory full conditions we could get this error here */
1233 check_memory_full_error ((GtkWidget *) parent_window, err);
1238 /* Get the error message depending on the protocol */
1239 proto = modest_tny_account_get_protocol_type (account);
1240 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1241 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1244 /* Create the error messages */
1245 if (tny_list_get_length (not_opened_headers) == 1) {
1246 ModestProtocol *protocol;
1247 ModestProtocolRegistry *protocol_registry;
1252 protocol_registry = modest_runtime_get_protocol_registry ();
1253 iter = tny_list_create_iterator (not_opened_headers);
1254 header = TNY_HEADER (tny_iterator_get_current (iter));
1255 subject = tny_header_dup_subject (header);
1257 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1258 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1261 g_object_unref (header);
1262 g_object_unref (iter);
1264 if (error_msg == NULL) {
1265 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1268 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1270 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1274 TnyFolderType folder_type;
1276 iter = tny_list_create_iterator (not_opened_headers);
1277 header = TNY_HEADER (tny_iterator_get_current (iter));
1278 folder = tny_header_get_folder (header);
1279 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1280 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1281 g_object_unref (folder);
1282 g_object_unref (header);
1283 g_object_unref (iter);
1286 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1289 /* Create the mail operation */
1291 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1292 modest_ui_actions_disk_operations_error_handler,
1294 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1297 if (show_open_draft) {
1298 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1299 #ifdef MODEST_TOOLKIT_HILDON2
1300 helper->banner_info->message = g_strdup (_("mail_me_opening"));
1302 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1304 helper->banner_info->banner = NULL;
1305 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1306 helper->banner_info);
1309 modest_mail_operation_get_msgs_full (mail_op,
1313 open_msgs_helper_destroyer);
1318 g_object_unref (mail_op);
1319 g_object_unref (account);
1323 * This function is used by both modest_ui_actions_on_open and
1324 * modest_ui_actions_on_header_activated. This way we always do the
1325 * same when trying to open messages.
1328 open_msgs_from_headers (TnyList *headers, ModestWindow *win)
1330 ModestWindowMgr *mgr = NULL;
1331 TnyIterator *iter = NULL, *iter_not_opened = NULL;
1332 TnyList *not_opened_headers = NULL;
1333 TnyHeaderFlags flags = 0;
1334 TnyAccount *account;
1335 gint uncached_msgs = 0;
1336 GtkWidget *header_view;
1337 GtkTreeModel *model;
1338 GHashTable *refs_for_headers;
1339 OpenMsgHelper *helper;
1340 GtkTreeSelection *sel;
1341 GList *sel_list = NULL, *sel_list_iter = NULL;
1343 g_return_if_fail (headers != NULL);
1345 /* Check that only one message is selected for opening */
1346 if (tny_list_get_length (headers) != 1) {
1347 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1348 NULL, _("mcen_ib_select_one_message"));
1352 mgr = modest_runtime_get_window_mgr ();
1353 iter = tny_list_create_iterator (headers);
1355 /* Get the account */
1356 account = get_account_from_header_list (headers);
1361 /* Get the selections, we need to get the references to the
1362 rows here because the treeview/model could dissapear (the
1363 user might want to select another folder)*/
1364 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1365 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1366 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
1367 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
1368 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
1369 refs_for_headers = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
1370 (GDestroyNotify) gtk_tree_row_reference_free);
1372 /* Look if we already have a message view for each header. If
1373 true, then remove the header from the list of headers to
1375 sel_list_iter = sel_list;
1376 not_opened_headers = tny_simple_list_new ();
1377 while (!tny_iterator_is_done (iter) && sel_list_iter) {
1379 ModestWindow *window = NULL;
1380 TnyHeader *header = NULL;
1381 gboolean found = FALSE;
1383 header = TNY_HEADER (tny_iterator_get_current (iter));
1385 flags = tny_header_get_flags (header);
1388 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1390 /* Do not open again the message and present the
1391 window to the user */
1394 #ifndef MODEST_TOOLKIT_HILDON2
1395 gtk_window_present (GTK_WINDOW (window));
1398 /* the header has been registered already, we don't do
1399 * anything but wait for the window to come up*/
1400 g_debug ("header %p already registered, waiting for window", header);
1403 GtkTreeRowReference *row_reference;
1405 tny_list_append (not_opened_headers, G_OBJECT (header));
1406 /* Create a new row reference and add it to the hash table */
1407 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list_iter->data);
1408 g_hash_table_insert (refs_for_headers, header, row_reference);
1412 g_object_unref (header);
1415 tny_iterator_next (iter);
1416 sel_list_iter = g_list_next (sel_list_iter);
1418 g_object_unref (iter);
1420 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
1421 g_list_free (sel_list);
1423 /* Open each message */
1424 if (tny_list_get_length (not_opened_headers) == 0) {
1425 g_hash_table_destroy (refs_for_headers);
1429 /* If some messages would have to be downloaded, ask the user to
1430 * make a connection. It's generally easier to do this here (in the mainloop)
1431 * than later in a thread:
1433 if (tny_list_get_length (not_opened_headers) > 0) {
1434 uncached_msgs = header_list_count_uncached_msgs (not_opened_headers);
1436 if (uncached_msgs > 0) {
1437 /* Allways download if we are online. */
1438 if (!tny_device_is_online (modest_runtime_get_device ())) {
1441 /* If ask for user permission to download the messages */
1442 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1443 ngettext("mcen_nc_get_msg",
1447 /* End if the user does not want to continue */
1448 if (response == GTK_RESPONSE_CANCEL) {
1449 g_hash_table_destroy (refs_for_headers);
1456 /* Register the headers before actually creating the windows: */
1457 iter_not_opened = tny_list_create_iterator (not_opened_headers);
1458 while (!tny_iterator_is_done (iter_not_opened)) {
1459 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1461 modest_window_mgr_register_header (mgr, header, NULL);
1462 g_object_unref (header);
1464 tny_iterator_next (iter_not_opened);
1466 g_object_unref (iter_not_opened);
1467 iter_not_opened = NULL;
1469 /* Create the helper. We need to get a reference to the model
1470 here because it could change while the message is readed
1471 (the user could switch between folders) */
1472 helper = g_slice_new (OpenMsgHelper);
1473 helper->model = g_object_ref (model);
1474 helper->headers = g_object_ref (not_opened_headers);
1475 helper->row_refs_per_header = refs_for_headers;
1476 helper->banner_info = NULL;
1478 /* Connect to the account and perform */
1479 if (uncached_msgs > 0) {
1480 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1481 open_msgs_performer, helper);
1483 /* Call directly the performer, do not need to connect */
1484 open_msgs_performer (FALSE, NULL, (GtkWindow *) win,
1485 g_object_ref (account), helper);
1490 g_object_unref (account);
1491 if (not_opened_headers)
1492 g_object_unref (not_opened_headers);
1496 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1500 /* we check for low-mem; in that case, show a warning, and don't allow
1503 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1507 headers = get_selected_headers (win);
1512 open_msgs_from_headers (headers, win);
1514 g_object_unref(headers);
1517 static ReplyForwardHelper*
1518 create_reply_forward_helper (ReplyForwardAction action,
1520 guint reply_forward_type,
1523 ReplyForwardHelper *rf_helper = NULL;
1524 const gchar *active_acc = modest_window_get_active_account (win);
1526 rf_helper = g_slice_new0 (ReplyForwardHelper);
1527 rf_helper->reply_forward_type = reply_forward_type;
1528 rf_helper->action = action;
1529 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1530 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1531 rf_helper->account_name = (active_acc) ?
1532 g_strdup (active_acc) :
1533 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1539 free_reply_forward_helper (gpointer data)
1541 ReplyForwardHelper *helper;
1543 helper = (ReplyForwardHelper *) data;
1544 g_free (helper->account_name);
1546 g_object_unref (helper->header);
1547 g_slice_free (ReplyForwardHelper, helper);
1551 reply_forward_cb (ModestMailOperation *mail_op,
1558 TnyMsg *new_msg = NULL;
1559 ReplyForwardHelper *rf_helper;
1560 ModestWindow *msg_win = NULL;
1561 ModestEditType edit_type;
1563 TnyAccount *account = NULL;
1564 ModestWindowMgr *mgr = NULL;
1565 gchar *signature = NULL;
1566 gboolean use_signature;
1568 /* If there was any error. The mail operation could be NULL,
1569 this means that we already have the message downloaded and
1570 that we didn't do a mail operation to retrieve it */
1571 rf_helper = (ReplyForwardHelper *) user_data;
1572 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1575 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1576 rf_helper->account_name);
1577 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr(),
1578 rf_helper->account_name,
1581 /* Create reply mail */
1582 switch (rf_helper->action) {
1585 modest_tny_msg_create_reply_msg (msg, header, from,
1586 (use_signature) ? signature : NULL,
1587 rf_helper->reply_forward_type,
1588 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1590 case ACTION_REPLY_TO_ALL:
1592 modest_tny_msg_create_reply_msg (msg, header, from,
1593 (use_signature) ? signature : NULL,
1594 rf_helper->reply_forward_type,
1595 MODEST_TNY_MSG_REPLY_MODE_ALL);
1596 edit_type = MODEST_EDIT_TYPE_REPLY;
1598 case ACTION_FORWARD:
1600 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1601 rf_helper->reply_forward_type);
1602 edit_type = MODEST_EDIT_TYPE_FORWARD;
1605 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1607 g_return_if_reached ();
1615 g_warning ("%s: failed to create message\n", __FUNCTION__);
1619 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1620 rf_helper->account_name,
1621 TNY_ACCOUNT_TYPE_STORE);
1623 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1627 /* Create and register the windows */
1628 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1629 mgr = modest_runtime_get_window_mgr ();
1630 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1632 if (rf_helper->parent_window != NULL) {
1633 gdouble parent_zoom;
1635 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1636 modest_window_set_zoom (msg_win, parent_zoom);
1639 /* Show edit window */
1640 gtk_widget_show_all (GTK_WIDGET (msg_win));
1643 /* We always unregister the header because the message is
1644 forwarded or replied so the original one is no longer
1646 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1649 g_object_unref (G_OBJECT (new_msg));
1651 g_object_unref (G_OBJECT (account));
1652 free_reply_forward_helper (rf_helper);
1655 /* Checks a list of headers. If any of them are not currently
1656 * downloaded (CACHED) then returns TRUE else returns FALSE.
1659 header_list_count_uncached_msgs (TnyList *header_list)
1662 gint uncached_messages = 0;
1664 iter = tny_list_create_iterator (header_list);
1665 while (!tny_iterator_is_done (iter)) {
1668 header = TNY_HEADER (tny_iterator_get_current (iter));
1670 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1671 uncached_messages ++;
1672 g_object_unref (header);
1675 tny_iterator_next (iter);
1677 g_object_unref (iter);
1679 return uncached_messages;
1682 /* Returns FALSE if the user does not want to download the
1683 * messages. Returns TRUE if the user allowed the download.
1686 connect_to_get_msg (ModestWindow *win,
1687 gint num_of_uncached_msgs,
1688 TnyAccount *account)
1690 GtkResponseType response;
1692 /* Allways download if we are online. */
1693 if (tny_device_is_online (modest_runtime_get_device ()))
1696 /* If offline, then ask for user permission to download the messages */
1697 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1698 ngettext("mcen_nc_get_msg",
1700 num_of_uncached_msgs));
1702 if (response == GTK_RESPONSE_CANCEL)
1705 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1709 reply_forward_performer (gboolean canceled,
1711 GtkWindow *parent_window,
1712 TnyAccount *account,
1715 ReplyForwardHelper *rf_helper = NULL;
1716 ModestMailOperation *mail_op;
1718 rf_helper = (ReplyForwardHelper *) user_data;
1720 if (canceled || err) {
1721 free_reply_forward_helper (rf_helper);
1725 /* Retrieve the message */
1726 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1727 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1728 modest_ui_actions_disk_operations_error_handler,
1730 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1731 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1734 g_object_unref(mail_op);
1738 * Common code for the reply and forward actions
1741 reply_forward (ReplyForwardAction action, ModestWindow *win)
1743 ReplyForwardHelper *rf_helper = NULL;
1744 guint reply_forward_type;
1746 g_return_if_fail (MODEST_IS_WINDOW(win));
1748 /* we check for low-mem; in that case, show a warning, and don't allow
1749 * reply/forward (because it could potentially require a lot of memory */
1750 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1754 /* we need an account when editing */
1755 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1756 if (!modest_ui_actions_run_account_setup_wizard (win))
1760 reply_forward_type =
1761 modest_conf_get_int (modest_runtime_get_conf (),
1762 (action == ACTION_FORWARD) ?
1763 MODEST_CONF_FORWARD_TYPE :
1764 MODEST_CONF_REPLY_TYPE,
1767 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1769 TnyHeader *header = NULL;
1770 /* Get header and message. Do not free them here, the
1771 reply_forward_cb must do it */
1772 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1773 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1775 if (msg && header) {
1777 rf_helper = create_reply_forward_helper (action, win,
1778 reply_forward_type, header);
1779 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1781 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1785 g_object_unref (msg);
1787 g_object_unref (header);
1789 TnyHeader *header = NULL;
1791 gboolean do_retrieve = TRUE;
1792 TnyList *header_list = NULL;
1794 header_list = get_selected_headers (win);
1797 /* Check that only one message is selected for replying */
1798 if (tny_list_get_length (header_list) != 1) {
1799 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1800 NULL, _("mcen_ib_select_one_message"));
1801 g_object_unref (header_list);
1805 /* Only reply/forward to one message */
1806 iter = tny_list_create_iterator (header_list);
1807 header = TNY_HEADER (tny_iterator_get_current (iter));
1808 g_object_unref (iter);
1810 /* Retrieve messages */
1811 do_retrieve = (action == ACTION_FORWARD) ||
1812 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1815 TnyAccount *account = NULL;
1816 TnyFolder *folder = NULL;
1817 gdouble download = TRUE;
1818 guint uncached_msgs = 0;
1820 folder = tny_header_get_folder (header);
1822 goto do_retrieve_frees;
1823 account = tny_folder_get_account (folder);
1825 goto do_retrieve_frees;
1827 uncached_msgs = header_list_count_uncached_msgs (header_list);
1829 if (uncached_msgs > 0) {
1830 /* Allways download if we are online. */
1831 if (!tny_device_is_online (modest_runtime_get_device ())) {
1834 /* If ask for user permission to download the messages */
1835 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1836 ngettext("mcen_nc_get_msg",
1840 /* End if the user does not want to continue */
1841 if (response == GTK_RESPONSE_CANCEL)
1848 rf_helper = create_reply_forward_helper (action, win,
1849 reply_forward_type, header);
1850 if (uncached_msgs > 0) {
1851 modest_platform_connect_and_perform (GTK_WINDOW (win),
1853 reply_forward_performer,
1856 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
1857 account, rf_helper);
1862 g_object_unref (account);
1864 g_object_unref (folder);
1866 reply_forward_cb (NULL, header, FALSE, NULL, NULL, rf_helper);
1869 g_object_unref (header_list);
1870 g_object_unref (header);
1875 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1877 g_return_if_fail (MODEST_IS_WINDOW(win));
1879 reply_forward (ACTION_REPLY, win);
1883 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1885 g_return_if_fail (MODEST_IS_WINDOW(win));
1887 reply_forward (ACTION_FORWARD, win);
1891 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1893 g_return_if_fail (MODEST_IS_WINDOW(win));
1895 reply_forward (ACTION_REPLY_TO_ALL, win);
1899 modest_ui_actions_on_next (GtkAction *action,
1900 ModestWindow *window)
1902 if (MODEST_IS_MAIN_WINDOW (window)) {
1903 GtkWidget *header_view;
1905 header_view = modest_main_window_get_child_widget (
1906 MODEST_MAIN_WINDOW(window),
1907 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1911 modest_header_view_select_next (
1912 MODEST_HEADER_VIEW(header_view));
1913 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1914 modest_msg_view_window_select_next_message (
1915 MODEST_MSG_VIEW_WINDOW (window));
1917 g_return_if_reached ();
1922 modest_ui_actions_on_prev (GtkAction *action,
1923 ModestWindow *window)
1925 g_return_if_fail (MODEST_IS_WINDOW(window));
1927 if (MODEST_IS_MAIN_WINDOW (window)) {
1928 GtkWidget *header_view;
1929 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1930 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1934 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1935 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1936 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1938 g_return_if_reached ();
1943 modest_ui_actions_on_sort (GtkAction *action,
1944 ModestWindow *window)
1946 g_return_if_fail (MODEST_IS_WINDOW(window));
1948 if (MODEST_IS_MAIN_WINDOW (window)) {
1949 GtkWidget *header_view;
1950 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1951 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1953 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1958 /* Show sorting dialog */
1959 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1964 new_messages_arrived (ModestMailOperation *self,
1965 TnyList *new_headers,
1969 gboolean show_visual_notifications;
1971 source = modest_mail_operation_get_source (self);
1972 show_visual_notifications = (source) ? FALSE : TRUE;
1974 g_object_unref (source);
1976 /* Notify new messages have been downloaded. If the
1977 send&receive was invoked by the user then do not show any
1978 visual notification, only play a sound and activate the LED
1979 (for the Maemo version) */
1980 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0)
1981 modest_platform_on_new_headers_received (new_headers,
1982 show_visual_notifications);
1987 retrieve_all_messages_cb (GObject *source,
1989 guint retrieve_limit)
1995 window = GTK_WINDOW (source);
1996 msg = g_strdup_printf (_("mail_nc_msg_count_limit_exceeded"),
1997 num_msgs, retrieve_limit);
1999 /* Ask the user if they want to retrieve all the messages */
2001 modest_platform_run_confirmation_dialog_with_buttons (window, msg,
2002 _("mcen_bd_get_all"),
2003 _("mcen_bd_newest_only"));
2004 /* Free and return */
2006 return (response == GTK_RESPONSE_ACCEPT) ? TRUE : FALSE;
2010 TnyAccount *account;
2012 gchar *account_name;
2013 gboolean poke_status;
2014 gboolean interactive;
2015 ModestMailOperation *mail_op;
2019 do_send_receive_performer (gboolean canceled,
2021 GtkWindow *parent_window,
2022 TnyAccount *account,
2025 SendReceiveInfo *info;
2027 info = (SendReceiveInfo *) user_data;
2029 if (err || canceled) {
2030 /* In memory full conditions we could get this error here */
2031 check_memory_full_error ((GtkWidget *) parent_window, err);
2033 if (info->mail_op) {
2034 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2040 /* Set send/receive operation in progress */
2041 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2042 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2045 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2046 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2047 G_CALLBACK (on_send_receive_finished),
2050 /* Send & receive. */
2051 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2052 (info->win) ? retrieve_all_messages_cb : NULL,
2053 new_messages_arrived, info->win);
2058 g_object_unref (G_OBJECT (info->mail_op));
2059 if (info->account_name)
2060 g_free (info->account_name);
2062 g_object_unref (info->win);
2064 g_object_unref (info->account);
2065 g_slice_free (SendReceiveInfo, info);
2069 * This function performs the send & receive required actions. The
2070 * window is used to create the mail operation. Typically it should
2071 * always be the main window, but we pass it as argument in order to
2075 modest_ui_actions_do_send_receive (const gchar *account_name,
2076 gboolean force_connection,
2077 gboolean poke_status,
2078 gboolean interactive,
2081 gchar *acc_name = NULL;
2082 SendReceiveInfo *info;
2083 ModestTnyAccountStore *acc_store;
2085 /* If no account name was provided then get the current account, and if
2086 there is no current account then pick the default one: */
2087 if (!account_name) {
2089 acc_name = g_strdup (modest_window_get_active_account (win));
2091 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2093 g_printerr ("modest: cannot get default account\n");
2097 acc_name = g_strdup (account_name);
2100 acc_store = modest_runtime_get_account_store ();
2102 /* Create the info for the connect and perform */
2103 info = g_slice_new (SendReceiveInfo);
2104 info->account_name = acc_name;
2105 info->win = (win) ? g_object_ref (win) : NULL;
2106 info->poke_status = poke_status;
2107 info->interactive = interactive;
2108 info->account = modest_tny_account_store_get_server_account (acc_store, acc_name,
2109 TNY_ACCOUNT_TYPE_STORE);
2110 /* We need to create the operation here, because otherwise it
2111 could happen that the queue emits the queue-empty signal
2112 while we're trying to connect the account */
2113 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2114 modest_ui_actions_disk_operations_error_handler,
2116 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2118 /* Invoke the connect and perform */
2119 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2120 force_connection, info->account,
2121 do_send_receive_performer, info);
2126 modest_ui_actions_do_cancel_send (const gchar *account_name,
2129 TnyTransportAccount *transport_account;
2130 TnySendQueue *send_queue = NULL;
2131 GError *error = NULL;
2133 /* Get transport account */
2135 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2136 (modest_runtime_get_account_store(),
2138 TNY_ACCOUNT_TYPE_TRANSPORT));
2139 if (!transport_account) {
2140 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2145 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2146 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2147 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2148 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2149 "modest: could not find send queue for account\n");
2151 /* Cancel the current send */
2152 tny_account_cancel (TNY_ACCOUNT (transport_account));
2154 /* Suspend all pending messages */
2155 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2159 if (transport_account != NULL)
2160 g_object_unref (G_OBJECT (transport_account));
2164 modest_ui_actions_cancel_send_all (ModestWindow *win)
2166 GSList *account_names, *iter;
2168 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2171 iter = account_names;
2173 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2174 iter = g_slist_next (iter);
2177 modest_account_mgr_free_account_names (account_names);
2178 account_names = NULL;
2182 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2185 /* Check if accounts exist */
2186 gboolean accounts_exist =
2187 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2189 /* If not, allow the user to create an account before trying to send/receive. */
2190 if (!accounts_exist)
2191 modest_ui_actions_on_accounts (NULL, win);
2193 /* Cancel all sending operaitons */
2194 modest_ui_actions_cancel_send_all (win);
2198 * Refreshes all accounts. This function will be used by automatic
2202 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2203 gboolean force_connection,
2204 gboolean poke_status,
2205 gboolean interactive)
2207 GSList *account_names, *iter;
2209 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2212 iter = account_names;
2214 modest_ui_actions_do_send_receive ((const char*) iter->data,
2216 poke_status, interactive, win);
2217 iter = g_slist_next (iter);
2220 modest_account_mgr_free_account_names (account_names);
2221 account_names = NULL;
2225 * Handler of the click on Send&Receive button in the main toolbar
2228 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2230 /* Check if accounts exist */
2231 gboolean accounts_exist;
2234 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2236 /* If not, allow the user to create an account before trying to send/receive. */
2237 if (!accounts_exist)
2238 modest_ui_actions_on_accounts (NULL, win);
2240 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2241 if (MODEST_IS_MAIN_WINDOW (win)) {
2242 GtkWidget *folder_view;
2243 TnyFolderStore *folder_store;
2246 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2247 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2251 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2254 g_object_unref (folder_store);
2257 /* Refresh the active account. Force the connection if needed
2258 and poke the status of all folders */
2259 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2264 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2267 GtkWidget *header_view;
2269 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2271 header_view = modest_main_window_get_child_widget (main_window,
2272 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2276 conf = modest_runtime_get_conf ();
2278 /* what is saved/restored is depending on the style; thus; we save with
2279 * old style, then update the style, and restore for this new style
2281 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2283 if (modest_header_view_get_style
2284 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2285 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2286 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2288 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2289 MODEST_HEADER_VIEW_STYLE_DETAILS);
2291 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2292 MODEST_CONF_HEADER_VIEW_KEY);
2297 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2299 ModestMainWindow *main_window)
2301 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2302 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2304 /* in the case the folder is empty, show the empty folder message and focus
2306 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2307 if (modest_header_view_is_empty (header_view)) {
2308 TnyFolder *folder = modest_header_view_get_folder (header_view);
2309 GtkWidget *folder_view =
2310 modest_main_window_get_child_widget (main_window,
2311 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2312 if (folder != NULL) {
2313 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2314 g_object_unref (folder);
2316 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2320 /* If no header has been selected then exit */
2325 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2326 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2328 /* Update toolbar dimming state */
2329 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2330 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2334 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2336 ModestMainWindow *main_window)
2340 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2345 if (modest_header_view_count_selected_headers (header_view) > 1) {
2346 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2350 /* we check for low-mem; in that case, show a warning, and don't allow
2351 * activating headers
2353 if (modest_platform_check_memory_low (MODEST_WINDOW(main_window), TRUE))
2356 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2358 headers = modest_header_view_get_selected_headers (header_view);
2360 open_msgs_from_headers (headers, MODEST_WINDOW (main_window));
2362 g_object_unref (headers);
2366 set_active_account_from_tny_account (TnyAccount *account,
2367 ModestWindow *window)
2369 const gchar *server_acc_name = tny_account_get_id (account);
2371 /* We need the TnyAccount provided by the
2372 account store because that is the one that
2373 knows the name of the Modest account */
2374 TnyAccount *modest_server_account = modest_server_account =
2375 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2376 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2378 if (!modest_server_account) {
2379 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2383 /* Update active account, but only if it's not a pseudo-account */
2384 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2385 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2386 const gchar *modest_acc_name =
2387 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2388 if (modest_acc_name)
2389 modest_window_set_active_account (window, modest_acc_name);
2392 g_object_unref (modest_server_account);
2397 folder_refreshed_cb (ModestMailOperation *mail_op,
2401 ModestMainWindow *win = NULL;
2402 GtkWidget *folder_view;
2403 const GError *error;
2405 g_return_if_fail (TNY_IS_FOLDER (folder));
2407 win = MODEST_MAIN_WINDOW (user_data);
2409 /* Check if the operation failed due to memory low conditions */
2410 error = modest_mail_operation_get_error (mail_op);
2411 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2412 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2413 modest_platform_run_information_dialog (GTK_WINDOW (win),
2414 dgettext("ke-recv","memr_ib_operation_disabled"),
2420 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2423 TnyFolderStore *current_folder;
2425 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2426 if (current_folder) {
2427 gboolean different = ((TnyFolderStore *) folder != current_folder);
2428 g_object_unref (current_folder);
2434 /* Check if folder is empty and set headers view contents style */
2435 if (tny_folder_get_all_count (folder) == 0)
2436 modest_main_window_set_contents_style (win,
2437 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2442 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2443 TnyFolderStore *folder_store,
2445 ModestMainWindow *main_window)
2448 GtkWidget *header_view;
2450 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2452 header_view = modest_main_window_get_child_widget(main_window,
2453 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2457 conf = modest_runtime_get_conf ();
2459 if (TNY_IS_ACCOUNT (folder_store)) {
2461 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2463 /* Show account details */
2464 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2467 if (TNY_IS_FOLDER (folder_store) && selected) {
2468 TnyAccount *account;
2469 const gchar *account_name = NULL;
2471 /* Update the active account */
2472 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2474 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2476 modest_tny_account_get_parent_modest_account_name_for_server_account (account);
2477 g_object_unref (account);
2481 /* Set the header style by default, it could
2482 be changed later by the refresh callback to
2484 modest_main_window_set_contents_style (main_window,
2485 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2487 /* Set folder on header view. This function
2488 will call tny_folder_refresh_async so we
2489 pass a callback that will be called when
2490 finished. We use that callback to set the
2491 empty view if there are no messages */
2492 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2493 TNY_FOLDER (folder_store),
2495 folder_refreshed_cb,
2498 /* Restore configuration. We need to do this
2499 *after* the set_folder because the widget
2500 memory asks the header view about its
2502 modest_widget_memory_restore (modest_runtime_get_conf (),
2503 G_OBJECT(header_view),
2504 MODEST_CONF_HEADER_VIEW_KEY);
2506 /* No need to save the header view
2507 configuration for Maemo because it only
2508 saves the sorting stuff and that it's
2509 already being done by the sort
2510 dialog. Remove it when the GNOME version
2511 has the same behaviour */
2512 #ifdef MODEST_TOOLKIT_GTK
2513 if (modest_main_window_get_contents_style (main_window) ==
2514 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2515 modest_widget_memory_save (conf, G_OBJECT (header_view),
2516 MODEST_CONF_HEADER_VIEW_KEY);
2518 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2522 /* Update dimming state */
2523 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2524 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2528 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2535 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2537 online = tny_device_is_online (modest_runtime_get_device());
2540 /* already online -- the item is simply not there... */
2541 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2543 GTK_MESSAGE_WARNING,
2545 _("The %s you selected cannot be found"),
2547 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2548 gtk_dialog_run (GTK_DIALOG(dialog));
2550 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2553 _("mcen_bd_dialog_cancel"),
2554 GTK_RESPONSE_REJECT,
2555 _("mcen_bd_dialog_ok"),
2556 GTK_RESPONSE_ACCEPT,
2558 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2559 "Do you want to get online?"), item);
2560 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2561 gtk_label_new (txt), FALSE, FALSE, 0);
2562 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2565 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2566 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2567 /* TODO: Comment about why is this commented out: */
2568 /* modest_platform_connect_and_wait (); */
2571 gtk_widget_destroy (dialog);
2575 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2578 /* g_message ("%s %s", __FUNCTION__, link); */
2583 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2586 modest_platform_activate_uri (link);
2590 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2593 modest_platform_show_uri_popup (link);
2597 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2600 /* we check for low-mem; in that case, show a warning, and don't allow
2601 * viewing attachments
2603 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2606 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2610 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2611 const gchar *address,
2614 /* g_message ("%s %s", __FUNCTION__, address); */
2618 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2619 TnyMsg *saved_draft,
2622 ModestMsgEditWindow *edit_window;
2623 ModestMainWindow *win;
2625 /* FIXME. Make the header view sensitive again. This is a
2626 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2628 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2629 modest_runtime_get_window_mgr(), FALSE));
2631 GtkWidget *hdrview = modest_main_window_get_child_widget(
2632 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2633 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2636 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2638 /* Set draft is there was no error */
2639 if (!modest_mail_operation_get_error (mail_op))
2640 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2642 g_object_unref(edit_window);
2646 enough_space_for_message (ModestMsgEditWindow *edit_window,
2649 TnyAccountStore *acc_store;
2650 guint64 available_disk, expected_size;
2655 acc_store = TNY_ACCOUNT_STORE (modest_runtime_get_account_store());
2656 available_disk = modest_utils_get_available_space (NULL);
2657 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2658 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2663 /* Double check: memory full condition or message too big */
2664 if (available_disk < MIN_FREE_SPACE ||
2665 expected_size > available_disk) {
2667 modest_platform_information_banner (NULL, NULL,
2669 "cerm_device_memory_full"));
2674 * djcb: if we're in low-memory state, we only allow for
2675 * saving messages smaller than
2676 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2677 * should still allow for sending anything critical...
2679 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2680 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2684 * djcb: we also make sure that the attachments are smaller than the max size
2685 * this is for the case where we'd try to forward a message with attachments
2686 * bigger than our max allowed size, or sending an message from drafts which
2687 * somehow got past our checks when attaching.
2689 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2690 modest_platform_run_information_dialog (
2691 GTK_WINDOW(edit_window),
2692 dgettext("ke-recv","memr_ib_operation_disabled"),
2701 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2703 TnyTransportAccount *transport_account;
2704 ModestMailOperation *mail_operation;
2706 gchar *account_name, *from;
2707 ModestAccountMgr *account_mgr;
2708 gboolean had_error = FALSE;
2709 ModestMainWindow *win = NULL;
2711 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2713 data = modest_msg_edit_window_get_msg_data (edit_window);
2716 if (!enough_space_for_message (edit_window, data)) {
2717 modest_msg_edit_window_free_msg_data (edit_window, data);
2721 account_name = g_strdup (data->account_name);
2722 account_mgr = modest_runtime_get_account_mgr();
2724 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2726 account_name = modest_account_mgr_get_default_account (account_mgr);
2727 if (!account_name) {
2728 g_printerr ("modest: no account found\n");
2729 modest_msg_edit_window_free_msg_data (edit_window, data);
2733 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2734 account_name = g_strdup (data->account_name);
2738 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2739 (modest_runtime_get_account_store (),
2741 TNY_ACCOUNT_TYPE_TRANSPORT));
2742 if (!transport_account) {
2743 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2744 g_free (account_name);
2745 modest_msg_edit_window_free_msg_data (edit_window, data);
2748 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2750 /* Create the mail operation */
2751 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
2753 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2755 modest_mail_operation_save_to_drafts (mail_operation,
2767 data->priority_flags,
2768 on_save_to_drafts_cb,
2769 g_object_ref(edit_window));
2771 #ifdef MODEST_TOOLKIT_HILDON2
2772 /* In hildon2 we always show the information banner on saving to drafts.
2773 * It will be a system information banner in this case.
2775 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2776 modest_platform_information_banner (NULL, NULL, text);
2779 /* Use the main window as the parent of the banner, if the
2780 main window does not exist it won't be shown, if the parent
2781 window exists then it's properly shown. We don't use the
2782 editor window because it could be closed (save to drafts
2783 could happen after closing the window */
2784 win = (ModestMainWindow *)
2785 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
2787 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2788 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
2792 modest_msg_edit_window_set_modified (edit_window, FALSE);
2796 g_free (account_name);
2797 g_object_unref (G_OBJECT (transport_account));
2798 g_object_unref (G_OBJECT (mail_operation));
2800 modest_msg_edit_window_free_msg_data (edit_window, data);
2803 * If the drafts folder is selected then make the header view
2804 * insensitive while the message is being saved to drafts
2805 * (it'll be sensitive again in on_save_to_drafts_cb()). This
2806 * is not very clean but it avoids letting the drafts folder
2807 * in an inconsistent state: the user could edit the message
2808 * being saved and undesirable things would happen.
2809 * In the average case the user won't notice anything at
2810 * all. In the worst case (the user is editing a really big
2811 * file from Drafts) the header view will be insensitive
2812 * during the saving process (10 or 20 seconds, depending on
2813 * the message). Anyway this is just a quick workaround: once
2814 * we find a better solution it should be removed
2815 * See NB#65125 (commend #18) for details.
2817 if (!had_error && win != NULL) {
2818 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
2819 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
2821 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
2823 if (modest_tny_folder_is_local_folder(folder)) {
2824 TnyFolderType folder_type;
2825 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
2826 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
2827 GtkWidget *hdrview = modest_main_window_get_child_widget(
2828 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2829 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
2833 if (folder != NULL) g_object_unref(folder);
2840 /* For instance, when clicking the Send toolbar button when editing a message: */
2842 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2844 TnyTransportAccount *transport_account = NULL;
2845 gboolean had_error = FALSE;
2847 ModestAccountMgr *account_mgr;
2848 gchar *account_name;
2850 ModestMailOperation *mail_operation;
2852 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
2854 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2857 data = modest_msg_edit_window_get_msg_data (edit_window);
2860 if (!enough_space_for_message (edit_window, data)) {
2861 modest_msg_edit_window_free_msg_data (edit_window, data);
2865 account_mgr = modest_runtime_get_account_mgr();
2866 account_name = g_strdup (data->account_name);
2868 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2871 account_name = modest_account_mgr_get_default_account (account_mgr);
2873 if (!account_name) {
2874 modest_msg_edit_window_free_msg_data (edit_window, data);
2875 /* Run account setup wizard */
2876 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
2881 /* Get the currently-active transport account for this modest account: */
2882 if (strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
2884 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2885 (modest_runtime_get_account_store (),
2886 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
2889 if (!transport_account) {
2890 modest_msg_edit_window_free_msg_data (edit_window, data);
2891 /* Run account setup wizard */
2892 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2897 /* Create the mail operation */
2898 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2899 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
2900 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2902 modest_mail_operation_send_new_mail (mail_operation,
2914 data->priority_flags);
2916 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
2917 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2920 if (modest_mail_operation_get_error (mail_operation) != NULL) {
2921 const GError *error = modest_mail_operation_get_error (mail_operation);
2922 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
2923 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
2924 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
2925 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
2932 g_free (account_name);
2933 g_object_unref (G_OBJECT (transport_account));
2934 g_object_unref (G_OBJECT (mail_operation));
2936 modest_msg_edit_window_free_msg_data (edit_window, data);
2939 modest_msg_edit_window_set_sent (edit_window, TRUE);
2941 /* Save settings and close the window: */
2942 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2949 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2950 ModestMsgEditWindow *window)
2952 ModestMsgEditFormatState *format_state = NULL;
2954 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2955 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2957 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2960 format_state = modest_msg_edit_window_get_format_state (window);
2961 g_return_if_fail (format_state != NULL);
2963 format_state->bold = gtk_toggle_action_get_active (action);
2964 modest_msg_edit_window_set_format_state (window, format_state);
2965 g_free (format_state);
2970 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2971 ModestMsgEditWindow *window)
2973 ModestMsgEditFormatState *format_state = NULL;
2975 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2976 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2978 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2981 format_state = modest_msg_edit_window_get_format_state (window);
2982 g_return_if_fail (format_state != NULL);
2984 format_state->italics = gtk_toggle_action_get_active (action);
2985 modest_msg_edit_window_set_format_state (window, format_state);
2986 g_free (format_state);
2991 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2992 ModestMsgEditWindow *window)
2994 ModestMsgEditFormatState *format_state = NULL;
2996 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2997 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2999 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3002 format_state = modest_msg_edit_window_get_format_state (window);
3003 g_return_if_fail (format_state != NULL);
3005 format_state->bullet = gtk_toggle_action_get_active (action);
3006 modest_msg_edit_window_set_format_state (window, format_state);
3007 g_free (format_state);
3012 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3013 GtkRadioAction *selected,
3014 ModestMsgEditWindow *window)
3016 ModestMsgEditFormatState *format_state = NULL;
3017 GtkJustification value;
3019 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3021 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3024 value = gtk_radio_action_get_current_value (selected);
3026 format_state = modest_msg_edit_window_get_format_state (window);
3027 g_return_if_fail (format_state != NULL);
3029 format_state->justification = value;
3030 modest_msg_edit_window_set_format_state (window, format_state);
3031 g_free (format_state);
3035 modest_ui_actions_on_select_editor_color (GtkAction *action,
3036 ModestMsgEditWindow *window)
3038 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3039 g_return_if_fail (GTK_IS_ACTION (action));
3041 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3044 modest_msg_edit_window_select_color (window);
3048 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3049 ModestMsgEditWindow *window)
3051 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3052 g_return_if_fail (GTK_IS_ACTION (action));
3054 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3057 modest_msg_edit_window_select_background_color (window);
3061 modest_ui_actions_on_insert_image (GtkAction *action,
3062 ModestMsgEditWindow *window)
3064 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3065 g_return_if_fail (GTK_IS_ACTION (action));
3068 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3071 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3074 modest_msg_edit_window_insert_image (window);
3078 modest_ui_actions_on_attach_file (GtkAction *action,
3079 ModestMsgEditWindow *window)
3081 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3082 g_return_if_fail (GTK_IS_ACTION (action));
3084 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3087 modest_msg_edit_window_offer_attach_file (window);
3091 modest_ui_actions_on_remove_attachments (GtkAction *action,
3092 ModestMsgEditWindow *window)
3094 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3095 g_return_if_fail (GTK_IS_ACTION (action));
3097 modest_msg_edit_window_remove_attachments (window, NULL);
3101 #ifndef MODEST_TOOLKIT_GTK
3106 TnyFolderStore *folder;
3107 } CreateFolderHelper;
3110 show_create_folder_in_timeout (gpointer data)
3112 CreateFolderHelper *helper = (CreateFolderHelper *) data;
3114 /* Remove the timeout ASAP, we can not wait until the dialog
3115 is shown because it could take a lot of time and so the
3116 timeout could be called twice or more times */
3117 g_source_remove (helper->handler);
3119 gdk_threads_enter ();
3120 do_create_folder (helper->win, helper->folder, helper->name);
3121 gdk_threads_leave ();
3123 g_object_unref (helper->win);
3124 g_object_unref (helper->folder);
3125 g_free (helper->name);
3126 g_slice_free (CreateFolderHelper, helper);
3133 do_create_folder_cb (ModestMailOperation *mail_op,
3134 TnyFolderStore *parent_folder,
3135 TnyFolder *new_folder,
3138 gchar *suggested_name = (gchar *) user_data;
3139 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3141 if (modest_mail_operation_get_error (mail_op)) {
3143 /* Show an error. If there was some problem writing to
3144 disk, show it, otherwise show the generic folder
3145 create error. We do it here and not in an error
3146 handler because the call to do_create_folder will
3147 stop the main loop in a gtk_dialog_run and then,
3148 the message won't be shown until that dialog is
3150 modest_ui_actions_disk_operations_error_handler (mail_op,
3151 _("mail_in_ui_folder_create_error"));
3153 /* Try again. Do *NOT* show any error because the mail
3154 operations system will do it for us because we
3155 created the mail_op with new_with_error_handler */
3156 #ifndef MODEST_TOOLKIT_GTK
3157 CreateFolderHelper *helper;
3158 helper = g_slice_new0 (CreateFolderHelper);
3159 helper->name = g_strdup (suggested_name);
3160 helper->folder = g_object_ref (parent_folder);
3161 helper->win = g_object_ref (source_win);
3163 /* Ugly but neccesary stuff. The problem is that the
3164 dialog when is shown calls a function that destroys
3165 all the temporary windows, so the banner is
3167 helper->handler = g_timeout_add (2000, show_create_folder_in_timeout, helper);
3169 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3172 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3173 * FIXME: any other? */
3174 GtkWidget *folder_view;
3176 if (MODEST_IS_MAIN_WINDOW(source_win))
3178 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3179 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3182 get_folder_view_from_move_to_dialog (GTK_WIDGET(source_win));
3184 /* Select the newly created folder. It could happen
3185 that the widget is no longer there (i.e. the window
3186 has been destroyed, so we need to check this */
3188 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3190 g_object_unref (new_folder);
3192 /* Free. Note that the first time it'll be NULL so noop */
3193 g_free (suggested_name);
3194 g_object_unref (source_win);
3198 do_create_folder (GtkWindow *parent_window,
3199 TnyFolderStore *parent_folder,
3200 const gchar *suggested_name)
3203 gchar *folder_name = NULL;
3205 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3207 (gchar *) suggested_name,
3210 if (result == GTK_RESPONSE_ACCEPT) {
3211 ModestMailOperation *mail_op;
3213 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3214 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3216 modest_mail_operation_create_folder (mail_op,
3218 (const gchar *) folder_name,
3219 do_create_folder_cb,
3221 g_object_unref (mail_op);
3226 create_folder_performer (gboolean canceled,
3228 GtkWindow *parent_window,
3229 TnyAccount *account,
3232 TnyFolderStore *parent_folder = TNY_FOLDER_STORE (user_data);
3234 if (canceled || err) {
3235 /* In memory full conditions we could get this error here */
3236 check_memory_full_error ((GtkWidget *) parent_window, err);
3240 /* Run the new folder dialog */
3241 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3244 g_object_unref (parent_folder);
3248 modest_ui_actions_create_folder(GtkWidget *parent_window,
3249 GtkWidget *folder_view)
3251 TnyFolderStore *parent_folder;
3253 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3255 if (parent_folder) {
3256 /* The parent folder will be freed in the callback */
3257 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3260 create_folder_performer,
3266 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
3268 GtkWidget *folder_view;
3270 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3272 folder_view = modest_main_window_get_child_widget (main_window,
3273 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3277 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
3281 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3284 const GError *error = NULL;
3285 const gchar *message = NULL;
3287 /* Get error message */
3288 error = modest_mail_operation_get_error (mail_op);
3290 g_return_if_reached ();
3292 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3293 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3294 message = _CS("ckdg_ib_folder_already_exists");
3295 } else if (error->domain == TNY_ERROR_DOMAIN &&
3296 error->code == TNY_SERVICE_ERROR_STATE) {
3297 /* This means that the folder is already in use (a
3298 message is opened for example */
3299 message = _("emev_ni_internal_error");
3301 message = _("emev_ib_ui_imap_unable_to_rename");
3304 /* We don't set a parent for the dialog because the dialog
3305 will be destroyed so the banner won't appear */
3306 modest_platform_information_banner (NULL, NULL, message);
3310 TnyFolderStore *folder;
3315 on_rename_folder_cb (ModestMailOperation *mail_op,
3316 TnyFolder *new_folder,
3319 ModestFolderView *folder_view;
3321 /* If the window was closed when renaming a folder this could
3323 if (!MODEST_IS_FOLDER_VIEW (user_data))
3326 folder_view = MODEST_FOLDER_VIEW (user_data);
3327 /* Note that if the rename fails new_folder will be NULL */
3329 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3331 modest_folder_view_select_first_inbox_or_local (folder_view);
3333 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3337 on_rename_folder_performer (gboolean canceled,
3339 GtkWindow *parent_window,
3340 TnyAccount *account,
3343 ModestMailOperation *mail_op = NULL;
3344 GtkTreeSelection *sel = NULL;
3345 GtkWidget *folder_view = NULL;
3346 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3348 if (canceled || err) {
3349 /* In memory full conditions we could get this error here */
3350 check_memory_full_error ((GtkWidget *) parent_window, err);
3351 } else if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3353 folder_view = modest_main_window_get_child_widget (
3354 MODEST_MAIN_WINDOW (parent_window),
3355 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3358 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3359 modest_ui_actions_rename_folder_error_handler,
3360 parent_window, NULL);
3362 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3365 /* Clear the headers view */
3366 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3367 gtk_tree_selection_unselect_all (sel);
3369 /* Actually rename the folder */
3370 modest_mail_operation_rename_folder (mail_op,
3371 TNY_FOLDER (data->folder),
3372 (const gchar *) (data->new_name),
3373 on_rename_folder_cb,
3375 g_object_unref (data->folder);
3376 g_object_unref (mail_op);
3379 g_free (data->new_name);
3384 modest_ui_actions_on_rename_folder (GtkAction *action,
3385 ModestMainWindow *main_window)
3387 TnyFolderStore *folder;
3388 GtkWidget *folder_view;
3389 GtkWidget *header_view;
3391 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3393 folder_view = modest_main_window_get_child_widget (main_window,
3394 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3398 header_view = modest_main_window_get_child_widget (main_window,
3399 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3404 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3409 if (TNY_IS_FOLDER (folder)) {
3410 gchar *folder_name = NULL;
3412 const gchar *current_name;
3413 TnyFolderStore *parent;
3414 gboolean do_rename = TRUE;
3416 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3417 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3418 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
3419 parent, current_name,
3421 g_object_unref (parent);
3423 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3426 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3427 rename_folder_data->folder = g_object_ref (folder);
3428 rename_folder_data->new_name = folder_name;
3429 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(main_window), TRUE,
3430 folder, on_rename_folder_performer, rename_folder_data);
3433 g_object_unref (folder);
3437 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3440 GObject *win = modest_mail_operation_get_source (mail_op);
3442 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3443 _("mail_in_ui_folder_delete_error"),
3445 g_object_unref (win);
3449 TnyFolderStore *folder;
3450 gboolean move_to_trash;
3454 on_delete_folder_cb (gboolean canceled,
3456 GtkWindow *parent_window,
3457 TnyAccount *account,
3460 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3461 GtkWidget *folder_view;
3462 ModestMailOperation *mail_op;
3463 GtkTreeSelection *sel;
3465 if (!MODEST_IS_MAIN_WINDOW(parent_window) || canceled || (err!=NULL)) {
3466 g_object_unref (G_OBJECT (info->folder));
3471 folder_view = modest_main_window_get_child_widget (
3472 MODEST_MAIN_WINDOW (parent_window),
3473 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3475 /* Unselect the folder before deleting it to free the headers */
3476 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3477 gtk_tree_selection_unselect_all (sel);
3479 /* Create the mail operation */
3481 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3482 modest_ui_actions_delete_folder_error_handler,
3485 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3487 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3489 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3491 g_object_unref (G_OBJECT (mail_op));
3492 g_object_unref (G_OBJECT (info->folder));
3497 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
3499 TnyFolderStore *folder;
3500 GtkWidget *folder_view;
3504 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3506 folder_view = modest_main_window_get_child_widget (main_window,
3507 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3511 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3513 /* Show an error if it's an account */
3514 if (!TNY_IS_FOLDER (folder)) {
3515 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
3516 _("mail_in_ui_folder_delete_error"),
3518 g_object_unref (G_OBJECT (folder));
3523 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3524 tny_folder_get_name (TNY_FOLDER (folder)));
3525 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
3526 (const gchar *) message);
3529 if (response == GTK_RESPONSE_OK) {
3530 DeleteFolderInfo *info;
3531 info = g_new0(DeleteFolderInfo, 1);
3532 info->folder = folder;
3533 info->move_to_trash = move_to_trash;
3534 g_object_ref (G_OBJECT (info->folder));
3535 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder));
3536 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (main_window),
3538 TNY_FOLDER_STORE (account),
3539 on_delete_folder_cb, info);
3540 g_object_unref (account);
3542 g_object_unref (G_OBJECT (folder));
3546 modest_ui_actions_on_delete_folder (GtkAction *action,
3547 ModestMainWindow *main_window)
3549 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3551 delete_folder (main_window, FALSE);
3555 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3557 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3559 delete_folder (main_window, TRUE);
3563 typedef struct _PasswordDialogFields {
3564 GtkWidget *username;
3565 GtkWidget *password;
3567 } PasswordDialogFields;
3570 password_dialog_check_field (GtkEditable *editable,
3571 PasswordDialogFields *fields)
3574 gboolean any_value_empty = FALSE;
3576 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
3577 if ((value == NULL) || value[0] == '\0') {
3578 any_value_empty = TRUE;
3580 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
3581 if ((value == NULL) || value[0] == '\0') {
3582 any_value_empty = TRUE;
3584 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3588 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3589 const gchar* server_account_name,
3594 ModestMainWindow *main_window)
3596 g_return_if_fail(server_account_name);
3597 gboolean completed = FALSE;
3598 PasswordDialogFields *fields = NULL;
3600 /* Initalize output parameters: */
3607 #ifndef MODEST_TOOLKIT_GTK
3608 /* Maemo uses a different (awkward) button order,
3609 * It should probably just use gtk_alternative_dialog_button_order ().
3611 #ifdef MODEST_TOOLKIT_HILDON2
3613 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3616 _HL("wdgt_bd_done"),
3617 GTK_RESPONSE_ACCEPT,
3621 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3624 _("mcen_bd_dialog_ok"),
3625 GTK_RESPONSE_ACCEPT,
3626 _("mcen_bd_dialog_cancel"),
3627 GTK_RESPONSE_REJECT,
3629 #endif /* MODEST_TOOLKIT_HILDON2 */
3632 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3636 GTK_RESPONSE_REJECT,
3638 GTK_RESPONSE_ACCEPT,
3640 #endif /* MODEST_TOOLKIT_GTK */
3642 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3644 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3645 modest_runtime_get_account_mgr(), server_account_name);
3646 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3647 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3650 gtk_widget_destroy (dialog);
3654 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3655 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
3658 g_free (server_name);
3662 gchar *initial_username = modest_account_mgr_get_server_account_username (
3663 modest_runtime_get_account_mgr(), server_account_name);
3665 GtkWidget *entry_username = gtk_entry_new ();
3666 if (initial_username)
3667 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
3668 /* Dim this if a connection has ever succeeded with this username,
3669 * as per the UI spec: */
3670 /* const gboolean username_known = */
3671 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3672 /* modest_runtime_get_account_mgr(), server_account_name); */
3673 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3675 /* We drop the username sensitive code and disallow changing it here
3676 * as tinymail does not support really changing the username in the callback
3678 gtk_widget_set_sensitive (entry_username, FALSE);
3680 #ifndef MODEST_TOOLKIT_GTK
3681 /* Auto-capitalization is the default, so let's turn it off: */
3682 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3684 /* Create a size group to be used by all captions.
3685 * Note that HildonCaption does not create a default size group if we do not specify one.
3686 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3687 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3689 GtkWidget *caption = hildon_caption_new (sizegroup,
3690 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
3691 gtk_widget_show (entry_username);
3692 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3693 FALSE, FALSE, MODEST_MARGIN_HALF);
3694 gtk_widget_show (caption);
3696 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
3698 #endif /* !MODEST_TOOLKIT_GTK */
3701 GtkWidget *entry_password = gtk_entry_new ();
3702 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3703 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3705 #ifndef MODEST_TOOLKIT_GTK
3706 /* Auto-capitalization is the default, so let's turn it off: */
3707 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3708 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3710 caption = hildon_caption_new (sizegroup,
3711 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
3712 gtk_widget_show (entry_password);
3713 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3714 FALSE, FALSE, MODEST_MARGIN_HALF);
3715 gtk_widget_show (caption);
3716 g_object_unref (sizegroup);
3718 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
3720 #endif /* !MODEST_TOOLKIT_GTK */
3722 if (initial_username != NULL)
3723 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3725 /* This is not in the Maemo UI spec:
3726 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3727 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3731 fields = g_slice_new0 (PasswordDialogFields);
3732 fields->username = entry_username;
3733 fields->password = entry_password;
3734 fields->dialog = dialog;
3736 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3737 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3738 password_dialog_check_field (NULL, fields);
3740 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3742 while (!completed) {
3744 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3746 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
3748 /* Note that an empty field becomes the "" string */
3749 if (*username && strlen (*username) > 0) {
3750 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
3751 server_account_name,
3755 const gboolean username_was_changed =
3756 (strcmp (*username, initial_username) != 0);
3757 if (username_was_changed) {
3758 g_warning ("%s: tinymail does not yet support changing the "
3759 "username in the get_password() callback.\n", __FUNCTION__);
3765 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
3766 _("mcen_ib_username_pw_incorrect"));
3772 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
3774 /* We do not save the password in the configuration,
3775 * because this function is only called for passwords that should
3776 * not be remembered:
3777 modest_server_account_set_password (
3778 modest_runtime_get_account_mgr(), server_account_name,
3785 #ifndef MODEST_TOOLKIT_HILDON2
3786 /* Set parent to NULL or the banner will disappear with its parent dialog */
3787 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
3799 /* This is not in the Maemo UI spec:
3800 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3806 g_free (initial_username);
3807 gtk_widget_destroy (dialog);
3808 g_slice_free (PasswordDialogFields, fields);
3810 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3814 modest_ui_actions_on_cut (GtkAction *action,
3815 ModestWindow *window)
3817 GtkWidget *focused_widget;
3818 GtkClipboard *clipboard;
3820 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3821 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3822 if (GTK_IS_EDITABLE (focused_widget)) {
3823 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3824 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3825 gtk_clipboard_store (clipboard);
3826 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3827 GtkTextBuffer *buffer;
3829 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3830 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3831 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3832 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3833 gtk_clipboard_store (clipboard);
3835 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3836 TnyList *header_list = modest_header_view_get_selected_headers (
3837 MODEST_HEADER_VIEW (focused_widget));
3838 gboolean continue_download = FALSE;
3839 gint num_of_unc_msgs;
3841 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3843 if (num_of_unc_msgs) {
3844 TnyAccount *account = get_account_from_header_list (header_list);
3846 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3847 g_object_unref (account);
3851 if (num_of_unc_msgs == 0 || continue_download) {
3852 /* modest_platform_information_banner (
3853 NULL, NULL, _CS("mcen_ib_getting_items"));*/
3854 modest_header_view_cut_selection (
3855 MODEST_HEADER_VIEW (focused_widget));
3858 g_object_unref (header_list);
3859 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3860 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3865 modest_ui_actions_on_copy (GtkAction *action,
3866 ModestWindow *window)
3868 GtkClipboard *clipboard;
3869 GtkWidget *focused_widget;
3870 gboolean copied = TRUE;
3872 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3873 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3875 if (GTK_IS_LABEL (focused_widget)) {
3877 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
3878 gtk_clipboard_set_text (clipboard, selection, -1);
3880 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3881 gtk_clipboard_store (clipboard);
3882 } else if (GTK_IS_EDITABLE (focused_widget)) {
3883 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3884 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3885 gtk_clipboard_store (clipboard);
3886 } else if (GTK_IS_HTML (focused_widget)) {
3889 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
3890 if ((sel == NULL) || (sel[0] == '\0')) {
3893 gtk_html_copy (GTK_HTML (focused_widget));
3894 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3895 gtk_clipboard_store (clipboard);
3897 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3898 GtkTextBuffer *buffer;
3899 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3900 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3901 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3902 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3903 gtk_clipboard_store (clipboard);
3905 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3906 TnyList *header_list = modest_header_view_get_selected_headers (
3907 MODEST_HEADER_VIEW (focused_widget));
3908 gboolean continue_download = FALSE;
3909 gint num_of_unc_msgs;
3911 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3913 if (num_of_unc_msgs) {
3914 TnyAccount *account = get_account_from_header_list (header_list);
3916 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3917 g_object_unref (account);
3921 if (num_of_unc_msgs == 0 || continue_download) {
3922 modest_platform_information_banner (
3923 NULL, NULL, _CS("mcen_ib_getting_items"));
3924 modest_header_view_copy_selection (
3925 MODEST_HEADER_VIEW (focused_widget));
3929 g_object_unref (header_list);
3931 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3932 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3935 /* Show information banner if there was a copy to clipboard */
3937 modest_platform_information_banner (
3938 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3942 modest_ui_actions_on_undo (GtkAction *action,
3943 ModestWindow *window)
3945 ModestEmailClipboard *clipboard = NULL;
3947 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3948 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3949 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3950 /* Clear clipboard source */
3951 clipboard = modest_runtime_get_email_clipboard ();
3952 modest_email_clipboard_clear (clipboard);
3955 g_return_if_reached ();
3960 modest_ui_actions_on_redo (GtkAction *action,
3961 ModestWindow *window)
3963 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3964 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3967 g_return_if_reached ();
3973 destroy_information_note (ModestMailOperation *mail_op,
3976 /* destroy information note */
3977 gtk_widget_destroy (GTK_WIDGET(user_data));
3981 destroy_folder_information_note (ModestMailOperation *mail_op,
3982 TnyFolder *new_folder,
3985 /* destroy information note */
3986 gtk_widget_destroy (GTK_WIDGET(user_data));
3991 paste_as_attachment_free (gpointer data)
3993 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3995 if (helper->banner) {
3996 gtk_widget_destroy (helper->banner);
3997 g_object_unref (helper->banner);
4003 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4008 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4009 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4014 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4019 modest_ui_actions_on_paste (GtkAction *action,
4020 ModestWindow *window)
4022 GtkWidget *focused_widget = NULL;
4023 GtkWidget *inf_note = NULL;
4024 ModestMailOperation *mail_op = NULL;
4026 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4027 if (GTK_IS_EDITABLE (focused_widget)) {
4028 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4029 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4030 ModestEmailClipboard *e_clipboard = NULL;
4031 e_clipboard = modest_runtime_get_email_clipboard ();
4032 if (modest_email_clipboard_cleared (e_clipboard)) {
4033 GtkTextBuffer *buffer;
4034 GtkClipboard *clipboard;
4036 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4037 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4038 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4039 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4040 ModestMailOperation *mail_op;
4041 TnyFolder *src_folder = NULL;
4042 TnyList *data = NULL;
4044 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4045 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4046 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4047 _CS("ckct_nw_pasting"));
4048 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4049 mail_op = modest_mail_operation_new (G_OBJECT (window));
4050 if (helper->banner != NULL) {
4051 g_object_ref (G_OBJECT (helper->banner));
4052 gtk_widget_show (GTK_WIDGET (helper->banner));
4056 modest_mail_operation_get_msgs_full (mail_op,
4058 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4060 paste_as_attachment_free);
4064 g_object_unref (data);
4066 g_object_unref (src_folder);
4069 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4070 ModestEmailClipboard *clipboard = NULL;
4071 TnyFolder *src_folder = NULL;
4072 TnyFolderStore *folder_store = NULL;
4073 TnyList *data = NULL;
4074 gboolean delete = FALSE;
4076 /* Check clipboard source */
4077 clipboard = modest_runtime_get_email_clipboard ();
4078 if (modest_email_clipboard_cleared (clipboard))
4081 /* Get elements to paste */
4082 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4084 /* Create a new mail operation */
4085 mail_op = modest_mail_operation_new (G_OBJECT(window));
4087 /* Get destination folder */
4088 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4090 /* transfer messages */
4094 /* Ask for user confirmation */
4096 modest_ui_actions_msgs_move_to_confirmation (window,
4097 TNY_FOLDER (folder_store),
4101 if (response == GTK_RESPONSE_OK) {
4102 /* Launch notification */
4103 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4104 _CS("ckct_nw_pasting"));
4105 if (inf_note != NULL) {
4106 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4107 gtk_widget_show (GTK_WIDGET(inf_note));
4110 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4111 modest_mail_operation_xfer_msgs (mail_op,
4113 TNY_FOLDER (folder_store),
4115 destroy_information_note,
4118 g_object_unref (mail_op);
4121 } else if (src_folder != NULL) {
4122 /* Launch notification */
4123 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4124 _CS("ckct_nw_pasting"));
4125 if (inf_note != NULL) {
4126 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4127 gtk_widget_show (GTK_WIDGET(inf_note));
4130 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4131 modest_mail_operation_xfer_folder (mail_op,
4135 destroy_folder_information_note,
4141 g_object_unref (data);
4142 if (src_folder != NULL)
4143 g_object_unref (src_folder);
4144 if (folder_store != NULL)
4145 g_object_unref (folder_store);
4151 modest_ui_actions_on_select_all (GtkAction *action,
4152 ModestWindow *window)
4154 GtkWidget *focused_widget;
4156 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4157 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4158 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4159 } else if (GTK_IS_LABEL (focused_widget)) {
4160 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4161 } else if (GTK_IS_EDITABLE (focused_widget)) {
4162 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4163 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4164 GtkTextBuffer *buffer;
4165 GtkTextIter start, end;
4167 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4168 gtk_text_buffer_get_start_iter (buffer, &start);
4169 gtk_text_buffer_get_end_iter (buffer, &end);
4170 gtk_text_buffer_select_range (buffer, &start, &end);
4171 } else if (GTK_IS_HTML (focused_widget)) {
4172 gtk_html_select_all (GTK_HTML (focused_widget));
4173 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4174 GtkWidget *header_view = focused_widget;
4175 GtkTreeSelection *selection = NULL;
4177 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4178 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4179 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4182 /* Disable window dimming management */
4183 modest_window_disable_dimming (MODEST_WINDOW(window));
4185 /* Select all messages */
4186 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4187 gtk_tree_selection_select_all (selection);
4189 /* Set focuse on header view */
4190 gtk_widget_grab_focus (header_view);
4192 /* Enable window dimming management */
4193 modest_window_enable_dimming (MODEST_WINDOW(window));
4194 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4195 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4201 modest_ui_actions_on_mark_as_read (GtkAction *action,
4202 ModestWindow *window)
4204 g_return_if_fail (MODEST_IS_WINDOW(window));
4206 /* Mark each header as read */
4207 do_headers_action (window, headers_action_mark_as_read, NULL);
4211 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4212 ModestWindow *window)
4214 g_return_if_fail (MODEST_IS_WINDOW(window));
4216 /* Mark each header as read */
4217 do_headers_action (window, headers_action_mark_as_unread, NULL);
4221 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4222 GtkRadioAction *selected,
4223 ModestWindow *window)
4227 value = gtk_radio_action_get_current_value (selected);
4228 if (MODEST_IS_WINDOW (window)) {
4229 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4234 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4235 GtkRadioAction *selected,
4236 ModestWindow *window)
4238 TnyHeaderFlags flags;
4239 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4241 flags = gtk_radio_action_get_current_value (selected);
4242 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4246 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4247 GtkRadioAction *selected,
4248 ModestWindow *window)
4252 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4254 file_format = gtk_radio_action_get_current_value (selected);
4255 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4260 modest_ui_actions_on_zoom_plus (GtkAction *action,
4261 ModestWindow *window)
4263 g_return_if_fail (MODEST_IS_WINDOW (window));
4265 modest_window_zoom_plus (MODEST_WINDOW (window));
4269 modest_ui_actions_on_zoom_minus (GtkAction *action,
4270 ModestWindow *window)
4272 g_return_if_fail (MODEST_IS_WINDOW (window));
4274 modest_window_zoom_minus (MODEST_WINDOW (window));
4278 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4279 ModestWindow *window)
4281 ModestWindowMgr *mgr;
4282 gboolean fullscreen, active;
4283 g_return_if_fail (MODEST_IS_WINDOW (window));
4285 mgr = modest_runtime_get_window_mgr ();
4287 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4288 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4290 if (active != fullscreen) {
4291 modest_window_mgr_set_fullscreen_mode (mgr, active);
4292 #ifndef MODEST_TOOLKIT_HILDON2
4293 gtk_window_present (GTK_WINDOW (window));
4299 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4300 ModestWindow *window)
4302 ModestWindowMgr *mgr;
4303 gboolean fullscreen;
4305 g_return_if_fail (MODEST_IS_WINDOW (window));
4307 mgr = modest_runtime_get_window_mgr ();
4308 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4309 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4311 #ifndef MODEST_TOOLKIT_HILDON2
4312 gtk_window_present (GTK_WINDOW (window));
4317 * Used by modest_ui_actions_on_details to call do_headers_action
4320 headers_action_show_details (TnyHeader *header,
4321 ModestWindow *window,
4325 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header);
4329 * Show the header details in a ModestDetailsDialog widget
4332 modest_ui_actions_on_details (GtkAction *action,
4335 TnyList * headers_list;
4339 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4342 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4345 g_object_unref (msg);
4347 headers_list = get_selected_headers (win);
4351 iter = tny_list_create_iterator (headers_list);
4353 header = TNY_HEADER (tny_iterator_get_current (iter));
4355 headers_action_show_details (header, win, NULL);
4356 g_object_unref (header);
4359 g_object_unref (iter);
4360 g_object_unref (headers_list);
4362 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4363 GtkWidget *folder_view, *header_view;
4365 /* Check which widget has the focus */
4366 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4367 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4368 if (gtk_widget_is_focus (folder_view)) {
4369 TnyFolderStore *folder_store
4370 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4371 if (!folder_store) {
4372 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4375 /* Show only when it's a folder */
4376 /* This function should not be called for account items,
4377 * because we dim the menu item for them. */
4378 if (TNY_IS_FOLDER (folder_store)) {
4379 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4380 TNY_FOLDER (folder_store));
4383 g_object_unref (folder_store);
4386 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4387 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4388 /* Show details of each header */
4389 do_headers_action (win, headers_action_show_details, header_view);
4395 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4396 ModestMsgEditWindow *window)
4398 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4400 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4404 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4405 ModestMsgEditWindow *window)
4407 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4409 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4413 modest_ui_actions_toggle_folders_view (GtkAction *action,
4414 ModestMainWindow *main_window)
4416 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4418 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4419 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4421 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4425 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4426 ModestWindow *window)
4428 gboolean active, fullscreen = FALSE;
4429 ModestWindowMgr *mgr;
4431 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4433 /* Check if we want to toggle the toolbar view in fullscreen
4435 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4436 "ViewShowToolbarFullScreen")) {
4440 /* Toggle toolbar */
4441 mgr = modest_runtime_get_window_mgr ();
4442 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4446 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4447 ModestMsgEditWindow *window)
4449 modest_msg_edit_window_select_font (window);
4454 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4455 const gchar *display_name,
4458 /* don't update the display name if it was already set;
4459 * updating the display name apparently is expensive */
4460 const gchar* old_name = gtk_window_get_title (window);
4462 if (display_name == NULL)
4465 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4466 return; /* don't do anything */
4468 /* This is usually used to change the title of the main window, which
4469 * is the one that holds the folder view. Note that this change can
4470 * happen even when the widget doesn't have the focus. */
4471 gtk_window_set_title (window, display_name);
4476 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4478 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4479 modest_msg_edit_window_select_contacts (window);
4483 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4485 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4486 modest_msg_edit_window_check_names (window, FALSE);
4490 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
4492 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
4493 GTK_WIDGET (user_data));
4497 * This function is used to track changes in the selection of the
4498 * folder view that is inside the "move to" dialog to enable/disable
4499 * the OK button because we do not want the user to select a disallowed
4500 * destination for a folder.
4501 * The user also not desired to be able to use NEW button on items where
4502 * folder creation is not possibel.
4505 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4506 TnyFolderStore *folder_store,
4510 GtkWidget *dialog = NULL;
4511 GtkWidget *ok_button = NULL, *new_button = NULL;
4512 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4513 gboolean moving_folder = FALSE;
4514 gboolean is_local_account = TRUE;
4515 GtkWidget *folder_view = NULL;
4516 ModestTnyFolderRules rules;
4518 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
4523 /* Get the OK button */
4524 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
4528 ok_button = g_object_get_data (G_OBJECT (dialog), MOVE_FOLDER_OK_BUTTON);
4529 new_button = g_object_get_data (G_OBJECT (dialog), MOVE_FOLDER_NEW_BUTTON);
4531 /* check if folder_store is an remote account */
4532 if (TNY_IS_ACCOUNT (folder_store)) {
4533 TnyAccount *local_account = NULL;
4534 TnyAccount *mmc_account = NULL;
4535 ModestTnyAccountStore *account_store = NULL;
4537 account_store = modest_runtime_get_account_store ();
4538 local_account = modest_tny_account_store_get_local_folders_account (account_store);
4539 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
4541 if ((gpointer) local_account != (gpointer) folder_store &&
4542 (gpointer) mmc_account != (gpointer) folder_store) {
4543 ModestProtocolType proto;
4544 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
4545 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
4546 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
4548 is_local_account = FALSE;
4549 /* New button should be dimmed on remote
4551 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4553 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
4555 g_object_unref (local_account);
4557 /* It could not exist */
4559 g_object_unref (mmc_account);
4562 /* Check the target folder rules */
4563 if (TNY_IS_FOLDER (folder_store)) {
4564 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
4565 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
4566 ok_sensitive = FALSE;
4567 new_sensitive = FALSE;
4572 /* Check if we're moving a folder */
4573 if (MODEST_IS_MAIN_WINDOW (user_data)) {
4574 /* Get the widgets */
4575 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
4576 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4577 if (gtk_widget_is_focus (folder_view))
4578 moving_folder = TRUE;
4581 if (moving_folder) {
4582 TnyFolderStore *moved_folder = NULL, *parent = NULL;
4584 /* Get the folder to move */
4585 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4587 /* Check that we're not moving to the same folder */
4588 if (TNY_IS_FOLDER (moved_folder)) {
4589 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
4590 if (parent == folder_store)
4591 ok_sensitive = FALSE;
4592 g_object_unref (parent);
4595 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
4596 /* Do not allow to move to an account unless it's the
4597 local folders account */
4598 if (!is_local_account)
4599 ok_sensitive = FALSE;
4602 if (ok_sensitive && (moved_folder == folder_store)) {
4603 /* Do not allow to move to itself */
4604 ok_sensitive = FALSE;
4606 g_object_unref (moved_folder);
4608 TnyFolder *src_folder = NULL;
4610 /* Moving a message */
4611 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
4613 TnyHeader *header = NULL;
4614 header = modest_msg_view_window_get_header
4615 (MODEST_MSG_VIEW_WINDOW (user_data));
4616 if (!TNY_IS_HEADER(header))
4617 g_warning ("%s: could not get source header", __FUNCTION__);
4619 src_folder = tny_header_get_folder (header);
4622 g_object_unref (header);
4625 TNY_FOLDER (modest_folder_view_get_selected
4626 (MODEST_FOLDER_VIEW (folder_view)));
4629 if (TNY_IS_FOLDER(src_folder)) {
4630 /* Do not allow to move the msg to the same folder */
4631 /* Do not allow to move the msg to an account */
4632 if ((gpointer) src_folder == (gpointer) folder_store ||
4633 TNY_IS_ACCOUNT (folder_store))
4634 ok_sensitive = FALSE;
4635 g_object_unref (src_folder);
4637 g_warning ("%s: could not get source folder", __FUNCTION__);
4641 /* Set sensitivity of the OK button */
4642 gtk_widget_set_sensitive (ok_button, ok_sensitive);
4643 /* Set sensitivity of the NEW button */
4644 gtk_widget_set_sensitive (new_button, new_sensitive);
4648 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
4651 get_folder_view_from_move_to_dialog (GtkWidget *move_to_dialog)
4653 return GTK_WIDGET(g_object_get_data (G_OBJECT(move_to_dialog),
4654 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4658 create_move_to_dialog (GtkWindow *win,
4659 GtkWidget *folder_view,
4660 GtkWidget **tree_view)
4663 #ifdef MODEST_TOOLKIT_HILDON2
4664 GtkWidget *pannable;
4668 GtkWidget *new_button, *ok_button;
4670 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
4672 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
4675 #ifndef MODEST_TOOLKIT_GTK
4676 ok_button = gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
4677 /* We do this manually so GTK+ does not associate a response ID for
4679 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
4680 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
4681 gtk_widget_show (new_button);
4682 #ifndef MODEST_TOOLKIT_HILDON2
4683 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
4686 /* We do this manually so GTK+ does not associate a response ID for
4688 new_button = gtk_button_new_with_label (_("mcen_ti_new_folder"));
4689 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
4690 gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (GTK_DIALOG (dialog)->action_area), new_button, TRUE);
4691 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
4692 ok_button = gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
4693 gtk_container_set_border_width (GTK_CONTAINER (dialog), 12);
4694 gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 24);
4696 g_object_set_data (G_OBJECT (dialog), MOVE_FOLDER_OK_BUTTON, ok_button);
4697 g_object_set_data (G_OBJECT (dialog), MOVE_FOLDER_NEW_BUTTON, new_button);
4699 /* Create scrolled window */
4700 #ifdef MODEST_TOOLKIT_HILDON2
4701 pannable = hildon_pannable_area_new ();
4703 scroll = gtk_scrolled_window_new (NULL, NULL);
4704 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
4705 GTK_POLICY_AUTOMATIC,
4706 GTK_POLICY_AUTOMATIC);
4709 #ifdef MODEST_TOOLKIT_GTK
4710 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN);
4713 /* Create folder view */
4714 *tree_view = modest_platform_create_folder_view (NULL);
4716 /* Track changes in the selection to
4717 * disable the OK button whenever "Move to" is not possible
4718 * disbale NEW button whenever New is not possible */
4719 g_signal_connect (*tree_view,
4720 "folder_selection_changed",
4721 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
4724 /* Listen to clicks on New button */
4725 g_signal_connect (G_OBJECT (new_button),
4727 G_CALLBACK(create_move_to_dialog_on_new_folder),
4730 /* It could happen that we're trying to move a message from a
4731 window (msg window for example) after the main window was
4732 closed, so we can not just get the model of the folder
4734 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4735 const gchar *visible_id = NULL;
4737 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4738 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4739 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4740 MODEST_FOLDER_VIEW(*tree_view));
4743 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4745 /* Show the same account than the one that is shown in the main window */
4746 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
4749 const gchar *active_account_name = NULL;
4750 ModestAccountMgr *mgr = NULL;
4751 ModestAccountSettings *settings = NULL;
4752 ModestServerAccountSettings *store_settings = NULL;
4754 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4755 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4756 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
4757 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
4759 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4760 mgr = modest_runtime_get_account_mgr ();
4761 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4764 const gchar *store_account_name;
4765 store_settings = modest_account_settings_get_store_settings (settings);
4766 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4768 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
4769 store_account_name);
4770 g_object_unref (store_settings);
4771 g_object_unref (settings);
4775 /* we keep a pointer to the embedded folder view, so we can retrieve it with
4776 * get_folder_view_from_move_to_dialog
4777 * (see above) later (needed for focus handling)
4779 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, *tree_view);
4782 /* Hide special folders */
4783 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
4785 #ifdef MODEST_TOOLKIT_HILDON2
4786 gtk_container_add (GTK_CONTAINER (pannable), *tree_view);
4787 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
4788 pannable, TRUE, TRUE, 0);
4790 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
4791 /* Add scroll to dialog */
4792 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
4793 scroll, TRUE, TRUE, 0);
4797 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4798 #ifndef MODEST_TOOLKIT_GTK
4799 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
4801 gtk_window_set_default_size (GTK_WINDOW (dialog), 600, 400);
4810 * Shows a confirmation dialog to the user when we're moving messages
4811 * from a remote server to the local storage. Returns the dialog
4812 * response. If it's other kind of movement then it always returns
4815 * This one is used by the next functions:
4816 * modest_ui_actions_on_paste - commented out
4817 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4820 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4821 TnyFolder *dest_folder,
4825 gint response = GTK_RESPONSE_OK;
4826 TnyAccount *account = NULL;
4827 TnyFolder *src_folder = NULL;
4828 TnyIterator *iter = NULL;
4829 TnyHeader *header = NULL;
4831 /* return with OK if the destination is a remote folder */
4832 if (modest_tny_folder_is_remote_folder (dest_folder))
4833 return GTK_RESPONSE_OK;
4835 /* Get source folder */
4836 iter = tny_list_create_iterator (headers);
4837 header = TNY_HEADER (tny_iterator_get_current (iter));
4839 src_folder = tny_header_get_folder (header);
4840 g_object_unref (header);
4842 g_object_unref (iter);
4844 /* if no src_folder, message may be an attahcment */
4845 if (src_folder == NULL)
4846 return GTK_RESPONSE_CANCEL;
4848 /* If the source is a local or MMC folder */
4849 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4850 g_object_unref (src_folder);
4851 return GTK_RESPONSE_OK;
4854 /* Get the account */
4855 account = tny_folder_get_account (src_folder);
4857 /* now if offline we ask the user */
4858 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4859 response = GTK_RESPONSE_OK;
4861 response = GTK_RESPONSE_CANCEL;
4864 g_object_unref (src_folder);
4865 g_object_unref (account);
4871 move_to_helper_destroyer (gpointer user_data)
4873 MoveToHelper *helper = (MoveToHelper *) user_data;
4875 /* Close the "Pasting" information banner */
4876 if (helper->banner) {
4877 gtk_widget_destroy (GTK_WIDGET (helper->banner));
4878 g_object_unref (helper->banner);
4880 if (gtk_tree_row_reference_valid (helper->reference)) {
4881 gtk_tree_row_reference_free (helper->reference);
4882 helper->reference = NULL;
4888 move_to_cb (ModestMailOperation *mail_op,
4891 MoveToHelper *helper = (MoveToHelper *) user_data;
4893 /* Note that the operation could have failed, in that case do
4895 if (modest_mail_operation_get_status (mail_op) ==
4896 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
4898 GObject *object = modest_mail_operation_get_source (mail_op);
4899 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4900 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4902 if (!modest_msg_view_window_select_next_message (self) &&
4903 !modest_msg_view_window_select_previous_message (self)) {
4904 /* No more messages to view, so close this window */
4905 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4907 } else if (MODEST_IS_MAIN_WINDOW (object) &&
4908 gtk_tree_row_reference_valid (helper->reference)) {
4909 GtkWidget *header_view;
4911 GtkTreeSelection *sel;
4913 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4914 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4915 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
4916 path = gtk_tree_row_reference_get_path (helper->reference);
4917 /* We need to unselect the previous one
4918 because we could be copying instead of
4920 gtk_tree_selection_unselect_all (sel);
4921 gtk_tree_selection_select_path (sel, path);
4922 gtk_tree_path_free (path);
4924 g_object_unref (object);
4926 /* Destroy the helper */
4927 move_to_helper_destroyer (helper);
4931 folder_move_to_cb (ModestMailOperation *mail_op,
4932 TnyFolder *new_folder,
4935 GtkWidget *folder_view;
4938 object = modest_mail_operation_get_source (mail_op);
4939 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4940 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4941 g_object_ref (folder_view);
4942 g_object_unref (object);
4943 move_to_cb (mail_op, user_data);
4944 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
4945 g_object_unref (folder_view);
4949 msgs_move_to_cb (ModestMailOperation *mail_op,
4952 move_to_cb (mail_op, user_data);
4956 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
4959 ModestWindow *main_window = NULL;
4961 /* Disable next automatic folder selection */
4962 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
4963 FALSE); /* don't create */
4965 GObject *win = NULL;
4966 GtkWidget *folder_view = NULL;
4968 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
4969 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4970 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
4972 if (user_data && TNY_IS_FOLDER (user_data)) {
4973 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
4974 TNY_FOLDER (user_data), FALSE);
4977 /* Show notification dialog only if the main window exists */
4978 win = modest_mail_operation_get_source (mail_op);
4979 modest_platform_run_information_dialog ((GtkWindow *) win,
4980 _("mail_in_ui_folder_move_target_error"),
4983 g_object_unref (win);
4988 open_msg_for_purge_cb (ModestMailOperation *mail_op,
4997 gint pending_purges = 0;
4998 gboolean some_purged = FALSE;
4999 ModestWindow *win = MODEST_WINDOW (user_data);
5000 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5002 /* If there was any error */
5003 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5004 modest_window_mgr_unregister_header (mgr, header);
5008 /* Once the message has been retrieved for purging, we check if
5009 * it's all ok for purging */
5011 parts = tny_simple_list_new ();
5012 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5013 iter = tny_list_create_iterator (parts);
5015 while (!tny_iterator_is_done (iter)) {
5017 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5018 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5019 if (tny_mime_part_is_purged (part))
5026 g_object_unref (part);
5028 tny_iterator_next (iter);
5030 g_object_unref (iter);
5033 if (pending_purges>0) {
5035 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5037 if (response == GTK_RESPONSE_OK) {
5040 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5041 iter = tny_list_create_iterator (parts);
5042 while (!tny_iterator_is_done (iter)) {
5045 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5046 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5047 tny_mime_part_set_purged (part);
5050 g_object_unref (part);
5052 tny_iterator_next (iter);
5054 g_object_unref (iter);
5056 tny_msg_rewrite_cache (msg);
5058 gtk_widget_destroy (info);
5062 modest_window_mgr_unregister_header (mgr, header);
5064 g_object_unref (parts);
5068 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5069 ModestMainWindow *win)
5071 GtkWidget *header_view;
5072 TnyList *header_list;
5074 TnyHeaderFlags flags;
5075 ModestWindow *msg_view_window = NULL;
5078 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5080 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5081 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5083 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5085 g_warning ("%s: no header selected", __FUNCTION__);
5089 if (tny_list_get_length (header_list) == 1) {
5090 TnyIterator *iter = tny_list_create_iterator (header_list);
5091 header = TNY_HEADER (tny_iterator_get_current (iter));
5092 g_object_unref (iter);
5096 if (!header || !TNY_IS_HEADER(header)) {
5097 g_warning ("%s: header is not valid", __FUNCTION__);
5101 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5102 header, &msg_view_window);
5103 flags = tny_header_get_flags (header);
5104 if (!(flags & TNY_HEADER_FLAG_CACHED))
5107 if (msg_view_window != NULL)
5108 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5110 /* do nothing; uid was registered before, so window is probably on it's way */
5111 g_warning ("debug: header %p has already been registered", header);
5114 ModestMailOperation *mail_op = NULL;
5115 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5116 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5117 modest_ui_actions_disk_operations_error_handler,
5119 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5120 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5122 g_object_unref (mail_op);
5125 g_object_unref (header);
5127 g_object_unref (header_list);
5131 * Checks if we need a connection to do the transfer and if the user
5132 * wants to connect to complete it
5135 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5136 TnyFolderStore *src_folder,
5138 TnyFolder *dst_folder,
5139 gboolean delete_originals,
5140 gboolean *need_connection,
5143 TnyAccount *src_account;
5144 gint uncached_msgs = 0;
5146 uncached_msgs = header_list_count_uncached_msgs (headers);
5148 /* We don't need any further check if
5150 * 1- the source folder is local OR
5151 * 2- the device is already online
5153 if (!modest_tny_folder_store_is_remote (src_folder) ||
5154 tny_device_is_online (modest_runtime_get_device())) {
5155 *need_connection = FALSE;
5160 /* We must ask for a connection when
5162 * - the message(s) is not already cached OR
5163 * - the message(s) is cached but the leave_on_server setting
5164 * is FALSE (because we need to sync the source folder to
5165 * delete the message from the server (for IMAP we could do it
5166 * offline, it'll take place the next time we get a
5169 src_account = get_account_from_folder_store (src_folder);
5170 if (uncached_msgs > 0) {
5174 *need_connection = TRUE;
5175 num_headers = tny_list_get_length (headers);
5176 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5178 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5179 GTK_RESPONSE_CANCEL) {
5185 /* The transfer is possible and the user wants to */
5188 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5189 const gchar *account_name;
5190 gboolean leave_on_server;
5192 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5193 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5196 if (leave_on_server == TRUE) {
5197 *need_connection = FALSE;
5199 *need_connection = TRUE;
5202 *need_connection = FALSE;
5207 g_object_unref (src_account);
5211 xfer_messages_error_handler (ModestMailOperation *mail_op,
5214 ModestWindow *main_window = NULL;
5216 /* Disable next automatic folder selection */
5217 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5218 FALSE); /* don't create */
5220 GObject *win = modest_mail_operation_get_source (mail_op);
5221 modest_platform_run_information_dialog ((GtkWindow *) win,
5222 _("mail_in_ui_folder_move_target_error"),
5225 g_object_unref (win);
5227 move_to_helper_destroyer (user_data);
5231 TnyFolderStore *dst_folder;
5236 * Utility function that transfer messages from both the main window
5237 * and the msg view window when using the "Move to" dialog
5240 xfer_messages_performer (gboolean canceled,
5242 GtkWindow *parent_window,
5243 TnyAccount *account,
5246 ModestWindow *win = MODEST_WINDOW (parent_window);
5247 TnyAccount *dst_account = NULL;
5248 gboolean dst_forbids_message_add = FALSE;
5249 XferMsgsHelper *helper;
5250 MoveToHelper *movehelper;
5251 ModestMailOperation *mail_op;
5253 helper = (XferMsgsHelper *) user_data;
5255 if (canceled || err) {
5256 if (!check_memory_full_error ((GtkWidget *) parent_window, err)) {
5257 /* Show the proper error message */
5258 modest_ui_actions_on_account_connection_error (parent_window, account);
5263 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5265 /* tinymail will return NULL for local folders it seems */
5266 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5267 modest_tny_account_get_protocol_type (dst_account),
5268 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_MESSAGE_ADD);
5269 g_object_unref (dst_account);
5271 if (dst_forbids_message_add) {
5272 modest_platform_information_banner (GTK_WIDGET (win),
5274 ngettext("mail_in_ui_folder_move_target_error",
5275 "mail_in_ui_folder_move_targets_error",
5276 tny_list_get_length (helper->headers)));
5280 movehelper = g_new0 (MoveToHelper, 1);
5281 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5282 _CS("ckct_nw_pasting"));
5283 if (movehelper->banner != NULL) {
5284 g_object_ref (movehelper->banner);
5285 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5288 if (MODEST_IS_MAIN_WINDOW (win)) {
5289 GtkWidget *header_view =
5290 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5291 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5292 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5295 /* Perform the mail operation */
5296 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5297 xfer_messages_error_handler,
5299 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5302 modest_mail_operation_xfer_msgs (mail_op,
5304 TNY_FOLDER (helper->dst_folder),
5309 g_object_unref (G_OBJECT (mail_op));
5311 g_object_unref (helper->dst_folder);
5312 g_object_unref (helper->headers);
5313 g_slice_free (XferMsgsHelper, helper);
5317 TnyFolder *src_folder;
5318 TnyFolderStore *dst_folder;
5319 gboolean delete_original;
5320 GtkWidget *folder_view;
5324 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
5325 TnyAccount *account, gpointer user_data)
5327 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5328 GtkTreeSelection *sel;
5329 ModestMailOperation *mail_op = NULL;
5331 if (canceled || err || !MODEST_IS_MAIN_WINDOW (parent_window)) {
5332 g_object_unref (G_OBJECT (info->src_folder));
5333 g_object_unref (G_OBJECT (info->dst_folder));
5338 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5339 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5340 _CS("ckct_nw_pasting"));
5341 if (helper->banner != NULL) {
5342 g_object_ref (helper->banner);
5343 gtk_widget_show (GTK_WIDGET(helper->banner));
5345 /* Clean folder on header view before moving it */
5346 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5347 gtk_tree_selection_unselect_all (sel);
5349 /* Let gtk events run. We need that the folder
5350 view frees its reference to the source
5351 folder *before* issuing the mail operation
5352 so we need the signal handler of selection
5353 changed to happen before the mail
5355 while (gtk_events_pending ())
5356 gtk_main_iteration (); */
5359 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5360 modest_ui_actions_move_folder_error_handler,
5361 info->src_folder, NULL);
5362 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5365 /* Select *after* the changes */
5366 /* TODO: this function hangs UI after transfer */
5367 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
5368 /* TNY_FOLDER (src_folder), TRUE); */
5370 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5371 TNY_FOLDER (info->dst_folder), TRUE);
5372 modest_mail_operation_xfer_folder (mail_op,
5373 TNY_FOLDER (info->src_folder),
5375 info->delete_original,
5378 g_object_unref (G_OBJECT (info->src_folder));
5380 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5383 /* Unref mail operation */
5384 g_object_unref (G_OBJECT (mail_op));
5385 g_object_unref (G_OBJECT (info->dst_folder));
5390 get_account_from_folder_store (TnyFolderStore *folder_store)
5392 if (TNY_IS_ACCOUNT (folder_store))
5393 return g_object_ref (folder_store);
5395 return tny_folder_get_account (TNY_FOLDER (folder_store));
5399 * UI handler for the "Move to" action when invoked from the
5403 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5404 GtkWidget *folder_view,
5405 TnyFolderStore *dst_folder,
5406 ModestMainWindow *win)
5408 ModestHeaderView *header_view = NULL;
5409 TnyFolderStore *src_folder = NULL;
5411 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5413 /* Get the source folder */
5414 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5416 /* Get header view */
5417 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
5419 /* Get folder or messages to transfer */
5420 if (gtk_widget_is_focus (folder_view)) {
5421 gboolean do_xfer = TRUE;
5423 /* Allow only to transfer folders to the local root folder */
5424 if (TNY_IS_ACCOUNT (dst_folder) &&
5425 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5426 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5428 } else if (!TNY_IS_FOLDER (src_folder)) {
5429 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5434 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5435 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5437 info->src_folder = g_object_ref (src_folder);
5438 info->dst_folder = g_object_ref (dst_folder);
5439 info->delete_original = TRUE;
5440 info->folder_view = folder_view;
5442 connect_info->callback = on_move_folder_cb;
5443 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5444 connect_info->data = info;
5446 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5447 TNY_FOLDER_STORE (src_folder),
5450 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5453 headers = modest_header_view_get_selected_headers(header_view);
5455 /* Transfer the messages */
5456 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
5457 headers, TNY_FOLDER (dst_folder));
5459 g_object_unref (headers);
5463 g_object_unref (src_folder);
5468 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
5469 TnyFolder *src_folder,
5471 TnyFolder *dst_folder)
5473 gboolean need_connection = TRUE;
5474 gboolean do_xfer = TRUE;
5475 XferMsgsHelper *helper;
5477 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5478 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5479 g_return_if_fail (TNY_IS_LIST (headers));
5481 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5482 headers, TNY_FOLDER (dst_folder),
5483 TRUE, &need_connection,
5486 /* If we don't want to transfer just return */
5490 /* Create the helper */
5491 helper = g_slice_new (XferMsgsHelper);
5492 helper->dst_folder = g_object_ref (dst_folder);
5493 helper->headers = g_object_ref (headers);
5495 if (need_connection) {
5496 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5497 connect_info->callback = xfer_messages_performer;
5498 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5499 connect_info->data = helper;
5501 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5502 TNY_FOLDER_STORE (src_folder),
5505 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5506 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
5507 src_account, helper);
5508 g_object_unref (src_account);
5513 * UI handler for the "Move to" action when invoked from the
5514 * ModestMsgViewWindow
5517 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
5518 TnyFolderStore *dst_folder,
5519 ModestMsgViewWindow *win)
5521 TnyList *headers = NULL;
5522 TnyHeader *header = NULL;
5523 TnyFolder *src_folder = NULL;
5525 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5527 /* Create header list */
5528 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
5529 src_folder = TNY_FOLDER (tny_header_get_folder(header));
5530 headers = tny_simple_list_new ();
5531 tny_list_append (headers, G_OBJECT (header));
5533 /* Transfer the messages */
5534 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder, headers,
5535 TNY_FOLDER (dst_folder));
5538 g_object_unref (src_folder);
5539 g_object_unref (header);
5540 g_object_unref (headers);
5544 modest_ui_actions_on_move_to (GtkAction *action,
5547 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
5549 TnyFolderStore *dst_folder = NULL;
5550 ModestMainWindow *main_window;
5552 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
5553 MODEST_IS_MSG_VIEW_WINDOW (win));
5555 /* Get the main window if exists */
5556 if (MODEST_IS_MAIN_WINDOW (win))
5557 main_window = MODEST_MAIN_WINDOW (win);
5560 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5561 FALSE)); /* don't create */
5563 /* Get the folder view widget if exists */
5565 folder_view = modest_main_window_get_child_widget (main_window,
5566 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5570 /* Create and run the dialog */
5571 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
5572 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5573 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog), (GtkWindow *) win);
5574 result = gtk_dialog_run (GTK_DIALOG(dialog));
5575 g_object_ref (tree_view);
5576 gtk_widget_destroy (dialog);
5578 if (result != GTK_RESPONSE_ACCEPT)
5581 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
5582 /* Do window specific stuff */
5583 if (MODEST_IS_MAIN_WINDOW (win)) {
5584 modest_ui_actions_on_main_window_move_to (action,
5587 MODEST_MAIN_WINDOW (win));
5589 modest_ui_actions_on_msg_view_window_move_to (action,
5591 MODEST_MSG_VIEW_WINDOW (win));
5595 g_object_unref (dst_folder);
5599 * Calls #HeadersFunc for each header already selected in the main
5600 * window or the message currently being shown in the msg view window
5603 do_headers_action (ModestWindow *win,
5607 TnyList *headers_list = NULL;
5608 TnyIterator *iter = NULL;
5609 TnyHeader *header = NULL;
5610 TnyFolder *folder = NULL;
5613 headers_list = get_selected_headers (win);
5617 /* Get the folder */
5618 iter = tny_list_create_iterator (headers_list);
5619 header = TNY_HEADER (tny_iterator_get_current (iter));
5621 folder = tny_header_get_folder (header);
5622 g_object_unref (header);
5625 /* Call the function for each header */
5626 while (!tny_iterator_is_done (iter)) {
5627 header = TNY_HEADER (tny_iterator_get_current (iter));
5628 func (header, win, user_data);
5629 g_object_unref (header);
5630 tny_iterator_next (iter);
5633 /* Trick: do a poke status in order to speed up the signaling
5635 tny_folder_poke_status (folder);
5638 g_object_unref (folder);
5639 g_object_unref (iter);
5640 g_object_unref (headers_list);
5644 modest_ui_actions_view_attachment (GtkAction *action,
5645 ModestWindow *window)
5647 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5648 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5650 /* not supported window for this action */
5651 g_return_if_reached ();
5656 modest_ui_actions_save_attachments (GtkAction *action,
5657 ModestWindow *window)
5659 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5661 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5664 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5666 /* not supported window for this action */
5667 g_return_if_reached ();
5672 modest_ui_actions_remove_attachments (GtkAction *action,
5673 ModestWindow *window)
5675 if (MODEST_IS_MAIN_WINDOW (window)) {
5676 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
5677 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5678 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5680 /* not supported window for this action */
5681 g_return_if_reached ();
5686 modest_ui_actions_on_settings (GtkAction *action,
5691 dialog = modest_platform_get_global_settings_dialog ();
5692 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
5693 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5694 gtk_widget_show_all (dialog);
5696 gtk_dialog_run (GTK_DIALOG (dialog));
5698 gtk_widget_destroy (dialog);
5702 modest_ui_actions_on_help (GtkAction *action,
5705 /* Help app is not available at all in fremantle */
5706 #ifndef MODEST_TOOLKIT_HILDON2
5707 const gchar *help_id;
5709 g_return_if_fail (win && GTK_IS_WINDOW(win));
5711 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5714 modest_platform_show_help (GTK_WINDOW (win), help_id);
5719 modest_ui_actions_on_csm_help (GtkAction *action,
5722 /* Help app is not available at all in fremantle */
5723 #ifndef MODEST_TOOLKIT_HILDON2
5725 const gchar* help_id = NULL;
5726 GtkWidget *folder_view;
5727 TnyFolderStore *folder_store;
5729 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
5731 /* Get selected folder */
5732 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5733 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5734 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5736 /* Switch help_id */
5737 if (folder_store && TNY_IS_FOLDER (folder_store))
5738 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
5741 g_object_unref (folder_store);
5744 modest_platform_show_help (GTK_WINDOW (win), help_id);
5746 modest_ui_actions_on_help (action, win);
5751 retrieve_contents_cb (ModestMailOperation *mail_op,
5758 /* We only need this callback to show an error in case of
5759 memory low condition */
5760 modest_ui_actions_msg_retrieval_check (mail_op, header, msg);
5764 retrieve_msg_contents_performer (gboolean canceled,
5766 GtkWindow *parent_window,
5767 TnyAccount *account,
5770 ModestMailOperation *mail_op;
5771 TnyList *headers = TNY_LIST (user_data);
5773 if (err || canceled) {
5774 check_memory_full_error ((GtkWidget *) parent_window, err);
5778 /* Create mail operation */
5779 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5780 modest_ui_actions_disk_operations_error_handler,
5782 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5783 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
5786 g_object_unref (mail_op);
5788 g_object_unref (headers);
5789 g_object_unref (account);
5793 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5794 ModestWindow *window)
5796 TnyList *headers = NULL;
5797 TnyAccount *account = NULL;
5798 TnyIterator *iter = NULL;
5799 TnyHeader *header = NULL;
5800 TnyFolder *folder = NULL;
5803 headers = get_selected_headers (window);
5807 /* Pick the account */
5808 iter = tny_list_create_iterator (headers);
5809 header = TNY_HEADER (tny_iterator_get_current (iter));
5810 folder = tny_header_get_folder (header);
5811 account = tny_folder_get_account (folder);
5812 g_object_unref (folder);
5813 g_object_unref (header);
5814 g_object_unref (iter);
5816 /* Connect and perform the message retrieval */
5817 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
5818 g_object_ref (account),
5819 retrieve_msg_contents_performer,
5820 g_object_ref (headers));
5823 g_object_unref (account);
5824 g_object_unref (headers);
5828 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
5830 g_return_if_fail (MODEST_IS_WINDOW (window));
5833 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
5837 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
5839 g_return_if_fail (MODEST_IS_WINDOW (window));
5842 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
5846 modest_ui_actions_on_email_menu_activated (GtkAction *action,
5847 ModestWindow *window)
5849 g_return_if_fail (MODEST_IS_WINDOW (window));
5852 modest_ui_actions_check_menu_dimming_rules (window);
5856 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
5857 ModestWindow *window)
5859 g_return_if_fail (MODEST_IS_WINDOW (window));
5862 modest_ui_actions_check_menu_dimming_rules (window);
5866 modest_ui_actions_on_view_menu_activated (GtkAction *action,
5867 ModestWindow *window)
5869 g_return_if_fail (MODEST_IS_WINDOW (window));
5872 modest_ui_actions_check_menu_dimming_rules (window);
5876 modest_ui_actions_on_format_menu_activated (GtkAction *action,
5877 ModestWindow *window)
5879 g_return_if_fail (MODEST_IS_WINDOW (window));
5882 modest_ui_actions_check_menu_dimming_rules (window);
5886 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
5887 ModestWindow *window)
5889 g_return_if_fail (MODEST_IS_WINDOW (window));
5892 modest_ui_actions_check_menu_dimming_rules (window);
5896 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
5897 ModestWindow *window)
5899 g_return_if_fail (MODEST_IS_WINDOW (window));
5902 modest_ui_actions_check_menu_dimming_rules (window);
5906 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
5907 ModestWindow *window)
5909 g_return_if_fail (MODEST_IS_WINDOW (window));
5912 modest_ui_actions_check_menu_dimming_rules (window);
5916 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
5917 ModestWindow *window)
5919 g_return_if_fail (MODEST_IS_WINDOW (window));
5922 modest_ui_actions_check_menu_dimming_rules (window);
5926 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
5927 ModestWindow *window)
5929 g_return_if_fail (MODEST_IS_WINDOW (window));
5932 modest_ui_actions_check_menu_dimming_rules (window);
5936 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
5938 g_return_if_fail (MODEST_IS_WINDOW (window));
5940 /* we check for low-mem; in that case, show a warning, and don't allow
5943 if (modest_platform_check_memory_low (window, TRUE))
5946 modest_platform_show_search_messages (GTK_WINDOW (window));
5950 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
5952 g_return_if_fail (MODEST_IS_WINDOW (win));
5955 /* we check for low-mem; in that case, show a warning, and don't allow
5956 * for the addressbook
5958 if (modest_platform_check_memory_low (win, TRUE))
5962 modest_platform_show_addressbook (GTK_WINDOW (win));
5967 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
5968 ModestWindow *window)
5970 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5972 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
5976 on_send_receive_finished (ModestMailOperation *mail_op,
5979 GtkWidget *header_view, *folder_view;
5980 TnyFolderStore *folder_store;
5981 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
5983 /* Set send/receive operation finished */
5984 modest_main_window_notify_send_receive_completed (main_win);
5986 /* Don't refresh the current folder if there were any errors */
5987 if (modest_mail_operation_get_status (mail_op) !=
5988 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5991 /* Refresh the current folder if we're viewing a window. We do
5992 this because the user won't be able to see the new mails in
5993 the selected folder after a Send&Receive because it only
5994 performs a poke_status, i.e, only the number of read/unread
5995 messages is updated, but the new headers are not
5997 folder_view = modest_main_window_get_child_widget (main_win,
5998 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6002 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6004 /* Do not need to refresh INBOX again because the
6005 update_account does it always automatically */
6006 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6007 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6008 ModestMailOperation *refresh_op;
6010 header_view = modest_main_window_get_child_widget (main_win,
6011 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6013 /* We do not need to set the contents style
6014 because it hasn't changed. We also do not
6015 need to save the widget status. Just force
6017 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6018 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6019 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6020 folder_refreshed_cb, main_win);
6021 g_object_unref (refresh_op);
6025 g_object_unref (folder_store);
6030 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6036 const gchar* server_name = NULL;
6037 TnyTransportAccount *server_account;
6038 gchar *message = NULL;
6040 /* Don't show anything if the user cancelled something or the
6041 * send receive request is not interactive. Authentication
6042 * errors are managed by the account store so no need to show
6043 * a dialog here again */
6044 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6045 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6046 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6050 /* Get the server name: */
6052 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
6054 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
6056 g_return_if_reached ();
6058 /* Show the appropriate message text for the GError: */
6059 switch (err->code) {
6060 case TNY_SERVICE_ERROR_CONNECT:
6061 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6063 case TNY_SERVICE_ERROR_SEND:
6064 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
6066 case TNY_SERVICE_ERROR_UNAVAILABLE:
6067 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6070 g_warning ("%s: unexpected ERROR %d",
6071 __FUNCTION__, err->code);
6072 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
6076 modest_platform_run_information_dialog (NULL, message, FALSE);
6078 g_object_unref (server_account);
6082 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6087 ModestMainWindow *main_window = NULL;
6088 ModestWindowMgr *mgr = NULL;
6089 GtkWidget *folder_view = NULL, *header_view = NULL;
6090 TnyFolderStore *selected_folder = NULL;
6091 TnyFolderType folder_type;
6093 mgr = modest_runtime_get_window_mgr ();
6094 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr,
6095 FALSE));/* don't create */
6099 /* Check if selected folder is OUTBOX */
6100 folder_view = modest_main_window_get_child_widget (main_window,
6101 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6102 header_view = modest_main_window_get_child_widget (main_window,
6103 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6105 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6106 if (!TNY_IS_FOLDER (selected_folder))
6109 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6110 #if GTK_CHECK_VERSION(2, 8, 0)
6111 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
6112 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6113 GtkTreeViewColumn *tree_column;
6115 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6116 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6118 gtk_tree_view_column_queue_resize (tree_column);
6121 gtk_widget_queue_draw (header_view);
6124 /* Rerun dimming rules, because the message could become deletable for example */
6125 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6126 MODEST_DIMMING_RULES_TOOLBAR);
6127 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6128 MODEST_DIMMING_RULES_MENU);
6132 if (selected_folder != NULL)
6133 g_object_unref (selected_folder);
6137 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6138 TnyAccount *account)
6140 ModestProtocolType protocol_type;
6141 ModestProtocol *protocol;
6142 gchar *error_note = NULL;
6144 protocol_type = modest_tny_account_get_protocol_type (account);
6145 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6148 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6149 if (error_note == NULL) {
6150 g_warning ("%s: This should not be reached", __FUNCTION__);
6152 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6153 g_free (error_note);
6158 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6162 TnyFolderStore *folder = NULL;
6163 TnyAccount *account = NULL;
6164 ModestProtocolType proto;
6165 ModestProtocol *protocol;
6166 TnyHeader *header = NULL;
6168 if (MODEST_IS_MAIN_WINDOW (win)) {
6169 GtkWidget *header_view;
6170 TnyList* headers = NULL;
6172 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6173 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6174 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6175 if (!headers || tny_list_get_length (headers) == 0) {
6177 g_object_unref (headers);
6180 iter = tny_list_create_iterator (headers);
6181 header = TNY_HEADER (tny_iterator_get_current (iter));
6182 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6183 g_object_unref (iter);
6184 g_object_unref (headers);
6185 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6186 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6187 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6190 /* Get the account type */
6191 account = tny_folder_get_account (TNY_FOLDER (folder));
6192 proto = modest_tny_account_get_protocol_type (account);
6193 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6196 subject = tny_header_dup_subject (header);
6197 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6201 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6205 g_object_unref (account);
6206 g_object_unref (folder);
6207 g_object_unref (header);
6213 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6214 const gchar *account_name,
6215 const gchar *account_title)
6217 ModestAccountMgr *account_mgr;
6220 ModestProtocol *protocol;
6221 gboolean removed = FALSE;
6223 g_return_val_if_fail (account_name, FALSE);
6224 g_return_val_if_fail (account_title, FALSE);
6226 account_mgr = modest_runtime_get_account_mgr();
6228 /* The warning text depends on the account type: */
6229 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6230 modest_account_mgr_get_store_protocol (account_mgr,
6232 txt = modest_protocol_get_translation (protocol,
6233 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6236 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6238 response = modest_platform_run_confirmation_dialog (parent_window, txt);
6242 if (response == GTK_RESPONSE_OK) {
6243 /* Remove account. If it succeeds then it also removes
6244 the account from the ModestAccountView: */
6245 gboolean is_default = FALSE;
6246 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6247 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6249 g_free (default_account_name);
6251 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6253 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);