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-protocol-info.h"
45 #include "modest-tny-platform-factory.h"
46 #include "modest-platform.h"
47 #include "modest-debug.h"
48 #include <tny-mime-part.h>
49 #include <tny-camel-folder.h>
50 #include <tny-camel-imap-folder.h>
51 #include <tny-camel-pop-folder.h>
53 #ifdef MODEST_PLATFORM_MAEMO
54 #include "maemo/modest-osso-state-saving.h"
55 #include "maemo/modest-hildon-includes.h"
56 #include "maemo/modest-connection-specific-smtp-window.h"
57 #endif /* MODEST_PLATFORM_MAEMO */
58 #include <modest-utils.h>
60 #include "widgets/modest-ui-constants.h"
61 #include <widgets/modest-main-window.h>
62 #include <widgets/modest-msg-view-window.h>
63 #include <widgets/modest-account-view-window.h>
64 #include <widgets/modest-details-dialog.h>
65 #include <widgets/modest-attachments-view.h>
66 #include "widgets/modest-folder-view.h"
67 #include "widgets/modest-global-settings-dialog.h"
68 #include "modest-account-mgr-helpers.h"
69 #include "modest-mail-operation.h"
70 #include "modest-text-utils.h"
72 #ifdef MODEST_HAVE_EASYSETUP
73 #include "easysetup/modest-easysetup-wizard-dialog.h"
74 #endif /* MODEST_HAVE_EASYSETUP */
76 #include <modest-widget-memory.h>
77 #include <tny-error.h>
78 #include <tny-simple-list.h>
79 #include <tny-msg-view.h>
80 #include <tny-device.h>
81 #include <tny-merge-folder.h>
83 #include <gtkhtml/gtkhtml.h>
85 typedef struct _GetMsgAsyncHelper {
87 ModestMailOperation *mail_op;
94 typedef enum _ReplyForwardAction {
100 typedef struct _ReplyForwardHelper {
101 guint reply_forward_type;
102 ReplyForwardAction action;
104 GtkWidget *parent_window;
106 } ReplyForwardHelper;
108 typedef struct _MoveToHelper {
109 GtkTreeRowReference *reference;
113 typedef struct _PasteAsAttachmentHelper {
114 ModestMsgEditWindow *window;
116 } PasteAsAttachmentHelper;
120 * The do_headers_action uses this kind of functions to perform some
121 * action to each member of a list of headers
123 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
125 static void do_headers_action (ModestWindow *win,
129 static void open_msg_cb (ModestMailOperation *mail_op,
136 static void reply_forward_cb (ModestMailOperation *mail_op,
143 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
145 static void folder_refreshed_cb (ModestMailOperation *mail_op,
149 static void on_send_receive_finished (ModestMailOperation *mail_op,
152 static gint header_list_count_uncached_msgs (TnyList *header_list);
154 static gboolean connect_to_get_msg (ModestWindow *win,
155 gint num_of_uncached_msgs,
156 TnyAccount *account);
158 static gboolean remote_folder_is_pop (TnyFolderStore *folder);
160 static void do_create_folder (GtkWindow *window,
161 TnyFolderStore *parent_folder,
162 const gchar *suggested_name);
164 static GtkWidget* get_folder_view_from_move_to_dialog (GtkWidget *move_to_dialog);
166 static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store);
169 * This function checks whether a TnyFolderStore is a pop account
172 remote_folder_is_pop (TnyFolderStore *folder)
174 const gchar *proto = NULL;
175 TnyAccount *account = NULL;
177 g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
179 account = get_account_from_folder_store (folder);
180 proto = tny_account_get_proto (account);
181 g_object_unref (account);
183 return (modest_protocol_info_get_transport_store_protocol (proto) == MODEST_PROTOCOL_STORE_POP);
186 /* FIXME: this should be merged with the similar code in modest-account-view-window */
187 /* Show the account creation wizard dialog.
188 * returns: TRUE if an account was created. FALSE if the user cancelled.
191 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
193 gboolean result = FALSE;
194 GtkWindow *dialog, *wizard;
195 gint dialog_response;
197 /* Show the easy-setup wizard: */
198 dialog = modest_window_mgr_get_modal (modest_runtime_get_window_mgr());
200 /* old wizard is active already;
202 gtk_window_present (GTK_WINDOW(dialog));
207 /* there is no such wizard yet */
208 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
209 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), wizard);
211 /* always present a main window in the background
212 * we do it here, so we cannot end up with two wizards (as this
213 * function might be called in modest_window_mgr_get_main_window as well */
215 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
216 TRUE); /* create if not existent */
218 /* make sure the mainwindow is visible */
219 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
220 gtk_widget_show_all (GTK_WIDGET(win));
221 gtk_window_present (GTK_WINDOW(win));
223 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
224 gtk_widget_destroy (GTK_WIDGET (wizard));
225 if (gtk_events_pending ())
226 gtk_main_iteration ();
228 if (dialog_response == GTK_RESPONSE_CANCEL) {
231 /* Check whether an account was created: */
232 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
239 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
242 const gchar *authors[] = {
243 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
246 about = gtk_about_dialog_new ();
247 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
248 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
249 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
250 _("Copyright (c) 2006, Nokia Corporation\n"
251 "All rights reserved."));
252 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
253 _("a modest e-mail client\n\n"
254 "design and implementation: Dirk-Jan C. Binnema\n"
255 "contributions from the fine people at KC and Ig\n"
256 "uses the tinymail email framework written by Philip van Hoof"));
257 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
258 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
259 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
260 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
262 gtk_dialog_run (GTK_DIALOG (about));
263 gtk_widget_destroy(about);
267 * Gets the list of currently selected messages. If the win is the
268 * main window, then it returns a newly allocated list of the headers
269 * selected in the header view. If win is the msg view window, then
270 * the value returned is a list with just a single header.
272 * The caller of this funcion must free the list.
275 get_selected_headers (ModestWindow *win)
277 if (MODEST_IS_MAIN_WINDOW(win)) {
278 GtkWidget *header_view;
280 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
281 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
282 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
284 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
285 /* for MsgViewWindows, we simply return a list with one element */
287 TnyList *list = NULL;
289 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
290 if (header != NULL) {
291 list = tny_simple_list_new ();
292 tny_list_prepend (list, G_OBJECT(header));
293 g_object_unref (G_OBJECT(header));
302 static GtkTreeRowReference *
303 get_next_after_selected_headers (ModestHeaderView *header_view)
305 GtkTreeSelection *sel;
306 GList *selected_rows, *node;
308 GtkTreeRowReference *result;
311 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
312 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
313 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
315 if (selected_rows == NULL)
318 node = g_list_last (selected_rows);
319 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
320 gtk_tree_path_next (path);
322 result = gtk_tree_row_reference_new (model, path);
324 gtk_tree_path_free (path);
325 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
326 g_list_free (selected_rows);
332 headers_action_mark_as_read (TnyHeader *header,
336 TnyHeaderFlags flags;
338 g_return_if_fail (TNY_IS_HEADER(header));
340 flags = tny_header_get_flags (header);
341 if (flags & TNY_HEADER_FLAG_SEEN) return;
342 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
346 headers_action_mark_as_unread (TnyHeader *header,
350 TnyHeaderFlags flags;
352 g_return_if_fail (TNY_IS_HEADER(header));
354 flags = tny_header_get_flags (header);
355 if (flags & TNY_HEADER_FLAG_SEEN) {
356 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
360 /** After deleing a message that is currently visible in a window,
361 * show the next message from the list, or close the window if there are no more messages.
364 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
366 /* Close msg view window or select next */
367 if (!modest_msg_view_window_select_next_message (win) &&
368 !modest_msg_view_window_select_previous_message (win)) {
370 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
376 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
378 TnyList *header_list = NULL;
379 TnyIterator *iter = NULL;
380 TnyHeader *header = NULL;
381 gchar *message = NULL;
384 ModestWindowMgr *mgr;
385 GtkWidget *header_view = NULL;
387 g_return_if_fail (MODEST_IS_WINDOW(win));
389 /* Check first if the header view has the focus */
390 if (MODEST_IS_MAIN_WINDOW (win)) {
392 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
393 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
394 if (!gtk_widget_is_focus (header_view))
398 /* Get the headers, either from the header view (if win is the main window),
399 * or from the message view window: */
400 header_list = get_selected_headers (win);
401 if (!header_list) return;
403 /* Check if any of the headers are already opened, or in the process of being opened */
404 if (MODEST_IS_MAIN_WINDOW (win)) {
405 gint opened_headers = 0;
407 iter = tny_list_create_iterator (header_list);
408 mgr = modest_runtime_get_window_mgr ();
409 while (!tny_iterator_is_done (iter)) {
410 header = TNY_HEADER (tny_iterator_get_current (iter));
412 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
414 g_object_unref (header);
416 tny_iterator_next (iter);
418 g_object_unref (iter);
420 if (opened_headers > 0) {
423 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
426 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg, FALSE);
429 g_object_unref (header_list);
435 if (tny_list_get_length(header_list) == 1) {
436 iter = tny_list_create_iterator (header_list);
437 header = TNY_HEADER (tny_iterator_get_current (iter));
440 subject = tny_header_dup_subject (header);
441 desc = g_strdup_printf ("%s", subject);
443 g_object_unref (header);
446 g_object_unref (iter);
448 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
449 tny_list_get_length(header_list)), desc);
451 /* Confirmation dialog */
452 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
456 if (response == GTK_RESPONSE_OK) {
457 ModestWindow *main_window = NULL;
458 ModestWindowMgr *mgr = NULL;
459 GtkTreeModel *model = NULL;
460 GtkTreeSelection *sel = NULL;
461 GList *sel_list = NULL, *tmp = NULL;
462 GtkTreeRowReference *next_row_reference = NULL;
463 GtkTreeRowReference *prev_row_reference = NULL;
464 GtkTreePath *next_path = NULL;
465 GtkTreePath *prev_path = NULL;
466 ModestMailOperation *mail_op = NULL;
468 /* Find last selected row */
469 if (MODEST_IS_MAIN_WINDOW (win)) {
470 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
471 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
472 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
473 for (tmp=sel_list; tmp; tmp=tmp->next) {
474 if (tmp->next == NULL) {
475 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
476 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
478 gtk_tree_path_prev (prev_path);
479 gtk_tree_path_next (next_path);
481 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
482 next_row_reference = gtk_tree_row_reference_new (model, next_path);
487 /* Disable window dimming management */
488 modest_window_disable_dimming (MODEST_WINDOW(win));
490 /* Remove each header. If it's a view window header_view == NULL */
491 mail_op = modest_mail_operation_new ((GObject *) win);
492 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
494 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
495 g_object_unref (mail_op);
497 /* Enable window dimming management */
499 gtk_tree_selection_unselect_all (sel);
501 modest_window_enable_dimming (MODEST_WINDOW(win));
503 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
504 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
506 /* Get main window */
507 mgr = modest_runtime_get_window_mgr ();
508 main_window = modest_window_mgr_get_main_window (mgr, FALSE); /* don't create */
510 /* Move cursor to next row */
513 /* Select next or previous row */
514 if (gtk_tree_row_reference_valid (next_row_reference)) {
515 /* next_path = gtk_tree_row_reference_get_path (row_reference); */
516 gtk_tree_selection_select_path (sel, next_path);
518 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
519 gtk_tree_selection_select_path (sel, prev_path);
523 if (next_row_reference != NULL)
524 gtk_tree_row_reference_free (next_row_reference);
525 if (next_path != NULL)
526 gtk_tree_path_free (next_path);
527 if (prev_row_reference != NULL)
528 gtk_tree_row_reference_free (prev_row_reference);
529 if (prev_path != NULL)
530 gtk_tree_path_free (prev_path);
533 /* Update toolbar dimming state */
535 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
538 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
539 g_list_free (sel_list);
545 g_object_unref (header_list);
551 /* delete either message or folder, based on where we are */
553 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
555 g_return_if_fail (MODEST_IS_WINDOW(win));
557 /* Check first if the header view has the focus */
558 if (MODEST_IS_MAIN_WINDOW (win)) {
560 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
561 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
562 if (gtk_widget_is_focus (w)) {
563 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
567 modest_ui_actions_on_delete_message (action, win);
571 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
573 ModestWindowMgr *mgr = NULL;
575 #ifdef MODEST_PLATFORM_MAEMO
576 modest_osso_save_state();
577 #endif /* MODEST_PLATFORM_MAEMO */
579 g_debug ("closing down, clearing %d item(s) from operation queue",
580 modest_mail_operation_queue_num_elements
581 (modest_runtime_get_mail_operation_queue()));
583 /* cancel all outstanding operations */
584 modest_mail_operation_queue_cancel_all
585 (modest_runtime_get_mail_operation_queue());
587 g_debug ("queue has been cleared");
590 /* Check if there are opened editing windows */
591 mgr = modest_runtime_get_window_mgr ();
592 modest_window_mgr_close_all_windows (mgr);
594 /* note: when modest-tny-account-store is finalized,
595 it will automatically set all network connections
598 /* gtk_main_quit (); */
602 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
606 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
608 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
609 /* gtk_widget_destroy (GTK_WIDGET (win)); */
610 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
611 /* gboolean ret_value; */
612 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
613 /* } else if (MODEST_IS_WINDOW (win)) { */
614 /* gtk_widget_destroy (GTK_WIDGET (win)); */
616 /* g_return_if_reached (); */
621 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
623 GtkClipboard *clipboard = NULL;
624 gchar *selection = NULL;
626 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
627 selection = gtk_clipboard_wait_for_text (clipboard);
629 /* Question: why is the clipboard being used here?
630 * It doesn't really make a lot of sense. */
634 modest_address_book_add_address (selection);
640 modest_ui_actions_on_accounts (GtkAction *action,
643 /* This is currently only implemented for Maemo */
644 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
645 if (!modest_ui_actions_run_account_setup_wizard (win))
646 g_debug ("%s: wizard was already running", __FUNCTION__);
650 /* Show the list of accounts */
651 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
653 /* The accounts dialog must be modal */
654 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), account_win);
655 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
660 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
662 /* This is currently only implemented for Maemo,
663 * because it requires an API (libconic) to detect different connection
666 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
668 /* Create the window if necessary: */
669 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
670 modest_connection_specific_smtp_window_fill_with_connections (
671 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
672 modest_runtime_get_account_mgr());
674 /* Show the window: */
675 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
676 GTK_WINDOW (specific_window));
677 gtk_widget_show (specific_window);
678 #endif /* MODEST_PLATFORM_MAEMO */
682 modest_ui_actions_compose_msg(ModestWindow *win,
685 const gchar *bcc_str,
686 const gchar *subject_str,
687 const gchar *body_str,
689 gboolean set_as_modified)
691 gchar *account_name = NULL;
693 TnyAccount *account = NULL;
694 TnyFolder *folder = NULL;
695 gchar *from_str = NULL, *signature = NULL, *body = NULL;
696 gboolean use_signature = FALSE;
697 ModestWindow *msg_win = NULL;
698 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
699 ModestTnyAccountStore *store = modest_runtime_get_account_store();
700 GnomeVFSFileSize total_size, allowed_size;
702 /* we check for low-mem; in that case, show a warning, and don't allow
703 * composing a message with attachments
705 if (attachments && modest_platform_check_memory_low (win, TRUE))
708 account_name = modest_account_mgr_get_default_account(mgr);
710 g_printerr ("modest: no account found\n");
713 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
715 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
718 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
720 g_printerr ("modest: failed to find Drafts folder\n");
723 from_str = modest_account_mgr_get_from_string (mgr, account_name);
725 g_printerr ("modest: failed get from string for '%s'\n", account_name);
729 signature = modest_account_mgr_get_signature (mgr, account_name, &use_signature);
730 if (body_str != NULL) {
731 body = use_signature ? g_strconcat(body_str, "\n", signature, NULL) : g_strdup(body_str);
733 body = use_signature ? g_strconcat("\n", signature, NULL) : g_strdup("");
736 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, body, NULL, NULL);
738 g_printerr ("modest: failed to create new msg\n");
742 /* Create and register edit window */
743 /* This is destroyed by TODO. */
745 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
746 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
747 while (attachments) {
749 modest_msg_edit_window_attach_file_one(
750 (ModestMsgEditWindow *)msg_win,
751 attachments->data, allowed_size);
753 if (total_size > allowed_size) {
754 g_warning ("%s: total size: %u",
755 __FUNCTION__, (unsigned int)total_size);
758 allowed_size -= total_size;
760 attachments = g_slist_next(attachments);
762 modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win);
763 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
765 gtk_widget_show_all (GTK_WIDGET (msg_win));
771 g_free (account_name);
773 g_object_unref (G_OBJECT(account));
775 g_object_unref (G_OBJECT(folder));
777 g_object_unref (G_OBJECT(msg));
781 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
783 /* if there are no accounts yet, just show the wizard */
784 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
785 if (!modest_ui_actions_run_account_setup_wizard (win))
788 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
793 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
797 ModestMailOperationStatus status;
799 /* If there is no message or the operation was not successful */
800 status = modest_mail_operation_get_status (mail_op);
801 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
804 /* If it's a memory low issue, then show a banner */
805 error = modest_mail_operation_get_error (mail_op);
806 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
807 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
808 GObject *source = modest_mail_operation_get_source (mail_op);
809 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
810 dgettext("ke-recv","memr_ib_operation_disabled"),
812 g_object_unref (source);
815 /* Remove the header from the preregistered uids */
816 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
834 OpenMsgBannerInfo *banner_info;
835 GHashTable *row_refs_per_header;
839 open_msg_banner_idle (gpointer userdata)
841 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
843 gdk_threads_enter ();
844 banner_info->idle_handler = 0;
845 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
846 g_object_ref (banner_info->banner);
848 gdk_threads_leave ();
855 open_msg_cb (ModestMailOperation *mail_op,
862 ModestWindowMgr *mgr = NULL;
863 ModestWindow *parent_win = NULL;
864 ModestWindow *win = NULL;
865 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
866 gchar *account = NULL;
868 gboolean open_in_editor = FALSE;
869 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
871 /* Do nothing if there was any problem with the mail
872 operation. The error will be shown by the error_handler of
873 the mail operation */
874 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
877 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
878 folder = tny_header_get_folder (header);
880 /* Mark header as read */
881 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
883 /* Gets folder type (OUTBOX headers will be opened in edit window */
884 if (modest_tny_folder_is_local_folder (folder)) {
885 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
886 if (folder_type == TNY_FOLDER_TYPE_INVALID)
887 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
891 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
892 TnyTransportAccount *traccount = NULL;
893 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
894 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
896 ModestTnySendQueue *send_queue = NULL;
897 ModestTnySendQueueStatus status;
899 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
900 TNY_ACCOUNT(traccount)));
901 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
902 if (TNY_IS_SEND_QUEUE (send_queue)) {
903 msg_id = modest_tny_send_queue_get_msg_id (header);
904 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
905 /* Only open messages in outbox with the editor if they are in Failed state */
906 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
907 open_in_editor = TRUE;
911 g_object_unref(traccount);
913 g_warning("Cannot get transport account for message in outbox!!");
915 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
916 open_in_editor = TRUE; /* Open in editor if the message is in the Drafts folder */
921 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
923 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
925 if (open_in_editor) {
926 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
927 gchar *from_header = NULL;
929 from_header = tny_header_dup_from (header);
931 /* we cannot edit without a valid account... */
932 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
933 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
934 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
936 g_free (from_header);
942 GSList *accounts = modest_account_mgr_account_names (mgr, TRUE);
945 for (node = accounts; node != NULL; node = g_slist_next (node)) {
946 gchar *from = modest_account_mgr_get_from_string (mgr, node->data);
948 if (from && (strcmp (from_header, from) == 0)) {
950 account = g_strdup (node->data);
956 g_free (from_header);
957 g_slist_foreach (accounts, (GFunc) g_free, NULL);
958 g_slist_free (accounts);
961 win = modest_msg_edit_window_new (msg, account, TRUE);
966 gchar *uid = modest_tny_folder_get_header_unique_id (header);
968 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
969 GtkTreeRowReference *row_reference;
971 row_reference = (GtkTreeRowReference *) g_hash_table_lookup (helper->row_refs_per_header, header);
973 win = modest_msg_view_window_new_with_header_model (msg, account, (const gchar*) uid,
974 helper->model, row_reference);
976 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
981 /* Register and show new window */
983 mgr = modest_runtime_get_window_mgr ();
984 modest_window_mgr_register_window (mgr, win);
985 gtk_widget_show_all (GTK_WIDGET(win));
988 /* Update toolbar dimming state */
989 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
990 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
996 g_object_unref (parent_win);
997 g_object_unref (folder);
1001 is_memory_full_error (GError *error)
1003 if (error->code == TNY_SYSTEM_ERROR_MEMORY ||
1004 error->code == TNY_IO_ERROR_WRITE ||
1005 error->code == TNY_IO_ERROR_READ) {
1013 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1016 const GError *error;
1017 GObject *win = NULL;
1018 ModestMailOperationStatus status;
1020 win = modest_mail_operation_get_source (mail_op);
1021 error = modest_mail_operation_get_error (mail_op);
1022 status = modest_mail_operation_get_status (mail_op);
1024 /* If the mail op has been cancelled then it's not an error:
1025 don't show any message */
1026 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1027 if (is_memory_full_error ((GError *) error)) {
1028 modest_platform_information_banner ((GtkWidget *) win,
1029 NULL, dgettext("ke-recv",
1030 "cerm_device_memory_full"));
1031 } else if (error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1032 modest_platform_information_banner ((GtkWidget *) win,
1033 NULL, dgettext ("hildon-common-strings", "sfil_ni_unable_to_open_file_not_found"));
1034 } else if (user_data) {
1035 modest_platform_information_banner ((GtkWidget *) win,
1041 g_object_unref (win);
1045 * Returns the account a list of headers belongs to. It returns a
1046 * *new* reference so don't forget to unref it
1049 get_account_from_header_list (TnyList *headers)
1051 TnyAccount *account = NULL;
1053 if (tny_list_get_length (headers) > 0) {
1054 TnyIterator *iter = tny_list_create_iterator (headers);
1055 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1056 TnyFolder *folder = tny_header_get_folder (header);
1059 g_object_unref (header);
1061 while (!tny_iterator_is_done (iter)) {
1062 header = TNY_HEADER (tny_iterator_get_current (iter));
1063 folder = tny_header_get_folder (header);
1066 g_object_unref (header);
1068 tny_iterator_next (iter);
1073 account = tny_folder_get_account (folder);
1074 g_object_unref (folder);
1078 g_object_unref (header);
1080 g_object_unref (iter);
1086 foreach_unregister_headers (gpointer data,
1089 ModestWindowMgr *mgr = (ModestWindowMgr *) user_data;
1090 TnyHeader *header = TNY_HEADER (data);
1092 modest_window_mgr_unregister_header (mgr, header);
1096 open_msgs_helper_destroyer (gpointer user_data)
1098 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1100 if (helper->banner_info) {
1101 g_free (helper->banner_info->message);
1102 if (helper->banner_info->idle_handler > 0) {
1103 g_source_remove (helper->banner_info->idle_handler);
1104 helper->banner_info->idle_handler = 0;
1106 if (helper->banner_info->banner != NULL) {
1107 gtk_widget_destroy (helper->banner_info->banner);
1108 g_object_unref (helper->banner_info->banner);
1109 helper->banner_info->banner = NULL;
1111 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1112 helper->banner_info = NULL;
1114 g_object_unref (helper->model);
1115 g_object_unref (helper->headers);
1116 g_hash_table_destroy (helper->row_refs_per_header);
1117 g_slice_free (OpenMsgHelper, helper);
1121 open_msgs_performer(gboolean canceled,
1123 GtkWindow *parent_window,
1124 TnyAccount *account,
1127 ModestMailOperation *mail_op = NULL;
1128 const gchar *proto_name;
1130 ModestTransportStoreProtocol proto;
1131 TnyList *not_opened_headers;
1132 TnyConnectionStatus status;
1133 gboolean show_open_draft = FALSE;
1134 OpenMsgHelper *helper = NULL;
1136 helper = (OpenMsgHelper *) user_data;
1137 not_opened_headers = helper->headers;
1139 status = tny_account_get_connection_status (account);
1140 if (err || canceled) {
1141 /* Unregister the already registered headers */
1142 tny_list_foreach (not_opened_headers, foreach_unregister_headers,
1143 modest_runtime_get_window_mgr ());
1144 /* Free the helper */
1145 open_msgs_helper_destroyer (helper);
1147 /* In memory full conditions we could get this error here */
1148 if (err && is_memory_full_error (err)) {
1149 modest_platform_information_banner ((GtkWidget *) parent_window,
1150 NULL, dgettext("ke-recv",
1151 "cerm_device_memory_full"));
1156 /* Get the error message depending on the protocol */
1157 proto_name = tny_account_get_proto (account);
1158 if (proto_name != NULL) {
1159 proto = modest_protocol_info_get_transport_store_protocol (proto_name);
1161 proto = MODEST_PROTOCOL_STORE_MAILDIR;
1164 /* Create the error messages */
1165 if (tny_list_get_length (not_opened_headers) == 1) {
1166 if (proto == MODEST_PROTOCOL_STORE_POP) {
1167 error_msg = g_strdup (_("emev_ni_ui_pop3_msg_recv_error"));
1168 } else if (proto == MODEST_PROTOCOL_STORE_IMAP) {
1169 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1170 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1171 gchar *subject = tny_header_dup_subject (header);
1172 error_msg = g_strdup_printf (_("emev_ni_ui_imap_message_not_available_in_server"),
1175 g_object_unref (header);
1176 g_object_unref (iter);
1181 TnyFolderType folder_type;
1183 iter = tny_list_create_iterator (not_opened_headers);
1184 header = TNY_HEADER (tny_iterator_get_current (iter));
1185 folder = tny_header_get_folder (header);
1186 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1187 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1188 g_object_unref (folder);
1189 g_object_unref (header);
1190 g_object_unref (iter);
1191 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1194 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1197 /* Create the mail operation */
1199 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1200 modest_ui_actions_disk_operations_error_handler,
1202 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1205 if (show_open_draft) {
1206 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1207 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1208 helper->banner_info->banner = NULL;
1209 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1210 helper->banner_info);
1213 modest_mail_operation_get_msgs_full (mail_op,
1217 open_msgs_helper_destroyer);
1222 g_object_unref (mail_op);
1223 g_object_unref (account);
1227 * This function is used by both modest_ui_actions_on_open and
1228 * modest_ui_actions_on_header_activated. This way we always do the
1229 * same when trying to open messages.
1232 open_msgs_from_headers (TnyList *headers, ModestWindow *win)
1234 ModestWindowMgr *mgr = NULL;
1235 TnyIterator *iter = NULL, *iter_not_opened = NULL;
1236 TnyList *not_opened_headers = NULL;
1237 TnyHeaderFlags flags = 0;
1238 TnyAccount *account;
1239 gint uncached_msgs = 0;
1240 GtkWidget *header_view;
1241 GtkTreeModel *model;
1242 GHashTable *refs_for_headers;
1243 OpenMsgHelper *helper;
1244 GtkTreeSelection *sel;
1245 GList *sel_list = NULL, *sel_list_iter = NULL;
1247 g_return_if_fail (headers != NULL);
1249 /* Check that only one message is selected for opening */
1250 if (tny_list_get_length (headers) != 1) {
1251 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1252 NULL, _("mcen_ib_select_one_message"));
1256 mgr = modest_runtime_get_window_mgr ();
1257 iter = tny_list_create_iterator (headers);
1259 /* Get the account */
1260 account = get_account_from_header_list (headers);
1265 /* Get the selections, we need to get the references to the
1266 rows here because the treeview/model could dissapear (the
1267 user might want to select another folder)*/
1268 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1269 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1270 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
1271 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
1272 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
1273 refs_for_headers = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
1274 (GDestroyNotify) gtk_tree_row_reference_free);
1276 /* Look if we already have a message view for each header. If
1277 true, then remove the header from the list of headers to
1279 sel_list_iter = sel_list;
1280 not_opened_headers = tny_simple_list_new ();
1281 while (!tny_iterator_is_done (iter) && sel_list_iter) {
1283 ModestWindow *window = NULL;
1284 TnyHeader *header = NULL;
1285 gboolean found = FALSE;
1287 header = TNY_HEADER (tny_iterator_get_current (iter));
1289 flags = tny_header_get_flags (header);
1292 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1294 /* Do not open again the message and present the
1295 window to the user */
1298 gtk_window_present (GTK_WINDOW (window));
1300 /* the header has been registered already, we don't do
1301 * anything but wait for the window to come up*/
1302 g_debug ("header %p already registered, waiting for window", header);
1305 GtkTreeRowReference *row_reference;
1307 tny_list_append (not_opened_headers, G_OBJECT (header));
1308 /* Create a new row reference and add it to the hash table */
1309 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list_iter->data);
1310 g_hash_table_insert (refs_for_headers, header, row_reference);
1314 g_object_unref (header);
1317 tny_iterator_next (iter);
1318 sel_list_iter = g_list_next (sel_list_iter);
1320 g_object_unref (iter);
1322 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
1323 g_list_free (sel_list);
1325 /* Open each message */
1326 if (tny_list_get_length (not_opened_headers) == 0) {
1327 g_hash_table_destroy (refs_for_headers);
1331 /* If some messages would have to be downloaded, ask the user to
1332 * make a connection. It's generally easier to do this here (in the mainloop)
1333 * than later in a thread:
1335 if (tny_list_get_length (not_opened_headers) > 0) {
1336 uncached_msgs = header_list_count_uncached_msgs (not_opened_headers);
1338 if (uncached_msgs > 0) {
1339 /* Allways download if we are online. */
1340 if (!tny_device_is_online (modest_runtime_get_device ())) {
1343 /* If ask for user permission to download the messages */
1344 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1345 ngettext("mcen_nc_get_msg",
1349 /* End if the user does not want to continue */
1350 if (response == GTK_RESPONSE_CANCEL) {
1351 g_hash_table_destroy (refs_for_headers);
1358 /* Register the headers before actually creating the windows: */
1359 iter_not_opened = tny_list_create_iterator (not_opened_headers);
1360 while (!tny_iterator_is_done (iter_not_opened)) {
1361 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1363 modest_window_mgr_register_header (mgr, header, NULL);
1364 g_object_unref (header);
1366 tny_iterator_next (iter_not_opened);
1368 g_object_unref (iter_not_opened);
1369 iter_not_opened = NULL;
1371 /* Create the helper. We need to get a reference to the model
1372 here because it could change while the message is readed
1373 (the user could switch between folders) */
1374 helper = g_slice_new (OpenMsgHelper);
1375 helper->model = g_object_ref (model);
1376 helper->headers = g_object_ref (not_opened_headers);
1377 helper->row_refs_per_header = refs_for_headers;
1378 helper->banner_info = NULL;
1380 /* Connect to the account and perform */
1381 if (uncached_msgs > 0) {
1382 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1383 open_msgs_performer, helper);
1385 /* Call directly the performer, do not need to connect */
1386 open_msgs_performer (FALSE, NULL, (GtkWindow *) win,
1387 g_object_ref (account), helper);
1392 g_object_unref (account);
1393 if (not_opened_headers)
1394 g_object_unref (not_opened_headers);
1398 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1402 /* we check for low-mem; in that case, show a warning, and don't allow
1405 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1409 headers = get_selected_headers (win);
1414 open_msgs_from_headers (headers, win);
1416 g_object_unref(headers);
1419 static ReplyForwardHelper*
1420 create_reply_forward_helper (ReplyForwardAction action,
1422 guint reply_forward_type,
1425 ReplyForwardHelper *rf_helper = NULL;
1426 const gchar *active_acc = modest_window_get_active_account (win);
1428 rf_helper = g_slice_new0 (ReplyForwardHelper);
1429 rf_helper->reply_forward_type = reply_forward_type;
1430 rf_helper->action = action;
1431 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1432 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1433 rf_helper->account_name = (active_acc) ?
1434 g_strdup (active_acc) :
1435 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1441 free_reply_forward_helper (gpointer data)
1443 ReplyForwardHelper *helper;
1445 helper = (ReplyForwardHelper *) data;
1446 g_free (helper->account_name);
1448 g_object_unref (helper->header);
1449 g_slice_free (ReplyForwardHelper, helper);
1453 reply_forward_cb (ModestMailOperation *mail_op,
1460 TnyMsg *new_msg = NULL;
1461 ReplyForwardHelper *rf_helper;
1462 ModestWindow *msg_win = NULL;
1463 ModestEditType edit_type;
1465 TnyAccount *account = NULL;
1466 ModestWindowMgr *mgr = NULL;
1467 gchar *signature = NULL;
1468 gboolean use_signature;
1470 /* If there was any error. The mail operation could be NULL,
1471 this means that we already have the message downloaded and
1472 that we didn't do a mail operation to retrieve it */
1473 rf_helper = (ReplyForwardHelper *) user_data;
1474 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1477 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1478 rf_helper->account_name);
1479 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr(),
1480 rf_helper->account_name,
1483 /* Create reply mail */
1484 switch (rf_helper->action) {
1487 modest_tny_msg_create_reply_msg (msg, header, from,
1488 (use_signature) ? signature : NULL,
1489 rf_helper->reply_forward_type,
1490 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1492 case ACTION_REPLY_TO_ALL:
1494 modest_tny_msg_create_reply_msg (msg, header, from,
1495 (use_signature) ? signature : NULL,
1496 rf_helper->reply_forward_type,
1497 MODEST_TNY_MSG_REPLY_MODE_ALL);
1498 edit_type = MODEST_EDIT_TYPE_REPLY;
1500 case ACTION_FORWARD:
1502 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1503 rf_helper->reply_forward_type);
1504 edit_type = MODEST_EDIT_TYPE_FORWARD;
1507 g_return_if_reached ();
1515 g_warning ("%s: failed to create message\n", __FUNCTION__);
1519 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1520 rf_helper->account_name,
1521 TNY_ACCOUNT_TYPE_STORE);
1523 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1527 /* Create and register the windows */
1528 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1529 mgr = modest_runtime_get_window_mgr ();
1530 modest_window_mgr_register_window (mgr, msg_win);
1532 if (rf_helper->parent_window != NULL) {
1533 gdouble parent_zoom;
1535 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1536 modest_window_set_zoom (msg_win, parent_zoom);
1539 /* Show edit window */
1540 gtk_widget_show_all (GTK_WIDGET (msg_win));
1544 g_object_unref (G_OBJECT (new_msg));
1546 g_object_unref (G_OBJECT (account));
1547 free_reply_forward_helper (rf_helper);
1550 /* Checks a list of headers. If any of them are not currently
1551 * downloaded (CACHED) then returns TRUE else returns FALSE.
1554 header_list_count_uncached_msgs (TnyList *header_list)
1557 gint uncached_messages = 0;
1559 iter = tny_list_create_iterator (header_list);
1560 while (!tny_iterator_is_done (iter)) {
1563 header = TNY_HEADER (tny_iterator_get_current (iter));
1565 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1566 uncached_messages ++;
1567 g_object_unref (header);
1570 tny_iterator_next (iter);
1572 g_object_unref (iter);
1574 return uncached_messages;
1577 /* Returns FALSE if the user does not want to download the
1578 * messages. Returns TRUE if the user allowed the download.
1581 connect_to_get_msg (ModestWindow *win,
1582 gint num_of_uncached_msgs,
1583 TnyAccount *account)
1585 GtkResponseType response;
1587 /* Allways download if we are online. */
1588 if (tny_device_is_online (modest_runtime_get_device ()))
1591 /* If offline, then ask for user permission to download the messages */
1592 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1593 ngettext("mcen_nc_get_msg",
1595 num_of_uncached_msgs));
1597 if (response == GTK_RESPONSE_CANCEL)
1600 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1604 reply_forward_performer (gboolean canceled,
1606 GtkWindow *parent_window,
1607 TnyAccount *account,
1610 ReplyForwardHelper *rf_helper = NULL;
1611 ModestMailOperation *mail_op;
1613 rf_helper = (ReplyForwardHelper *) user_data;
1615 if (canceled || err) {
1616 free_reply_forward_helper (rf_helper);
1620 /* Retrieve the message */
1621 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1622 modest_ui_actions_disk_operations_error_handler,
1624 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1625 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1628 g_object_unref(mail_op);
1632 * Common code for the reply and forward actions
1635 reply_forward (ReplyForwardAction action, ModestWindow *win)
1637 ReplyForwardHelper *rf_helper = NULL;
1638 guint reply_forward_type;
1640 g_return_if_fail (MODEST_IS_WINDOW(win));
1642 /* we check for low-mem; in that case, show a warning, and don't allow
1643 * reply/forward (because it could potentially require a lot of memory */
1644 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1648 /* we need an account when editing */
1649 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1650 if (!modest_ui_actions_run_account_setup_wizard (win))
1654 reply_forward_type =
1655 modest_conf_get_int (modest_runtime_get_conf (),
1656 (action == ACTION_FORWARD) ?
1657 MODEST_CONF_FORWARD_TYPE :
1658 MODEST_CONF_REPLY_TYPE,
1661 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1663 TnyHeader *header = NULL;
1664 /* Get header and message. Do not free them here, the
1665 reply_forward_cb must do it */
1666 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1667 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1669 if (msg && header) {
1671 rf_helper = create_reply_forward_helper (action, win,
1672 reply_forward_type, header);
1673 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1675 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1679 g_object_unref (msg);
1681 g_object_unref (header);
1683 TnyHeader *header = NULL;
1685 gboolean do_retrieve = TRUE;
1686 TnyList *header_list = NULL;
1688 header_list = get_selected_headers (win);
1691 if (tny_list_get_length (header_list) == 0) {
1692 g_object_unref (header_list);
1696 /* Only reply/forward to one message */
1697 iter = tny_list_create_iterator (header_list);
1698 header = TNY_HEADER (tny_iterator_get_current (iter));
1699 g_object_unref (iter);
1701 /* Retrieve messages */
1702 do_retrieve = (action == ACTION_FORWARD) ||
1703 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1706 TnyAccount *account = NULL;
1707 TnyFolder *folder = NULL;
1708 gdouble download = TRUE;
1709 guint uncached_msgs = 0;
1711 folder = tny_header_get_folder (header);
1713 goto do_retrieve_frees;
1714 account = tny_folder_get_account (folder);
1716 goto do_retrieve_frees;
1718 uncached_msgs = header_list_count_uncached_msgs (header_list);
1720 if (uncached_msgs > 0) {
1721 /* Allways download if we are online. */
1722 if (!tny_device_is_online (modest_runtime_get_device ())) {
1725 /* If ask for user permission to download the messages */
1726 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1727 ngettext("mcen_nc_get_msg",
1731 /* End if the user does not want to continue */
1732 if (response == GTK_RESPONSE_CANCEL)
1739 rf_helper = create_reply_forward_helper (action, win,
1740 reply_forward_type, header);
1741 if (uncached_msgs > 0) {
1742 modest_platform_connect_and_perform (GTK_WINDOW (win),
1744 reply_forward_performer,
1747 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
1748 account, rf_helper);
1753 g_object_unref (account);
1755 g_object_unref (folder);
1757 reply_forward_cb (NULL, header, FALSE, NULL, NULL, rf_helper);
1760 g_object_unref (header_list);
1761 g_object_unref (header);
1766 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1768 g_return_if_fail (MODEST_IS_WINDOW(win));
1770 reply_forward (ACTION_REPLY, win);
1774 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1776 g_return_if_fail (MODEST_IS_WINDOW(win));
1778 reply_forward (ACTION_FORWARD, win);
1782 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1784 g_return_if_fail (MODEST_IS_WINDOW(win));
1786 reply_forward (ACTION_REPLY_TO_ALL, win);
1790 modest_ui_actions_on_next (GtkAction *action,
1791 ModestWindow *window)
1793 if (MODEST_IS_MAIN_WINDOW (window)) {
1794 GtkWidget *header_view;
1796 header_view = modest_main_window_get_child_widget (
1797 MODEST_MAIN_WINDOW(window),
1798 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1802 modest_header_view_select_next (
1803 MODEST_HEADER_VIEW(header_view));
1804 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1805 modest_msg_view_window_select_next_message (
1806 MODEST_MSG_VIEW_WINDOW (window));
1808 g_return_if_reached ();
1813 modest_ui_actions_on_prev (GtkAction *action,
1814 ModestWindow *window)
1816 g_return_if_fail (MODEST_IS_WINDOW(window));
1818 if (MODEST_IS_MAIN_WINDOW (window)) {
1819 GtkWidget *header_view;
1820 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1821 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1825 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1826 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1827 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1829 g_return_if_reached ();
1834 modest_ui_actions_on_sort (GtkAction *action,
1835 ModestWindow *window)
1837 g_return_if_fail (MODEST_IS_WINDOW(window));
1839 if (MODEST_IS_MAIN_WINDOW (window)) {
1840 GtkWidget *header_view;
1841 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1842 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1844 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1849 /* Show sorting dialog */
1850 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1855 new_messages_arrived (ModestMailOperation *self,
1856 TnyList *new_headers,
1860 gboolean show_visual_notifications;
1862 source = modest_mail_operation_get_source (self);
1863 show_visual_notifications = (source) ? FALSE : TRUE;
1865 g_object_unref (source);
1867 /* Notify new messages have been downloaded. If the
1868 send&receive was invoked by the user then do not show any
1869 visual notification, only play a sound and activate the LED
1870 (for the Maemo version) */
1871 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0)
1872 modest_platform_on_new_headers_received (new_headers,
1873 show_visual_notifications);
1878 retrieve_all_messages_cb (GObject *source,
1880 guint retrieve_limit)
1886 window = GTK_WINDOW (source);
1887 msg = g_strdup_printf (_("mail_nc_msg_count_limit_exceeded"),
1888 num_msgs, retrieve_limit);
1890 /* Ask the user if they want to retrieve all the messages */
1892 modest_platform_run_confirmation_dialog_with_buttons (window, msg,
1893 _("mcen_bd_get_all"),
1894 _("mcen_bd_newest_only"));
1895 /* Free and return */
1897 return (response == GTK_RESPONSE_ACCEPT) ? TRUE : FALSE;
1901 TnyAccount *account;
1903 gchar *account_name;
1904 gboolean poke_status;
1905 gboolean interactive;
1906 ModestMailOperation *mail_op;
1910 do_send_receive_performer (gboolean canceled,
1912 GtkWindow *parent_window,
1913 TnyAccount *account,
1916 SendReceiveInfo *info;
1918 info = (SendReceiveInfo *) user_data;
1920 if (err || canceled) {
1921 /* In memory full conditions we could get this error here */
1922 if (err && is_memory_full_error (err)) {
1923 modest_platform_information_banner ((GtkWidget *) parent_window,
1924 NULL, dgettext("ke-recv",
1925 "cerm_device_memory_full"));
1927 if (info->mail_op) {
1928 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
1934 /* Set send/receive operation in progress */
1935 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
1936 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
1939 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
1940 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
1941 G_CALLBACK (on_send_receive_finished),
1944 /* Send & receive. */
1945 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
1946 (info->win) ? retrieve_all_messages_cb : NULL,
1947 new_messages_arrived, info->win);
1952 g_object_unref (G_OBJECT (info->mail_op));
1953 if (info->account_name)
1954 g_free (info->account_name);
1956 g_object_unref (info->win);
1958 g_object_unref (info->account);
1959 g_slice_free (SendReceiveInfo, info);
1963 * This function performs the send & receive required actions. The
1964 * window is used to create the mail operation. Typically it should
1965 * always be the main window, but we pass it as argument in order to
1969 modest_ui_actions_do_send_receive (const gchar *account_name,
1970 gboolean force_connection,
1971 gboolean poke_status,
1972 gboolean interactive,
1975 gchar *acc_name = NULL;
1976 SendReceiveInfo *info;
1977 ModestTnyAccountStore *acc_store;
1979 /* If no account name was provided then get the current account, and if
1980 there is no current account then pick the default one: */
1981 if (!account_name) {
1983 acc_name = g_strdup (modest_window_get_active_account (win));
1985 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1987 g_printerr ("modest: cannot get default account\n");
1991 acc_name = g_strdup (account_name);
1994 acc_store = modest_runtime_get_account_store ();
1996 /* Create the info for the connect and perform */
1997 info = g_slice_new (SendReceiveInfo);
1998 info->account_name = acc_name;
1999 info->win = (win) ? g_object_ref (win) : NULL;
2000 info->poke_status = poke_status;
2001 info->interactive = interactive;
2002 info->account = modest_tny_account_store_get_server_account (acc_store, acc_name,
2003 TNY_ACCOUNT_TYPE_STORE);
2004 /* We need to create the operation here, because otherwise it
2005 could happen that the queue emits the queue-empty signal
2006 while we're trying to connect the account */
2007 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2008 modest_ui_actions_disk_operations_error_handler,
2010 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2012 /* Invoke the connect and perform */
2013 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2014 force_connection, info->account,
2015 do_send_receive_performer, info);
2020 modest_ui_actions_do_cancel_send (const gchar *account_name,
2023 TnyTransportAccount *transport_account;
2024 TnySendQueue *send_queue = NULL;
2025 GError *error = NULL;
2027 /* Get transport account */
2029 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2030 (modest_runtime_get_account_store(),
2032 TNY_ACCOUNT_TYPE_TRANSPORT));
2033 if (!transport_account) {
2034 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2039 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2040 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2041 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2042 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2043 "modest: could not find send queue for account\n");
2045 /* Cancel the current send */
2046 tny_account_cancel (TNY_ACCOUNT (transport_account));
2048 /* Suspend all pending messages */
2049 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2053 if (transport_account != NULL)
2054 g_object_unref (G_OBJECT (transport_account));
2058 modest_ui_actions_cancel_send_all (ModestWindow *win)
2060 GSList *account_names, *iter;
2062 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2065 iter = account_names;
2067 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2068 iter = g_slist_next (iter);
2071 modest_account_mgr_free_account_names (account_names);
2072 account_names = NULL;
2076 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2079 /* Check if accounts exist */
2080 gboolean accounts_exist =
2081 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2083 /* If not, allow the user to create an account before trying to send/receive. */
2084 if (!accounts_exist)
2085 modest_ui_actions_on_accounts (NULL, win);
2087 /* Cancel all sending operaitons */
2088 modest_ui_actions_cancel_send_all (win);
2092 * Refreshes all accounts. This function will be used by automatic
2096 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2097 gboolean force_connection,
2098 gboolean poke_status,
2099 gboolean interactive)
2101 GSList *account_names, *iter;
2103 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2106 iter = account_names;
2108 modest_ui_actions_do_send_receive ((const char*) iter->data,
2110 poke_status, interactive, win);
2111 iter = g_slist_next (iter);
2114 modest_account_mgr_free_account_names (account_names);
2115 account_names = NULL;
2119 * Handler of the click on Send&Receive button in the main toolbar
2122 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2124 /* Check if accounts exist */
2125 gboolean accounts_exist;
2128 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2130 /* If not, allow the user to create an account before trying to send/receive. */
2131 if (!accounts_exist)
2132 modest_ui_actions_on_accounts (NULL, win);
2134 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2135 if (MODEST_IS_MAIN_WINDOW (win)) {
2136 GtkWidget *folder_view;
2137 TnyFolderStore *folder_store;
2140 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2141 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2145 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2148 g_object_unref (folder_store);
2151 /* Refresh the active account. Force the connection if needed
2152 and poke the status of all folders */
2153 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2158 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2161 GtkWidget *header_view;
2163 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2165 header_view = modest_main_window_get_child_widget (main_window,
2166 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2170 conf = modest_runtime_get_conf ();
2172 /* what is saved/restored is depending on the style; thus; we save with
2173 * old style, then update the style, and restore for this new style
2175 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2177 if (modest_header_view_get_style
2178 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2179 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2180 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2182 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2183 MODEST_HEADER_VIEW_STYLE_DETAILS);
2185 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2186 MODEST_CONF_HEADER_VIEW_KEY);
2191 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2193 ModestMainWindow *main_window)
2195 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2196 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2198 /* in the case the folder is empty, show the empty folder message and focus
2200 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2201 if (modest_header_view_is_empty (header_view)) {
2202 TnyFolder *folder = modest_header_view_get_folder (header_view);
2203 GtkWidget *folder_view =
2204 modest_main_window_get_child_widget (main_window,
2205 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2207 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2208 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2212 /* If no header has been selected then exit */
2217 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2218 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2220 /* Update toolbar dimming state */
2221 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2222 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2226 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2228 ModestMainWindow *main_window)
2231 GtkWidget *open_widget;
2233 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2238 if (modest_header_view_count_selected_headers (header_view) > 1) {
2239 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2243 /* we check for low-mem; in that case, show a warning, and don't allow
2244 * activating headers
2246 if (modest_platform_check_memory_low (MODEST_WINDOW(main_window), TRUE))
2249 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2250 open_widget = modest_window_get_action_widget (MODEST_WINDOW (main_window), "/MenuBar/EmailMenu/EmailOpenMenu");
2251 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2254 headers = modest_header_view_get_selected_headers (header_view);
2256 open_msgs_from_headers (headers, MODEST_WINDOW (main_window));
2258 g_object_unref (headers);
2262 set_active_account_from_tny_account (TnyAccount *account,
2263 ModestWindow *window)
2265 const gchar *server_acc_name = tny_account_get_id (account);
2267 /* We need the TnyAccount provided by the
2268 account store because that is the one that
2269 knows the name of the Modest account */
2270 TnyAccount *modest_server_account = modest_server_account =
2271 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2272 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2274 if (!modest_server_account) {
2275 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2279 /* Update active account, but only if it's not a pseudo-account */
2280 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2281 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2282 const gchar *modest_acc_name =
2283 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2284 if (modest_acc_name)
2285 modest_window_set_active_account (window, modest_acc_name);
2288 g_object_unref (modest_server_account);
2293 folder_refreshed_cb (ModestMailOperation *mail_op,
2297 ModestMainWindow *win = NULL;
2298 GtkWidget *header_view;
2299 const GError *error;
2301 g_return_if_fail (TNY_IS_FOLDER (folder));
2303 win = MODEST_MAIN_WINDOW (user_data);
2305 /* Check if the operation failed due to memory low conditions */
2306 error = modest_mail_operation_get_error (mail_op);
2307 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2308 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2309 modest_platform_run_information_dialog (GTK_WINDOW (win),
2310 dgettext("ke-recv","memr_ib_operation_disabled"),
2316 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2319 TnyFolder *current_folder;
2321 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
2322 if (current_folder != NULL && folder != current_folder) {
2323 g_object_unref (current_folder);
2325 } else if (current_folder)
2326 g_object_unref (current_folder);
2329 /* Check if folder is empty and set headers view contents style */
2330 if (tny_folder_get_all_count (folder) == 0)
2331 modest_main_window_set_contents_style (win,
2332 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2337 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2338 TnyFolderStore *folder_store,
2340 ModestMainWindow *main_window)
2343 GtkWidget *header_view;
2345 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2347 header_view = modest_main_window_get_child_widget(main_window,
2348 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2352 conf = modest_runtime_get_conf ();
2354 if (TNY_IS_ACCOUNT (folder_store)) {
2356 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2358 /* Show account details */
2359 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2362 if (TNY_IS_FOLDER (folder_store) && selected) {
2363 TnyAccount *account;
2364 const gchar *account_name = NULL;
2367 /* Update the active account */
2368 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2370 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2372 modest_tny_account_get_parent_modest_account_name_for_server_account (account);
2373 g_object_unref (account);
2377 /* Set the header style by default, it could
2378 be changed later by the refresh callback to
2380 modest_main_window_set_contents_style (main_window,
2381 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2383 refresh = !modest_account_mgr_account_is_busy (modest_runtime_get_account_mgr (), account_name);
2385 /* Set folder on header view. This function
2386 will call tny_folder_refresh_async so we
2387 pass a callback that will be called when
2388 finished. We use that callback to set the
2389 empty view if there are no messages */
2390 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2391 TNY_FOLDER (folder_store),
2393 folder_refreshed_cb,
2396 /* Restore configuration. We need to do this
2397 *after* the set_folder because the widget
2398 memory asks the header view about its
2400 modest_widget_memory_restore (modest_runtime_get_conf (),
2401 G_OBJECT(header_view),
2402 MODEST_CONF_HEADER_VIEW_KEY);
2404 /* No need to save the header view
2405 configuration for Maemo because it only
2406 saves the sorting stuff and that it's
2407 already being done by the sort
2408 dialog. Remove it when the GNOME version
2409 has the same behaviour */
2410 #ifdef MODEST_PLATFORM_GNOME
2411 if (modest_main_window_get_contents_style (main_window) ==
2412 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2413 modest_widget_memory_save (conf, G_OBJECT (header_view),
2414 MODEST_CONF_HEADER_VIEW_KEY);
2416 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2420 /* Update dimming state */
2421 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2422 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2426 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2433 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2435 online = tny_device_is_online (modest_runtime_get_device());
2438 /* already online -- the item is simply not there... */
2439 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2441 GTK_MESSAGE_WARNING,
2443 _("The %s you selected cannot be found"),
2445 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2446 gtk_dialog_run (GTK_DIALOG(dialog));
2448 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2451 _("mcen_bd_dialog_cancel"),
2452 GTK_RESPONSE_REJECT,
2453 _("mcen_bd_dialog_ok"),
2454 GTK_RESPONSE_ACCEPT,
2456 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2457 "Do you want to get online?"), item);
2458 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2459 gtk_label_new (txt), FALSE, FALSE, 0);
2460 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2463 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2464 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2465 /* TODO: Comment about why is this commented out: */
2466 /* modest_platform_connect_and_wait (); */
2469 gtk_widget_destroy (dialog);
2473 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2476 /* g_message ("%s %s", __FUNCTION__, link); */
2481 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2484 modest_platform_activate_uri (link);
2488 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2491 modest_platform_show_uri_popup (link);
2495 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2498 /* we check for low-mem; in that case, show a warning, and don't allow
2499 * viewing attachments
2501 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2504 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2508 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2509 const gchar *address,
2512 /* g_message ("%s %s", __FUNCTION__, address); */
2516 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2517 TnyMsg *saved_draft,
2520 ModestMsgEditWindow *edit_window;
2521 ModestMainWindow *win;
2523 /* FIXME. Make the header view sensitive again. This is a
2524 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2526 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2527 modest_runtime_get_window_mgr(), FALSE));
2529 GtkWidget *hdrview = modest_main_window_get_child_widget(
2530 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2531 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2534 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2536 /* Set draft is there was no error */
2537 if (!modest_mail_operation_get_error (mail_op))
2538 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2540 g_object_unref(edit_window);
2544 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2546 TnyTransportAccount *transport_account;
2547 ModestMailOperation *mail_operation;
2549 gchar *account_name, *from;
2550 ModestAccountMgr *account_mgr;
2551 /* char *info_text; */
2552 gboolean had_error = FALSE;
2553 guint64 available_disk, expected_size;
2556 ModestMainWindow *win;
2558 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2560 data = modest_msg_edit_window_get_msg_data (edit_window);
2563 available_disk = modest_folder_available_space (NULL);
2564 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2565 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2570 if ((available_disk != -1) && expected_size > available_disk) {
2571 modest_msg_edit_window_free_msg_data (edit_window, data);
2573 modest_platform_information_banner (NULL, NULL, dgettext("ke-recv", "cerm_device_memory_full"));
2578 * djcb: if we're in low-memory state, we only allow for
2579 * saving messages smaller than
2580 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2581 * should still allow for sending anything critical...
2583 if (expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) {
2585 if (modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE)) {
2586 modest_msg_edit_window_free_msg_data (edit_window, data);
2592 * djcb: we also make sure that the attachments are smaller than the max size
2593 * this is for the case where we'd try to forward a message with attachments
2594 * bigger than our max allowed size, or sending an message from drafts which
2595 * somehow got past our checks when attaching.
2597 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2598 modest_platform_run_information_dialog (
2599 GTK_WINDOW(edit_window),
2600 dgettext("ke-recv","memr_ib_operation_disabled"),
2602 modest_msg_edit_window_free_msg_data (edit_window, data);
2606 account_name = g_strdup (data->account_name);
2607 account_mgr = modest_runtime_get_account_mgr();
2609 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2611 account_name = modest_account_mgr_get_default_account (account_mgr);
2612 if (!account_name) {
2613 g_printerr ("modest: no account found\n");
2614 modest_msg_edit_window_free_msg_data (edit_window, data);
2618 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2619 account_name = g_strdup (data->account_name);
2623 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2624 (modest_runtime_get_account_store(),
2626 TNY_ACCOUNT_TYPE_TRANSPORT));
2627 if (!transport_account) {
2628 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2629 g_free (account_name);
2630 modest_msg_edit_window_free_msg_data (edit_window, data);
2633 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2635 /* Create the mail operation */
2636 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
2638 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2640 modest_mail_operation_save_to_drafts (mail_operation,
2652 data->priority_flags,
2653 on_save_to_drafts_cb,
2654 g_object_ref(edit_window));
2656 /* Use the main window as the parent of the banner, if the
2657 main window does not exist it won't be shown, if the parent
2658 window exists then it's properly shown. We don't use the
2659 editor window because it could be closed (save to drafts
2660 could happen after closing the window */
2661 win = (ModestMainWindow *)
2662 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
2664 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2665 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
2668 modest_msg_edit_window_set_modified (edit_window, FALSE);
2672 g_free (account_name);
2673 g_object_unref (G_OBJECT (transport_account));
2674 g_object_unref (G_OBJECT (mail_operation));
2676 modest_msg_edit_window_free_msg_data (edit_window, data);
2679 * If the drafts folder is selected then make the header view
2680 * insensitive while the message is being saved to drafts
2681 * (it'll be sensitive again in on_save_to_drafts_cb()). This
2682 * is not very clean but it avoids letting the drafts folder
2683 * in an inconsistent state: the user could edit the message
2684 * being saved and undesirable things would happen.
2685 * In the average case the user won't notice anything at
2686 * all. In the worst case (the user is editing a really big
2687 * file from Drafts) the header view will be insensitive
2688 * during the saving process (10 or 20 seconds, depending on
2689 * the message). Anyway this is just a quick workaround: once
2690 * we find a better solution it should be removed
2691 * See NB#65125 (commend #18) for details.
2693 if (!had_error && win != NULL) {
2694 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
2695 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
2697 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
2699 if (modest_tny_folder_is_local_folder(folder)) {
2700 TnyFolderType folder_type;
2701 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
2702 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
2703 GtkWidget *hdrview = modest_main_window_get_child_widget(
2704 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2705 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
2709 if (folder != NULL) g_object_unref(folder);
2716 /* For instance, when clicking the Send toolbar button when editing a message: */
2718 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2720 TnyTransportAccount *transport_account = NULL;
2721 gboolean had_error = FALSE;
2722 guint64 available_disk, expected_size;
2726 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
2728 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2731 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2734 available_disk = modest_folder_available_space (NULL);
2735 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2736 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2741 if ((available_disk != -1) && expected_size > available_disk) {
2742 modest_msg_edit_window_free_msg_data (edit_window, data);
2744 modest_platform_information_banner (NULL, NULL, dgettext("ke-recv", "cerm_device_memory_full"));
2750 * djcb: if we're in low-memory state, we only allow for sending messages
2751 * smaller than MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h)
2752 * this should still allow for sending anything critical...
2754 if (expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) {
2755 if (modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE)) {
2756 modest_msg_edit_window_free_msg_data (edit_window, data);
2762 * djcb: we also make sure that the attachments are smaller than the max size
2763 * this is for the case where we'd try to forward a message with attachments
2764 * bigger than our max allowed size, or sending an message from drafts which
2765 * somehow got past our checks when attaching.
2767 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2768 modest_platform_run_information_dialog (
2769 GTK_WINDOW(edit_window),
2770 dgettext("ke-recv","memr_ib_operation_disabled"),
2772 modest_msg_edit_window_free_msg_data (edit_window, data);
2776 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2777 gchar *account_name = g_strdup (data->account_name);
2779 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2782 account_name = modest_account_mgr_get_default_account (account_mgr);
2784 if (!account_name) {
2785 modest_msg_edit_window_free_msg_data (edit_window, data);
2786 /* Run account setup wizard */
2787 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
2792 /* Get the currently-active transport account for this modest account: */
2793 if (strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
2794 transport_account = TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2795 (modest_runtime_get_account_store(),
2796 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
2799 if (!transport_account) {
2800 modest_msg_edit_window_free_msg_data (edit_window, data);
2801 /* Run account setup wizard */
2802 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2806 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2808 /* Create the mail operation */
2809 ModestMailOperation *mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
2810 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2812 modest_mail_operation_send_new_mail (mail_operation,
2824 data->priority_flags);
2826 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
2827 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2830 if (modest_mail_operation_get_error (mail_operation) != NULL) {
2831 const GError *error = modest_mail_operation_get_error (mail_operation);
2832 if (error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
2833 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
2834 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
2841 g_free (account_name);
2842 g_object_unref (G_OBJECT (transport_account));
2843 g_object_unref (G_OBJECT (mail_operation));
2845 modest_msg_edit_window_free_msg_data (edit_window, data);
2848 modest_msg_edit_window_set_sent (edit_window, TRUE);
2850 /* Save settings and close the window: */
2851 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2858 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2859 ModestMsgEditWindow *window)
2861 ModestMsgEditFormatState *format_state = NULL;
2863 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2864 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2866 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2869 format_state = modest_msg_edit_window_get_format_state (window);
2870 g_return_if_fail (format_state != NULL);
2872 format_state->bold = gtk_toggle_action_get_active (action);
2873 modest_msg_edit_window_set_format_state (window, format_state);
2874 g_free (format_state);
2879 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2880 ModestMsgEditWindow *window)
2882 ModestMsgEditFormatState *format_state = NULL;
2884 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2885 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2887 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2890 format_state = modest_msg_edit_window_get_format_state (window);
2891 g_return_if_fail (format_state != NULL);
2893 format_state->italics = gtk_toggle_action_get_active (action);
2894 modest_msg_edit_window_set_format_state (window, format_state);
2895 g_free (format_state);
2900 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2901 ModestMsgEditWindow *window)
2903 ModestMsgEditFormatState *format_state = NULL;
2905 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2906 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2908 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2911 format_state = modest_msg_edit_window_get_format_state (window);
2912 g_return_if_fail (format_state != NULL);
2914 format_state->bullet = gtk_toggle_action_get_active (action);
2915 modest_msg_edit_window_set_format_state (window, format_state);
2916 g_free (format_state);
2921 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2922 GtkRadioAction *selected,
2923 ModestMsgEditWindow *window)
2925 ModestMsgEditFormatState *format_state = NULL;
2926 GtkJustification value;
2928 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2930 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2933 value = gtk_radio_action_get_current_value (selected);
2935 format_state = modest_msg_edit_window_get_format_state (window);
2936 g_return_if_fail (format_state != NULL);
2938 format_state->justification = value;
2939 modest_msg_edit_window_set_format_state (window, format_state);
2940 g_free (format_state);
2944 modest_ui_actions_on_select_editor_color (GtkAction *action,
2945 ModestMsgEditWindow *window)
2947 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2948 g_return_if_fail (GTK_IS_ACTION (action));
2950 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2953 modest_msg_edit_window_select_color (window);
2957 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2958 ModestMsgEditWindow *window)
2960 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2961 g_return_if_fail (GTK_IS_ACTION (action));
2963 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2966 modest_msg_edit_window_select_background_color (window);
2970 modest_ui_actions_on_insert_image (GtkAction *action,
2971 ModestMsgEditWindow *window)
2973 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2974 g_return_if_fail (GTK_IS_ACTION (action));
2977 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2980 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2983 modest_msg_edit_window_insert_image (window);
2987 modest_ui_actions_on_attach_file (GtkAction *action,
2988 ModestMsgEditWindow *window)
2990 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2991 g_return_if_fail (GTK_IS_ACTION (action));
2993 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2996 modest_msg_edit_window_offer_attach_file (window);
3000 modest_ui_actions_on_remove_attachments (GtkAction *action,
3001 ModestMsgEditWindow *window)
3003 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3004 g_return_if_fail (GTK_IS_ACTION (action));
3006 modest_msg_edit_window_remove_attachments (window, NULL);
3010 do_create_folder_cb (ModestMailOperation *mail_op,
3011 TnyFolderStore *parent_folder,
3012 TnyFolder *new_folder,
3015 gchar *suggested_name = (gchar *) user_data;
3016 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3018 if (modest_mail_operation_get_error (mail_op)) {
3020 /* Show an error. If there was some problem writing to
3021 disk, show it, otherwise show the generic folder
3022 create error. We do it here and not in an error
3023 handler because the call to do_create_folder will
3024 stop the main loop in a gtk_dialog_run and then,
3025 the message won't be shown until that dialog is
3027 modest_ui_actions_disk_operations_error_handler (mail_op,
3028 _("mail_in_ui_folder_create_error"));
3030 /* Try again. Do *NOT* show any error because the mail
3031 operations system will do it for us because we
3032 created the mail_op with new_with_error_handler */
3033 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3035 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3036 * FIXME: any other? */
3037 GtkWidget *folder_view;
3039 if (MODEST_IS_MAIN_WINDOW(source_win))
3041 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3042 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3045 get_folder_view_from_move_to_dialog (GTK_WIDGET(source_win));
3047 /* Select the newly created folder. It could happen
3048 that the widget is no longer there (i.e. the window
3049 has been destroyed, so we need to check this */
3051 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3053 g_object_unref (new_folder);
3055 /* Free. Note that the first time it'll be NULL so noop */
3056 g_free (suggested_name);
3057 g_object_unref (source_win);
3061 do_create_folder (GtkWindow *parent_window,
3062 TnyFolderStore *parent_folder,
3063 const gchar *suggested_name)
3066 gchar *folder_name = NULL;
3068 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3070 (gchar *) suggested_name,
3073 if (result == GTK_RESPONSE_ACCEPT) {
3074 ModestMailOperation *mail_op;
3076 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3077 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3079 modest_mail_operation_create_folder (mail_op,
3081 (const gchar *) folder_name,
3082 do_create_folder_cb,
3084 g_object_unref (mail_op);
3089 create_folder_performer (gboolean canceled,
3091 GtkWindow *parent_window,
3092 TnyAccount *account,
3095 TnyFolderStore *parent_folder = TNY_FOLDER_STORE (user_data);
3097 if (canceled || err) {
3098 /* In memory full conditions we could get this error here */
3099 if (err && is_memory_full_error (err)) {
3100 modest_platform_information_banner ((GtkWidget *) parent_window,
3101 NULL, dgettext("ke-recv",
3102 "cerm_device_memory_full"));
3107 /* Run the new folder dialog */
3108 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3111 g_object_unref (parent_folder);
3115 modest_ui_actions_create_folder(GtkWidget *parent_window,
3116 GtkWidget *folder_view)
3118 TnyFolderStore *parent_folder;
3120 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3122 if (parent_folder) {
3123 /* The parent folder will be freed in the callback */
3124 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3127 create_folder_performer,
3133 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
3135 GtkWidget *folder_view;
3137 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3139 folder_view = modest_main_window_get_child_widget (main_window,
3140 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3144 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
3148 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3151 const GError *error = NULL;
3152 const gchar *message = NULL;
3154 /* Get error message */
3155 error = modest_mail_operation_get_error (mail_op);
3157 g_return_if_reached ();
3159 switch (error->code) {
3160 case MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS:
3161 message = _CS("ckdg_ib_folder_already_exists");
3164 message = _("emev_ib_ui_imap_unable_to_rename");
3167 /* We don't set a parent for the dialog because the dialog
3168 will be destroyed so the banner won't appear */
3169 modest_platform_information_banner (NULL, NULL, message);
3173 TnyFolderStore *folder;
3178 on_rename_folder_cb (ModestMailOperation *mail_op,
3179 TnyFolder *new_folder,
3182 ModestFolderView *folder_view;
3184 /* If the window was closed when renaming a folder this could
3186 if (!MODEST_IS_FOLDER_VIEW (user_data))
3189 folder_view = MODEST_FOLDER_VIEW (user_data);
3190 /* Note that if the rename fails new_folder will be NULL */
3192 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3194 modest_folder_view_select_first_inbox_or_local (folder_view);
3196 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3200 on_rename_folder_performer (gboolean canceled,
3202 GtkWindow *parent_window,
3203 TnyAccount *account,
3206 ModestMailOperation *mail_op = NULL;
3207 GtkTreeSelection *sel = NULL;
3208 GtkWidget *folder_view = NULL;
3209 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3211 if (canceled || err) {
3212 /* In memory full conditions we could get this error here */
3213 if (err && is_memory_full_error (err)) {
3214 modest_platform_information_banner ((GtkWidget *) parent_window,
3215 NULL, dgettext("ke-recv",
3216 "cerm_device_memory_full"));
3218 } else if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3220 folder_view = modest_main_window_get_child_widget (
3221 MODEST_MAIN_WINDOW (parent_window),
3222 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3225 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3226 modest_ui_actions_rename_folder_error_handler,
3227 parent_window, NULL);
3229 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3232 /* Clear the headers view */
3233 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3234 gtk_tree_selection_unselect_all (sel);
3236 /* Actually rename the folder */
3237 modest_mail_operation_rename_folder (mail_op,
3238 TNY_FOLDER (data->folder),
3239 (const gchar *) (data->new_name),
3240 on_rename_folder_cb,
3242 g_object_unref (mail_op);
3245 g_free (data->new_name);
3250 modest_ui_actions_on_rename_folder (GtkAction *action,
3251 ModestMainWindow *main_window)
3253 TnyFolderStore *folder;
3254 GtkWidget *folder_view;
3255 GtkWidget *header_view;
3257 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3259 folder_view = modest_main_window_get_child_widget (main_window,
3260 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3264 header_view = modest_main_window_get_child_widget (main_window,
3265 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3270 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3275 if (TNY_IS_FOLDER (folder)) {
3278 const gchar *current_name;
3279 TnyFolderStore *parent;
3280 gboolean do_rename = TRUE;
3282 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3283 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3284 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
3285 parent, current_name,
3287 g_object_unref (parent);
3289 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3292 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3293 rename_folder_data->folder = folder;
3294 rename_folder_data->new_name = folder_name;
3295 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(main_window), TRUE,
3296 folder, on_rename_folder_performer, rename_folder_data);
3299 g_object_unref (folder);
3303 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3306 GObject *win = modest_mail_operation_get_source (mail_op);
3308 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3309 _("mail_in_ui_folder_delete_error"),
3311 g_object_unref (win);
3315 TnyFolderStore *folder;
3316 gboolean move_to_trash;
3320 on_delete_folder_cb (gboolean canceled,
3322 GtkWindow *parent_window,
3323 TnyAccount *account,
3326 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3327 GtkWidget *folder_view;
3328 ModestMailOperation *mail_op;
3329 GtkTreeSelection *sel;
3331 if (!MODEST_IS_MAIN_WINDOW(parent_window) || canceled || (err!=NULL)) {
3332 g_object_unref (G_OBJECT (info->folder));
3337 folder_view = modest_main_window_get_child_widget (
3338 MODEST_MAIN_WINDOW (parent_window),
3339 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3341 /* Unselect the folder before deleting it to free the headers */
3342 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3343 gtk_tree_selection_unselect_all (sel);
3345 /* Create the mail operation */
3347 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3348 modest_ui_actions_delete_folder_error_handler,
3351 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3353 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3355 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3357 g_object_unref (G_OBJECT (mail_op));
3358 g_object_unref (G_OBJECT (info->folder));
3363 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
3365 TnyFolderStore *folder;
3366 GtkWidget *folder_view;
3370 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3372 folder_view = modest_main_window_get_child_widget (main_window,
3373 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3377 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3379 /* Show an error if it's an account */
3380 if (!TNY_IS_FOLDER (folder)) {
3381 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
3382 _("mail_in_ui_folder_delete_error"),
3384 g_object_unref (G_OBJECT (folder));
3389 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3390 tny_folder_get_name (TNY_FOLDER (folder)));
3391 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
3392 (const gchar *) message);
3395 if (response == GTK_RESPONSE_OK) {
3396 DeleteFolderInfo *info;
3397 info = g_new0(DeleteFolderInfo, 1);
3398 info->folder = folder;
3399 info->move_to_trash = move_to_trash;
3400 g_object_ref (G_OBJECT (info->folder));
3401 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder));
3402 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (main_window),
3404 TNY_FOLDER_STORE (account),
3405 on_delete_folder_cb, info);
3406 g_object_unref (account);
3408 g_object_unref (G_OBJECT (folder));
3412 modest_ui_actions_on_delete_folder (GtkAction *action,
3413 ModestMainWindow *main_window)
3415 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3417 delete_folder (main_window, FALSE);
3421 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3423 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3425 delete_folder (main_window, TRUE);
3429 typedef struct _PasswordDialogFields {
3430 GtkWidget *username;
3431 GtkWidget *password;
3433 } PasswordDialogFields;
3436 password_dialog_check_field (GtkEditable *editable,
3437 PasswordDialogFields *fields)
3440 gboolean any_value_empty = FALSE;
3442 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
3443 if ((value == NULL) || value[0] == '\0') {
3444 any_value_empty = TRUE;
3446 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
3447 if ((value == NULL) || value[0] == '\0') {
3448 any_value_empty = TRUE;
3450 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3454 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3455 const gchar* server_account_name,
3460 ModestMainWindow *main_window)
3462 g_return_if_fail(server_account_name);
3463 gboolean completed = FALSE;
3464 PasswordDialogFields *fields = NULL;
3466 /* Initalize output parameters: */
3473 #ifdef MODEST_PLATFORM_MAEMO
3474 /* Maemo uses a different (awkward) button order,
3475 * It should probably just use gtk_alternative_dialog_button_order ().
3477 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3480 _("mcen_bd_dialog_ok"),
3481 GTK_RESPONSE_ACCEPT,
3482 _("mcen_bd_dialog_cancel"),
3483 GTK_RESPONSE_REJECT,
3486 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3490 GTK_RESPONSE_REJECT,
3492 GTK_RESPONSE_ACCEPT,
3494 #endif /* MODEST_PLATFORM_MAEMO */
3496 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog));
3498 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3499 modest_runtime_get_account_mgr(), server_account_name);
3500 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3501 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3507 /* This causes a warning because the logical ID has no %s in it,
3508 * though the translation does, but there is not much we can do about that: */
3509 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3510 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
3513 g_free (server_name);
3517 gchar *initial_username = modest_account_mgr_get_server_account_username (
3518 modest_runtime_get_account_mgr(), server_account_name);
3520 GtkWidget *entry_username = gtk_entry_new ();
3521 if (initial_username)
3522 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
3523 /* Dim this if a connection has ever succeeded with this username,
3524 * as per the UI spec: */
3525 /* const gboolean username_known = */
3526 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3527 /* modest_runtime_get_account_mgr(), server_account_name); */
3528 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3530 /* We drop the username sensitive code and disallow changing it here
3531 * as tinymail does not support really changing the username in the callback
3533 gtk_widget_set_sensitive (entry_username, FALSE);
3535 #ifdef MODEST_PLATFORM_MAEMO
3536 /* Auto-capitalization is the default, so let's turn it off: */
3537 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3539 /* Create a size group to be used by all captions.
3540 * Note that HildonCaption does not create a default size group if we do not specify one.
3541 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3542 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3544 GtkWidget *caption = hildon_caption_new (sizegroup,
3545 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
3546 gtk_widget_show (entry_username);
3547 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3548 FALSE, FALSE, MODEST_MARGIN_HALF);
3549 gtk_widget_show (caption);
3551 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
3553 #endif /* MODEST_PLATFORM_MAEMO */
3556 GtkWidget *entry_password = gtk_entry_new ();
3557 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3558 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3560 #ifdef MODEST_PLATFORM_MAEMO
3561 /* Auto-capitalization is the default, so let's turn it off: */
3562 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3563 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3565 caption = hildon_caption_new (sizegroup,
3566 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
3567 gtk_widget_show (entry_password);
3568 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3569 FALSE, FALSE, MODEST_MARGIN_HALF);
3570 gtk_widget_show (caption);
3571 g_object_unref (sizegroup);
3573 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
3575 #endif /* MODEST_PLATFORM_MAEMO */
3577 if (initial_username != NULL)
3578 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3580 /* This is not in the Maemo UI spec:
3581 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3582 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3586 fields = g_slice_new0 (PasswordDialogFields);
3587 fields->username = entry_username;
3588 fields->password = entry_password;
3589 fields->dialog = dialog;
3591 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3592 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3593 password_dialog_check_field (NULL, fields);
3595 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3597 while (!completed) {
3599 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3601 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
3603 /* Note that an empty field becomes the "" string */
3604 if (*username && strlen (*username) > 0) {
3605 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
3606 server_account_name,
3610 const gboolean username_was_changed =
3611 (strcmp (*username, initial_username) != 0);
3612 if (username_was_changed) {
3613 g_warning ("%s: tinymail does not yet support changing the "
3614 "username in the get_password() callback.\n", __FUNCTION__);
3618 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
3619 _("mcen_ib_username_pw_incorrect"));
3625 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
3627 /* We do not save the password in the configuration,
3628 * because this function is only called for passwords that should
3629 * not be remembered:
3630 modest_server_account_set_password (
3631 modest_runtime_get_account_mgr(), server_account_name,
3638 /* Set parent to NULL or the banner will disappear with its parent dialog */
3639 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
3650 /* This is not in the Maemo UI spec:
3651 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3657 gtk_widget_destroy (dialog);
3658 g_slice_free (PasswordDialogFields, fields);
3660 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3664 modest_ui_actions_on_cut (GtkAction *action,
3665 ModestWindow *window)
3667 GtkWidget *focused_widget;
3668 GtkClipboard *clipboard;
3670 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3671 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3672 if (GTK_IS_EDITABLE (focused_widget)) {
3673 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3674 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3675 gtk_clipboard_store (clipboard);
3676 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3677 GtkTextBuffer *buffer;
3679 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3680 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3681 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3682 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3683 gtk_clipboard_store (clipboard);
3685 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3686 TnyList *header_list = modest_header_view_get_selected_headers (
3687 MODEST_HEADER_VIEW (focused_widget));
3688 gboolean continue_download = FALSE;
3689 gint num_of_unc_msgs;
3691 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3693 if (num_of_unc_msgs) {
3694 TnyAccount *account = get_account_from_header_list (header_list);
3696 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3697 g_object_unref (account);
3701 if (num_of_unc_msgs == 0 || continue_download) {
3702 /* modest_platform_information_banner (
3703 NULL, NULL, _CS("mcen_ib_getting_items"));*/
3704 modest_header_view_cut_selection (
3705 MODEST_HEADER_VIEW (focused_widget));
3708 g_object_unref (header_list);
3709 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3710 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3715 modest_ui_actions_on_copy (GtkAction *action,
3716 ModestWindow *window)
3718 GtkClipboard *clipboard;
3719 GtkWidget *focused_widget;
3720 gboolean copied = TRUE;
3722 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3723 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3725 if (GTK_IS_LABEL (focused_widget)) {
3727 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
3728 gtk_clipboard_set_text (clipboard, selection, -1);
3730 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3731 gtk_clipboard_store (clipboard);
3732 } else if (GTK_IS_EDITABLE (focused_widget)) {
3733 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3734 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3735 gtk_clipboard_store (clipboard);
3736 } else if (GTK_IS_HTML (focused_widget)) {
3737 gtk_html_copy (GTK_HTML (focused_widget));
3738 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3739 gtk_clipboard_store (clipboard);
3740 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3741 GtkTextBuffer *buffer;
3742 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3743 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3744 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3745 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3746 gtk_clipboard_store (clipboard);
3748 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3749 TnyList *header_list = modest_header_view_get_selected_headers (
3750 MODEST_HEADER_VIEW (focused_widget));
3751 gboolean continue_download = FALSE;
3752 gint num_of_unc_msgs;
3754 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3756 if (num_of_unc_msgs) {
3757 TnyAccount *account = get_account_from_header_list (header_list);
3759 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3760 g_object_unref (account);
3764 if (num_of_unc_msgs == 0 || continue_download) {
3765 modest_platform_information_banner (
3766 NULL, NULL, _CS("mcen_ib_getting_items"));
3767 modest_header_view_copy_selection (
3768 MODEST_HEADER_VIEW (focused_widget));
3772 g_object_unref (header_list);
3774 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3775 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3778 /* Show information banner if there was a copy to clipboard */
3780 modest_platform_information_banner (
3781 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3785 modest_ui_actions_on_undo (GtkAction *action,
3786 ModestWindow *window)
3788 ModestEmailClipboard *clipboard = NULL;
3790 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3791 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3792 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3793 /* Clear clipboard source */
3794 clipboard = modest_runtime_get_email_clipboard ();
3795 modest_email_clipboard_clear (clipboard);
3798 g_return_if_reached ();
3803 modest_ui_actions_on_redo (GtkAction *action,
3804 ModestWindow *window)
3806 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3807 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3810 g_return_if_reached ();
3816 destroy_information_note (ModestMailOperation *mail_op,
3819 /* destroy information note */
3820 gtk_widget_destroy (GTK_WIDGET(user_data));
3824 destroy_folder_information_note (ModestMailOperation *mail_op,
3825 TnyFolder *new_folder,
3828 /* destroy information note */
3829 gtk_widget_destroy (GTK_WIDGET(user_data));
3834 paste_as_attachment_free (gpointer data)
3836 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3838 gtk_widget_destroy (helper->banner);
3839 g_object_unref (helper->banner);
3844 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3849 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3850 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3855 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3860 modest_ui_actions_on_paste (GtkAction *action,
3861 ModestWindow *window)
3863 GtkWidget *focused_widget = NULL;
3864 GtkWidget *inf_note = NULL;
3865 ModestMailOperation *mail_op = NULL;
3867 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3868 if (GTK_IS_EDITABLE (focused_widget)) {
3869 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3870 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3871 ModestEmailClipboard *e_clipboard = NULL;
3872 e_clipboard = modest_runtime_get_email_clipboard ();
3873 if (modest_email_clipboard_cleared (e_clipboard)) {
3874 GtkTextBuffer *buffer;
3875 GtkClipboard *clipboard;
3877 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3878 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3879 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3880 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3881 ModestMailOperation *mail_op;
3882 TnyFolder *src_folder;
3885 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3886 helper->window = MODEST_MSG_EDIT_WINDOW (window);
3887 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3888 _CS("ckct_nw_pasting"));
3889 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
3890 mail_op = modest_mail_operation_new (G_OBJECT (window));
3891 if (helper->banner != NULL) {
3892 g_object_ref (G_OBJECT (helper->banner));
3893 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
3894 gtk_widget_show (GTK_WIDGET (helper->banner));
3898 modest_mail_operation_get_msgs_full (mail_op,
3900 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
3902 paste_as_attachment_free);
3905 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3906 ModestEmailClipboard *clipboard = NULL;
3907 TnyFolder *src_folder = NULL;
3908 TnyFolderStore *folder_store = NULL;
3909 TnyList *data = NULL;
3910 gboolean delete = FALSE;
3912 /* Check clipboard source */
3913 clipboard = modest_runtime_get_email_clipboard ();
3914 if (modest_email_clipboard_cleared (clipboard))
3917 /* Get elements to paste */
3918 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
3920 /* Create a new mail operation */
3921 mail_op = modest_mail_operation_new (G_OBJECT(window));
3923 /* Get destination folder */
3924 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
3926 /* transfer messages */
3930 /* Ask for user confirmation */
3932 modest_ui_actions_msgs_move_to_confirmation (window,
3933 TNY_FOLDER (folder_store),
3937 if (response == GTK_RESPONSE_OK) {
3938 /* Launch notification */
3939 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3940 _CS("ckct_nw_pasting"));
3941 if (inf_note != NULL) {
3942 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3943 gtk_widget_show (GTK_WIDGET(inf_note));
3946 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3947 modest_mail_operation_xfer_msgs (mail_op,
3949 TNY_FOLDER (folder_store),
3951 destroy_information_note,
3954 g_object_unref (mail_op);
3957 } else if (src_folder != NULL) {
3958 /* Launch notification */
3959 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3960 _CS("ckct_nw_pasting"));
3961 if (inf_note != NULL) {
3962 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3963 gtk_widget_show (GTK_WIDGET(inf_note));
3966 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3967 modest_mail_operation_xfer_folder (mail_op,
3971 destroy_folder_information_note,
3977 g_object_unref (data);
3978 if (src_folder != NULL)
3979 g_object_unref (src_folder);
3980 if (folder_store != NULL)
3981 g_object_unref (folder_store);
3987 modest_ui_actions_on_select_all (GtkAction *action,
3988 ModestWindow *window)
3990 GtkWidget *focused_widget;
3992 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3993 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3994 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3995 } else if (GTK_IS_LABEL (focused_widget)) {
3996 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3997 } else if (GTK_IS_EDITABLE (focused_widget)) {
3998 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3999 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4000 GtkTextBuffer *buffer;
4001 GtkTextIter start, end;
4003 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4004 gtk_text_buffer_get_start_iter (buffer, &start);
4005 gtk_text_buffer_get_end_iter (buffer, &end);
4006 gtk_text_buffer_select_range (buffer, &start, &end);
4007 } else if (GTK_IS_HTML (focused_widget)) {
4008 gtk_html_select_all (GTK_HTML (focused_widget));
4009 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4010 GtkWidget *header_view = focused_widget;
4011 GtkTreeSelection *selection = NULL;
4013 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4014 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4015 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4018 /* Disable window dimming management */
4019 modest_window_disable_dimming (MODEST_WINDOW(window));
4021 /* Select all messages */
4022 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4023 gtk_tree_selection_select_all (selection);
4025 /* Set focuse on header view */
4026 gtk_widget_grab_focus (header_view);
4029 /* Enable window dimming management */
4030 modest_window_enable_dimming (MODEST_WINDOW(window));
4031 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4037 modest_ui_actions_on_mark_as_read (GtkAction *action,
4038 ModestWindow *window)
4040 g_return_if_fail (MODEST_IS_WINDOW(window));
4042 /* Mark each header as read */
4043 do_headers_action (window, headers_action_mark_as_read, NULL);
4047 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4048 ModestWindow *window)
4050 g_return_if_fail (MODEST_IS_WINDOW(window));
4052 /* Mark each header as read */
4053 do_headers_action (window, headers_action_mark_as_unread, NULL);
4057 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4058 GtkRadioAction *selected,
4059 ModestWindow *window)
4063 value = gtk_radio_action_get_current_value (selected);
4064 if (MODEST_IS_WINDOW (window)) {
4065 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4070 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4071 GtkRadioAction *selected,
4072 ModestWindow *window)
4074 TnyHeaderFlags flags;
4075 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4077 flags = gtk_radio_action_get_current_value (selected);
4078 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4082 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4083 GtkRadioAction *selected,
4084 ModestWindow *window)
4088 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4090 file_format = gtk_radio_action_get_current_value (selected);
4091 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4096 modest_ui_actions_on_zoom_plus (GtkAction *action,
4097 ModestWindow *window)
4099 g_return_if_fail (MODEST_IS_WINDOW (window));
4101 modest_window_zoom_plus (MODEST_WINDOW (window));
4105 modest_ui_actions_on_zoom_minus (GtkAction *action,
4106 ModestWindow *window)
4108 g_return_if_fail (MODEST_IS_WINDOW (window));
4110 modest_window_zoom_minus (MODEST_WINDOW (window));
4114 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4115 ModestWindow *window)
4117 ModestWindowMgr *mgr;
4118 gboolean fullscreen, active;
4119 g_return_if_fail (MODEST_IS_WINDOW (window));
4121 mgr = modest_runtime_get_window_mgr ();
4123 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4124 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4126 if (active != fullscreen) {
4127 modest_window_mgr_set_fullscreen_mode (mgr, active);
4128 gtk_window_present (GTK_WINDOW (window));
4133 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4134 ModestWindow *window)
4136 ModestWindowMgr *mgr;
4137 gboolean fullscreen;
4139 g_return_if_fail (MODEST_IS_WINDOW (window));
4141 mgr = modest_runtime_get_window_mgr ();
4142 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4143 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4145 gtk_window_present (GTK_WINDOW (window));
4149 * Used by modest_ui_actions_on_details to call do_headers_action
4152 headers_action_show_details (TnyHeader *header,
4153 ModestWindow *window,
4160 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
4163 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4164 gtk_widget_show_all (dialog);
4165 gtk_dialog_run (GTK_DIALOG (dialog));
4167 gtk_widget_destroy (dialog);
4171 * Show the folder details in a ModestDetailsDialog widget
4174 show_folder_details (TnyFolder *folder,
4180 dialog = modest_details_dialog_new_with_folder (window, folder);
4183 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4184 gtk_widget_show_all (dialog);
4185 gtk_dialog_run (GTK_DIALOG (dialog));
4187 gtk_widget_destroy (dialog);
4191 * Show the header details in a ModestDetailsDialog widget
4194 modest_ui_actions_on_details (GtkAction *action,
4197 TnyList * headers_list;
4201 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4204 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4207 g_object_unref (msg);
4209 headers_list = get_selected_headers (win);
4213 iter = tny_list_create_iterator (headers_list);
4215 header = TNY_HEADER (tny_iterator_get_current (iter));
4217 headers_action_show_details (header, win, NULL);
4218 g_object_unref (header);
4221 g_object_unref (iter);
4222 g_object_unref (headers_list);
4224 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4225 GtkWidget *folder_view, *header_view;
4227 /* Check which widget has the focus */
4228 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4229 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4230 if (gtk_widget_is_focus (folder_view)) {
4231 TnyFolderStore *folder_store
4232 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4233 if (!folder_store) {
4234 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4237 /* Show only when it's a folder */
4238 /* This function should not be called for account items,
4239 * because we dim the menu item for them. */
4240 if (TNY_IS_FOLDER (folder_store)) {
4241 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
4244 g_object_unref (folder_store);
4247 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4248 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4249 /* Show details of each header */
4250 do_headers_action (win, headers_action_show_details, header_view);
4256 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4257 ModestMsgEditWindow *window)
4259 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4261 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4265 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4266 ModestMsgEditWindow *window)
4268 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4270 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4274 modest_ui_actions_toggle_folders_view (GtkAction *action,
4275 ModestMainWindow *main_window)
4277 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4279 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4280 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4282 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4286 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4287 ModestWindow *window)
4289 gboolean active, fullscreen = FALSE;
4290 ModestWindowMgr *mgr;
4292 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4294 /* Check if we want to toggle the toolbar vuew in fullscreen
4296 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4297 "ViewShowToolbarFullScreen")) {
4301 /* Toggle toolbar */
4302 mgr = modest_runtime_get_window_mgr ();
4303 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4307 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4308 ModestMsgEditWindow *window)
4310 modest_msg_edit_window_select_font (window);
4315 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4316 const gchar *display_name,
4319 /* don't update the display name if it was already set;
4320 * updating the display name apparently is expensive */
4321 const gchar* old_name = gtk_window_get_title (window);
4323 if (display_name == NULL)
4326 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4327 return; /* don't do anything */
4329 /* This is usually used to change the title of the main window, which
4330 * is the one that holds the folder view. Note that this change can
4331 * happen even when the widget doesn't have the focus. */
4332 gtk_window_set_title (window, display_name);
4337 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4339 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4340 modest_msg_edit_window_select_contacts (window);
4344 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4346 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4347 modest_msg_edit_window_check_names (window, FALSE);
4351 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
4353 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
4354 GTK_WIDGET (user_data));
4358 * This function is used to track changes in the selection of the
4359 * folder view that is inside the "move to" dialog to enable/disable
4360 * the OK button because we do not want the user to select a disallowed
4361 * destination for a folder.
4362 * The user also not desired to be able to use NEW button on items where
4363 * folder creation is not possibel.
4366 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4367 TnyFolderStore *folder_store,
4371 GtkWidget *dialog = NULL;
4372 GtkWidget *ok_button = NULL, *new_button = NULL;
4373 GList *children = NULL;
4374 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4375 gboolean moving_folder = FALSE;
4376 gboolean is_local_account = TRUE;
4377 GtkWidget *folder_view = NULL;
4378 ModestTnyFolderRules rules;
4380 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
4385 /* Get the OK button */
4386 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
4390 children = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
4391 ok_button = GTK_WIDGET (children->next->next->data);
4392 new_button = GTK_WIDGET (children->next->data);
4393 g_list_free (children);
4395 /* check if folder_store is an remote account */
4396 if (TNY_IS_ACCOUNT (folder_store)) {
4397 TnyAccount *local_account = NULL;
4398 TnyAccount *mmc_account = NULL;
4399 ModestTnyAccountStore *account_store = NULL;
4401 account_store = modest_runtime_get_account_store ();
4402 local_account = modest_tny_account_store_get_local_folders_account (account_store);
4403 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
4405 if ((gpointer) local_account != (gpointer) folder_store &&
4406 (gpointer) mmc_account != (gpointer) folder_store) {
4407 const char *proto_name = tny_account_get_proto (TNY_ACCOUNT (folder_store));
4408 ModestTransportStoreProtocol proto = MODEST_PROTOCOL_STORE_MAILDIR;
4409 if (proto_name != NULL) {
4410 proto = modest_protocol_info_get_transport_store_protocol (proto_name);
4412 is_local_account = FALSE;
4413 /* New button should be dimmed on remote
4415 new_sensitive = (proto != MODEST_PROTOCOL_STORE_POP);
4417 g_object_unref (local_account);
4418 g_object_unref (mmc_account);
4421 /* Check the target folder rules */
4422 if (TNY_IS_FOLDER (folder_store)) {
4423 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
4424 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
4425 ok_sensitive = FALSE;
4426 new_sensitive = FALSE;
4431 /* Check if we're moving a folder */
4432 if (MODEST_IS_MAIN_WINDOW (user_data)) {
4433 /* Get the widgets */
4434 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
4435 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4436 if (gtk_widget_is_focus (folder_view))
4437 moving_folder = TRUE;
4440 if (moving_folder) {
4441 TnyFolderStore *moved_folder = NULL, *parent = NULL;
4443 /* Get the folder to move */
4444 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4446 /* Check that we're not moving to the same folder */
4447 if (TNY_IS_FOLDER (moved_folder)) {
4448 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
4449 if (parent == folder_store)
4450 ok_sensitive = FALSE;
4451 g_object_unref (parent);
4454 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
4455 /* Do not allow to move to an account unless it's the
4456 local folders account */
4457 if (!is_local_account)
4458 ok_sensitive = FALSE;
4461 if (ok_sensitive && (moved_folder == folder_store)) {
4462 /* Do not allow to move to itself */
4463 ok_sensitive = FALSE;
4465 g_object_unref (moved_folder);
4467 TnyFolder *src_folder = NULL;
4469 /* Moving a message */
4470 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
4472 TnyHeader *header = NULL;
4473 header = modest_msg_view_window_get_header
4474 (MODEST_MSG_VIEW_WINDOW (user_data));
4475 if (!TNY_IS_HEADER(header))
4476 g_warning ("%s: could not get source header", __FUNCTION__);
4478 src_folder = tny_header_get_folder (header);
4481 g_object_unref (header);
4484 TNY_FOLDER (modest_folder_view_get_selected
4485 (MODEST_FOLDER_VIEW (folder_view)));
4488 if (TNY_IS_FOLDER(src_folder)) {
4489 /* Do not allow to move the msg to the same folder */
4490 /* Do not allow to move the msg to an account */
4491 if ((gpointer) src_folder == (gpointer) folder_store ||
4492 TNY_IS_ACCOUNT (folder_store))
4493 ok_sensitive = FALSE;
4494 g_object_unref (src_folder);
4496 g_warning ("%s: could not get source folder", __FUNCTION__);
4500 /* Set sensitivity of the OK button */
4501 gtk_widget_set_sensitive (ok_button, ok_sensitive);
4502 /* Set sensitivity of the NEW button */
4503 gtk_widget_set_sensitive (new_button, new_sensitive);
4507 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
4510 get_folder_view_from_move_to_dialog (GtkWidget *move_to_dialog)
4512 return GTK_WIDGET(g_object_get_data (G_OBJECT(move_to_dialog),
4513 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4517 create_move_to_dialog (GtkWindow *win,
4518 GtkWidget *folder_view,
4519 GtkWidget **tree_view)
4521 GtkWidget *dialog, *scroll;
4522 GtkWidget *new_button;
4524 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
4526 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
4529 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
4530 /* We do this manually so GTK+ does not associate a response ID for
4532 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
4533 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
4534 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
4536 /* Create scrolled window */
4537 scroll = gtk_scrolled_window_new (NULL, NULL);
4538 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
4539 GTK_POLICY_AUTOMATIC,
4540 GTK_POLICY_AUTOMATIC);
4542 /* Create folder view */
4543 *tree_view = modest_platform_create_folder_view (NULL);
4545 /* Track changes in the selection to
4546 * disable the OK button whenever "Move to" is not possible
4547 * disbale NEW button whenever New is not possible */
4548 g_signal_connect (*tree_view,
4549 "folder_selection_changed",
4550 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
4553 /* Listen to clicks on New button */
4554 g_signal_connect (G_OBJECT (new_button),
4556 G_CALLBACK(create_move_to_dialog_on_new_folder),
4559 /* It could happen that we're trying to move a message from a
4560 window (msg window for example) after the main window was
4561 closed, so we can not just get the model of the folder
4563 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4564 const gchar *visible_id = NULL;
4566 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4567 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4568 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4569 MODEST_FOLDER_VIEW(*tree_view));
4572 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4574 /* Show the same account than the one that is shown in the main window */
4575 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
4578 const gchar *active_account_name = NULL;
4579 ModestAccountMgr *mgr = NULL;
4580 ModestAccountSettings *settings = NULL;
4581 ModestServerAccountSettings *store_settings = NULL;
4583 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4584 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4585 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
4586 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
4588 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4589 mgr = modest_runtime_get_account_mgr ();
4590 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4593 const gchar *store_account_name;
4594 store_settings = modest_account_settings_get_store_settings (settings);
4595 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4597 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
4598 store_account_name);
4599 g_object_unref (store_settings);
4600 g_object_unref (settings);
4604 /* we keep a pointer to the embedded folder view, so we can retrieve it with
4605 * get_folder_view_from_move_to_dialog
4606 * (see above) later (needed for focus handling)
4608 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, *tree_view);
4611 /* Hide special folders */
4612 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
4614 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
4616 /* Add scroll to dialog */
4617 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
4618 scroll, TRUE, TRUE, 0);
4620 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4621 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
4629 * Shows a confirmation dialog to the user when we're moving messages
4630 * from a remote server to the local storage. Returns the dialog
4631 * response. If it's other kind of movement then it always returns
4634 * This one is used by the next functions:
4635 * modest_ui_actions_on_paste - commented out
4636 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4639 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4640 TnyFolder *dest_folder,
4644 gint response = GTK_RESPONSE_OK;
4645 TnyAccount *account = NULL;
4646 TnyFolder *src_folder = NULL;
4647 TnyIterator *iter = NULL;
4648 TnyHeader *header = NULL;
4650 /* return with OK if the destination is a remote folder */
4651 if (modest_tny_folder_is_remote_folder (dest_folder))
4652 return GTK_RESPONSE_OK;
4654 /* Get source folder */
4655 iter = tny_list_create_iterator (headers);
4656 header = TNY_HEADER (tny_iterator_get_current (iter));
4658 src_folder = tny_header_get_folder (header);
4659 g_object_unref (header);
4661 g_object_unref (iter);
4663 /* if no src_folder, message may be an attahcment */
4664 if (src_folder == NULL)
4665 return GTK_RESPONSE_CANCEL;
4667 /* If the source is a local or MMC folder */
4668 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4669 g_object_unref (src_folder);
4670 return GTK_RESPONSE_OK;
4673 /* Get the account */
4674 account = tny_folder_get_account (src_folder);
4676 /* now if offline we ask the user */
4677 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4678 response = GTK_RESPONSE_OK;
4680 response = GTK_RESPONSE_CANCEL;
4683 g_object_unref (src_folder);
4684 g_object_unref (account);
4690 move_to_cb (ModestMailOperation *mail_op,
4693 MoveToHelper *helper = (MoveToHelper *) user_data;
4695 /* Note that the operation could have failed, in that case do
4697 if (modest_mail_operation_get_status (mail_op) ==
4698 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
4700 GObject *object = modest_mail_operation_get_source (mail_op);
4701 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4702 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4704 if (!modest_msg_view_window_select_next_message (self) &&
4705 !modest_msg_view_window_select_previous_message (self)) {
4706 /* No more messages to view, so close this window */
4707 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4709 } else if (MODEST_IS_MAIN_WINDOW (object) && helper->reference != NULL) {
4710 GtkWidget *header_view;
4712 GtkTreeSelection *sel;
4714 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4715 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4716 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
4717 path = gtk_tree_row_reference_get_path (helper->reference);
4718 /* We need to unselect the previous one
4719 because we could be copying instead of
4721 gtk_tree_selection_unselect_all (sel);
4722 gtk_tree_selection_select_path (sel, path);
4723 gtk_tree_path_free (path);
4725 g_object_unref (object);
4728 /* Close the "Pasting" information banner */
4729 gtk_widget_destroy (GTK_WIDGET(helper->banner));
4730 g_object_unref (helper->banner);
4731 if (helper->reference != NULL)
4732 gtk_tree_row_reference_free (helper->reference);
4737 folder_move_to_cb (ModestMailOperation *mail_op,
4738 TnyFolder *new_folder,
4741 GtkWidget *folder_view;
4744 object = modest_mail_operation_get_source (mail_op);
4745 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4746 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4747 g_object_ref (folder_view);
4748 g_object_unref (object);
4749 move_to_cb (mail_op, user_data);
4750 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
4751 g_object_unref (folder_view);
4755 msgs_move_to_cb (ModestMailOperation *mail_op,
4758 move_to_cb (mail_op, user_data);
4762 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
4765 ModestWindow *main_window = NULL;
4767 /* Disable next automatic folder selection */
4768 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
4769 FALSE); /* don't create */
4771 GObject *win = NULL;
4772 GtkWidget *folder_view = NULL;
4774 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
4775 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4776 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
4778 if (user_data && TNY_IS_FOLDER (user_data)) {
4779 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
4780 TNY_FOLDER (user_data), FALSE);
4783 /* Show notification dialog only if the main window exists */
4784 win = modest_mail_operation_get_source (mail_op);
4785 modest_platform_run_information_dialog ((GtkWindow *) win,
4786 _("mail_in_ui_folder_move_target_error"),
4789 g_object_unref (win);
4794 open_msg_for_purge_cb (ModestMailOperation *mail_op,
4803 gint pending_purges = 0;
4804 gboolean some_purged = FALSE;
4805 ModestWindow *win = MODEST_WINDOW (user_data);
4806 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
4808 /* If there was any error */
4809 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
4810 modest_window_mgr_unregister_header (mgr, header);
4814 /* Once the message has been retrieved for purging, we check if
4815 * it's all ok for purging */
4817 parts = tny_simple_list_new ();
4818 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
4819 iter = tny_list_create_iterator (parts);
4821 while (!tny_iterator_is_done (iter)) {
4823 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4824 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
4825 if (tny_mime_part_is_purged (part))
4832 g_object_unref (part);
4834 tny_iterator_next (iter);
4836 g_object_unref (iter);
4839 if (pending_purges>0) {
4841 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
4843 if (response == GTK_RESPONSE_OK) {
4844 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
4845 iter = tny_list_create_iterator (parts);
4846 while (!tny_iterator_is_done (iter)) {
4849 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4850 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
4851 tny_mime_part_set_purged (part);
4854 g_object_unref (part);
4856 tny_iterator_next (iter);
4858 g_object_unref (iter);
4860 tny_msg_rewrite_cache (msg);
4863 /* This string no longer exists, refer to NB#75415 for more info */
4864 /* modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged")); */
4867 modest_window_mgr_unregister_header (mgr, header);
4869 g_object_unref (parts);
4873 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
4874 ModestMainWindow *win)
4876 GtkWidget *header_view;
4877 TnyList *header_list;
4879 TnyHeaderFlags flags;
4880 ModestWindow *msg_view_window = NULL;
4883 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4885 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4886 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4888 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
4890 g_warning ("%s: no header selected", __FUNCTION__);
4894 if (tny_list_get_length (header_list) == 1) {
4895 TnyIterator *iter = tny_list_create_iterator (header_list);
4896 header = TNY_HEADER (tny_iterator_get_current (iter));
4897 g_object_unref (iter);
4901 if (!header || !TNY_IS_HEADER(header)) {
4902 g_warning ("%s: header is not valid", __FUNCTION__);
4906 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
4907 header, &msg_view_window);
4908 flags = tny_header_get_flags (header);
4909 if (!(flags & TNY_HEADER_FLAG_CACHED))
4912 if (msg_view_window != NULL)
4913 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
4915 /* do nothing; uid was registered before, so window is probably on it's way */
4916 g_warning ("debug: header %p has already been registered", header);
4919 ModestMailOperation *mail_op = NULL;
4920 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
4921 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
4922 modest_ui_actions_disk_operations_error_handler,
4924 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4925 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
4927 g_object_unref (mail_op);
4930 g_object_unref (header);
4932 g_object_unref (header_list);
4936 * Checks if we need a connection to do the transfer and if the user
4937 * wants to connect to complete it
4940 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
4941 TnyFolderStore *src_folder,
4943 TnyFolder *dst_folder,
4944 gboolean delete_originals,
4945 gboolean *need_connection,
4948 TnyAccount *src_account;
4949 gint uncached_msgs = 0;
4951 uncached_msgs = header_list_count_uncached_msgs (headers);
4953 /* We don't need any further check if
4955 * 1- the source folder is local OR
4956 * 2- the device is already online
4958 if (!modest_tny_folder_store_is_remote (src_folder) ||
4959 tny_device_is_online (modest_runtime_get_device())) {
4960 *need_connection = FALSE;
4965 /* We must ask for a connection when
4967 * - the message(s) is not already cached OR
4968 * - the message(s) is cached but the leave_on_server setting
4969 * is FALSE (because we need to sync the source folder to
4970 * delete the message from the server (for IMAP we could do it
4971 * offline, it'll take place the next time we get a
4974 src_account = get_account_from_folder_store (src_folder);
4975 if (uncached_msgs > 0) {
4979 *need_connection = TRUE;
4980 num_headers = tny_list_get_length (headers);
4981 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
4983 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
4984 GTK_RESPONSE_CANCEL) {
4990 /* The transfer is possible and the user wants to */
4993 if (remote_folder_is_pop (src_folder) && delete_originals) {
4994 const gchar *account_name;
4995 gboolean leave_on_server;
4997 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
4998 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5001 if (leave_on_server == TRUE) {
5002 *need_connection = FALSE;
5004 *need_connection = TRUE;
5007 *need_connection = FALSE;
5012 g_object_unref (src_account);
5016 xfer_messages_error_handler (ModestMailOperation *mail_op,
5019 ModestWindow *main_window = NULL;
5021 /* Disable next automatic folder selection */
5022 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5023 FALSE); /* don't create */
5025 GObject *win = modest_mail_operation_get_source (mail_op);
5026 modest_platform_run_information_dialog ((GtkWindow *) win,
5027 _("mail_in_ui_folder_move_target_error"),
5030 g_object_unref (win);
5035 TnyFolderStore *dst_folder;
5040 * Utility function that transfer messages from both the main window
5041 * and the msg view window when using the "Move to" dialog
5044 xfer_messages_performer (gboolean canceled,
5046 GtkWindow *parent_window,
5047 TnyAccount *account,
5050 ModestWindow *win = MODEST_WINDOW (parent_window);
5051 TnyAccount *dst_account = NULL;
5052 const gchar *proto_str = NULL;
5053 gboolean dst_is_pop = FALSE;
5054 XferMsgsHelper *helper;
5055 MoveToHelper *movehelper;
5056 ModestMailOperation *mail_op;
5058 helper = (XferMsgsHelper *) user_data;
5064 if (is_memory_full_error (err)) {
5065 modest_platform_information_banner ((GtkWidget *) parent_window,
5066 NULL, dgettext("ke-recv",
5067 "cerm_device_memory_full"));
5069 /* Show the proper error message */
5070 modest_ui_actions_on_account_connection_error (parent_window, account);
5075 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5076 proto_str = tny_account_get_proto (dst_account);
5078 /* tinymail will return NULL for local folders it seems */
5079 dst_is_pop = proto_str &&
5080 (modest_protocol_info_get_transport_store_protocol (proto_str) ==
5081 MODEST_PROTOCOL_STORE_POP);
5083 g_object_unref (dst_account);
5086 modest_platform_information_banner (GTK_WIDGET (win),
5088 ngettext("mail_in_ui_folder_move_target_error",
5089 "mail_in_ui_folder_move_targets_error",
5090 tny_list_get_length (helper->headers)));
5094 movehelper = g_new0 (MoveToHelper, 1);
5095 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5096 _CS("ckct_nw_pasting"));
5097 if (movehelper->banner != NULL) {
5098 g_object_ref (movehelper->banner);
5099 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5102 if (MODEST_IS_MAIN_WINDOW (win)) {
5103 GtkWidget *header_view =
5104 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5105 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5106 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5109 /* Perform the mail operation */
5110 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5111 xfer_messages_error_handler,
5113 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5116 modest_mail_operation_xfer_msgs (mail_op,
5118 TNY_FOLDER (helper->dst_folder),
5123 g_object_unref (G_OBJECT (mail_op));
5125 g_object_unref (helper->dst_folder);
5126 g_object_unref (helper->headers);
5127 g_slice_free (XferMsgsHelper, helper);
5131 TnyFolder *src_folder;
5132 TnyFolderStore *dst_folder;
5133 gboolean delete_original;
5134 GtkWidget *folder_view;
5138 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
5139 TnyAccount *account, gpointer user_data)
5141 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5142 GtkTreeSelection *sel;
5143 ModestMailOperation *mail_op = NULL;
5145 if (canceled || err || !MODEST_IS_MAIN_WINDOW (parent_window)) {
5146 g_object_unref (G_OBJECT (info->src_folder));
5147 g_object_unref (G_OBJECT (info->dst_folder));
5152 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5153 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5154 _CS("ckct_nw_pasting"));
5155 if (helper->banner != NULL) {
5156 g_object_ref (helper->banner);
5157 gtk_window_set_modal (GTK_WINDOW(helper->banner), FALSE);
5158 gtk_widget_show (GTK_WIDGET(helper->banner));
5160 /* Clean folder on header view before moving it */
5161 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5162 gtk_tree_selection_unselect_all (sel);
5164 /* Let gtk events run. We need that the folder
5165 view frees its reference to the source
5166 folder *before* issuing the mail operation
5167 so we need the signal handler of selection
5168 changed to happen before the mail
5170 while (gtk_events_pending ())
5171 gtk_main_iteration (); */
5174 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5175 modest_ui_actions_move_folder_error_handler,
5176 info->src_folder, NULL);
5177 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5180 /* Select *after* the changes */
5181 /* TODO: this function hangs UI after transfer */
5182 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
5183 /* TNY_FOLDER (src_folder), TRUE); */
5185 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5186 TNY_FOLDER (info->dst_folder), TRUE);
5187 modest_mail_operation_xfer_folder (mail_op,
5188 TNY_FOLDER (info->src_folder),
5190 info->delete_original,
5193 g_object_unref (G_OBJECT (info->src_folder));
5195 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5198 /* Unref mail operation */
5199 g_object_unref (G_OBJECT (mail_op));
5200 g_object_unref (G_OBJECT (info->dst_folder));
5205 get_account_from_folder_store (TnyFolderStore *folder_store)
5207 if (TNY_IS_ACCOUNT (folder_store))
5208 return g_object_ref (folder_store);
5210 return tny_folder_get_account (TNY_FOLDER (folder_store));
5214 * UI handler for the "Move to" action when invoked from the
5218 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5219 GtkWidget *folder_view,
5220 TnyFolderStore *dst_folder,
5221 ModestMainWindow *win)
5223 ModestHeaderView *header_view = NULL;
5224 TnyFolderStore *src_folder = NULL;
5226 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5228 /* Get the source folder */
5229 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5231 /* Get header view */
5232 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
5234 /* Get folder or messages to transfer */
5235 if (gtk_widget_is_focus (folder_view)) {
5236 gboolean do_xfer = TRUE;
5238 /* Allow only to transfer folders to the local root folder */
5239 if (TNY_IS_ACCOUNT (dst_folder) &&
5240 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5241 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5243 } else if (!TNY_IS_FOLDER (src_folder)) {
5244 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5249 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5250 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5252 info->src_folder = g_object_ref (src_folder);
5253 info->dst_folder = g_object_ref (dst_folder);
5254 info->delete_original = TRUE;
5255 info->folder_view = folder_view;
5257 connect_info->callback = on_move_folder_cb;
5258 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5259 connect_info->data = info;
5261 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5262 TNY_FOLDER_STORE (src_folder),
5265 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5268 headers = modest_header_view_get_selected_headers(header_view);
5270 /* Transfer the messages */
5271 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
5272 headers, TNY_FOLDER (dst_folder));
5274 g_object_unref (headers);
5278 g_object_unref (src_folder);
5283 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
5284 TnyFolder *src_folder,
5286 TnyFolder *dst_folder)
5288 gboolean need_connection = TRUE;
5289 gboolean do_xfer = TRUE;
5290 XferMsgsHelper *helper;
5292 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5293 headers, TNY_FOLDER (dst_folder),
5294 TRUE, &need_connection,
5297 /* If we don't want to transfer just return */
5301 /* Create the helper */
5302 helper = g_slice_new (XferMsgsHelper);
5303 helper->dst_folder = g_object_ref (dst_folder);
5304 helper->headers = g_object_ref (headers);
5306 if (need_connection) {
5307 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5308 connect_info->callback = xfer_messages_performer;
5309 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5310 connect_info->data = helper;
5312 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5313 TNY_FOLDER_STORE (src_folder),
5316 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5317 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
5318 src_account, helper);
5319 g_object_unref (src_account);
5324 * UI handler for the "Move to" action when invoked from the
5325 * ModestMsgViewWindow
5328 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
5329 TnyFolderStore *dst_folder,
5330 ModestMsgViewWindow *win)
5332 TnyList *headers = NULL;
5333 TnyHeader *header = NULL;
5334 TnyFolder *src_folder = NULL;
5336 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5338 /* Create header list */
5339 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
5340 src_folder = TNY_FOLDER (tny_header_get_folder(header));
5341 headers = tny_simple_list_new ();
5342 tny_list_append (headers, G_OBJECT (header));
5344 /* Transfer the messages */
5345 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder, headers,
5346 TNY_FOLDER (dst_folder));
5349 g_object_unref (header);
5350 g_object_unref (headers);
5354 modest_ui_actions_on_move_to (GtkAction *action,
5357 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
5359 TnyFolderStore *dst_folder = NULL;
5360 ModestMainWindow *main_window;
5362 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
5363 MODEST_IS_MSG_VIEW_WINDOW (win));
5365 /* Get the main window if exists */
5366 if (MODEST_IS_MAIN_WINDOW (win))
5367 main_window = MODEST_MAIN_WINDOW (win);
5370 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5371 FALSE)); /* don't create */
5373 /* Get the folder view widget if exists */
5375 folder_view = modest_main_window_get_child_widget (main_window,
5376 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5380 /* Create and run the dialog */
5381 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
5382 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5383 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5384 result = gtk_dialog_run (GTK_DIALOG(dialog));
5385 g_object_ref (tree_view);
5386 gtk_widget_destroy (dialog);
5388 if (result != GTK_RESPONSE_ACCEPT)
5391 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
5392 /* Do window specific stuff */
5393 if (MODEST_IS_MAIN_WINDOW (win)) {
5394 modest_ui_actions_on_main_window_move_to (action,
5397 MODEST_MAIN_WINDOW (win));
5399 modest_ui_actions_on_msg_view_window_move_to (action,
5401 MODEST_MSG_VIEW_WINDOW (win));
5405 g_object_unref (dst_folder);
5409 * Calls #HeadersFunc for each header already selected in the main
5410 * window or the message currently being shown in the msg view window
5413 do_headers_action (ModestWindow *win,
5417 TnyList *headers_list = NULL;
5418 TnyIterator *iter = NULL;
5419 TnyHeader *header = NULL;
5420 TnyFolder *folder = NULL;
5423 headers_list = get_selected_headers (win);
5427 /* Get the folder */
5428 iter = tny_list_create_iterator (headers_list);
5429 header = TNY_HEADER (tny_iterator_get_current (iter));
5431 folder = tny_header_get_folder (header);
5432 g_object_unref (header);
5435 /* Call the function for each header */
5436 while (!tny_iterator_is_done (iter)) {
5437 header = TNY_HEADER (tny_iterator_get_current (iter));
5438 func (header, win, user_data);
5439 g_object_unref (header);
5440 tny_iterator_next (iter);
5443 /* Trick: do a poke status in order to speed up the signaling
5445 tny_folder_poke_status (folder);
5448 g_object_unref (folder);
5449 g_object_unref (iter);
5450 g_object_unref (headers_list);
5454 modest_ui_actions_view_attachment (GtkAction *action,
5455 ModestWindow *window)
5457 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5458 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5460 /* not supported window for this action */
5461 g_return_if_reached ();
5466 modest_ui_actions_save_attachments (GtkAction *action,
5467 ModestWindow *window)
5469 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5471 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5474 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5476 /* not supported window for this action */
5477 g_return_if_reached ();
5482 modest_ui_actions_remove_attachments (GtkAction *action,
5483 ModestWindow *window)
5485 if (MODEST_IS_MAIN_WINDOW (window)) {
5486 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
5487 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5488 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5490 /* not supported window for this action */
5491 g_return_if_reached ();
5496 modest_ui_actions_on_settings (GtkAction *action,
5501 dialog = modest_platform_get_global_settings_dialog ();
5502 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
5503 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5504 gtk_widget_show_all (dialog);
5506 gtk_dialog_run (GTK_DIALOG (dialog));
5508 gtk_widget_destroy (dialog);
5512 modest_ui_actions_on_help (GtkAction *action,
5515 const gchar *help_id;
5517 g_return_if_fail (win && GTK_IS_WINDOW(win));
5519 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5522 modest_platform_show_help (GTK_WINDOW (win), help_id);
5526 modest_ui_actions_on_csm_help (GtkAction *action,
5529 const gchar* help_id = NULL;
5530 GtkWidget *folder_view;
5531 TnyFolderStore *folder_store;
5533 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
5535 /* Get selected folder */
5536 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5537 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5538 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5540 /* Switch help_id */
5541 if (folder_store && TNY_IS_FOLDER (folder_store))
5542 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
5545 g_object_unref (folder_store);
5548 modest_platform_show_help (GTK_WINDOW (win), help_id);
5550 modest_ui_actions_on_help (action, win);
5554 retrieve_contents_cb (ModestMailOperation *mail_op,
5561 /* We only need this callback to show an error in case of
5562 memory low condition */
5563 modest_ui_actions_msg_retrieval_check (mail_op, header, msg);
5567 retrieve_msg_contents_performer (gboolean canceled,
5569 GtkWindow *parent_window,
5570 TnyAccount *account,
5573 ModestMailOperation *mail_op;
5574 TnyList *headers = TNY_LIST (user_data);
5576 if (err || canceled) {
5577 if (err && is_memory_full_error (err)) {
5578 modest_platform_information_banner ((GtkWidget *) parent_window,
5579 NULL, dgettext("ke-recv",
5580 "cerm_device_memory_full"));
5585 /* Create mail operation */
5586 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5587 modest_ui_actions_disk_operations_error_handler,
5589 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5590 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
5593 g_object_unref (mail_op);
5595 g_object_unref (headers);
5596 g_object_unref (account);
5600 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5601 ModestWindow *window)
5603 TnyList *headers = NULL;
5604 TnyAccount *account = NULL;
5605 TnyIterator *iter = NULL;
5606 TnyHeader *header = NULL;
5607 TnyFolder *folder = NULL;
5610 headers = get_selected_headers (window);
5614 /* Pick the account */
5615 iter = tny_list_create_iterator (headers);
5616 header = TNY_HEADER (tny_iterator_get_current (iter));
5617 folder = tny_header_get_folder (header);
5618 account = tny_folder_get_account (folder);
5619 g_object_unref (folder);
5620 g_object_unref (header);
5621 g_object_unref (iter);
5623 /* Connect and perform the message retrieval */
5624 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
5625 g_object_ref (account),
5626 retrieve_msg_contents_performer,
5627 g_object_ref (headers));
5630 g_object_unref (account);
5631 g_object_unref (headers);
5635 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
5637 g_return_if_fail (MODEST_IS_WINDOW (window));
5640 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
5644 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
5646 g_return_if_fail (MODEST_IS_WINDOW (window));
5649 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
5653 modest_ui_actions_on_email_menu_activated (GtkAction *action,
5654 ModestWindow *window)
5656 g_return_if_fail (MODEST_IS_WINDOW (window));
5659 modest_ui_actions_check_menu_dimming_rules (window);
5663 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
5664 ModestWindow *window)
5666 g_return_if_fail (MODEST_IS_WINDOW (window));
5669 modest_ui_actions_check_menu_dimming_rules (window);
5673 modest_ui_actions_on_view_menu_activated (GtkAction *action,
5674 ModestWindow *window)
5676 g_return_if_fail (MODEST_IS_WINDOW (window));
5679 modest_ui_actions_check_menu_dimming_rules (window);
5683 modest_ui_actions_on_format_menu_activated (GtkAction *action,
5684 ModestWindow *window)
5686 g_return_if_fail (MODEST_IS_WINDOW (window));
5689 modest_ui_actions_check_menu_dimming_rules (window);
5693 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
5694 ModestWindow *window)
5696 g_return_if_fail (MODEST_IS_WINDOW (window));
5699 modest_ui_actions_check_menu_dimming_rules (window);
5703 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
5704 ModestWindow *window)
5706 g_return_if_fail (MODEST_IS_WINDOW (window));
5709 modest_ui_actions_check_menu_dimming_rules (window);
5713 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
5714 ModestWindow *window)
5716 g_return_if_fail (MODEST_IS_WINDOW (window));
5719 modest_ui_actions_check_menu_dimming_rules (window);
5723 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
5724 ModestWindow *window)
5726 g_return_if_fail (MODEST_IS_WINDOW (window));
5729 modest_ui_actions_check_menu_dimming_rules (window);
5733 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
5734 ModestWindow *window)
5736 g_return_if_fail (MODEST_IS_WINDOW (window));
5739 modest_ui_actions_check_menu_dimming_rules (window);
5743 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
5745 g_return_if_fail (MODEST_IS_WINDOW (window));
5747 /* we check for low-mem; in that case, show a warning, and don't allow
5750 if (modest_platform_check_memory_low (window, TRUE))
5753 modest_platform_show_search_messages (GTK_WINDOW (window));
5757 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
5759 g_return_if_fail (MODEST_IS_WINDOW (win));
5762 /* we check for low-mem; in that case, show a warning, and don't allow
5763 * for the addressbook
5765 if (modest_platform_check_memory_low (win, TRUE))
5769 modest_platform_show_addressbook (GTK_WINDOW (win));
5774 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
5775 ModestWindow *window)
5777 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5779 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
5783 on_send_receive_finished (ModestMailOperation *mail_op,
5786 GtkWidget *header_view, *folder_view;
5787 TnyFolderStore *folder_store;
5788 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
5790 /* Set send/receive operation finished */
5791 modest_main_window_notify_send_receive_completed (main_win);
5793 /* Don't refresh the current folder if there were any errors */
5794 if (modest_mail_operation_get_status (mail_op) !=
5795 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5798 /* Refresh the current folder if we're viewing a window. We do
5799 this because the user won't be able to see the new mails in
5800 the selected folder after a Send&Receive because it only
5801 performs a poke_status, i.e, only the number of read/unread
5802 messages is updated, but the new headers are not
5804 folder_view = modest_main_window_get_child_widget (main_win,
5805 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5809 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5811 /* Do not need to refresh INBOX again because the
5812 update_account does it always automatically */
5813 if (folder_store && TNY_IS_FOLDER (folder_store) &&
5814 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
5815 ModestMailOperation *refresh_op;
5817 header_view = modest_main_window_get_child_widget (main_win,
5818 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5820 /* We do not need to set the contents style
5821 because it hasn't changed. We also do not
5822 need to save the widget status. Just force
5824 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
5825 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
5826 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
5827 folder_refreshed_cb, main_win);
5828 g_object_unref (refresh_op);
5832 g_object_unref (folder_store);
5837 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
5843 const gchar* server_name = NULL;
5844 TnyTransportAccount *server_account;
5845 gchar *message = NULL;
5847 /* Don't show anything if the user cancelled something or the send receive request is not
5849 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
5850 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
5854 /* Get the server name: */
5856 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
5858 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
5860 g_return_if_reached ();
5862 /* Show the appropriate message text for the GError: */
5863 switch (err->code) {
5864 case TNY_SERVICE_ERROR_CONNECT:
5865 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
5867 case TNY_SERVICE_ERROR_AUTHENTICATE:
5868 message = g_strdup_printf (_("emev_ni_ui_smtp_authentication_fail_error"), server_name);
5870 case TNY_SERVICE_ERROR_SEND:
5871 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
5873 case TNY_SERVICE_ERROR_UNAVAILABLE:
5874 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
5877 g_warning ("%s: unexpected ERROR %d",
5878 __FUNCTION__, err->code);
5879 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
5883 /* TODO if the username or the password where not defined we
5884 should show the Accounts Settings dialog or the Connection
5885 specific SMTP server window */
5887 modest_platform_run_information_dialog (NULL, message, FALSE);
5889 g_object_unref (server_account);
5893 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
5898 ModestMainWindow *main_window = NULL;
5899 ModestWindowMgr *mgr = NULL;
5900 GtkWidget *folder_view = NULL, *header_view = NULL;
5901 TnyFolderStore *selected_folder = NULL;
5902 TnyFolderType folder_type;
5904 mgr = modest_runtime_get_window_mgr ();
5905 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr,
5906 FALSE));/* don't create */
5910 /* Check if selected folder is OUTBOX */
5911 folder_view = modest_main_window_get_child_widget (main_window,
5912 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5913 header_view = modest_main_window_get_child_widget (main_window,
5914 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5916 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5917 if (!TNY_IS_FOLDER (selected_folder))
5920 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
5921 #if GTK_CHECK_VERSION(2, 8, 0)
5922 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
5923 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
5924 GtkTreeViewColumn *tree_column;
5926 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
5927 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
5928 gtk_tree_view_column_queue_resize (tree_column);
5931 gtk_widget_queue_draw (header_view);
5934 /* Rerun dimming rules, because the message could become deletable for example */
5935 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
5936 MODEST_DIMMING_RULES_TOOLBAR);
5940 if (selected_folder != NULL)
5941 g_object_unref (selected_folder);
5945 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
5946 TnyAccount *account)
5948 ModestTransportStoreProtocol proto;
5949 const gchar *proto_name;
5950 gchar *error_note = NULL;
5952 proto_name = tny_account_get_proto (account);
5953 proto = modest_protocol_info_get_transport_store_protocol (proto_name);
5956 case MODEST_PROTOCOL_STORE_POP:
5957 error_note = g_strdup_printf (_("emev_ni_ui_pop3_msg_connect_error"),
5958 tny_account_get_hostname (account));
5960 case MODEST_PROTOCOL_STORE_IMAP:
5961 error_note = g_strdup_printf (_("emev_ni_ui_imap_connect_server_error"),
5962 tny_account_get_hostname (account));
5964 case MODEST_PROTOCOL_STORE_MAILDIR:
5965 case MODEST_PROTOCOL_STORE_MBOX:
5966 error_note = g_strdup (_("emev_nc_mailbox_notavailable"));
5969 g_warning ("%s: This should not be reached", __FUNCTION__);
5973 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
5974 g_free (error_note);
5979 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
5982 TnyFolderStore *folder = NULL;
5983 TnyAccount *account = NULL;
5984 ModestTransportStoreProtocol proto;
5985 TnyHeader *header = NULL;
5987 if (MODEST_IS_MAIN_WINDOW (win)) {
5988 GtkWidget *header_view;
5989 TnyList* headers = NULL;
5991 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5992 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5993 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5994 if (!headers || tny_list_get_length (headers) == 0) {
5996 g_object_unref (headers);
5999 iter = tny_list_create_iterator (headers);
6000 header = TNY_HEADER (tny_iterator_get_current (iter));
6001 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6002 g_object_unref (iter);
6003 g_object_unref (headers);
6004 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6005 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6006 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6009 /* Get the account type */
6010 account = tny_folder_get_account (TNY_FOLDER (folder));
6011 proto = modest_protocol_info_get_transport_store_protocol (tny_account_get_proto (account));
6012 if (proto == MODEST_PROTOCOL_STORE_POP) {
6013 msg = g_strdup (_("emev_ni_ui_pop3_msg_recv_error"));
6014 } else if (proto == MODEST_PROTOCOL_STORE_IMAP) {
6016 subject = tny_header_dup_subject (header);
6017 msg = g_strdup_printf (_("emev_ni_ui_imap_message_not_available_in_server"),
6021 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6025 g_object_unref (account);
6026 g_object_unref (folder);
6027 g_object_unref (header);