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"),
3623 _("mcen_bd_dialog_ok"),
3624 GTK_RESPONSE_ACCEPT,
3625 _("mcen_bd_dialog_cancel"),
3626 GTK_RESPONSE_REJECT,
3628 #endif /* MODEST_TOOLKIT_HILDON2 */
3631 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3635 GTK_RESPONSE_REJECT,
3637 GTK_RESPONSE_ACCEPT,
3639 #endif /* MODEST_TOOLKIT_GTK */
3641 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3643 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3644 modest_runtime_get_account_mgr(), server_account_name);
3645 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3646 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3649 gtk_widget_destroy (dialog);
3653 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3654 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
3657 g_free (server_name);
3661 gchar *initial_username = modest_account_mgr_get_server_account_username (
3662 modest_runtime_get_account_mgr(), server_account_name);
3664 GtkWidget *entry_username = gtk_entry_new ();
3665 if (initial_username)
3666 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
3667 /* Dim this if a connection has ever succeeded with this username,
3668 * as per the UI spec: */
3669 /* const gboolean username_known = */
3670 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3671 /* modest_runtime_get_account_mgr(), server_account_name); */
3672 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3674 /* We drop the username sensitive code and disallow changing it here
3675 * as tinymail does not support really changing the username in the callback
3677 gtk_widget_set_sensitive (entry_username, FALSE);
3679 #ifndef MODEST_TOOLKIT_GTK
3680 /* Auto-capitalization is the default, so let's turn it off: */
3681 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3683 /* Create a size group to be used by all captions.
3684 * Note that HildonCaption does not create a default size group if we do not specify one.
3685 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3686 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3688 GtkWidget *caption = hildon_caption_new (sizegroup,
3689 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
3690 gtk_widget_show (entry_username);
3691 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3692 FALSE, FALSE, MODEST_MARGIN_HALF);
3693 gtk_widget_show (caption);
3695 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
3697 #endif /* !MODEST_TOOLKIT_GTK */
3700 GtkWidget *entry_password = gtk_entry_new ();
3701 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3702 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3704 #ifndef MODEST_TOOLKIT_GTK
3705 /* Auto-capitalization is the default, so let's turn it off: */
3706 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3707 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3709 caption = hildon_caption_new (sizegroup,
3710 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
3711 gtk_widget_show (entry_password);
3712 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3713 FALSE, FALSE, MODEST_MARGIN_HALF);
3714 gtk_widget_show (caption);
3715 g_object_unref (sizegroup);
3717 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
3719 #endif /* !MODEST_TOOLKIT_GTK */
3721 if (initial_username != NULL)
3722 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3724 /* This is not in the Maemo UI spec:
3725 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3726 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3730 fields = g_slice_new0 (PasswordDialogFields);
3731 fields->username = entry_username;
3732 fields->password = entry_password;
3733 fields->dialog = dialog;
3735 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3736 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3737 password_dialog_check_field (NULL, fields);
3739 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3741 while (!completed) {
3743 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3745 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
3747 /* Note that an empty field becomes the "" string */
3748 if (*username && strlen (*username) > 0) {
3749 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
3750 server_account_name,
3754 const gboolean username_was_changed =
3755 (strcmp (*username, initial_username) != 0);
3756 if (username_was_changed) {
3757 g_warning ("%s: tinymail does not yet support changing the "
3758 "username in the get_password() callback.\n", __FUNCTION__);
3764 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
3765 _("mcen_ib_username_pw_incorrect"));
3771 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
3773 /* We do not save the password in the configuration,
3774 * because this function is only called for passwords that should
3775 * not be remembered:
3776 modest_server_account_set_password (
3777 modest_runtime_get_account_mgr(), server_account_name,
3784 #ifndef MODEST_TOOLKIT_HILDON2
3785 /* Set parent to NULL or the banner will disappear with its parent dialog */
3786 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
3798 /* This is not in the Maemo UI spec:
3799 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3805 g_free (initial_username);
3806 gtk_widget_destroy (dialog);
3807 g_slice_free (PasswordDialogFields, fields);
3809 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3813 modest_ui_actions_on_cut (GtkAction *action,
3814 ModestWindow *window)
3816 GtkWidget *focused_widget;
3817 GtkClipboard *clipboard;
3819 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3820 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3821 if (GTK_IS_EDITABLE (focused_widget)) {
3822 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3823 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3824 gtk_clipboard_store (clipboard);
3825 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3826 GtkTextBuffer *buffer;
3828 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3829 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3830 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3831 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3832 gtk_clipboard_store (clipboard);
3834 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3835 TnyList *header_list = modest_header_view_get_selected_headers (
3836 MODEST_HEADER_VIEW (focused_widget));
3837 gboolean continue_download = FALSE;
3838 gint num_of_unc_msgs;
3840 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3842 if (num_of_unc_msgs) {
3843 TnyAccount *account = get_account_from_header_list (header_list);
3845 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3846 g_object_unref (account);
3850 if (num_of_unc_msgs == 0 || continue_download) {
3851 /* modest_platform_information_banner (
3852 NULL, NULL, _CS("mcen_ib_getting_items"));*/
3853 modest_header_view_cut_selection (
3854 MODEST_HEADER_VIEW (focused_widget));
3857 g_object_unref (header_list);
3858 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3859 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3864 modest_ui_actions_on_copy (GtkAction *action,
3865 ModestWindow *window)
3867 GtkClipboard *clipboard;
3868 GtkWidget *focused_widget;
3869 gboolean copied = TRUE;
3871 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3872 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3874 if (GTK_IS_LABEL (focused_widget)) {
3876 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
3877 gtk_clipboard_set_text (clipboard, selection, -1);
3879 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3880 gtk_clipboard_store (clipboard);
3881 } else if (GTK_IS_EDITABLE (focused_widget)) {
3882 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3883 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3884 gtk_clipboard_store (clipboard);
3885 } else if (GTK_IS_HTML (focused_widget)) {
3888 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
3889 if ((sel == NULL) || (sel[0] == '\0')) {
3892 gtk_html_copy (GTK_HTML (focused_widget));
3893 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3894 gtk_clipboard_store (clipboard);
3896 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3897 GtkTextBuffer *buffer;
3898 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3899 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3900 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3901 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3902 gtk_clipboard_store (clipboard);
3904 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3905 TnyList *header_list = modest_header_view_get_selected_headers (
3906 MODEST_HEADER_VIEW (focused_widget));
3907 gboolean continue_download = FALSE;
3908 gint num_of_unc_msgs;
3910 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3912 if (num_of_unc_msgs) {
3913 TnyAccount *account = get_account_from_header_list (header_list);
3915 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3916 g_object_unref (account);
3920 if (num_of_unc_msgs == 0 || continue_download) {
3921 modest_platform_information_banner (
3922 NULL, NULL, _CS("mcen_ib_getting_items"));
3923 modest_header_view_copy_selection (
3924 MODEST_HEADER_VIEW (focused_widget));
3928 g_object_unref (header_list);
3930 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3931 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3934 /* Show information banner if there was a copy to clipboard */
3936 modest_platform_information_banner (
3937 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3941 modest_ui_actions_on_undo (GtkAction *action,
3942 ModestWindow *window)
3944 ModestEmailClipboard *clipboard = NULL;
3946 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3947 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3948 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3949 /* Clear clipboard source */
3950 clipboard = modest_runtime_get_email_clipboard ();
3951 modest_email_clipboard_clear (clipboard);
3954 g_return_if_reached ();
3959 modest_ui_actions_on_redo (GtkAction *action,
3960 ModestWindow *window)
3962 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3963 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3966 g_return_if_reached ();
3972 destroy_information_note (ModestMailOperation *mail_op,
3975 /* destroy information note */
3976 gtk_widget_destroy (GTK_WIDGET(user_data));
3980 destroy_folder_information_note (ModestMailOperation *mail_op,
3981 TnyFolder *new_folder,
3984 /* destroy information note */
3985 gtk_widget_destroy (GTK_WIDGET(user_data));
3990 paste_as_attachment_free (gpointer data)
3992 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3994 if (helper->banner) {
3995 gtk_widget_destroy (helper->banner);
3996 g_object_unref (helper->banner);
4002 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4007 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4008 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4013 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4018 modest_ui_actions_on_paste (GtkAction *action,
4019 ModestWindow *window)
4021 GtkWidget *focused_widget = NULL;
4022 GtkWidget *inf_note = NULL;
4023 ModestMailOperation *mail_op = NULL;
4025 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4026 if (GTK_IS_EDITABLE (focused_widget)) {
4027 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4028 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4029 ModestEmailClipboard *e_clipboard = NULL;
4030 e_clipboard = modest_runtime_get_email_clipboard ();
4031 if (modest_email_clipboard_cleared (e_clipboard)) {
4032 GtkTextBuffer *buffer;
4033 GtkClipboard *clipboard;
4035 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4036 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4037 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4038 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4039 ModestMailOperation *mail_op;
4040 TnyFolder *src_folder = NULL;
4041 TnyList *data = NULL;
4043 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4044 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4045 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4046 _CS("ckct_nw_pasting"));
4047 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4048 mail_op = modest_mail_operation_new (G_OBJECT (window));
4049 if (helper->banner != NULL) {
4050 g_object_ref (G_OBJECT (helper->banner));
4051 gtk_widget_show (GTK_WIDGET (helper->banner));
4055 modest_mail_operation_get_msgs_full (mail_op,
4057 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4059 paste_as_attachment_free);
4063 g_object_unref (data);
4065 g_object_unref (src_folder);
4068 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4069 ModestEmailClipboard *clipboard = NULL;
4070 TnyFolder *src_folder = NULL;
4071 TnyFolderStore *folder_store = NULL;
4072 TnyList *data = NULL;
4073 gboolean delete = FALSE;
4075 /* Check clipboard source */
4076 clipboard = modest_runtime_get_email_clipboard ();
4077 if (modest_email_clipboard_cleared (clipboard))
4080 /* Get elements to paste */
4081 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4083 /* Create a new mail operation */
4084 mail_op = modest_mail_operation_new (G_OBJECT(window));
4086 /* Get destination folder */
4087 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4089 /* transfer messages */
4093 /* Ask for user confirmation */
4095 modest_ui_actions_msgs_move_to_confirmation (window,
4096 TNY_FOLDER (folder_store),
4100 if (response == GTK_RESPONSE_OK) {
4101 /* Launch notification */
4102 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4103 _CS("ckct_nw_pasting"));
4104 if (inf_note != NULL) {
4105 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4106 gtk_widget_show (GTK_WIDGET(inf_note));
4109 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4110 modest_mail_operation_xfer_msgs (mail_op,
4112 TNY_FOLDER (folder_store),
4114 destroy_information_note,
4117 g_object_unref (mail_op);
4120 } else if (src_folder != NULL) {
4121 /* Launch notification */
4122 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4123 _CS("ckct_nw_pasting"));
4124 if (inf_note != NULL) {
4125 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4126 gtk_widget_show (GTK_WIDGET(inf_note));
4129 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4130 modest_mail_operation_xfer_folder (mail_op,
4134 destroy_folder_information_note,
4140 g_object_unref (data);
4141 if (src_folder != NULL)
4142 g_object_unref (src_folder);
4143 if (folder_store != NULL)
4144 g_object_unref (folder_store);
4150 modest_ui_actions_on_select_all (GtkAction *action,
4151 ModestWindow *window)
4153 GtkWidget *focused_widget;
4155 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4156 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4157 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4158 } else if (GTK_IS_LABEL (focused_widget)) {
4159 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4160 } else if (GTK_IS_EDITABLE (focused_widget)) {
4161 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4162 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4163 GtkTextBuffer *buffer;
4164 GtkTextIter start, end;
4166 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4167 gtk_text_buffer_get_start_iter (buffer, &start);
4168 gtk_text_buffer_get_end_iter (buffer, &end);
4169 gtk_text_buffer_select_range (buffer, &start, &end);
4170 } else if (GTK_IS_HTML (focused_widget)) {
4171 gtk_html_select_all (GTK_HTML (focused_widget));
4172 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4173 GtkWidget *header_view = focused_widget;
4174 GtkTreeSelection *selection = NULL;
4176 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4177 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4178 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4181 /* Disable window dimming management */
4182 modest_window_disable_dimming (MODEST_WINDOW(window));
4184 /* Select all messages */
4185 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4186 gtk_tree_selection_select_all (selection);
4188 /* Set focuse on header view */
4189 gtk_widget_grab_focus (header_view);
4191 /* Enable window dimming management */
4192 modest_window_enable_dimming (MODEST_WINDOW(window));
4193 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4194 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4200 modest_ui_actions_on_mark_as_read (GtkAction *action,
4201 ModestWindow *window)
4203 g_return_if_fail (MODEST_IS_WINDOW(window));
4205 /* Mark each header as read */
4206 do_headers_action (window, headers_action_mark_as_read, NULL);
4210 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4211 ModestWindow *window)
4213 g_return_if_fail (MODEST_IS_WINDOW(window));
4215 /* Mark each header as read */
4216 do_headers_action (window, headers_action_mark_as_unread, NULL);
4220 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4221 GtkRadioAction *selected,
4222 ModestWindow *window)
4226 value = gtk_radio_action_get_current_value (selected);
4227 if (MODEST_IS_WINDOW (window)) {
4228 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4233 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4234 GtkRadioAction *selected,
4235 ModestWindow *window)
4237 TnyHeaderFlags flags;
4238 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4240 flags = gtk_radio_action_get_current_value (selected);
4241 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4245 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4246 GtkRadioAction *selected,
4247 ModestWindow *window)
4251 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4253 file_format = gtk_radio_action_get_current_value (selected);
4254 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4259 modest_ui_actions_on_zoom_plus (GtkAction *action,
4260 ModestWindow *window)
4262 g_return_if_fail (MODEST_IS_WINDOW (window));
4264 modest_window_zoom_plus (MODEST_WINDOW (window));
4268 modest_ui_actions_on_zoom_minus (GtkAction *action,
4269 ModestWindow *window)
4271 g_return_if_fail (MODEST_IS_WINDOW (window));
4273 modest_window_zoom_minus (MODEST_WINDOW (window));
4277 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4278 ModestWindow *window)
4280 ModestWindowMgr *mgr;
4281 gboolean fullscreen, active;
4282 g_return_if_fail (MODEST_IS_WINDOW (window));
4284 mgr = modest_runtime_get_window_mgr ();
4286 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4287 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4289 if (active != fullscreen) {
4290 modest_window_mgr_set_fullscreen_mode (mgr, active);
4291 #ifndef MODEST_TOOLKIT_HILDON2
4292 gtk_window_present (GTK_WINDOW (window));
4298 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4299 ModestWindow *window)
4301 ModestWindowMgr *mgr;
4302 gboolean fullscreen;
4304 g_return_if_fail (MODEST_IS_WINDOW (window));
4306 mgr = modest_runtime_get_window_mgr ();
4307 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4308 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4310 #ifndef MODEST_TOOLKIT_HILDON2
4311 gtk_window_present (GTK_WINDOW (window));
4316 * Used by modest_ui_actions_on_details to call do_headers_action
4319 headers_action_show_details (TnyHeader *header,
4320 ModestWindow *window,
4324 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header);
4328 * Show the header details in a ModestDetailsDialog widget
4331 modest_ui_actions_on_details (GtkAction *action,
4334 TnyList * headers_list;
4338 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4341 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4344 g_object_unref (msg);
4346 headers_list = get_selected_headers (win);
4350 iter = tny_list_create_iterator (headers_list);
4352 header = TNY_HEADER (tny_iterator_get_current (iter));
4354 headers_action_show_details (header, win, NULL);
4355 g_object_unref (header);
4358 g_object_unref (iter);
4359 g_object_unref (headers_list);
4361 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4362 GtkWidget *folder_view, *header_view;
4364 /* Check which widget has the focus */
4365 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4366 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4367 if (gtk_widget_is_focus (folder_view)) {
4368 TnyFolderStore *folder_store
4369 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4370 if (!folder_store) {
4371 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4374 /* Show only when it's a folder */
4375 /* This function should not be called for account items,
4376 * because we dim the menu item for them. */
4377 if (TNY_IS_FOLDER (folder_store)) {
4378 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4379 TNY_FOLDER (folder_store));
4382 g_object_unref (folder_store);
4385 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4386 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4387 /* Show details of each header */
4388 do_headers_action (win, headers_action_show_details, header_view);
4394 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4395 ModestMsgEditWindow *window)
4397 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4399 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4403 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4404 ModestMsgEditWindow *window)
4406 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4408 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4412 modest_ui_actions_toggle_folders_view (GtkAction *action,
4413 ModestMainWindow *main_window)
4415 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4417 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4418 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4420 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4424 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4425 ModestWindow *window)
4427 gboolean active, fullscreen = FALSE;
4428 ModestWindowMgr *mgr;
4430 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4432 /* Check if we want to toggle the toolbar view in fullscreen
4434 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4435 "ViewShowToolbarFullScreen")) {
4439 /* Toggle toolbar */
4440 mgr = modest_runtime_get_window_mgr ();
4441 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4445 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4446 ModestMsgEditWindow *window)
4448 modest_msg_edit_window_select_font (window);
4453 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4454 const gchar *display_name,
4457 /* don't update the display name if it was already set;
4458 * updating the display name apparently is expensive */
4459 const gchar* old_name = gtk_window_get_title (window);
4461 if (display_name == NULL)
4464 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4465 return; /* don't do anything */
4467 /* This is usually used to change the title of the main window, which
4468 * is the one that holds the folder view. Note that this change can
4469 * happen even when the widget doesn't have the focus. */
4470 gtk_window_set_title (window, display_name);
4475 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4477 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4478 modest_msg_edit_window_select_contacts (window);
4482 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4484 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4485 modest_msg_edit_window_check_names (window, FALSE);
4489 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
4491 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
4492 GTK_WIDGET (user_data));
4496 * This function is used to track changes in the selection of the
4497 * folder view that is inside the "move to" dialog to enable/disable
4498 * the OK button because we do not want the user to select a disallowed
4499 * destination for a folder.
4500 * The user also not desired to be able to use NEW button on items where
4501 * folder creation is not possibel.
4504 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4505 TnyFolderStore *folder_store,
4509 GtkWidget *dialog = NULL;
4510 GtkWidget *ok_button = NULL, *new_button = NULL;
4511 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4512 gboolean moving_folder = FALSE;
4513 gboolean is_local_account = TRUE;
4514 GtkWidget *folder_view = NULL;
4515 ModestTnyFolderRules rules;
4517 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
4522 /* Get the OK button */
4523 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
4527 ok_button = g_object_get_data (G_OBJECT (dialog), MOVE_FOLDER_OK_BUTTON);
4528 new_button = g_object_get_data (G_OBJECT (dialog), MOVE_FOLDER_NEW_BUTTON);
4530 /* check if folder_store is an remote account */
4531 if (TNY_IS_ACCOUNT (folder_store)) {
4532 TnyAccount *local_account = NULL;
4533 TnyAccount *mmc_account = NULL;
4534 ModestTnyAccountStore *account_store = NULL;
4536 account_store = modest_runtime_get_account_store ();
4537 local_account = modest_tny_account_store_get_local_folders_account (account_store);
4538 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
4540 if ((gpointer) local_account != (gpointer) folder_store &&
4541 (gpointer) mmc_account != (gpointer) folder_store) {
4542 ModestProtocolType proto;
4543 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
4544 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
4545 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
4547 is_local_account = FALSE;
4548 /* New button should be dimmed on remote
4550 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4552 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
4554 g_object_unref (local_account);
4556 /* It could not exist */
4558 g_object_unref (mmc_account);
4561 /* Check the target folder rules */
4562 if (TNY_IS_FOLDER (folder_store)) {
4563 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
4564 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
4565 ok_sensitive = FALSE;
4566 new_sensitive = FALSE;
4571 /* Check if we're moving a folder */
4572 if (MODEST_IS_MAIN_WINDOW (user_data)) {
4573 /* Get the widgets */
4574 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
4575 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4576 if (gtk_widget_is_focus (folder_view))
4577 moving_folder = TRUE;
4580 if (moving_folder) {
4581 TnyFolderStore *moved_folder = NULL, *parent = NULL;
4583 /* Get the folder to move */
4584 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4586 /* Check that we're not moving to the same folder */
4587 if (TNY_IS_FOLDER (moved_folder)) {
4588 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
4589 if (parent == folder_store)
4590 ok_sensitive = FALSE;
4591 g_object_unref (parent);
4594 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
4595 /* Do not allow to move to an account unless it's the
4596 local folders account */
4597 if (!is_local_account)
4598 ok_sensitive = FALSE;
4601 if (ok_sensitive && (moved_folder == folder_store)) {
4602 /* Do not allow to move to itself */
4603 ok_sensitive = FALSE;
4605 g_object_unref (moved_folder);
4607 TnyFolder *src_folder = NULL;
4609 /* Moving a message */
4610 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
4612 TnyHeader *header = NULL;
4613 header = modest_msg_view_window_get_header
4614 (MODEST_MSG_VIEW_WINDOW (user_data));
4615 if (!TNY_IS_HEADER(header))
4616 g_warning ("%s: could not get source header", __FUNCTION__);
4618 src_folder = tny_header_get_folder (header);
4621 g_object_unref (header);
4624 TNY_FOLDER (modest_folder_view_get_selected
4625 (MODEST_FOLDER_VIEW (folder_view)));
4628 if (TNY_IS_FOLDER(src_folder)) {
4629 /* Do not allow to move the msg to the same folder */
4630 /* Do not allow to move the msg to an account */
4631 if ((gpointer) src_folder == (gpointer) folder_store ||
4632 TNY_IS_ACCOUNT (folder_store))
4633 ok_sensitive = FALSE;
4634 g_object_unref (src_folder);
4636 g_warning ("%s: could not get source folder", __FUNCTION__);
4640 /* Set sensitivity of the OK button */
4641 gtk_widget_set_sensitive (ok_button, ok_sensitive);
4642 /* Set sensitivity of the NEW button */
4643 gtk_widget_set_sensitive (new_button, new_sensitive);
4647 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
4650 get_folder_view_from_move_to_dialog (GtkWidget *move_to_dialog)
4652 return GTK_WIDGET(g_object_get_data (G_OBJECT(move_to_dialog),
4653 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4657 create_move_to_dialog (GtkWindow *win,
4658 GtkWidget *folder_view,
4659 GtkWidget **tree_view)
4662 #ifdef MODEST_TOOLKIT_HILDON2
4663 GtkWidget *pannable;
4667 GtkWidget *new_button, *ok_button;
4669 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
4671 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
4674 #ifndef MODEST_TOOLKIT_GTK
4675 ok_button = gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
4676 /* We do this manually so GTK+ does not associate a response ID for
4678 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
4679 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
4680 gtk_widget_show (new_button);
4681 #ifndef MODEST_TOOLKIT_HILDON2
4682 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
4685 /* We do this manually so GTK+ does not associate a response ID for
4687 new_button = gtk_button_new_with_label (_("mcen_ti_new_folder"));
4688 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
4689 gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (GTK_DIALOG (dialog)->action_area), new_button, TRUE);
4690 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
4691 ok_button = gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
4692 gtk_container_set_border_width (GTK_CONTAINER (dialog), 12);
4693 gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 24);
4695 g_object_set_data (G_OBJECT (dialog), MOVE_FOLDER_OK_BUTTON, ok_button);
4696 g_object_set_data (G_OBJECT (dialog), MOVE_FOLDER_NEW_BUTTON, new_button);
4698 /* Create scrolled window */
4699 #ifdef MODEST_TOOLKIT_HILDON2
4700 pannable = hildon_pannable_area_new ();
4702 scroll = gtk_scrolled_window_new (NULL, NULL);
4703 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
4704 GTK_POLICY_AUTOMATIC,
4705 GTK_POLICY_AUTOMATIC);
4708 #ifdef MODEST_TOOLKIT_GTK
4709 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN);
4712 /* Create folder view */
4713 *tree_view = modest_platform_create_folder_view (NULL);
4715 /* Track changes in the selection to
4716 * disable the OK button whenever "Move to" is not possible
4717 * disbale NEW button whenever New is not possible */
4718 g_signal_connect (*tree_view,
4719 "folder_selection_changed",
4720 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
4723 /* Listen to clicks on New button */
4724 g_signal_connect (G_OBJECT (new_button),
4726 G_CALLBACK(create_move_to_dialog_on_new_folder),
4729 /* It could happen that we're trying to move a message from a
4730 window (msg window for example) after the main window was
4731 closed, so we can not just get the model of the folder
4733 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4734 const gchar *visible_id = NULL;
4736 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4737 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4738 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4739 MODEST_FOLDER_VIEW(*tree_view));
4742 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4744 /* Show the same account than the one that is shown in the main window */
4745 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
4748 const gchar *active_account_name = NULL;
4749 ModestAccountMgr *mgr = NULL;
4750 ModestAccountSettings *settings = NULL;
4751 ModestServerAccountSettings *store_settings = NULL;
4753 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4754 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4755 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
4756 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
4758 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4759 mgr = modest_runtime_get_account_mgr ();
4760 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4763 const gchar *store_account_name;
4764 store_settings = modest_account_settings_get_store_settings (settings);
4765 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4767 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
4768 store_account_name);
4769 g_object_unref (store_settings);
4770 g_object_unref (settings);
4774 /* we keep a pointer to the embedded folder view, so we can retrieve it with
4775 * get_folder_view_from_move_to_dialog
4776 * (see above) later (needed for focus handling)
4778 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, *tree_view);
4781 /* Hide special folders */
4782 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
4784 #ifdef MODEST_TOOLKIT_HILDON2
4785 gtk_container_add (GTK_CONTAINER (pannable), *tree_view);
4786 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
4787 pannable, TRUE, TRUE, 0);
4789 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
4790 /* Add scroll to dialog */
4791 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
4792 scroll, TRUE, TRUE, 0);
4796 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4797 #ifndef MODEST_TOOLKIT_GTK
4798 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
4800 gtk_window_set_default_size (GTK_WINDOW (dialog), 600, 400);
4809 * Shows a confirmation dialog to the user when we're moving messages
4810 * from a remote server to the local storage. Returns the dialog
4811 * response. If it's other kind of movement then it always returns
4814 * This one is used by the next functions:
4815 * modest_ui_actions_on_paste - commented out
4816 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4819 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4820 TnyFolder *dest_folder,
4824 gint response = GTK_RESPONSE_OK;
4825 TnyAccount *account = NULL;
4826 TnyFolder *src_folder = NULL;
4827 TnyIterator *iter = NULL;
4828 TnyHeader *header = NULL;
4830 /* return with OK if the destination is a remote folder */
4831 if (modest_tny_folder_is_remote_folder (dest_folder))
4832 return GTK_RESPONSE_OK;
4834 /* Get source folder */
4835 iter = tny_list_create_iterator (headers);
4836 header = TNY_HEADER (tny_iterator_get_current (iter));
4838 src_folder = tny_header_get_folder (header);
4839 g_object_unref (header);
4841 g_object_unref (iter);
4843 /* if no src_folder, message may be an attahcment */
4844 if (src_folder == NULL)
4845 return GTK_RESPONSE_CANCEL;
4847 /* If the source is a local or MMC folder */
4848 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4849 g_object_unref (src_folder);
4850 return GTK_RESPONSE_OK;
4853 /* Get the account */
4854 account = tny_folder_get_account (src_folder);
4856 /* now if offline we ask the user */
4857 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4858 response = GTK_RESPONSE_OK;
4860 response = GTK_RESPONSE_CANCEL;
4863 g_object_unref (src_folder);
4864 g_object_unref (account);
4870 move_to_helper_destroyer (gpointer user_data)
4872 MoveToHelper *helper = (MoveToHelper *) user_data;
4874 /* Close the "Pasting" information banner */
4875 if (helper->banner) {
4876 gtk_widget_destroy (GTK_WIDGET (helper->banner));
4877 g_object_unref (helper->banner);
4879 if (gtk_tree_row_reference_valid (helper->reference)) {
4880 gtk_tree_row_reference_free (helper->reference);
4881 helper->reference = NULL;
4887 move_to_cb (ModestMailOperation *mail_op,
4890 MoveToHelper *helper = (MoveToHelper *) user_data;
4892 /* Note that the operation could have failed, in that case do
4894 if (modest_mail_operation_get_status (mail_op) ==
4895 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
4897 GObject *object = modest_mail_operation_get_source (mail_op);
4898 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4899 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4901 if (!modest_msg_view_window_select_next_message (self) &&
4902 !modest_msg_view_window_select_previous_message (self)) {
4903 /* No more messages to view, so close this window */
4904 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4906 } else if (MODEST_IS_MAIN_WINDOW (object) &&
4907 gtk_tree_row_reference_valid (helper->reference)) {
4908 GtkWidget *header_view;
4910 GtkTreeSelection *sel;
4912 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4913 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4914 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
4915 path = gtk_tree_row_reference_get_path (helper->reference);
4916 /* We need to unselect the previous one
4917 because we could be copying instead of
4919 gtk_tree_selection_unselect_all (sel);
4920 gtk_tree_selection_select_path (sel, path);
4921 gtk_tree_path_free (path);
4923 g_object_unref (object);
4925 /* Destroy the helper */
4926 move_to_helper_destroyer (helper);
4930 folder_move_to_cb (ModestMailOperation *mail_op,
4931 TnyFolder *new_folder,
4934 GtkWidget *folder_view;
4937 object = modest_mail_operation_get_source (mail_op);
4938 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4939 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4940 g_object_ref (folder_view);
4941 g_object_unref (object);
4942 move_to_cb (mail_op, user_data);
4943 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
4944 g_object_unref (folder_view);
4948 msgs_move_to_cb (ModestMailOperation *mail_op,
4951 move_to_cb (mail_op, user_data);
4955 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
4958 ModestWindow *main_window = NULL;
4960 /* Disable next automatic folder selection */
4961 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
4962 FALSE); /* don't create */
4964 GObject *win = NULL;
4965 GtkWidget *folder_view = NULL;
4967 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
4968 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4969 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
4971 if (user_data && TNY_IS_FOLDER (user_data)) {
4972 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
4973 TNY_FOLDER (user_data), FALSE);
4976 /* Show notification dialog only if the main window exists */
4977 win = modest_mail_operation_get_source (mail_op);
4978 modest_platform_run_information_dialog ((GtkWindow *) win,
4979 _("mail_in_ui_folder_move_target_error"),
4982 g_object_unref (win);
4987 open_msg_for_purge_cb (ModestMailOperation *mail_op,
4996 gint pending_purges = 0;
4997 gboolean some_purged = FALSE;
4998 ModestWindow *win = MODEST_WINDOW (user_data);
4999 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5001 /* If there was any error */
5002 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5003 modest_window_mgr_unregister_header (mgr, header);
5007 /* Once the message has been retrieved for purging, we check if
5008 * it's all ok for purging */
5010 parts = tny_simple_list_new ();
5011 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5012 iter = tny_list_create_iterator (parts);
5014 while (!tny_iterator_is_done (iter)) {
5016 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5017 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5018 if (tny_mime_part_is_purged (part))
5025 g_object_unref (part);
5027 tny_iterator_next (iter);
5029 g_object_unref (iter);
5032 if (pending_purges>0) {
5034 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5036 if (response == GTK_RESPONSE_OK) {
5039 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5040 iter = tny_list_create_iterator (parts);
5041 while (!tny_iterator_is_done (iter)) {
5044 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5045 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5046 tny_mime_part_set_purged (part);
5049 g_object_unref (part);
5051 tny_iterator_next (iter);
5053 g_object_unref (iter);
5055 tny_msg_rewrite_cache (msg);
5057 gtk_widget_destroy (info);
5061 modest_window_mgr_unregister_header (mgr, header);
5063 g_object_unref (parts);
5067 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5068 ModestMainWindow *win)
5070 GtkWidget *header_view;
5071 TnyList *header_list;
5073 TnyHeaderFlags flags;
5074 ModestWindow *msg_view_window = NULL;
5077 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5079 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5080 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5082 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5084 g_warning ("%s: no header selected", __FUNCTION__);
5088 if (tny_list_get_length (header_list) == 1) {
5089 TnyIterator *iter = tny_list_create_iterator (header_list);
5090 header = TNY_HEADER (tny_iterator_get_current (iter));
5091 g_object_unref (iter);
5095 if (!header || !TNY_IS_HEADER(header)) {
5096 g_warning ("%s: header is not valid", __FUNCTION__);
5100 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5101 header, &msg_view_window);
5102 flags = tny_header_get_flags (header);
5103 if (!(flags & TNY_HEADER_FLAG_CACHED))
5106 if (msg_view_window != NULL)
5107 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5109 /* do nothing; uid was registered before, so window is probably on it's way */
5110 g_warning ("debug: header %p has already been registered", header);
5113 ModestMailOperation *mail_op = NULL;
5114 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5115 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5116 modest_ui_actions_disk_operations_error_handler,
5118 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5119 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5121 g_object_unref (mail_op);
5124 g_object_unref (header);
5126 g_object_unref (header_list);
5130 * Checks if we need a connection to do the transfer and if the user
5131 * wants to connect to complete it
5134 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5135 TnyFolderStore *src_folder,
5137 TnyFolder *dst_folder,
5138 gboolean delete_originals,
5139 gboolean *need_connection,
5142 TnyAccount *src_account;
5143 gint uncached_msgs = 0;
5145 uncached_msgs = header_list_count_uncached_msgs (headers);
5147 /* We don't need any further check if
5149 * 1- the source folder is local OR
5150 * 2- the device is already online
5152 if (!modest_tny_folder_store_is_remote (src_folder) ||
5153 tny_device_is_online (modest_runtime_get_device())) {
5154 *need_connection = FALSE;
5159 /* We must ask for a connection when
5161 * - the message(s) is not already cached OR
5162 * - the message(s) is cached but the leave_on_server setting
5163 * is FALSE (because we need to sync the source folder to
5164 * delete the message from the server (for IMAP we could do it
5165 * offline, it'll take place the next time we get a
5168 src_account = get_account_from_folder_store (src_folder);
5169 if (uncached_msgs > 0) {
5173 *need_connection = TRUE;
5174 num_headers = tny_list_get_length (headers);
5175 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5177 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5178 GTK_RESPONSE_CANCEL) {
5184 /* The transfer is possible and the user wants to */
5187 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5188 const gchar *account_name;
5189 gboolean leave_on_server;
5191 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5192 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5195 if (leave_on_server == TRUE) {
5196 *need_connection = FALSE;
5198 *need_connection = TRUE;
5201 *need_connection = FALSE;
5206 g_object_unref (src_account);
5210 xfer_messages_error_handler (ModestMailOperation *mail_op,
5213 ModestWindow *main_window = NULL;
5215 /* Disable next automatic folder selection */
5216 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5217 FALSE); /* don't create */
5219 GObject *win = modest_mail_operation_get_source (mail_op);
5220 modest_platform_run_information_dialog ((GtkWindow *) win,
5221 _("mail_in_ui_folder_move_target_error"),
5224 g_object_unref (win);
5226 move_to_helper_destroyer (user_data);
5230 TnyFolderStore *dst_folder;
5235 * Utility function that transfer messages from both the main window
5236 * and the msg view window when using the "Move to" dialog
5239 xfer_messages_performer (gboolean canceled,
5241 GtkWindow *parent_window,
5242 TnyAccount *account,
5245 ModestWindow *win = MODEST_WINDOW (parent_window);
5246 TnyAccount *dst_account = NULL;
5247 gboolean dst_forbids_message_add = FALSE;
5248 XferMsgsHelper *helper;
5249 MoveToHelper *movehelper;
5250 ModestMailOperation *mail_op;
5252 helper = (XferMsgsHelper *) user_data;
5254 if (canceled || err) {
5255 if (!check_memory_full_error ((GtkWidget *) parent_window, err)) {
5256 /* Show the proper error message */
5257 modest_ui_actions_on_account_connection_error (parent_window, account);
5262 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5264 /* tinymail will return NULL for local folders it seems */
5265 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5266 modest_tny_account_get_protocol_type (dst_account),
5267 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_MESSAGE_ADD);
5268 g_object_unref (dst_account);
5270 if (dst_forbids_message_add) {
5271 modest_platform_information_banner (GTK_WIDGET (win),
5273 ngettext("mail_in_ui_folder_move_target_error",
5274 "mail_in_ui_folder_move_targets_error",
5275 tny_list_get_length (helper->headers)));
5279 movehelper = g_new0 (MoveToHelper, 1);
5280 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5281 _CS("ckct_nw_pasting"));
5282 if (movehelper->banner != NULL) {
5283 g_object_ref (movehelper->banner);
5284 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5287 if (MODEST_IS_MAIN_WINDOW (win)) {
5288 GtkWidget *header_view =
5289 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5290 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5291 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5294 /* Perform the mail operation */
5295 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5296 xfer_messages_error_handler,
5298 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5301 modest_mail_operation_xfer_msgs (mail_op,
5303 TNY_FOLDER (helper->dst_folder),
5308 g_object_unref (G_OBJECT (mail_op));
5310 g_object_unref (helper->dst_folder);
5311 g_object_unref (helper->headers);
5312 g_slice_free (XferMsgsHelper, helper);
5316 TnyFolder *src_folder;
5317 TnyFolderStore *dst_folder;
5318 gboolean delete_original;
5319 GtkWidget *folder_view;
5323 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
5324 TnyAccount *account, gpointer user_data)
5326 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5327 GtkTreeSelection *sel;
5328 ModestMailOperation *mail_op = NULL;
5330 if (canceled || err || !MODEST_IS_MAIN_WINDOW (parent_window)) {
5331 g_object_unref (G_OBJECT (info->src_folder));
5332 g_object_unref (G_OBJECT (info->dst_folder));
5337 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5338 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5339 _CS("ckct_nw_pasting"));
5340 if (helper->banner != NULL) {
5341 g_object_ref (helper->banner);
5342 gtk_widget_show (GTK_WIDGET(helper->banner));
5344 /* Clean folder on header view before moving it */
5345 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5346 gtk_tree_selection_unselect_all (sel);
5348 /* Let gtk events run. We need that the folder
5349 view frees its reference to the source
5350 folder *before* issuing the mail operation
5351 so we need the signal handler of selection
5352 changed to happen before the mail
5354 while (gtk_events_pending ())
5355 gtk_main_iteration (); */
5358 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5359 modest_ui_actions_move_folder_error_handler,
5360 info->src_folder, NULL);
5361 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5364 /* Select *after* the changes */
5365 /* TODO: this function hangs UI after transfer */
5366 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
5367 /* TNY_FOLDER (src_folder), TRUE); */
5369 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5370 TNY_FOLDER (info->dst_folder), TRUE);
5371 modest_mail_operation_xfer_folder (mail_op,
5372 TNY_FOLDER (info->src_folder),
5374 info->delete_original,
5377 g_object_unref (G_OBJECT (info->src_folder));
5379 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5382 /* Unref mail operation */
5383 g_object_unref (G_OBJECT (mail_op));
5384 g_object_unref (G_OBJECT (info->dst_folder));
5389 get_account_from_folder_store (TnyFolderStore *folder_store)
5391 if (TNY_IS_ACCOUNT (folder_store))
5392 return g_object_ref (folder_store);
5394 return tny_folder_get_account (TNY_FOLDER (folder_store));
5398 * UI handler for the "Move to" action when invoked from the
5402 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5403 GtkWidget *folder_view,
5404 TnyFolderStore *dst_folder,
5405 ModestMainWindow *win)
5407 ModestHeaderView *header_view = NULL;
5408 TnyFolderStore *src_folder = NULL;
5410 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5412 /* Get the source folder */
5413 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5415 /* Get header view */
5416 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
5418 /* Get folder or messages to transfer */
5419 if (gtk_widget_is_focus (folder_view)) {
5420 gboolean do_xfer = TRUE;
5422 /* Allow only to transfer folders to the local root folder */
5423 if (TNY_IS_ACCOUNT (dst_folder) &&
5424 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5425 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5427 } else if (!TNY_IS_FOLDER (src_folder)) {
5428 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5433 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5434 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5436 info->src_folder = g_object_ref (src_folder);
5437 info->dst_folder = g_object_ref (dst_folder);
5438 info->delete_original = TRUE;
5439 info->folder_view = folder_view;
5441 connect_info->callback = on_move_folder_cb;
5442 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5443 connect_info->data = info;
5445 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5446 TNY_FOLDER_STORE (src_folder),
5449 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5452 headers = modest_header_view_get_selected_headers(header_view);
5454 /* Transfer the messages */
5455 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
5456 headers, TNY_FOLDER (dst_folder));
5458 g_object_unref (headers);
5462 g_object_unref (src_folder);
5467 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
5468 TnyFolder *src_folder,
5470 TnyFolder *dst_folder)
5472 gboolean need_connection = TRUE;
5473 gboolean do_xfer = TRUE;
5474 XferMsgsHelper *helper;
5476 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5477 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5478 g_return_if_fail (TNY_IS_LIST (headers));
5480 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5481 headers, TNY_FOLDER (dst_folder),
5482 TRUE, &need_connection,
5485 /* If we don't want to transfer just return */
5489 /* Create the helper */
5490 helper = g_slice_new (XferMsgsHelper);
5491 helper->dst_folder = g_object_ref (dst_folder);
5492 helper->headers = g_object_ref (headers);
5494 if (need_connection) {
5495 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5496 connect_info->callback = xfer_messages_performer;
5497 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5498 connect_info->data = helper;
5500 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5501 TNY_FOLDER_STORE (src_folder),
5504 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5505 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
5506 src_account, helper);
5507 g_object_unref (src_account);
5512 * UI handler for the "Move to" action when invoked from the
5513 * ModestMsgViewWindow
5516 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
5517 TnyFolderStore *dst_folder,
5518 ModestMsgViewWindow *win)
5520 TnyList *headers = NULL;
5521 TnyHeader *header = NULL;
5522 TnyFolder *src_folder = NULL;
5524 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5526 /* Create header list */
5527 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
5528 src_folder = TNY_FOLDER (tny_header_get_folder(header));
5529 headers = tny_simple_list_new ();
5530 tny_list_append (headers, G_OBJECT (header));
5532 /* Transfer the messages */
5533 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder, headers,
5534 TNY_FOLDER (dst_folder));
5537 g_object_unref (src_folder);
5538 g_object_unref (header);
5539 g_object_unref (headers);
5543 modest_ui_actions_on_move_to (GtkAction *action,
5546 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
5548 TnyFolderStore *dst_folder = NULL;
5549 ModestMainWindow *main_window;
5551 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
5552 MODEST_IS_MSG_VIEW_WINDOW (win));
5554 /* Get the main window if exists */
5555 if (MODEST_IS_MAIN_WINDOW (win))
5556 main_window = MODEST_MAIN_WINDOW (win);
5559 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5560 FALSE)); /* don't create */
5562 /* Get the folder view widget if exists */
5564 folder_view = modest_main_window_get_child_widget (main_window,
5565 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5569 /* Create and run the dialog */
5570 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
5571 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5572 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog), (GtkWindow *) win);
5573 result = gtk_dialog_run (GTK_DIALOG(dialog));
5574 g_object_ref (tree_view);
5575 gtk_widget_destroy (dialog);
5577 if (result != GTK_RESPONSE_ACCEPT)
5580 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
5581 /* Do window specific stuff */
5582 if (MODEST_IS_MAIN_WINDOW (win)) {
5583 modest_ui_actions_on_main_window_move_to (action,
5586 MODEST_MAIN_WINDOW (win));
5588 modest_ui_actions_on_msg_view_window_move_to (action,
5590 MODEST_MSG_VIEW_WINDOW (win));
5594 g_object_unref (dst_folder);
5598 * Calls #HeadersFunc for each header already selected in the main
5599 * window or the message currently being shown in the msg view window
5602 do_headers_action (ModestWindow *win,
5606 TnyList *headers_list = NULL;
5607 TnyIterator *iter = NULL;
5608 TnyHeader *header = NULL;
5609 TnyFolder *folder = NULL;
5612 headers_list = get_selected_headers (win);
5616 /* Get the folder */
5617 iter = tny_list_create_iterator (headers_list);
5618 header = TNY_HEADER (tny_iterator_get_current (iter));
5620 folder = tny_header_get_folder (header);
5621 g_object_unref (header);
5624 /* Call the function for each header */
5625 while (!tny_iterator_is_done (iter)) {
5626 header = TNY_HEADER (tny_iterator_get_current (iter));
5627 func (header, win, user_data);
5628 g_object_unref (header);
5629 tny_iterator_next (iter);
5632 /* Trick: do a poke status in order to speed up the signaling
5634 tny_folder_poke_status (folder);
5637 g_object_unref (folder);
5638 g_object_unref (iter);
5639 g_object_unref (headers_list);
5643 modest_ui_actions_view_attachment (GtkAction *action,
5644 ModestWindow *window)
5646 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5647 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5649 /* not supported window for this action */
5650 g_return_if_reached ();
5655 modest_ui_actions_save_attachments (GtkAction *action,
5656 ModestWindow *window)
5658 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5660 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5663 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5665 /* not supported window for this action */
5666 g_return_if_reached ();
5671 modest_ui_actions_remove_attachments (GtkAction *action,
5672 ModestWindow *window)
5674 if (MODEST_IS_MAIN_WINDOW (window)) {
5675 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
5676 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5677 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5679 /* not supported window for this action */
5680 g_return_if_reached ();
5685 modest_ui_actions_on_settings (GtkAction *action,
5690 dialog = modest_platform_get_global_settings_dialog ();
5691 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
5692 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5693 gtk_widget_show_all (dialog);
5695 gtk_dialog_run (GTK_DIALOG (dialog));
5697 gtk_widget_destroy (dialog);
5701 modest_ui_actions_on_help (GtkAction *action,
5704 /* Help app is not available at all in fremantle */
5705 #ifndef MODEST_TOOLKIT_HILDON2
5706 const gchar *help_id;
5708 g_return_if_fail (win && GTK_IS_WINDOW(win));
5710 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5713 modest_platform_show_help (GTK_WINDOW (win), help_id);
5718 modest_ui_actions_on_csm_help (GtkAction *action,
5721 /* Help app is not available at all in fremantle */
5722 #ifndef MODEST_TOOLKIT_HILDON2
5724 const gchar* help_id = NULL;
5725 GtkWidget *folder_view;
5726 TnyFolderStore *folder_store;
5728 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
5730 /* Get selected folder */
5731 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5732 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5733 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5735 /* Switch help_id */
5736 if (folder_store && TNY_IS_FOLDER (folder_store))
5737 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
5740 g_object_unref (folder_store);
5743 modest_platform_show_help (GTK_WINDOW (win), help_id);
5745 modest_ui_actions_on_help (action, win);
5750 retrieve_contents_cb (ModestMailOperation *mail_op,
5757 /* We only need this callback to show an error in case of
5758 memory low condition */
5759 modest_ui_actions_msg_retrieval_check (mail_op, header, msg);
5763 retrieve_msg_contents_performer (gboolean canceled,
5765 GtkWindow *parent_window,
5766 TnyAccount *account,
5769 ModestMailOperation *mail_op;
5770 TnyList *headers = TNY_LIST (user_data);
5772 if (err || canceled) {
5773 check_memory_full_error ((GtkWidget *) parent_window, err);
5777 /* Create mail operation */
5778 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5779 modest_ui_actions_disk_operations_error_handler,
5781 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5782 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
5785 g_object_unref (mail_op);
5787 g_object_unref (headers);
5788 g_object_unref (account);
5792 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5793 ModestWindow *window)
5795 TnyList *headers = NULL;
5796 TnyAccount *account = NULL;
5797 TnyIterator *iter = NULL;
5798 TnyHeader *header = NULL;
5799 TnyFolder *folder = NULL;
5802 headers = get_selected_headers (window);
5806 /* Pick the account */
5807 iter = tny_list_create_iterator (headers);
5808 header = TNY_HEADER (tny_iterator_get_current (iter));
5809 folder = tny_header_get_folder (header);
5810 account = tny_folder_get_account (folder);
5811 g_object_unref (folder);
5812 g_object_unref (header);
5813 g_object_unref (iter);
5815 /* Connect and perform the message retrieval */
5816 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
5817 g_object_ref (account),
5818 retrieve_msg_contents_performer,
5819 g_object_ref (headers));
5822 g_object_unref (account);
5823 g_object_unref (headers);
5827 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
5829 g_return_if_fail (MODEST_IS_WINDOW (window));
5832 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
5836 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
5838 g_return_if_fail (MODEST_IS_WINDOW (window));
5841 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
5845 modest_ui_actions_on_email_menu_activated (GtkAction *action,
5846 ModestWindow *window)
5848 g_return_if_fail (MODEST_IS_WINDOW (window));
5851 modest_ui_actions_check_menu_dimming_rules (window);
5855 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
5856 ModestWindow *window)
5858 g_return_if_fail (MODEST_IS_WINDOW (window));
5861 modest_ui_actions_check_menu_dimming_rules (window);
5865 modest_ui_actions_on_view_menu_activated (GtkAction *action,
5866 ModestWindow *window)
5868 g_return_if_fail (MODEST_IS_WINDOW (window));
5871 modest_ui_actions_check_menu_dimming_rules (window);
5875 modest_ui_actions_on_format_menu_activated (GtkAction *action,
5876 ModestWindow *window)
5878 g_return_if_fail (MODEST_IS_WINDOW (window));
5881 modest_ui_actions_check_menu_dimming_rules (window);
5885 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
5886 ModestWindow *window)
5888 g_return_if_fail (MODEST_IS_WINDOW (window));
5891 modest_ui_actions_check_menu_dimming_rules (window);
5895 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
5896 ModestWindow *window)
5898 g_return_if_fail (MODEST_IS_WINDOW (window));
5901 modest_ui_actions_check_menu_dimming_rules (window);
5905 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
5906 ModestWindow *window)
5908 g_return_if_fail (MODEST_IS_WINDOW (window));
5911 modest_ui_actions_check_menu_dimming_rules (window);
5915 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
5916 ModestWindow *window)
5918 g_return_if_fail (MODEST_IS_WINDOW (window));
5921 modest_ui_actions_check_menu_dimming_rules (window);
5925 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
5926 ModestWindow *window)
5928 g_return_if_fail (MODEST_IS_WINDOW (window));
5931 modest_ui_actions_check_menu_dimming_rules (window);
5935 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
5937 g_return_if_fail (MODEST_IS_WINDOW (window));
5939 /* we check for low-mem; in that case, show a warning, and don't allow
5942 if (modest_platform_check_memory_low (window, TRUE))
5945 modest_platform_show_search_messages (GTK_WINDOW (window));
5949 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
5951 g_return_if_fail (MODEST_IS_WINDOW (win));
5954 /* we check for low-mem; in that case, show a warning, and don't allow
5955 * for the addressbook
5957 if (modest_platform_check_memory_low (win, TRUE))
5961 modest_platform_show_addressbook (GTK_WINDOW (win));
5966 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
5967 ModestWindow *window)
5969 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5971 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
5975 on_send_receive_finished (ModestMailOperation *mail_op,
5978 GtkWidget *header_view, *folder_view;
5979 TnyFolderStore *folder_store;
5980 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
5982 /* Set send/receive operation finished */
5983 modest_main_window_notify_send_receive_completed (main_win);
5985 /* Don't refresh the current folder if there were any errors */
5986 if (modest_mail_operation_get_status (mail_op) !=
5987 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5990 /* Refresh the current folder if we're viewing a window. We do
5991 this because the user won't be able to see the new mails in
5992 the selected folder after a Send&Receive because it only
5993 performs a poke_status, i.e, only the number of read/unread
5994 messages is updated, but the new headers are not
5996 folder_view = modest_main_window_get_child_widget (main_win,
5997 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6001 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6003 /* Do not need to refresh INBOX again because the
6004 update_account does it always automatically */
6005 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6006 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6007 ModestMailOperation *refresh_op;
6009 header_view = modest_main_window_get_child_widget (main_win,
6010 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6012 /* We do not need to set the contents style
6013 because it hasn't changed. We also do not
6014 need to save the widget status. Just force
6016 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6017 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6018 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6019 folder_refreshed_cb, main_win);
6020 g_object_unref (refresh_op);
6024 g_object_unref (folder_store);
6029 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6035 const gchar* server_name = NULL;
6036 TnyTransportAccount *server_account;
6037 gchar *message = NULL;
6039 /* Don't show anything if the user cancelled something or the
6040 * send receive request is not interactive. Authentication
6041 * errors are managed by the account store so no need to show
6042 * a dialog here again */
6043 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6044 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6045 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6049 /* Get the server name: */
6051 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
6053 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
6055 g_return_if_reached ();
6057 /* Show the appropriate message text for the GError: */
6058 switch (err->code) {
6059 case TNY_SERVICE_ERROR_CONNECT:
6060 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6062 case TNY_SERVICE_ERROR_SEND:
6063 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
6065 case TNY_SERVICE_ERROR_UNAVAILABLE:
6066 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6069 g_warning ("%s: unexpected ERROR %d",
6070 __FUNCTION__, err->code);
6071 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
6075 modest_platform_run_information_dialog (NULL, message, FALSE);
6077 g_object_unref (server_account);
6081 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6086 ModestMainWindow *main_window = NULL;
6087 ModestWindowMgr *mgr = NULL;
6088 GtkWidget *folder_view = NULL, *header_view = NULL;
6089 TnyFolderStore *selected_folder = NULL;
6090 TnyFolderType folder_type;
6092 mgr = modest_runtime_get_window_mgr ();
6093 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr,
6094 FALSE));/* don't create */
6098 /* Check if selected folder is OUTBOX */
6099 folder_view = modest_main_window_get_child_widget (main_window,
6100 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6101 header_view = modest_main_window_get_child_widget (main_window,
6102 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6104 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6105 if (!TNY_IS_FOLDER (selected_folder))
6108 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6109 #if GTK_CHECK_VERSION(2, 8, 0)
6110 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
6111 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6112 GtkTreeViewColumn *tree_column;
6114 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6115 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6117 gtk_tree_view_column_queue_resize (tree_column);
6120 gtk_widget_queue_draw (header_view);
6123 /* Rerun dimming rules, because the message could become deletable for example */
6124 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6125 MODEST_DIMMING_RULES_TOOLBAR);
6126 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6127 MODEST_DIMMING_RULES_MENU);
6131 if (selected_folder != NULL)
6132 g_object_unref (selected_folder);
6136 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6137 TnyAccount *account)
6139 ModestProtocolType protocol_type;
6140 ModestProtocol *protocol;
6141 gchar *error_note = NULL;
6143 protocol_type = modest_tny_account_get_protocol_type (account);
6144 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6147 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6148 if (error_note == NULL) {
6149 g_warning ("%s: This should not be reached", __FUNCTION__);
6151 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6152 g_free (error_note);
6157 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6161 TnyFolderStore *folder = NULL;
6162 TnyAccount *account = NULL;
6163 ModestProtocolType proto;
6164 ModestProtocol *protocol;
6165 TnyHeader *header = NULL;
6167 if (MODEST_IS_MAIN_WINDOW (win)) {
6168 GtkWidget *header_view;
6169 TnyList* headers = NULL;
6171 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6172 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6173 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6174 if (!headers || tny_list_get_length (headers) == 0) {
6176 g_object_unref (headers);
6179 iter = tny_list_create_iterator (headers);
6180 header = TNY_HEADER (tny_iterator_get_current (iter));
6181 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6182 g_object_unref (iter);
6183 g_object_unref (headers);
6184 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6185 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6186 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6189 /* Get the account type */
6190 account = tny_folder_get_account (TNY_FOLDER (folder));
6191 proto = modest_tny_account_get_protocol_type (account);
6192 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6195 subject = tny_header_dup_subject (header);
6196 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6200 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6204 g_object_unref (account);
6205 g_object_unref (folder);
6206 g_object_unref (header);
6212 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6213 const gchar *account_name,
6214 const gchar *account_title)
6216 ModestAccountMgr *account_mgr;
6219 ModestProtocol *protocol;
6220 gboolean removed = FALSE;
6222 g_return_val_if_fail (account_name, FALSE);
6223 g_return_val_if_fail (account_title, FALSE);
6225 account_mgr = modest_runtime_get_account_mgr();
6227 /* The warning text depends on the account type: */
6228 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6229 modest_account_mgr_get_store_protocol (account_mgr,
6231 txt = modest_protocol_get_translation (protocol,
6232 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6235 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6237 response = modest_platform_run_confirmation_dialog (parent_window, txt);
6241 if (response == GTK_RESPONSE_OK) {
6242 /* Remove account. If it succeeds then it also removes
6243 the account from the ModestAccountView: */
6244 gboolean is_default = FALSE;
6245 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6246 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6248 g_free (default_account_name);
6250 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6252 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);