1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #endif /*HAVE_CONFIG_H*/
34 #include <glib/gi18n.h>
35 #include <glib/gprintf.h>
37 #include <modest-runtime.h>
38 #include <modest-tny-folder.h>
39 #include <modest-tny-msg.h>
40 #include <modest-tny-account.h>
41 #include <modest-address-book.h>
42 #include "modest-error.h"
43 #include "modest-ui-actions.h"
44 #include "modest-tny-platform-factory.h"
45 #include "modest-platform.h"
46 #include "modest-debug.h"
47 #include <tny-mime-part.h>
48 #include <tny-camel-folder.h>
49 #include <tny-camel-imap-folder.h>
50 #include <tny-camel-pop-folder.h>
51 #ifdef MODEST_TOOLKIT_HILDON2
52 #include <hildon/hildon-pannable-area.h>
53 #include <modest-header-window.h>
56 #ifdef MODEST_PLATFORM_MAEMO
57 #include "maemo/modest-osso-state-saving.h"
58 #endif /* MODEST_PLATFORM_MAEMO */
59 #ifndef MODEST_TOOLKIT_GTK
60 #include "maemo/modest-hildon-includes.h"
61 #include "maemo/modest-connection-specific-smtp-window.h"
62 #endif /* !MODEST_TOOLKIT_GTK */
63 #include <modest-utils.h>
65 #include "widgets/modest-ui-constants.h"
66 #include <widgets/modest-main-window.h>
67 #include <widgets/modest-msg-view-window.h>
68 #include <widgets/modest-account-view-window.h>
69 #include <widgets/modest-details-dialog.h>
70 #include <widgets/modest-attachments-view.h>
71 #include "widgets/modest-folder-view.h"
72 #include "widgets/modest-global-settings-dialog.h"
73 #include "modest-account-mgr-helpers.h"
74 #include "modest-mail-operation.h"
75 #include "modest-text-utils.h"
77 #ifdef MODEST_HAVE_EASYSETUP
78 #ifdef MODEST_TOOLKIT_HILDON2
79 #include "modest-easysetup-wizard-dialog.h"
81 #include "easysetup/modest-easysetup-wizard-dialog.h"
83 #endif /* MODEST_HAVE_EASYSETUP */
85 #include <modest-widget-memory.h>
86 #include <tny-error.h>
87 #include <tny-simple-list.h>
88 #include <tny-msg-view.h>
89 #include <tny-device.h>
90 #include <tny-merge-folder.h>
92 #include <gtkhtml/gtkhtml.h>
94 #define MIN_FREE_SPACE 5 * 1024 * 1024
95 #define MOVE_FOLDER_OK_BUTTON "ok-button"
96 #define MOVE_FOLDER_NEW_BUTTON "new-button"
98 typedef struct _GetMsgAsyncHelper {
100 ModestMailOperation *mail_op;
107 typedef enum _ReplyForwardAction {
111 } ReplyForwardAction;
113 typedef struct _ReplyForwardHelper {
114 guint reply_forward_type;
115 ReplyForwardAction action;
117 GtkWidget *parent_window;
119 } ReplyForwardHelper;
121 typedef struct _MoveToHelper {
122 GtkTreeRowReference *reference;
126 typedef struct _PasteAsAttachmentHelper {
127 ModestMsgEditWindow *window;
129 } PasteAsAttachmentHelper;
133 * The do_headers_action uses this kind of functions to perform some
134 * action to each member of a list of headers
136 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
138 static void do_headers_action (ModestWindow *win,
142 static void open_msg_cb (ModestMailOperation *mail_op,
149 static void reply_forward_cb (ModestMailOperation *mail_op,
156 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
158 static void folder_refreshed_cb (ModestMailOperation *mail_op,
162 static void on_send_receive_finished (ModestMailOperation *mail_op,
165 static gint header_list_count_uncached_msgs (TnyList *header_list);
167 static gboolean connect_to_get_msg (ModestWindow *win,
168 gint num_of_uncached_msgs,
169 TnyAccount *account);
171 static gboolean remote_folder_has_leave_on_server (TnyFolderStore *folder);
173 static void do_create_folder (GtkWindow *window,
174 TnyFolderStore *parent_folder,
175 const gchar *suggested_name);
177 static GtkWidget* get_folder_view_from_move_to_dialog (GtkWidget *move_to_dialog);
179 static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store);
182 * This function checks whether a TnyFolderStore is a pop account
185 remote_folder_has_leave_on_server (TnyFolderStore *folder)
190 g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
192 account = get_account_from_folder_store (folder);
193 result = (modest_protocol_registry_protocol_type_has_leave_on_server (modest_runtime_get_protocol_registry (),
194 modest_tny_account_get_protocol_type (account)));
195 g_object_unref (account);
200 /* FIXME: this should be merged with the similar code in modest-account-view-window */
201 /* Show the account creation wizard dialog.
202 * returns: TRUE if an account was created. FALSE if the user cancelled.
205 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
207 gboolean result = FALSE;
209 gint dialog_response;
211 /* there is no such wizard yet */
212 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
213 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (wizard), (GtkWindow *) win);
215 /* always present a main window in the background
216 * we do it here, so we cannot end up with two wizards (as this
217 * function might be called in modest_window_mgr_get_main_window as well */
219 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
220 TRUE); /* create if not existent */
222 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
224 /* make sure the mainwindow is visible. We need to present the
225 wizard again to give it the focus back. show_all are needed
226 in order to get the widgets properly drawn (MainWindow main
227 paned won't be in its right position and the dialog will be
229 #ifndef MODEST_TOOLKIT_HILDON2
230 gtk_widget_show_all (GTK_WIDGET (win));
231 gtk_widget_show_all (GTK_WIDGET (wizard));
232 gtk_window_present (GTK_WINDOW (win));
233 gtk_window_present (GTK_WINDOW (wizard));
236 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
237 gtk_widget_destroy (GTK_WIDGET (wizard));
238 if (gtk_events_pending ())
239 gtk_main_iteration ();
241 if (dialog_response == GTK_RESPONSE_CANCEL) {
244 /* Check whether an account was created: */
245 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
252 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
255 const gchar *authors[] = {
256 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
259 about = gtk_about_dialog_new ();
260 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
261 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
262 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
263 _("Copyright (c) 2006, Nokia Corporation\n"
264 "All rights reserved."));
265 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
266 _("a modest e-mail client\n\n"
267 "design and implementation: Dirk-Jan C. Binnema\n"
268 "contributions from the fine people at KC and Ig\n"
269 "uses the tinymail email framework written by Philip van Hoof"));
270 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
271 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
272 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
273 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
275 gtk_dialog_run (GTK_DIALOG (about));
276 gtk_widget_destroy(about);
280 * Gets the list of currently selected messages. If the win is the
281 * main window, then it returns a newly allocated list of the headers
282 * selected in the header view. If win is the msg view window, then
283 * the value returned is a list with just a single header.
285 * The caller of this funcion must free the list.
288 get_selected_headers (ModestWindow *win)
290 if (MODEST_IS_MAIN_WINDOW(win)) {
291 GtkWidget *header_view;
293 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
294 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
295 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
297 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
298 /* for MsgViewWindows, we simply return a list with one element */
300 TnyList *list = NULL;
302 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
303 if (header != NULL) {
304 list = tny_simple_list_new ();
305 tny_list_prepend (list, G_OBJECT(header));
306 g_object_unref (G_OBJECT(header));
315 static GtkTreeRowReference *
316 get_next_after_selected_headers (ModestHeaderView *header_view)
318 GtkTreeSelection *sel;
319 GList *selected_rows, *node;
321 GtkTreeRowReference *result;
324 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
325 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
326 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
328 if (selected_rows == NULL)
331 node = g_list_last (selected_rows);
332 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
333 gtk_tree_path_next (path);
335 result = gtk_tree_row_reference_new (model, path);
337 gtk_tree_path_free (path);
338 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
339 g_list_free (selected_rows);
345 headers_action_mark_as_read (TnyHeader *header,
349 TnyHeaderFlags flags;
351 g_return_if_fail (TNY_IS_HEADER(header));
353 flags = tny_header_get_flags (header);
354 if (flags & TNY_HEADER_FLAG_SEEN) return;
355 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
359 headers_action_mark_as_unread (TnyHeader *header,
363 TnyHeaderFlags flags;
365 g_return_if_fail (TNY_IS_HEADER(header));
367 flags = tny_header_get_flags (header);
368 if (flags & TNY_HEADER_FLAG_SEEN) {
369 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
373 /** After deleing a message that is currently visible in a window,
374 * show the next message from the list, or close the window if there are no more messages.
377 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
379 /* Close msg view window or select next */
380 if (!modest_msg_view_window_select_next_message (win) &&
381 !modest_msg_view_window_select_previous_message (win)) {
383 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
389 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
391 TnyList *header_list = NULL;
392 TnyIterator *iter = NULL;
393 TnyHeader *header = NULL;
394 gchar *message = NULL;
397 ModestWindowMgr *mgr;
398 GtkWidget *header_view = NULL;
400 g_return_if_fail (MODEST_IS_WINDOW(win));
402 /* Check first if the header view has the focus */
403 if (MODEST_IS_MAIN_WINDOW (win)) {
405 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
406 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
407 if (!gtk_widget_is_focus (header_view))
411 /* Get the headers, either from the header view (if win is the main window),
412 * or from the message view window: */
413 header_list = get_selected_headers (win);
414 if (!header_list) return;
416 /* Check if any of the headers are already opened, or in the process of being opened */
417 if (MODEST_IS_MAIN_WINDOW (win)) {
418 gint opened_headers = 0;
420 iter = tny_list_create_iterator (header_list);
421 mgr = modest_runtime_get_window_mgr ();
422 while (!tny_iterator_is_done (iter)) {
423 header = TNY_HEADER (tny_iterator_get_current (iter));
425 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
427 g_object_unref (header);
429 tny_iterator_next (iter);
431 g_object_unref (iter);
433 if (opened_headers > 0) {
436 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
439 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg, FALSE);
442 g_object_unref (header_list);
448 if (tny_list_get_length(header_list) == 1) {
449 iter = tny_list_create_iterator (header_list);
450 header = TNY_HEADER (tny_iterator_get_current (iter));
453 subject = tny_header_dup_subject (header);
455 subject = g_strdup (_("mail_va_no_subject"));
456 desc = g_strdup_printf ("%s", subject);
458 g_object_unref (header);
461 g_object_unref (iter);
463 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
464 tny_list_get_length(header_list)), desc);
466 /* Confirmation dialog */
467 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
471 if (response == GTK_RESPONSE_OK) {
472 ModestWindow *main_window = NULL;
473 ModestWindowMgr *mgr = NULL;
474 GtkTreeModel *model = NULL;
475 GtkTreeSelection *sel = NULL;
476 GList *sel_list = NULL, *tmp = NULL;
477 GtkTreeRowReference *next_row_reference = NULL;
478 GtkTreeRowReference *prev_row_reference = NULL;
479 GtkTreePath *next_path = NULL;
480 GtkTreePath *prev_path = NULL;
481 ModestMailOperation *mail_op = NULL;
483 /* Find last selected row */
484 if (MODEST_IS_MAIN_WINDOW (win)) {
485 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
486 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
487 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
488 for (tmp=sel_list; tmp; tmp=tmp->next) {
489 if (tmp->next == NULL) {
490 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
491 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
493 gtk_tree_path_prev (prev_path);
494 gtk_tree_path_next (next_path);
496 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
497 next_row_reference = gtk_tree_row_reference_new (model, next_path);
502 /* Disable window dimming management */
503 modest_window_disable_dimming (MODEST_WINDOW(win));
505 /* Remove each header. If it's a view window header_view == NULL */
506 mail_op = modest_mail_operation_new ((GObject *) win);
507 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
509 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
510 g_object_unref (mail_op);
512 /* Enable window dimming management */
514 gtk_tree_selection_unselect_all (sel);
516 modest_window_enable_dimming (MODEST_WINDOW(win));
518 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
519 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
521 /* Get main window */
522 mgr = modest_runtime_get_window_mgr ();
523 main_window = modest_window_mgr_get_main_window (mgr, FALSE); /* don't create */
525 /* Move cursor to next row */
528 /* Select next or previous row */
529 if (gtk_tree_row_reference_valid (next_row_reference)) {
530 gtk_tree_selection_select_path (sel, next_path);
532 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
533 gtk_tree_selection_select_path (sel, prev_path);
537 if (gtk_tree_row_reference_valid (next_row_reference))
538 gtk_tree_row_reference_free (next_row_reference);
539 if (next_path != NULL)
540 gtk_tree_path_free (next_path);
541 if (gtk_tree_row_reference_valid (prev_row_reference))
542 gtk_tree_row_reference_free (prev_row_reference);
543 if (prev_path != NULL)
544 gtk_tree_path_free (prev_path);
547 /* Update toolbar dimming state */
549 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
550 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
554 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
555 g_list_free (sel_list);
561 g_object_unref (header_list);
567 /* delete either message or folder, based on where we are */
569 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
571 g_return_if_fail (MODEST_IS_WINDOW(win));
573 /* Check first if the header view has the focus */
574 if (MODEST_IS_MAIN_WINDOW (win)) {
576 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
577 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
578 if (gtk_widget_is_focus (w)) {
579 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
583 modest_ui_actions_on_delete_message (action, win);
587 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
589 ModestWindowMgr *mgr = NULL;
591 #ifdef MODEST_PLATFORM_MAEMO
592 modest_osso_save_state();
593 #endif /* MODEST_PLATFORM_MAEMO */
595 g_debug ("closing down, clearing %d item(s) from operation queue",
596 modest_mail_operation_queue_num_elements
597 (modest_runtime_get_mail_operation_queue()));
599 /* cancel all outstanding operations */
600 modest_mail_operation_queue_cancel_all
601 (modest_runtime_get_mail_operation_queue());
603 g_debug ("queue has been cleared");
606 /* Check if there are opened editing windows */
607 mgr = modest_runtime_get_window_mgr ();
608 modest_window_mgr_close_all_windows (mgr);
610 /* note: when modest-tny-account-store is finalized,
611 it will automatically set all network connections
614 /* gtk_main_quit (); */
618 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
622 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
624 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
625 /* gtk_widget_destroy (GTK_WIDGET (win)); */
626 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
627 /* gboolean ret_value; */
628 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
629 /* } else if (MODEST_IS_WINDOW (win)) { */
630 /* gtk_widget_destroy (GTK_WIDGET (win)); */
632 /* g_return_if_reached (); */
637 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
639 GtkClipboard *clipboard = NULL;
640 gchar *selection = NULL;
642 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
643 selection = gtk_clipboard_wait_for_text (clipboard);
645 /* Question: why is the clipboard being used here?
646 * It doesn't really make a lot of sense. */
650 modest_address_book_add_address (selection);
656 modest_ui_actions_on_accounts (GtkAction *action,
659 /* This is currently only implemented for Maemo */
660 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
661 if (!modest_ui_actions_run_account_setup_wizard (win))
662 g_debug ("%s: wizard was already running", __FUNCTION__);
666 /* Show the list of accounts */
667 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
669 /* The accounts dialog must be modal */
670 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
671 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
676 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
678 /* This is currently only implemented for Maemo,
679 * because it requires an API (libconic) to detect different connection
682 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
684 /* Create the window if necessary: */
685 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
686 modest_connection_specific_smtp_window_fill_with_connections (
687 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
688 modest_runtime_get_account_mgr());
690 /* Show the window: */
691 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
692 GTK_WINDOW (specific_window), (GtkWindow *) win);
693 gtk_widget_show (specific_window);
694 #endif /* !MODEST_TOOLKIT_GTK */
698 modest_ui_actions_compose_msg(ModestWindow *win,
701 const gchar *bcc_str,
702 const gchar *subject_str,
703 const gchar *body_str,
705 gboolean set_as_modified)
707 gchar *account_name = NULL;
709 TnyAccount *account = NULL;
710 TnyFolder *folder = NULL;
711 gchar *from_str = NULL, *signature = NULL, *body = NULL;
712 gboolean use_signature = FALSE;
713 ModestWindow *msg_win = NULL;
714 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
715 ModestTnyAccountStore *store = modest_runtime_get_account_store();
716 GnomeVFSFileSize total_size, allowed_size;
718 /* we check for low-mem; in that case, show a warning, and don't allow
719 * composing a message with attachments
721 if (attachments && modest_platform_check_memory_low (win, TRUE))
724 #ifdef MODEST_TOOLKIT_HILDON2
725 account_name = g_strdup (modest_window_get_active_account(win));
728 account_name = modest_account_mgr_get_default_account(mgr);
731 g_printerr ("modest: no account found\n");
734 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
736 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
739 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
741 g_printerr ("modest: failed to find Drafts folder\n");
744 from_str = modest_account_mgr_get_from_string (mgr, account_name);
746 g_printerr ("modest: failed get from string for '%s'\n", account_name);
750 signature = modest_account_mgr_get_signature (mgr, account_name, &use_signature);
751 if (body_str != NULL) {
752 body = use_signature ? g_strconcat(body_str, "\n--\n", signature, NULL) : g_strdup(body_str);
754 body = use_signature ? g_strconcat("\n--\n", signature, NULL) : g_strdup("");
757 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, body, NULL, NULL, NULL);
759 g_printerr ("modest: failed to create new msg\n");
763 /* Create and register edit window */
764 /* This is destroyed by TODO. */
766 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
767 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
769 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, NULL)) {
770 gtk_widget_destroy (GTK_WIDGET (msg_win));
773 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
774 gtk_widget_show_all (GTK_WIDGET (msg_win));
776 while (attachments) {
778 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
779 attachments->data, allowed_size);
781 if (total_size > allowed_size) {
782 g_warning ("%s: total size: %u",
783 __FUNCTION__, (unsigned int)total_size);
786 allowed_size -= total_size;
788 attachments = g_slist_next(attachments);
795 g_free (account_name);
797 g_object_unref (G_OBJECT(account));
799 g_object_unref (G_OBJECT(folder));
801 g_object_unref (G_OBJECT(msg));
805 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
807 /* if there are no accounts yet, just show the wizard */
808 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
809 if (!modest_ui_actions_run_account_setup_wizard (win))
812 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
817 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
821 ModestMailOperationStatus status;
823 /* If there is no message or the operation was not successful */
824 status = modest_mail_operation_get_status (mail_op);
825 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
828 /* If it's a memory low issue, then show a banner */
829 error = modest_mail_operation_get_error (mail_op);
830 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
831 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
832 GObject *source = modest_mail_operation_get_source (mail_op);
833 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
834 dgettext("ke-recv","memr_ib_operation_disabled"),
836 g_object_unref (source);
839 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
840 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
841 gchar *subject, *msg;
842 subject = tny_header_dup_subject (header);
844 subject = g_strdup (_("mail_va_no_subject"));;
845 msg = g_strdup_printf (_("emev_ni_ui_imap_message_not_available_in_server"),
847 modest_platform_run_information_dialog (NULL, msg, FALSE);
852 /* Remove the header from the preregistered uids */
853 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
871 OpenMsgBannerInfo *banner_info;
872 GtkTreeRowReference *rowref;
876 open_msg_banner_idle (gpointer userdata)
878 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
880 gdk_threads_enter ();
881 banner_info->idle_handler = 0;
882 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
884 g_object_ref (banner_info->banner);
886 gdk_threads_leave ();
893 get_header_view_from_window (ModestWindow *window)
895 GtkWidget *header_view;
897 if (MODEST_IS_MAIN_WINDOW (window)) {
898 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
899 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
900 #ifdef MODEST_TOOLKIT_HILDON2
901 } else if (MODEST_IS_HEADER_WINDOW (window)){
902 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
912 get_info_from_header (TnyHeader *header, gboolean *is_draft)
915 gchar *account = NULL;
916 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
920 folder = tny_header_get_folder (header);
921 /* Gets folder type (OUTBOX headers will be opened in edit window */
922 if (modest_tny_folder_is_local_folder (folder)) {
923 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
924 if (folder_type == TNY_FOLDER_TYPE_INVALID)
925 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
928 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
929 TnyTransportAccount *traccount = NULL;
930 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
931 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
933 ModestTnySendQueue *send_queue = NULL;
934 ModestTnySendQueueStatus status;
936 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
937 TNY_ACCOUNT(traccount)));
938 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
939 if (TNY_IS_SEND_QUEUE (send_queue)) {
940 msg_id = modest_tny_send_queue_get_msg_id (header);
941 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
942 /* Only open messages in outbox with the editor if they are in Failed state */
943 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
948 g_object_unref(traccount);
950 g_warning("Cannot get transport account for message in outbox!!");
952 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
953 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
956 g_object_unref (folder);
962 open_msg_cb (ModestMailOperation *mail_op,
969 ModestWindowMgr *mgr = NULL;
970 ModestWindow *parent_win = NULL;
971 ModestWindow *win = NULL;
972 gchar *account = NULL;
973 gboolean open_in_editor = FALSE;
974 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
976 /* Do nothing if there was any problem with the mail
977 operation. The error will be shown by the error_handler of
978 the mail operation */
979 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
982 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
984 /* Mark header as read */
985 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
987 account = get_info_from_header (header, &open_in_editor);
991 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
993 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
995 if (open_in_editor) {
996 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
997 gchar *from_header = NULL, *acc_name;
999 from_header = tny_header_dup_from (header);
1001 /* we cannot edit without a valid account... */
1002 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1003 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1004 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1006 g_free (from_header);
1011 acc_name = modest_utils_get_account_name_from_recipient (from_header);
1012 g_free (from_header);
1018 win = modest_msg_edit_window_new (msg, account, TRUE);
1020 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1022 if (helper->rowref && helper->model) {
1023 win = modest_msg_view_window_new_with_header_model (msg, account, (const gchar*) uid,
1024 helper->model, helper->rowref);
1026 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
1031 /* Register and show new window */
1033 mgr = modest_runtime_get_window_mgr ();
1034 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1035 gtk_widget_destroy (GTK_WIDGET (win));
1038 gtk_widget_show_all (GTK_WIDGET(win));
1041 /* Update toolbar dimming state */
1042 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1043 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1049 g_object_unref (parent_win);
1053 is_memory_full_error (GError *error)
1055 gboolean enough_free_space = TRUE;
1056 GnomeVFSURI *cache_dir_uri;
1057 const gchar *cache_dir;
1058 GnomeVFSFileSize free_space;
1060 cache_dir = tny_account_store_get_cache_dir (TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
1061 cache_dir_uri = gnome_vfs_uri_new (cache_dir);
1062 if (gnome_vfs_get_volume_free_space (cache_dir_uri, &free_space) == GNOME_VFS_OK) {
1063 if (free_space < MIN_FREE_SPACE)
1064 enough_free_space = FALSE;
1066 gnome_vfs_uri_unref (cache_dir_uri);
1068 if ((error->code == TNY_SYSTEM_ERROR_MEMORY ||
1069 /* When asking for a mail and no space left on device
1070 tinymail returns this error */
1071 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE ||
1072 /* When the folder summary could not be read or
1074 error->code == TNY_IO_ERROR_WRITE ||
1075 error->code == TNY_IO_ERROR_READ) &&
1076 !enough_free_space) {
1084 check_memory_full_error (GtkWidget *parent_window, GError *err)
1089 if (is_memory_full_error (err))
1090 modest_platform_information_banner (parent_window,
1091 NULL, dgettext("ke-recv",
1092 "cerm_device_memory_full"));
1093 else if (err->code == TNY_SYSTEM_ERROR_MEMORY)
1094 /* If the account was created in memory full
1095 conditions then tinymail won't be able to
1096 connect so it'll return this error code */
1097 modest_platform_information_banner (parent_window,
1098 NULL, _("emev_ui_imap_inbox_select_error"));
1106 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1109 const GError *error;
1110 GObject *win = NULL;
1111 ModestMailOperationStatus status;
1113 win = modest_mail_operation_get_source (mail_op);
1114 error = modest_mail_operation_get_error (mail_op);
1115 status = modest_mail_operation_get_status (mail_op);
1117 /* If the mail op has been cancelled then it's not an error:
1118 don't show any message */
1119 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1120 if (is_memory_full_error ((GError *) error)) {
1121 modest_platform_information_banner ((GtkWidget *) win,
1122 NULL, dgettext("ke-recv",
1123 "cerm_device_memory_full"));
1124 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1125 modest_platform_information_banner ((GtkWidget *) win,
1126 NULL, _("emev_ui_imap_inbox_select_error"));
1127 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1128 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1129 modest_platform_information_banner ((GtkWidget *) win,
1130 NULL, dgettext ("hildon-common-strings", "sfil_ni_unable_to_open_file_not_found"));
1131 } else if (user_data) {
1132 modest_platform_information_banner ((GtkWidget *) win,
1138 g_object_unref (win);
1142 * Returns the account a list of headers belongs to. It returns a
1143 * *new* reference so don't forget to unref it
1146 get_account_from_header_list (TnyList *headers)
1148 TnyAccount *account = NULL;
1150 if (tny_list_get_length (headers) > 0) {
1151 TnyIterator *iter = tny_list_create_iterator (headers);
1152 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1153 TnyFolder *folder = tny_header_get_folder (header);
1156 g_object_unref (header);
1158 while (!tny_iterator_is_done (iter)) {
1159 header = TNY_HEADER (tny_iterator_get_current (iter));
1160 folder = tny_header_get_folder (header);
1163 g_object_unref (header);
1165 tny_iterator_next (iter);
1170 account = tny_folder_get_account (folder);
1171 g_object_unref (folder);
1175 g_object_unref (header);
1177 g_object_unref (iter);
1183 get_account_from_header (TnyHeader *header)
1185 TnyAccount *account = NULL;
1188 folder = tny_header_get_folder (header);
1191 account = tny_folder_get_account (folder);
1192 g_object_unref (folder);
1199 open_msg_helper_destroyer (gpointer user_data)
1201 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1203 if (helper->banner_info) {
1204 g_free (helper->banner_info->message);
1205 if (helper->banner_info->idle_handler > 0) {
1206 g_source_remove (helper->banner_info->idle_handler);
1207 helper->banner_info->idle_handler = 0;
1209 if (helper->banner_info->banner != NULL) {
1210 gtk_widget_destroy (helper->banner_info->banner);
1211 g_object_unref (helper->banner_info->banner);
1212 helper->banner_info->banner = NULL;
1214 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1215 helper->banner_info = NULL;
1217 g_object_unref (helper->model);
1218 g_object_unref (helper->header);
1219 gtk_tree_row_reference_free (helper->rowref);
1220 g_slice_free (OpenMsgHelper, helper);
1224 open_msg_performer(gboolean canceled,
1226 GtkWindow *parent_window,
1227 TnyAccount *account,
1230 ModestMailOperation *mail_op = NULL;
1232 ModestProtocolType proto;
1233 TnyConnectionStatus status;
1234 gboolean show_open_draft = FALSE;
1235 OpenMsgHelper *helper = NULL;
1237 helper = (OpenMsgHelper *) user_data;
1239 status = tny_account_get_connection_status (account);
1240 if (err || canceled) {
1241 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1242 /* Free the helper */
1243 open_msg_helper_destroyer (helper);
1245 /* In memory full conditions we could get this error here */
1246 check_memory_full_error ((GtkWidget *) parent_window, err);
1251 /* Get the error message depending on the protocol */
1252 proto = modest_tny_account_get_protocol_type (account);
1253 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1254 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1257 ModestProtocol *protocol;
1258 ModestProtocolRegistry *protocol_registry;
1261 protocol_registry = modest_runtime_get_protocol_registry ();
1262 subject = tny_header_dup_subject (helper->header);
1264 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1265 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1269 if (error_msg == NULL) {
1270 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1273 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1275 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1277 TnyFolderType folder_type;
1279 folder = tny_header_get_folder (helper->header);
1280 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1281 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1282 g_object_unref (folder);
1285 #ifdef MODEST_TOOLKIT_HILDON2
1287 gchar *account_name = get_info_from_header (helper->header, &is_draft);
1290 ModestWindow *window;
1291 GtkWidget *header_view;
1294 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1295 uid = modest_tny_folder_get_header_unique_id (helper->header);
1297 window = modest_msg_view_window_new_from_header_view
1298 (MODEST_HEADER_VIEW (header_view), account_name, uid, helper->rowref);
1299 if (window != NULL) {
1300 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1302 gtk_widget_destroy (GTK_WIDGET (window));
1304 gtk_widget_show_all (GTK_WIDGET(window));
1308 g_free (account_name);
1310 open_msg_helper_destroyer (helper);
1313 g_free (account_name);
1315 /* Create the mail operation */
1317 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1318 modest_ui_actions_disk_operations_error_handler,
1320 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1323 if (show_open_draft) {
1324 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1325 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1326 helper->banner_info->banner = NULL;
1327 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1328 helper->banner_info);
1332 headers = TNY_LIST (tny_simple_list_new ());
1333 tny_list_prepend (headers, G_OBJECT (helper->header));
1334 modest_mail_operation_get_msgs_full (mail_op,
1338 open_msg_helper_destroyer);
1339 g_object_unref (headers);
1344 g_object_unref (mail_op);
1345 g_object_unref (account);
1349 * This function is used by both modest_ui_actions_on_open and
1350 * modest_ui_actions_on_header_activated. This way we always do the
1351 * same when trying to open messages.
1354 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1356 ModestWindowMgr *mgr = NULL;
1357 TnyAccount *account;
1358 gboolean cached = FALSE;
1360 GtkWidget *header_view = NULL;
1361 OpenMsgHelper *helper;
1362 ModestWindow *window;
1364 g_return_if_fail (header != NULL && rowref != NULL);
1366 mgr = modest_runtime_get_window_mgr ();
1369 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1370 if (header_view == NULL)
1373 /* Get the account */
1374 account = get_account_from_header (header);
1379 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1381 /* Do not open again the message and present the
1382 window to the user */
1385 #ifndef MODEST_TOOLKIT_HILDON2
1386 gtk_window_present (GTK_WINDOW (window));
1389 /* the header has been registered already, we don't do
1390 * anything but wait for the window to come up*/
1391 g_debug ("header %p already registered, waiting for window", header);
1396 /* Open each message */
1397 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1399 /* Allways download if we are online. */
1400 if (!tny_device_is_online (modest_runtime_get_device ())) {
1403 /* If ask for user permission to download the messages */
1404 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1405 _("mcen_nc_get_msg"));
1407 /* End if the user does not want to continue */
1408 if (response == GTK_RESPONSE_CANCEL) {
1414 /* We register the window for opening */
1415 modest_window_mgr_register_header (mgr, header, NULL);
1417 /* Create the helper. We need to get a reference to the model
1418 here because it could change while the message is readed
1419 (the user could switch between folders) */
1420 helper = g_slice_new (OpenMsgHelper);
1421 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1422 helper->header = g_object_ref (header);
1423 helper->rowref = gtk_tree_row_reference_copy (rowref);
1424 helper->banner_info = NULL;
1426 /* Connect to the account and perform */
1428 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1429 open_msg_performer, helper);
1431 /* Call directly the performer, do not need to connect */
1432 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1433 g_object_ref (account), helper);
1438 g_object_unref (account);
1442 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1449 /* we check for low-mem; in that case, show a warning, and don't allow
1452 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1456 headers = get_selected_headers (win);
1460 headers_count = tny_list_get_length (headers);
1461 if (headers_count != 1) {
1462 if (headers_count > 1) {
1463 /* Don't allow activation if there are more than one message selected */
1464 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1467 g_object_unref (headers);
1471 iter = tny_list_create_iterator (headers);
1472 header = TNY_HEADER (tny_iterator_get_current (iter));
1473 g_object_unref (iter);
1477 open_msg_from_header (header, NULL, win);
1478 g_object_unref (header);
1481 g_object_unref(headers);
1484 static ReplyForwardHelper*
1485 create_reply_forward_helper (ReplyForwardAction action,
1487 guint reply_forward_type,
1490 ReplyForwardHelper *rf_helper = NULL;
1491 const gchar *active_acc = modest_window_get_active_account (win);
1493 rf_helper = g_slice_new0 (ReplyForwardHelper);
1494 rf_helper->reply_forward_type = reply_forward_type;
1495 rf_helper->action = action;
1496 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1497 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1498 rf_helper->account_name = (active_acc) ?
1499 g_strdup (active_acc) :
1500 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1506 free_reply_forward_helper (gpointer data)
1508 ReplyForwardHelper *helper;
1510 helper = (ReplyForwardHelper *) data;
1511 g_free (helper->account_name);
1513 g_object_unref (helper->header);
1514 g_slice_free (ReplyForwardHelper, helper);
1518 reply_forward_cb (ModestMailOperation *mail_op,
1525 TnyMsg *new_msg = NULL;
1526 ReplyForwardHelper *rf_helper;
1527 ModestWindow *msg_win = NULL;
1528 ModestEditType edit_type;
1530 TnyAccount *account = NULL;
1531 ModestWindowMgr *mgr = NULL;
1532 gchar *signature = NULL;
1533 gboolean use_signature;
1535 /* If there was any error. The mail operation could be NULL,
1536 this means that we already have the message downloaded and
1537 that we didn't do a mail operation to retrieve it */
1538 rf_helper = (ReplyForwardHelper *) user_data;
1539 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1542 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1543 rf_helper->account_name);
1544 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr(),
1545 rf_helper->account_name,
1548 /* Create reply mail */
1549 switch (rf_helper->action) {
1552 modest_tny_msg_create_reply_msg (msg, header, from,
1553 (use_signature) ? signature : NULL,
1554 rf_helper->reply_forward_type,
1555 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1557 case ACTION_REPLY_TO_ALL:
1559 modest_tny_msg_create_reply_msg (msg, header, from,
1560 (use_signature) ? signature : NULL,
1561 rf_helper->reply_forward_type,
1562 MODEST_TNY_MSG_REPLY_MODE_ALL);
1563 edit_type = MODEST_EDIT_TYPE_REPLY;
1565 case ACTION_FORWARD:
1567 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1568 rf_helper->reply_forward_type);
1569 edit_type = MODEST_EDIT_TYPE_FORWARD;
1572 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1574 g_return_if_reached ();
1582 g_warning ("%s: failed to create message\n", __FUNCTION__);
1586 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1587 rf_helper->account_name,
1588 TNY_ACCOUNT_TYPE_STORE);
1590 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1594 /* Create and register the windows */
1595 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1596 mgr = modest_runtime_get_window_mgr ();
1597 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1599 if (rf_helper->parent_window != NULL) {
1600 gdouble parent_zoom;
1602 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1603 modest_window_set_zoom (msg_win, parent_zoom);
1606 /* Show edit window */
1607 gtk_widget_show_all (GTK_WIDGET (msg_win));
1610 /* We always unregister the header because the message is
1611 forwarded or replied so the original one is no longer
1613 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1616 g_object_unref (G_OBJECT (new_msg));
1618 g_object_unref (G_OBJECT (account));
1619 free_reply_forward_helper (rf_helper);
1622 /* Checks a list of headers. If any of them are not currently
1623 * downloaded (CACHED) then returns TRUE else returns FALSE.
1626 header_list_count_uncached_msgs (TnyList *header_list)
1629 gint uncached_messages = 0;
1631 iter = tny_list_create_iterator (header_list);
1632 while (!tny_iterator_is_done (iter)) {
1635 header = TNY_HEADER (tny_iterator_get_current (iter));
1637 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1638 uncached_messages ++;
1639 g_object_unref (header);
1642 tny_iterator_next (iter);
1644 g_object_unref (iter);
1646 return uncached_messages;
1649 /* Returns FALSE if the user does not want to download the
1650 * messages. Returns TRUE if the user allowed the download.
1653 connect_to_get_msg (ModestWindow *win,
1654 gint num_of_uncached_msgs,
1655 TnyAccount *account)
1657 GtkResponseType response;
1659 /* Allways download if we are online. */
1660 if (tny_device_is_online (modest_runtime_get_device ()))
1663 /* If offline, then ask for user permission to download the messages */
1664 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1665 ngettext("mcen_nc_get_msg",
1667 num_of_uncached_msgs));
1669 if (response == GTK_RESPONSE_CANCEL)
1672 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1676 reply_forward_performer (gboolean canceled,
1678 GtkWindow *parent_window,
1679 TnyAccount *account,
1682 ReplyForwardHelper *rf_helper = NULL;
1683 ModestMailOperation *mail_op;
1685 rf_helper = (ReplyForwardHelper *) user_data;
1687 if (canceled || err) {
1688 free_reply_forward_helper (rf_helper);
1692 /* Retrieve the message */
1693 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1694 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1695 modest_ui_actions_disk_operations_error_handler,
1697 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1698 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1701 g_object_unref(mail_op);
1705 * Common code for the reply and forward actions
1708 reply_forward (ReplyForwardAction action, ModestWindow *win)
1710 ReplyForwardHelper *rf_helper = NULL;
1711 guint reply_forward_type;
1713 g_return_if_fail (MODEST_IS_WINDOW(win));
1715 /* we check for low-mem; in that case, show a warning, and don't allow
1716 * reply/forward (because it could potentially require a lot of memory */
1717 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1721 /* we need an account when editing */
1722 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1723 if (!modest_ui_actions_run_account_setup_wizard (win))
1727 reply_forward_type =
1728 modest_conf_get_int (modest_runtime_get_conf (),
1729 (action == ACTION_FORWARD) ?
1730 MODEST_CONF_FORWARD_TYPE :
1731 MODEST_CONF_REPLY_TYPE,
1734 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1736 TnyHeader *header = NULL;
1737 /* Get header and message. Do not free them here, the
1738 reply_forward_cb must do it */
1739 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1740 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1742 if (msg && header) {
1744 rf_helper = create_reply_forward_helper (action, win,
1745 reply_forward_type, header);
1746 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1748 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1752 g_object_unref (msg);
1754 g_object_unref (header);
1756 TnyHeader *header = NULL;
1758 gboolean do_retrieve = TRUE;
1759 TnyList *header_list = NULL;
1761 header_list = get_selected_headers (win);
1764 /* Check that only one message is selected for replying */
1765 if (tny_list_get_length (header_list) != 1) {
1766 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1767 NULL, _("mcen_ib_select_one_message"));
1768 g_object_unref (header_list);
1772 /* Only reply/forward to one message */
1773 iter = tny_list_create_iterator (header_list);
1774 header = TNY_HEADER (tny_iterator_get_current (iter));
1775 g_object_unref (iter);
1777 /* Retrieve messages */
1778 do_retrieve = (action == ACTION_FORWARD) ||
1779 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1782 TnyAccount *account = NULL;
1783 TnyFolder *folder = NULL;
1784 gdouble download = TRUE;
1785 guint uncached_msgs = 0;
1787 folder = tny_header_get_folder (header);
1789 goto do_retrieve_frees;
1790 account = tny_folder_get_account (folder);
1792 goto do_retrieve_frees;
1794 uncached_msgs = header_list_count_uncached_msgs (header_list);
1796 if (uncached_msgs > 0) {
1797 /* Allways download if we are online. */
1798 if (!tny_device_is_online (modest_runtime_get_device ())) {
1801 /* If ask for user permission to download the messages */
1802 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1803 ngettext("mcen_nc_get_msg",
1807 /* End if the user does not want to continue */
1808 if (response == GTK_RESPONSE_CANCEL)
1815 rf_helper = create_reply_forward_helper (action, win,
1816 reply_forward_type, header);
1817 if (uncached_msgs > 0) {
1818 modest_platform_connect_and_perform (GTK_WINDOW (win),
1820 reply_forward_performer,
1823 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
1824 account, rf_helper);
1829 g_object_unref (account);
1831 g_object_unref (folder);
1833 reply_forward_cb (NULL, header, FALSE, NULL, NULL, rf_helper);
1836 g_object_unref (header_list);
1837 g_object_unref (header);
1842 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1844 g_return_if_fail (MODEST_IS_WINDOW(win));
1846 reply_forward (ACTION_REPLY, win);
1850 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1852 g_return_if_fail (MODEST_IS_WINDOW(win));
1854 reply_forward (ACTION_FORWARD, win);
1858 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1860 g_return_if_fail (MODEST_IS_WINDOW(win));
1862 reply_forward (ACTION_REPLY_TO_ALL, win);
1866 modest_ui_actions_on_next (GtkAction *action,
1867 ModestWindow *window)
1869 if (MODEST_IS_MAIN_WINDOW (window)) {
1870 GtkWidget *header_view;
1872 header_view = modest_main_window_get_child_widget (
1873 MODEST_MAIN_WINDOW(window),
1874 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1878 modest_header_view_select_next (
1879 MODEST_HEADER_VIEW(header_view));
1880 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1881 modest_msg_view_window_select_next_message (
1882 MODEST_MSG_VIEW_WINDOW (window));
1884 g_return_if_reached ();
1889 modest_ui_actions_on_prev (GtkAction *action,
1890 ModestWindow *window)
1892 g_return_if_fail (MODEST_IS_WINDOW(window));
1894 if (MODEST_IS_MAIN_WINDOW (window)) {
1895 GtkWidget *header_view;
1896 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1897 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1901 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1902 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1903 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1905 g_return_if_reached ();
1910 modest_ui_actions_on_sort (GtkAction *action,
1911 ModestWindow *window)
1913 GtkWidget *header_view = NULL;
1915 g_return_if_fail (MODEST_IS_WINDOW(window));
1917 if (MODEST_IS_MAIN_WINDOW (window)) {
1918 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1919 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1920 #ifdef MODEST_TOOLKIT_HILDON2
1921 } else if (MODEST_IS_HEADER_WINDOW (window)) {
1922 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
1927 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1932 /* Show sorting dialog */
1933 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1937 new_messages_arrived (ModestMailOperation *self,
1938 TnyList *new_headers,
1942 gboolean show_visual_notifications;
1944 source = modest_mail_operation_get_source (self);
1945 show_visual_notifications = (source) ? FALSE : TRUE;
1947 g_object_unref (source);
1949 /* Notify new messages have been downloaded. If the
1950 send&receive was invoked by the user then do not show any
1951 visual notification, only play a sound and activate the LED
1952 (for the Maemo version) */
1953 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0)
1954 modest_platform_on_new_headers_received (new_headers,
1955 show_visual_notifications);
1960 retrieve_all_messages_cb (GObject *source,
1962 guint retrieve_limit)
1968 window = GTK_WINDOW (source);
1969 msg = g_strdup_printf (_("mail_nc_msg_count_limit_exceeded"),
1970 num_msgs, retrieve_limit);
1972 /* Ask the user if they want to retrieve all the messages */
1974 modest_platform_run_confirmation_dialog_with_buttons (window, msg,
1975 _("mcen_bd_get_all"),
1976 _("mcen_bd_newest_only"));
1977 /* Free and return */
1979 return (response == GTK_RESPONSE_ACCEPT) ? TRUE : FALSE;
1983 TnyAccount *account;
1985 gchar *account_name;
1986 gboolean poke_status;
1987 gboolean interactive;
1988 ModestMailOperation *mail_op;
1992 do_send_receive_performer (gboolean canceled,
1994 GtkWindow *parent_window,
1995 TnyAccount *account,
1998 SendReceiveInfo *info;
2000 info = (SendReceiveInfo *) user_data;
2002 if (err || canceled) {
2003 /* In memory full conditions we could get this error here */
2004 check_memory_full_error ((GtkWidget *) parent_window, err);
2006 if (info->mail_op) {
2007 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2013 /* Set send/receive operation in progress */
2014 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2015 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2018 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2019 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2020 G_CALLBACK (on_send_receive_finished),
2023 /* Send & receive. */
2024 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2025 (info->win) ? retrieve_all_messages_cb : NULL,
2026 new_messages_arrived, info->win);
2031 g_object_unref (G_OBJECT (info->mail_op));
2032 if (info->account_name)
2033 g_free (info->account_name);
2035 g_object_unref (info->win);
2037 g_object_unref (info->account);
2038 g_slice_free (SendReceiveInfo, info);
2042 * This function performs the send & receive required actions. The
2043 * window is used to create the mail operation. Typically it should
2044 * always be the main window, but we pass it as argument in order to
2048 modest_ui_actions_do_send_receive (const gchar *account_name,
2049 gboolean force_connection,
2050 gboolean poke_status,
2051 gboolean interactive,
2054 gchar *acc_name = NULL;
2055 SendReceiveInfo *info;
2056 ModestTnyAccountStore *acc_store;
2058 /* If no account name was provided then get the current account, and if
2059 there is no current account then pick the default one: */
2060 if (!account_name) {
2062 acc_name = g_strdup (modest_window_get_active_account (win));
2064 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2066 g_printerr ("modest: cannot get default account\n");
2070 acc_name = g_strdup (account_name);
2073 acc_store = modest_runtime_get_account_store ();
2075 /* Create the info for the connect and perform */
2076 info = g_slice_new (SendReceiveInfo);
2077 info->account_name = acc_name;
2078 info->win = (win) ? g_object_ref (win) : NULL;
2079 info->poke_status = poke_status;
2080 info->interactive = interactive;
2081 info->account = modest_tny_account_store_get_server_account (acc_store, acc_name,
2082 TNY_ACCOUNT_TYPE_STORE);
2083 /* We need to create the operation here, because otherwise it
2084 could happen that the queue emits the queue-empty signal
2085 while we're trying to connect the account */
2086 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2087 modest_ui_actions_disk_operations_error_handler,
2089 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2091 /* Invoke the connect and perform */
2092 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2093 force_connection, info->account,
2094 do_send_receive_performer, info);
2099 modest_ui_actions_do_cancel_send (const gchar *account_name,
2102 TnyTransportAccount *transport_account;
2103 TnySendQueue *send_queue = NULL;
2104 GError *error = NULL;
2106 /* Get transport account */
2108 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2109 (modest_runtime_get_account_store(),
2111 TNY_ACCOUNT_TYPE_TRANSPORT));
2112 if (!transport_account) {
2113 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2118 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2119 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2120 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2121 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2122 "modest: could not find send queue for account\n");
2124 /* Cancel the current send */
2125 tny_account_cancel (TNY_ACCOUNT (transport_account));
2127 /* Suspend all pending messages */
2128 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2132 if (transport_account != NULL)
2133 g_object_unref (G_OBJECT (transport_account));
2137 modest_ui_actions_cancel_send_all (ModestWindow *win)
2139 GSList *account_names, *iter;
2141 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2144 iter = account_names;
2146 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2147 iter = g_slist_next (iter);
2150 modest_account_mgr_free_account_names (account_names);
2151 account_names = NULL;
2155 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2158 /* Check if accounts exist */
2159 gboolean accounts_exist =
2160 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2162 /* If not, allow the user to create an account before trying to send/receive. */
2163 if (!accounts_exist)
2164 modest_ui_actions_on_accounts (NULL, win);
2166 /* Cancel all sending operaitons */
2167 modest_ui_actions_cancel_send_all (win);
2171 * Refreshes all accounts. This function will be used by automatic
2175 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2176 gboolean force_connection,
2177 gboolean poke_status,
2178 gboolean interactive)
2180 GSList *account_names, *iter;
2182 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2185 iter = account_names;
2187 modest_ui_actions_do_send_receive ((const char*) iter->data,
2189 poke_status, interactive, win);
2190 iter = g_slist_next (iter);
2193 modest_account_mgr_free_account_names (account_names);
2194 account_names = NULL;
2198 * Handler of the click on Send&Receive button in the main toolbar
2201 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2203 /* Check if accounts exist */
2204 gboolean accounts_exist;
2207 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2209 /* If not, allow the user to create an account before trying to send/receive. */
2210 if (!accounts_exist)
2211 modest_ui_actions_on_accounts (NULL, win);
2213 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2214 if (MODEST_IS_MAIN_WINDOW (win)) {
2215 GtkWidget *folder_view;
2216 TnyFolderStore *folder_store;
2219 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2220 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2224 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2227 g_object_unref (folder_store);
2230 /* Refresh the active account. Force the connection if needed
2231 and poke the status of all folders */
2232 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2237 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2240 GtkWidget *header_view;
2242 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2244 header_view = modest_main_window_get_child_widget (main_window,
2245 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2249 conf = modest_runtime_get_conf ();
2251 /* what is saved/restored is depending on the style; thus; we save with
2252 * old style, then update the style, and restore for this new style
2254 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2256 if (modest_header_view_get_style
2257 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2258 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2259 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2261 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2262 MODEST_HEADER_VIEW_STYLE_DETAILS);
2264 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2265 MODEST_CONF_HEADER_VIEW_KEY);
2270 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2272 ModestMainWindow *main_window)
2274 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2275 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2277 /* in the case the folder is empty, show the empty folder message and focus
2279 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2280 if (modest_header_view_is_empty (header_view)) {
2281 TnyFolder *folder = modest_header_view_get_folder (header_view);
2282 GtkWidget *folder_view =
2283 modest_main_window_get_child_widget (main_window,
2284 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2285 if (folder != NULL) {
2286 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2287 g_object_unref (folder);
2289 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2293 /* If no header has been selected then exit */
2298 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2299 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2301 /* Update toolbar dimming state */
2302 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2303 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2307 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2310 ModestWindow *window)
2312 GtkWidget *open_widget;
2313 GtkTreeRowReference *rowref;
2315 g_return_if_fail (MODEST_IS_WINDOW(window));
2316 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2317 g_return_if_fail (TNY_IS_HEADER (header));
2319 if (modest_header_view_count_selected_headers (header_view) > 1) {
2320 /* Don't allow activation if there are more than one message selected */
2321 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2325 /* we check for low-mem; in that case, show a warning, and don't allow
2326 * activating headers
2328 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2331 if (MODEST_IS_MAIN_WINDOW (window)) {
2332 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2333 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2334 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2338 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2339 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2340 gtk_tree_row_reference_free (rowref);
2344 set_active_account_from_tny_account (TnyAccount *account,
2345 ModestWindow *window)
2347 const gchar *server_acc_name = tny_account_get_id (account);
2349 /* We need the TnyAccount provided by the
2350 account store because that is the one that
2351 knows the name of the Modest account */
2352 TnyAccount *modest_server_account = modest_server_account =
2353 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2354 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2356 if (!modest_server_account) {
2357 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2361 /* Update active account, but only if it's not a pseudo-account */
2362 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2363 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2364 const gchar *modest_acc_name =
2365 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2366 if (modest_acc_name)
2367 modest_window_set_active_account (window, modest_acc_name);
2370 g_object_unref (modest_server_account);
2375 folder_refreshed_cb (ModestMailOperation *mail_op,
2379 ModestMainWindow *win = NULL;
2380 GtkWidget *folder_view;
2381 const GError *error;
2383 g_return_if_fail (TNY_IS_FOLDER (folder));
2385 win = MODEST_MAIN_WINDOW (user_data);
2387 /* Check if the operation failed due to memory low conditions */
2388 error = modest_mail_operation_get_error (mail_op);
2389 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2390 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2391 modest_platform_run_information_dialog (GTK_WINDOW (win),
2392 dgettext("ke-recv","memr_ib_operation_disabled"),
2398 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2401 TnyFolderStore *current_folder;
2403 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2404 if (current_folder) {
2405 gboolean different = ((TnyFolderStore *) folder != current_folder);
2406 g_object_unref (current_folder);
2412 /* Check if folder is empty and set headers view contents style */
2413 if (tny_folder_get_all_count (folder) == 0)
2414 modest_main_window_set_contents_style (win,
2415 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2420 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2421 TnyFolderStore *folder_store,
2423 ModestMainWindow *main_window)
2426 GtkWidget *header_view;
2428 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2430 header_view = modest_main_window_get_child_widget(main_window,
2431 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2435 conf = modest_runtime_get_conf ();
2437 if (TNY_IS_ACCOUNT (folder_store)) {
2439 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2441 /* Show account details */
2442 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2445 if (TNY_IS_FOLDER (folder_store) && selected) {
2446 TnyAccount *account;
2447 const gchar *account_name = NULL;
2449 /* Update the active account */
2450 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2452 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2454 modest_tny_account_get_parent_modest_account_name_for_server_account (account);
2455 g_object_unref (account);
2459 /* Set the header style by default, it could
2460 be changed later by the refresh callback to
2462 modest_main_window_set_contents_style (main_window,
2463 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2465 /* Set folder on header view. This function
2466 will call tny_folder_refresh_async so we
2467 pass a callback that will be called when
2468 finished. We use that callback to set the
2469 empty view if there are no messages */
2470 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2471 TNY_FOLDER (folder_store),
2473 folder_refreshed_cb,
2476 /* Restore configuration. We need to do this
2477 *after* the set_folder because the widget
2478 memory asks the header view about its
2480 modest_widget_memory_restore (modest_runtime_get_conf (),
2481 G_OBJECT(header_view),
2482 MODEST_CONF_HEADER_VIEW_KEY);
2484 /* No need to save the header view
2485 configuration for Maemo because it only
2486 saves the sorting stuff and that it's
2487 already being done by the sort
2488 dialog. Remove it when the GNOME version
2489 has the same behaviour */
2490 #ifdef MODEST_TOOLKIT_GTK
2491 if (modest_main_window_get_contents_style (main_window) ==
2492 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2493 modest_widget_memory_save (conf, G_OBJECT (header_view),
2494 MODEST_CONF_HEADER_VIEW_KEY);
2496 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2500 /* Update dimming state */
2501 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2502 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2506 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2513 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2515 online = tny_device_is_online (modest_runtime_get_device());
2518 /* already online -- the item is simply not there... */
2519 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2521 GTK_MESSAGE_WARNING,
2523 _("The %s you selected cannot be found"),
2525 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2526 gtk_dialog_run (GTK_DIALOG(dialog));
2528 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2531 _("mcen_bd_dialog_cancel"),
2532 GTK_RESPONSE_REJECT,
2533 _("mcen_bd_dialog_ok"),
2534 GTK_RESPONSE_ACCEPT,
2536 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2537 "Do you want to get online?"), item);
2538 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2539 gtk_label_new (txt), FALSE, FALSE, 0);
2540 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2543 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2544 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2545 /* TODO: Comment about why is this commented out: */
2546 /* modest_platform_connect_and_wait (); */
2549 gtk_widget_destroy (dialog);
2553 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2556 /* g_message ("%s %s", __FUNCTION__, link); */
2561 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2564 modest_platform_activate_uri (link);
2568 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2571 modest_platform_show_uri_popup (link);
2575 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2578 /* we check for low-mem; in that case, show a warning, and don't allow
2579 * viewing attachments
2581 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2584 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2588 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2589 const gchar *address,
2592 /* g_message ("%s %s", __FUNCTION__, address); */
2596 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2597 TnyMsg *saved_draft,
2600 ModestMsgEditWindow *edit_window;
2601 ModestMainWindow *win;
2603 /* FIXME. Make the header view sensitive again. This is a
2604 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2606 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2607 modest_runtime_get_window_mgr(), FALSE));
2609 GtkWidget *hdrview = modest_main_window_get_child_widget(
2610 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2611 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2614 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2616 /* Set draft is there was no error */
2617 if (!modest_mail_operation_get_error (mail_op))
2618 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2620 g_object_unref(edit_window);
2624 enough_space_for_message (ModestMsgEditWindow *edit_window,
2627 TnyAccountStore *acc_store;
2628 guint64 available_disk, expected_size;
2633 acc_store = TNY_ACCOUNT_STORE (modest_runtime_get_account_store());
2634 available_disk = modest_utils_get_available_space (NULL);
2635 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2636 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2641 /* Double check: memory full condition or message too big */
2642 if (available_disk < MIN_FREE_SPACE ||
2643 expected_size > available_disk) {
2645 modest_platform_information_banner (NULL, NULL,
2647 "cerm_device_memory_full"));
2652 * djcb: if we're in low-memory state, we only allow for
2653 * saving messages smaller than
2654 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2655 * should still allow for sending anything critical...
2657 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2658 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2662 * djcb: we also make sure that the attachments are smaller than the max size
2663 * this is for the case where we'd try to forward a message with attachments
2664 * bigger than our max allowed size, or sending an message from drafts which
2665 * somehow got past our checks when attaching.
2667 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2668 modest_platform_run_information_dialog (
2669 GTK_WINDOW(edit_window),
2670 dgettext("ke-recv","memr_ib_operation_disabled"),
2679 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2681 TnyTransportAccount *transport_account;
2682 ModestMailOperation *mail_operation;
2684 gchar *account_name, *from;
2685 ModestAccountMgr *account_mgr;
2686 gboolean had_error = FALSE;
2687 ModestMainWindow *win = NULL;
2689 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2691 data = modest_msg_edit_window_get_msg_data (edit_window);
2694 if (!enough_space_for_message (edit_window, data)) {
2695 modest_msg_edit_window_free_msg_data (edit_window, data);
2699 account_name = g_strdup (data->account_name);
2700 account_mgr = modest_runtime_get_account_mgr();
2702 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2704 account_name = modest_account_mgr_get_default_account (account_mgr);
2705 if (!account_name) {
2706 g_printerr ("modest: no account found\n");
2707 modest_msg_edit_window_free_msg_data (edit_window, data);
2711 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2712 account_name = g_strdup (data->account_name);
2716 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2717 (modest_runtime_get_account_store (),
2719 TNY_ACCOUNT_TYPE_TRANSPORT));
2720 if (!transport_account) {
2721 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2722 g_free (account_name);
2723 modest_msg_edit_window_free_msg_data (edit_window, data);
2726 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2728 /* Create the mail operation */
2729 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
2731 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2733 modest_mail_operation_save_to_drafts (mail_operation,
2745 data->priority_flags,
2746 on_save_to_drafts_cb,
2747 g_object_ref(edit_window));
2749 #ifdef MODEST_TOOLKIT_HILDON2
2750 /* In hildon2 we always show the information banner on saving to drafts.
2751 * It will be a system information banner in this case.
2753 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2754 modest_platform_information_banner (NULL, NULL, text);
2757 /* Use the main window as the parent of the banner, if the
2758 main window does not exist it won't be shown, if the parent
2759 window exists then it's properly shown. We don't use the
2760 editor window because it could be closed (save to drafts
2761 could happen after closing the window */
2762 win = (ModestMainWindow *)
2763 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
2765 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2766 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
2770 modest_msg_edit_window_set_modified (edit_window, FALSE);
2774 g_free (account_name);
2775 g_object_unref (G_OBJECT (transport_account));
2776 g_object_unref (G_OBJECT (mail_operation));
2778 modest_msg_edit_window_free_msg_data (edit_window, data);
2781 * If the drafts folder is selected then make the header view
2782 * insensitive while the message is being saved to drafts
2783 * (it'll be sensitive again in on_save_to_drafts_cb()). This
2784 * is not very clean but it avoids letting the drafts folder
2785 * in an inconsistent state: the user could edit the message
2786 * being saved and undesirable things would happen.
2787 * In the average case the user won't notice anything at
2788 * all. In the worst case (the user is editing a really big
2789 * file from Drafts) the header view will be insensitive
2790 * during the saving process (10 or 20 seconds, depending on
2791 * the message). Anyway this is just a quick workaround: once
2792 * we find a better solution it should be removed
2793 * See NB#65125 (commend #18) for details.
2795 if (!had_error && win != NULL) {
2796 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
2797 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
2799 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
2801 if (modest_tny_folder_is_local_folder(folder)) {
2802 TnyFolderType folder_type;
2803 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
2804 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
2805 GtkWidget *hdrview = modest_main_window_get_child_widget(
2806 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2807 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
2811 if (folder != NULL) g_object_unref(folder);
2818 /* For instance, when clicking the Send toolbar button when editing a message: */
2820 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2822 TnyTransportAccount *transport_account = NULL;
2823 gboolean had_error = FALSE;
2825 ModestAccountMgr *account_mgr;
2826 gchar *account_name;
2828 ModestMailOperation *mail_operation;
2830 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
2832 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2835 data = modest_msg_edit_window_get_msg_data (edit_window);
2838 if (!enough_space_for_message (edit_window, data)) {
2839 modest_msg_edit_window_free_msg_data (edit_window, data);
2843 account_mgr = modest_runtime_get_account_mgr();
2844 account_name = g_strdup (data->account_name);
2846 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2849 account_name = modest_account_mgr_get_default_account (account_mgr);
2851 if (!account_name) {
2852 modest_msg_edit_window_free_msg_data (edit_window, data);
2853 /* Run account setup wizard */
2854 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
2859 /* Get the currently-active transport account for this modest account: */
2860 if (strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
2862 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2863 (modest_runtime_get_account_store (),
2864 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
2867 if (!transport_account) {
2868 modest_msg_edit_window_free_msg_data (edit_window, data);
2869 /* Run account setup wizard */
2870 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2875 /* Create the mail operation */
2876 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2877 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
2878 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2880 modest_mail_operation_send_new_mail (mail_operation,
2892 data->priority_flags);
2894 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
2895 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2898 if (modest_mail_operation_get_error (mail_operation) != NULL) {
2899 const GError *error = modest_mail_operation_get_error (mail_operation);
2900 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
2901 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
2902 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
2903 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
2910 g_free (account_name);
2911 g_object_unref (G_OBJECT (transport_account));
2912 g_object_unref (G_OBJECT (mail_operation));
2914 modest_msg_edit_window_free_msg_data (edit_window, data);
2917 modest_msg_edit_window_set_sent (edit_window, TRUE);
2919 /* Save settings and close the window: */
2920 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2927 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2928 ModestMsgEditWindow *window)
2930 ModestMsgEditFormatState *format_state = NULL;
2932 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2933 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2935 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2938 format_state = modest_msg_edit_window_get_format_state (window);
2939 g_return_if_fail (format_state != NULL);
2941 format_state->bold = gtk_toggle_action_get_active (action);
2942 modest_msg_edit_window_set_format_state (window, format_state);
2943 g_free (format_state);
2948 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2949 ModestMsgEditWindow *window)
2951 ModestMsgEditFormatState *format_state = NULL;
2953 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2954 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2956 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2959 format_state = modest_msg_edit_window_get_format_state (window);
2960 g_return_if_fail (format_state != NULL);
2962 format_state->italics = gtk_toggle_action_get_active (action);
2963 modest_msg_edit_window_set_format_state (window, format_state);
2964 g_free (format_state);
2969 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2970 ModestMsgEditWindow *window)
2972 ModestMsgEditFormatState *format_state = NULL;
2974 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2975 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2977 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2980 format_state = modest_msg_edit_window_get_format_state (window);
2981 g_return_if_fail (format_state != NULL);
2983 format_state->bullet = gtk_toggle_action_get_active (action);
2984 modest_msg_edit_window_set_format_state (window, format_state);
2985 g_free (format_state);
2990 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2991 GtkRadioAction *selected,
2992 ModestMsgEditWindow *window)
2994 ModestMsgEditFormatState *format_state = NULL;
2995 GtkJustification value;
2997 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2999 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3002 value = gtk_radio_action_get_current_value (selected);
3004 format_state = modest_msg_edit_window_get_format_state (window);
3005 g_return_if_fail (format_state != NULL);
3007 format_state->justification = value;
3008 modest_msg_edit_window_set_format_state (window, format_state);
3009 g_free (format_state);
3013 modest_ui_actions_on_select_editor_color (GtkAction *action,
3014 ModestMsgEditWindow *window)
3016 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3017 g_return_if_fail (GTK_IS_ACTION (action));
3019 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3022 modest_msg_edit_window_select_color (window);
3026 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3027 ModestMsgEditWindow *window)
3029 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3030 g_return_if_fail (GTK_IS_ACTION (action));
3032 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3035 modest_msg_edit_window_select_background_color (window);
3039 modest_ui_actions_on_insert_image (GtkAction *action,
3040 ModestMsgEditWindow *window)
3042 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3043 g_return_if_fail (GTK_IS_ACTION (action));
3046 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3049 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3052 modest_msg_edit_window_insert_image (window);
3056 modest_ui_actions_on_attach_file (GtkAction *action,
3057 ModestMsgEditWindow *window)
3059 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3060 g_return_if_fail (GTK_IS_ACTION (action));
3062 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3065 modest_msg_edit_window_offer_attach_file (window);
3069 modest_ui_actions_on_remove_attachments (GtkAction *action,
3070 ModestMsgEditWindow *window)
3072 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3073 g_return_if_fail (GTK_IS_ACTION (action));
3075 modest_msg_edit_window_remove_attachments (window, NULL);
3079 #ifndef MODEST_TOOLKIT_GTK
3084 TnyFolderStore *folder;
3085 } CreateFolderHelper;
3088 show_create_folder_in_timeout (gpointer data)
3090 CreateFolderHelper *helper = (CreateFolderHelper *) data;
3092 /* Remove the timeout ASAP, we can not wait until the dialog
3093 is shown because it could take a lot of time and so the
3094 timeout could be called twice or more times */
3095 g_source_remove (helper->handler);
3097 gdk_threads_enter ();
3098 do_create_folder (helper->win, helper->folder, helper->name);
3099 gdk_threads_leave ();
3101 g_object_unref (helper->win);
3102 g_object_unref (helper->folder);
3103 g_free (helper->name);
3104 g_slice_free (CreateFolderHelper, helper);
3111 do_create_folder_cb (ModestMailOperation *mail_op,
3112 TnyFolderStore *parent_folder,
3113 TnyFolder *new_folder,
3116 gchar *suggested_name = (gchar *) user_data;
3117 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3119 if (modest_mail_operation_get_error (mail_op)) {
3121 /* Show an error. If there was some problem writing to
3122 disk, show it, otherwise show the generic folder
3123 create error. We do it here and not in an error
3124 handler because the call to do_create_folder will
3125 stop the main loop in a gtk_dialog_run and then,
3126 the message won't be shown until that dialog is
3128 modest_ui_actions_disk_operations_error_handler (mail_op,
3129 _("mail_in_ui_folder_create_error"));
3131 /* Try again. Do *NOT* show any error because the mail
3132 operations system will do it for us because we
3133 created the mail_op with new_with_error_handler */
3134 #ifndef MODEST_TOOLKIT_GTK
3135 CreateFolderHelper *helper;
3136 helper = g_slice_new0 (CreateFolderHelper);
3137 helper->name = g_strdup (suggested_name);
3138 helper->folder = g_object_ref (parent_folder);
3139 helper->win = g_object_ref (source_win);
3141 /* Ugly but neccesary stuff. The problem is that the
3142 dialog when is shown calls a function that destroys
3143 all the temporary windows, so the banner is
3145 helper->handler = g_timeout_add (2000, show_create_folder_in_timeout, helper);
3147 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3150 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3151 * FIXME: any other? */
3152 GtkWidget *folder_view;
3154 if (MODEST_IS_MAIN_WINDOW(source_win))
3156 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3157 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3160 get_folder_view_from_move_to_dialog (GTK_WIDGET(source_win));
3162 /* Select the newly created folder. It could happen
3163 that the widget is no longer there (i.e. the window
3164 has been destroyed, so we need to check this */
3166 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3168 g_object_unref (new_folder);
3170 /* Free. Note that the first time it'll be NULL so noop */
3171 g_free (suggested_name);
3172 g_object_unref (source_win);
3176 do_create_folder (GtkWindow *parent_window,
3177 TnyFolderStore *parent_folder,
3178 const gchar *suggested_name)
3181 gchar *folder_name = NULL;
3183 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3185 (gchar *) suggested_name,
3188 if (result == GTK_RESPONSE_ACCEPT) {
3189 ModestMailOperation *mail_op;
3191 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3192 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3194 modest_mail_operation_create_folder (mail_op,
3196 (const gchar *) folder_name,
3197 do_create_folder_cb,
3199 g_object_unref (mail_op);
3204 create_folder_performer (gboolean canceled,
3206 GtkWindow *parent_window,
3207 TnyAccount *account,
3210 TnyFolderStore *parent_folder = TNY_FOLDER_STORE (user_data);
3212 if (canceled || err) {
3213 /* In memory full conditions we could get this error here */
3214 check_memory_full_error ((GtkWidget *) parent_window, err);
3218 /* Run the new folder dialog */
3219 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3222 g_object_unref (parent_folder);
3226 modest_ui_actions_create_folder(GtkWidget *parent_window,
3227 GtkWidget *folder_view)
3229 TnyFolderStore *parent_folder;
3231 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3233 if (parent_folder) {
3234 /* The parent folder will be freed in the callback */
3235 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3238 create_folder_performer,
3244 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
3246 GtkWidget *folder_view;
3248 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3250 folder_view = modest_main_window_get_child_widget (main_window,
3251 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3255 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
3259 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3262 const GError *error = NULL;
3263 const gchar *message = NULL;
3265 /* Get error message */
3266 error = modest_mail_operation_get_error (mail_op);
3268 g_return_if_reached ();
3270 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3271 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3272 message = _CS("ckdg_ib_folder_already_exists");
3273 } else if (error->domain == TNY_ERROR_DOMAIN &&
3274 error->code == TNY_SERVICE_ERROR_STATE) {
3275 /* This means that the folder is already in use (a
3276 message is opened for example */
3277 message = _("emev_ni_internal_error");
3279 message = _("emev_ib_ui_imap_unable_to_rename");
3282 /* We don't set a parent for the dialog because the dialog
3283 will be destroyed so the banner won't appear */
3284 modest_platform_information_banner (NULL, NULL, message);
3288 TnyFolderStore *folder;
3293 on_rename_folder_cb (ModestMailOperation *mail_op,
3294 TnyFolder *new_folder,
3297 ModestFolderView *folder_view;
3299 /* If the window was closed when renaming a folder this could
3301 if (!MODEST_IS_FOLDER_VIEW (user_data))
3304 folder_view = MODEST_FOLDER_VIEW (user_data);
3305 /* Note that if the rename fails new_folder will be NULL */
3307 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3309 modest_folder_view_select_first_inbox_or_local (folder_view);
3311 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3315 on_rename_folder_performer (gboolean canceled,
3317 GtkWindow *parent_window,
3318 TnyAccount *account,
3321 ModestMailOperation *mail_op = NULL;
3322 GtkTreeSelection *sel = NULL;
3323 GtkWidget *folder_view = NULL;
3324 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3326 if (canceled || err) {
3327 /* In memory full conditions we could get this error here */
3328 check_memory_full_error ((GtkWidget *) parent_window, err);
3329 } else if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3331 folder_view = modest_main_window_get_child_widget (
3332 MODEST_MAIN_WINDOW (parent_window),
3333 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3336 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3337 modest_ui_actions_rename_folder_error_handler,
3338 parent_window, NULL);
3340 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3343 /* Clear the headers view */
3344 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3345 gtk_tree_selection_unselect_all (sel);
3347 /* Actually rename the folder */
3348 modest_mail_operation_rename_folder (mail_op,
3349 TNY_FOLDER (data->folder),
3350 (const gchar *) (data->new_name),
3351 on_rename_folder_cb,
3353 g_object_unref (data->folder);
3354 g_object_unref (mail_op);
3357 g_free (data->new_name);
3362 modest_ui_actions_on_rename_folder (GtkAction *action,
3363 ModestMainWindow *main_window)
3365 TnyFolderStore *folder;
3366 GtkWidget *folder_view;
3367 GtkWidget *header_view;
3369 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3371 folder_view = modest_main_window_get_child_widget (main_window,
3372 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3376 header_view = modest_main_window_get_child_widget (main_window,
3377 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3382 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3387 if (TNY_IS_FOLDER (folder)) {
3388 gchar *folder_name = NULL;
3390 const gchar *current_name;
3391 TnyFolderStore *parent;
3392 gboolean do_rename = TRUE;
3394 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3395 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3396 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
3397 parent, current_name,
3399 g_object_unref (parent);
3401 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3404 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3405 rename_folder_data->folder = g_object_ref (folder);
3406 rename_folder_data->new_name = folder_name;
3407 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(main_window), TRUE,
3408 folder, on_rename_folder_performer, rename_folder_data);
3411 g_object_unref (folder);
3415 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3418 GObject *win = modest_mail_operation_get_source (mail_op);
3420 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3421 _("mail_in_ui_folder_delete_error"),
3423 g_object_unref (win);
3427 TnyFolderStore *folder;
3428 gboolean move_to_trash;
3432 on_delete_folder_cb (gboolean canceled,
3434 GtkWindow *parent_window,
3435 TnyAccount *account,
3438 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3439 GtkWidget *folder_view;
3440 ModestMailOperation *mail_op;
3441 GtkTreeSelection *sel;
3443 if (!MODEST_IS_MAIN_WINDOW(parent_window) || canceled || (err!=NULL)) {
3444 g_object_unref (G_OBJECT (info->folder));
3449 folder_view = modest_main_window_get_child_widget (
3450 MODEST_MAIN_WINDOW (parent_window),
3451 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3453 /* Unselect the folder before deleting it to free the headers */
3454 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3455 gtk_tree_selection_unselect_all (sel);
3457 /* Create the mail operation */
3459 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3460 modest_ui_actions_delete_folder_error_handler,
3463 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3465 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3467 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3469 g_object_unref (G_OBJECT (mail_op));
3470 g_object_unref (G_OBJECT (info->folder));
3475 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
3477 TnyFolderStore *folder;
3478 GtkWidget *folder_view;
3482 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3484 folder_view = modest_main_window_get_child_widget (main_window,
3485 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3489 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3491 /* Show an error if it's an account */
3492 if (!TNY_IS_FOLDER (folder)) {
3493 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
3494 _("mail_in_ui_folder_delete_error"),
3496 g_object_unref (G_OBJECT (folder));
3501 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3502 tny_folder_get_name (TNY_FOLDER (folder)));
3503 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
3504 (const gchar *) message);
3507 if (response == GTK_RESPONSE_OK) {
3508 DeleteFolderInfo *info;
3509 info = g_new0(DeleteFolderInfo, 1);
3510 info->folder = folder;
3511 info->move_to_trash = move_to_trash;
3512 g_object_ref (G_OBJECT (info->folder));
3513 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder));
3514 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (main_window),
3516 TNY_FOLDER_STORE (account),
3517 on_delete_folder_cb, info);
3518 g_object_unref (account);
3520 g_object_unref (G_OBJECT (folder));
3524 modest_ui_actions_on_delete_folder (GtkAction *action,
3525 ModestMainWindow *main_window)
3527 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3529 delete_folder (main_window, FALSE);
3533 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3535 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3537 delete_folder (main_window, TRUE);
3541 typedef struct _PasswordDialogFields {
3542 GtkWidget *username;
3543 GtkWidget *password;
3545 } PasswordDialogFields;
3548 password_dialog_check_field (GtkEditable *editable,
3549 PasswordDialogFields *fields)
3552 gboolean any_value_empty = FALSE;
3554 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
3555 if ((value == NULL) || value[0] == '\0') {
3556 any_value_empty = TRUE;
3558 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
3559 if ((value == NULL) || value[0] == '\0') {
3560 any_value_empty = TRUE;
3562 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3566 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3567 const gchar* server_account_name,
3572 ModestMainWindow *main_window)
3574 g_return_if_fail(server_account_name);
3575 gboolean completed = FALSE;
3576 PasswordDialogFields *fields = NULL;
3578 /* Initalize output parameters: */
3585 #ifndef MODEST_TOOLKIT_GTK
3586 /* Maemo uses a different (awkward) button order,
3587 * It should probably just use gtk_alternative_dialog_button_order ().
3589 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3592 _("mcen_bd_dialog_ok"),
3593 GTK_RESPONSE_ACCEPT,
3594 _("mcen_bd_dialog_cancel"),
3595 GTK_RESPONSE_REJECT,
3598 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3602 GTK_RESPONSE_REJECT,
3604 GTK_RESPONSE_ACCEPT,
3606 #endif /* !MODEST_TOOLKIT_GTK */
3608 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3610 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3611 modest_runtime_get_account_mgr(), server_account_name);
3612 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3613 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3616 gtk_widget_destroy (dialog);
3620 /* This causes a warning because the logical ID has no %s in it,
3621 * though the translation does, but there is not much we can do about that: */
3622 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3623 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
3626 g_free (server_name);
3630 gchar *initial_username = modest_account_mgr_get_server_account_username (
3631 modest_runtime_get_account_mgr(), server_account_name);
3633 GtkWidget *entry_username = gtk_entry_new ();
3634 if (initial_username)
3635 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
3636 /* Dim this if a connection has ever succeeded with this username,
3637 * as per the UI spec: */
3638 /* const gboolean username_known = */
3639 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3640 /* modest_runtime_get_account_mgr(), server_account_name); */
3641 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3643 /* We drop the username sensitive code and disallow changing it here
3644 * as tinymail does not support really changing the username in the callback
3646 gtk_widget_set_sensitive (entry_username, FALSE);
3648 #ifndef MODEST_TOOLKIT_GTK
3649 /* Auto-capitalization is the default, so let's turn it off: */
3650 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3652 /* Create a size group to be used by all captions.
3653 * Note that HildonCaption does not create a default size group if we do not specify one.
3654 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3655 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3657 GtkWidget *caption = hildon_caption_new (sizegroup,
3658 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
3659 gtk_widget_show (entry_username);
3660 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3661 FALSE, FALSE, MODEST_MARGIN_HALF);
3662 gtk_widget_show (caption);
3664 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
3666 #endif /* !MODEST_TOOLKIT_GTK */
3669 GtkWidget *entry_password = gtk_entry_new ();
3670 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3671 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3673 #ifndef MODEST_TOOLKIT_GTK
3674 /* Auto-capitalization is the default, so let's turn it off: */
3675 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3676 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3678 caption = hildon_caption_new (sizegroup,
3679 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
3680 gtk_widget_show (entry_password);
3681 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3682 FALSE, FALSE, MODEST_MARGIN_HALF);
3683 gtk_widget_show (caption);
3684 g_object_unref (sizegroup);
3686 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
3688 #endif /* !MODEST_TOOLKIT_GTK */
3690 if (initial_username != NULL)
3691 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3693 /* This is not in the Maemo UI spec:
3694 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3695 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3699 fields = g_slice_new0 (PasswordDialogFields);
3700 fields->username = entry_username;
3701 fields->password = entry_password;
3702 fields->dialog = dialog;
3704 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3705 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3706 password_dialog_check_field (NULL, fields);
3708 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3710 while (!completed) {
3712 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3714 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
3716 /* Note that an empty field becomes the "" string */
3717 if (*username && strlen (*username) > 0) {
3718 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
3719 server_account_name,
3723 const gboolean username_was_changed =
3724 (strcmp (*username, initial_username) != 0);
3725 if (username_was_changed) {
3726 g_warning ("%s: tinymail does not yet support changing the "
3727 "username in the get_password() callback.\n", __FUNCTION__);
3732 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
3733 _("mcen_ib_username_pw_incorrect"));
3739 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
3741 /* We do not save the password in the configuration,
3742 * because this function is only called for passwords that should
3743 * not be remembered:
3744 modest_server_account_set_password (
3745 modest_runtime_get_account_mgr(), server_account_name,
3752 /* Set parent to NULL or the banner will disappear with its parent dialog */
3753 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
3764 /* This is not in the Maemo UI spec:
3765 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3771 g_free (initial_username);
3772 gtk_widget_destroy (dialog);
3773 g_slice_free (PasswordDialogFields, fields);
3775 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3779 modest_ui_actions_on_cut (GtkAction *action,
3780 ModestWindow *window)
3782 GtkWidget *focused_widget;
3783 GtkClipboard *clipboard;
3785 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3786 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3787 if (GTK_IS_EDITABLE (focused_widget)) {
3788 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3789 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3790 gtk_clipboard_store (clipboard);
3791 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3792 GtkTextBuffer *buffer;
3794 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3795 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3796 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3797 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3798 gtk_clipboard_store (clipboard);
3800 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3801 TnyList *header_list = modest_header_view_get_selected_headers (
3802 MODEST_HEADER_VIEW (focused_widget));
3803 gboolean continue_download = FALSE;
3804 gint num_of_unc_msgs;
3806 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3808 if (num_of_unc_msgs) {
3809 TnyAccount *account = get_account_from_header_list (header_list);
3811 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3812 g_object_unref (account);
3816 if (num_of_unc_msgs == 0 || continue_download) {
3817 /* modest_platform_information_banner (
3818 NULL, NULL, _CS("mcen_ib_getting_items"));*/
3819 modest_header_view_cut_selection (
3820 MODEST_HEADER_VIEW (focused_widget));
3823 g_object_unref (header_list);
3824 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3825 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3830 modest_ui_actions_on_copy (GtkAction *action,
3831 ModestWindow *window)
3833 GtkClipboard *clipboard;
3834 GtkWidget *focused_widget;
3835 gboolean copied = TRUE;
3837 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3838 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3840 if (GTK_IS_LABEL (focused_widget)) {
3842 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
3843 gtk_clipboard_set_text (clipboard, selection, -1);
3845 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3846 gtk_clipboard_store (clipboard);
3847 } else if (GTK_IS_EDITABLE (focused_widget)) {
3848 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3849 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3850 gtk_clipboard_store (clipboard);
3851 } else if (GTK_IS_HTML (focused_widget)) {
3854 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
3855 if ((sel == NULL) || (sel[0] == '\0')) {
3858 gtk_html_copy (GTK_HTML (focused_widget));
3859 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3860 gtk_clipboard_store (clipboard);
3862 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3863 GtkTextBuffer *buffer;
3864 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3865 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3866 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3867 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3868 gtk_clipboard_store (clipboard);
3870 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3871 TnyList *header_list = modest_header_view_get_selected_headers (
3872 MODEST_HEADER_VIEW (focused_widget));
3873 gboolean continue_download = FALSE;
3874 gint num_of_unc_msgs;
3876 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3878 if (num_of_unc_msgs) {
3879 TnyAccount *account = get_account_from_header_list (header_list);
3881 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3882 g_object_unref (account);
3886 if (num_of_unc_msgs == 0 || continue_download) {
3887 modest_platform_information_banner (
3888 NULL, NULL, _CS("mcen_ib_getting_items"));
3889 modest_header_view_copy_selection (
3890 MODEST_HEADER_VIEW (focused_widget));
3894 g_object_unref (header_list);
3896 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3897 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3900 /* Show information banner if there was a copy to clipboard */
3902 modest_platform_information_banner (
3903 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3907 modest_ui_actions_on_undo (GtkAction *action,
3908 ModestWindow *window)
3910 ModestEmailClipboard *clipboard = NULL;
3912 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3913 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3914 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3915 /* Clear clipboard source */
3916 clipboard = modest_runtime_get_email_clipboard ();
3917 modest_email_clipboard_clear (clipboard);
3920 g_return_if_reached ();
3925 modest_ui_actions_on_redo (GtkAction *action,
3926 ModestWindow *window)
3928 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3929 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3932 g_return_if_reached ();
3938 destroy_information_note (ModestMailOperation *mail_op,
3941 /* destroy information note */
3942 gtk_widget_destroy (GTK_WIDGET(user_data));
3946 destroy_folder_information_note (ModestMailOperation *mail_op,
3947 TnyFolder *new_folder,
3950 /* destroy information note */
3951 gtk_widget_destroy (GTK_WIDGET(user_data));
3956 paste_as_attachment_free (gpointer data)
3958 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3960 if (helper->banner) {
3961 gtk_widget_destroy (helper->banner);
3962 g_object_unref (helper->banner);
3968 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3973 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3974 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3979 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3984 modest_ui_actions_on_paste (GtkAction *action,
3985 ModestWindow *window)
3987 GtkWidget *focused_widget = NULL;
3988 GtkWidget *inf_note = NULL;
3989 ModestMailOperation *mail_op = NULL;
3991 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3992 if (GTK_IS_EDITABLE (focused_widget)) {
3993 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3994 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3995 ModestEmailClipboard *e_clipboard = NULL;
3996 e_clipboard = modest_runtime_get_email_clipboard ();
3997 if (modest_email_clipboard_cleared (e_clipboard)) {
3998 GtkTextBuffer *buffer;
3999 GtkClipboard *clipboard;
4001 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4002 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4003 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4004 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4005 ModestMailOperation *mail_op;
4006 TnyFolder *src_folder = NULL;
4007 TnyList *data = NULL;
4009 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4010 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4011 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4012 _CS("ckct_nw_pasting"));
4013 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4014 mail_op = modest_mail_operation_new (G_OBJECT (window));
4015 if (helper->banner != NULL) {
4016 g_object_ref (G_OBJECT (helper->banner));
4017 gtk_widget_show (GTK_WIDGET (helper->banner));
4021 modest_mail_operation_get_msgs_full (mail_op,
4023 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4025 paste_as_attachment_free);
4029 g_object_unref (data);
4031 g_object_unref (src_folder);
4034 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4035 ModestEmailClipboard *clipboard = NULL;
4036 TnyFolder *src_folder = NULL;
4037 TnyFolderStore *folder_store = NULL;
4038 TnyList *data = NULL;
4039 gboolean delete = FALSE;
4041 /* Check clipboard source */
4042 clipboard = modest_runtime_get_email_clipboard ();
4043 if (modest_email_clipboard_cleared (clipboard))
4046 /* Get elements to paste */
4047 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4049 /* Create a new mail operation */
4050 mail_op = modest_mail_operation_new (G_OBJECT(window));
4052 /* Get destination folder */
4053 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4055 /* transfer messages */
4059 /* Ask for user confirmation */
4061 modest_ui_actions_msgs_move_to_confirmation (window,
4062 TNY_FOLDER (folder_store),
4066 if (response == GTK_RESPONSE_OK) {
4067 /* Launch notification */
4068 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4069 _CS("ckct_nw_pasting"));
4070 if (inf_note != NULL) {
4071 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4072 gtk_widget_show (GTK_WIDGET(inf_note));
4075 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4076 modest_mail_operation_xfer_msgs (mail_op,
4078 TNY_FOLDER (folder_store),
4080 destroy_information_note,
4083 g_object_unref (mail_op);
4086 } else if (src_folder != NULL) {
4087 /* Launch notification */
4088 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4089 _CS("ckct_nw_pasting"));
4090 if (inf_note != NULL) {
4091 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4092 gtk_widget_show (GTK_WIDGET(inf_note));
4095 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4096 modest_mail_operation_xfer_folder (mail_op,
4100 destroy_folder_information_note,
4106 g_object_unref (data);
4107 if (src_folder != NULL)
4108 g_object_unref (src_folder);
4109 if (folder_store != NULL)
4110 g_object_unref (folder_store);
4116 modest_ui_actions_on_select_all (GtkAction *action,
4117 ModestWindow *window)
4119 GtkWidget *focused_widget;
4121 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4122 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4123 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4124 } else if (GTK_IS_LABEL (focused_widget)) {
4125 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4126 } else if (GTK_IS_EDITABLE (focused_widget)) {
4127 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4128 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4129 GtkTextBuffer *buffer;
4130 GtkTextIter start, end;
4132 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4133 gtk_text_buffer_get_start_iter (buffer, &start);
4134 gtk_text_buffer_get_end_iter (buffer, &end);
4135 gtk_text_buffer_select_range (buffer, &start, &end);
4136 } else if (GTK_IS_HTML (focused_widget)) {
4137 gtk_html_select_all (GTK_HTML (focused_widget));
4138 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4139 GtkWidget *header_view = focused_widget;
4140 GtkTreeSelection *selection = NULL;
4142 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4143 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4144 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4147 /* Disable window dimming management */
4148 modest_window_disable_dimming (MODEST_WINDOW(window));
4150 /* Select all messages */
4151 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4152 gtk_tree_selection_select_all (selection);
4154 /* Set focuse on header view */
4155 gtk_widget_grab_focus (header_view);
4157 /* Enable window dimming management */
4158 modest_window_enable_dimming (MODEST_WINDOW(window));
4159 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4160 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4166 modest_ui_actions_on_mark_as_read (GtkAction *action,
4167 ModestWindow *window)
4169 g_return_if_fail (MODEST_IS_WINDOW(window));
4171 /* Mark each header as read */
4172 do_headers_action (window, headers_action_mark_as_read, NULL);
4176 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4177 ModestWindow *window)
4179 g_return_if_fail (MODEST_IS_WINDOW(window));
4181 /* Mark each header as read */
4182 do_headers_action (window, headers_action_mark_as_unread, NULL);
4186 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4187 GtkRadioAction *selected,
4188 ModestWindow *window)
4192 value = gtk_radio_action_get_current_value (selected);
4193 if (MODEST_IS_WINDOW (window)) {
4194 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4199 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4200 GtkRadioAction *selected,
4201 ModestWindow *window)
4203 TnyHeaderFlags flags;
4204 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4206 flags = gtk_radio_action_get_current_value (selected);
4207 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4211 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4212 GtkRadioAction *selected,
4213 ModestWindow *window)
4217 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4219 file_format = gtk_radio_action_get_current_value (selected);
4220 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4225 modest_ui_actions_on_zoom_plus (GtkAction *action,
4226 ModestWindow *window)
4228 g_return_if_fail (MODEST_IS_WINDOW (window));
4230 modest_window_zoom_plus (MODEST_WINDOW (window));
4234 modest_ui_actions_on_zoom_minus (GtkAction *action,
4235 ModestWindow *window)
4237 g_return_if_fail (MODEST_IS_WINDOW (window));
4239 modest_window_zoom_minus (MODEST_WINDOW (window));
4243 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4244 ModestWindow *window)
4246 ModestWindowMgr *mgr;
4247 gboolean fullscreen, active;
4248 g_return_if_fail (MODEST_IS_WINDOW (window));
4250 mgr = modest_runtime_get_window_mgr ();
4252 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4253 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4255 if (active != fullscreen) {
4256 modest_window_mgr_set_fullscreen_mode (mgr, active);
4257 #ifndef MODEST_TOOLKIT_HILDON2
4258 gtk_window_present (GTK_WINDOW (window));
4264 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4265 ModestWindow *window)
4267 ModestWindowMgr *mgr;
4268 gboolean fullscreen;
4270 g_return_if_fail (MODEST_IS_WINDOW (window));
4272 mgr = modest_runtime_get_window_mgr ();
4273 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4274 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4276 #ifndef MODEST_TOOLKIT_HILDON2
4277 gtk_window_present (GTK_WINDOW (window));
4282 * Used by modest_ui_actions_on_details to call do_headers_action
4285 headers_action_show_details (TnyHeader *header,
4286 ModestWindow *window,
4290 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header);
4294 * Show the header details in a ModestDetailsDialog widget
4297 modest_ui_actions_on_details (GtkAction *action,
4300 TnyList * headers_list;
4304 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4307 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4310 g_object_unref (msg);
4312 headers_list = get_selected_headers (win);
4316 iter = tny_list_create_iterator (headers_list);
4318 header = TNY_HEADER (tny_iterator_get_current (iter));
4320 headers_action_show_details (header, win, NULL);
4321 g_object_unref (header);
4324 g_object_unref (iter);
4325 g_object_unref (headers_list);
4327 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4328 GtkWidget *folder_view, *header_view;
4330 /* Check which widget has the focus */
4331 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4332 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4333 if (gtk_widget_is_focus (folder_view)) {
4334 TnyFolderStore *folder_store
4335 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4336 if (!folder_store) {
4337 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4340 /* Show only when it's a folder */
4341 /* This function should not be called for account items,
4342 * because we dim the menu item for them. */
4343 if (TNY_IS_FOLDER (folder_store)) {
4344 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4345 TNY_FOLDER (folder_store));
4348 g_object_unref (folder_store);
4351 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4352 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4353 /* Show details of each header */
4354 do_headers_action (win, headers_action_show_details, header_view);
4356 #ifdef MODEST_TOOLKIT_HILDON2
4357 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4359 GtkWidget *header_view;
4361 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4362 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4364 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4366 g_object_unref (folder);
4373 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4374 ModestMsgEditWindow *window)
4376 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4378 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4382 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4383 ModestMsgEditWindow *window)
4385 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4387 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4391 modest_ui_actions_toggle_folders_view (GtkAction *action,
4392 ModestMainWindow *main_window)
4394 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4396 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4397 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4399 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4403 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4404 ModestWindow *window)
4406 gboolean active, fullscreen = FALSE;
4407 ModestWindowMgr *mgr;
4409 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4411 /* Check if we want to toggle the toolbar view in fullscreen
4413 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4414 "ViewShowToolbarFullScreen")) {
4418 /* Toggle toolbar */
4419 mgr = modest_runtime_get_window_mgr ();
4420 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4424 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4425 ModestMsgEditWindow *window)
4427 modest_msg_edit_window_select_font (window);
4432 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4433 const gchar *display_name,
4436 /* don't update the display name if it was already set;
4437 * updating the display name apparently is expensive */
4438 const gchar* old_name = gtk_window_get_title (window);
4440 if (display_name == NULL)
4443 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4444 return; /* don't do anything */
4446 /* This is usually used to change the title of the main window, which
4447 * is the one that holds the folder view. Note that this change can
4448 * happen even when the widget doesn't have the focus. */
4449 gtk_window_set_title (window, display_name);
4454 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4456 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4457 modest_msg_edit_window_select_contacts (window);
4461 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4463 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4464 modest_msg_edit_window_check_names (window, FALSE);
4468 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
4470 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
4471 GTK_WIDGET (user_data));
4475 * This function is used to track changes in the selection of the
4476 * folder view that is inside the "move to" dialog to enable/disable
4477 * the OK button because we do not want the user to select a disallowed
4478 * destination for a folder.
4479 * The user also not desired to be able to use NEW button on items where
4480 * folder creation is not possibel.
4483 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4484 TnyFolderStore *folder_store,
4488 GtkWidget *dialog = NULL;
4489 GtkWidget *ok_button = NULL, *new_button = NULL;
4490 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4491 gboolean moving_folder = FALSE;
4492 gboolean is_local_account = TRUE;
4493 GtkWidget *folder_view = NULL;
4494 ModestTnyFolderRules rules;
4496 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
4501 /* Get the OK button */
4502 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
4506 ok_button = g_object_get_data (G_OBJECT (dialog), MOVE_FOLDER_OK_BUTTON);
4507 new_button = g_object_get_data (G_OBJECT (dialog), MOVE_FOLDER_NEW_BUTTON);
4509 /* check if folder_store is an remote account */
4510 if (TNY_IS_ACCOUNT (folder_store)) {
4511 TnyAccount *local_account = NULL;
4512 TnyAccount *mmc_account = NULL;
4513 ModestTnyAccountStore *account_store = NULL;
4515 account_store = modest_runtime_get_account_store ();
4516 local_account = modest_tny_account_store_get_local_folders_account (account_store);
4517 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
4519 if ((gpointer) local_account != (gpointer) folder_store &&
4520 (gpointer) mmc_account != (gpointer) folder_store) {
4521 ModestProtocolType proto;
4522 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
4523 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
4524 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
4526 is_local_account = FALSE;
4527 /* New button should be dimmed on remote
4529 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4531 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
4533 g_object_unref (local_account);
4535 /* It could not exist */
4537 g_object_unref (mmc_account);
4540 /* Check the target folder rules */
4541 if (TNY_IS_FOLDER (folder_store)) {
4542 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
4543 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
4544 ok_sensitive = FALSE;
4545 new_sensitive = FALSE;
4550 /* Check if we're moving a folder */
4551 if (MODEST_IS_MAIN_WINDOW (user_data)) {
4552 /* Get the widgets */
4553 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
4554 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4555 if (gtk_widget_is_focus (folder_view))
4556 moving_folder = TRUE;
4559 if (moving_folder) {
4560 TnyFolderStore *moved_folder = NULL, *parent = NULL;
4562 /* Get the folder to move */
4563 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4565 /* Check that we're not moving to the same folder */
4566 if (TNY_IS_FOLDER (moved_folder)) {
4567 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
4568 if (parent == folder_store)
4569 ok_sensitive = FALSE;
4570 g_object_unref (parent);
4573 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
4574 /* Do not allow to move to an account unless it's the
4575 local folders account */
4576 if (!is_local_account)
4577 ok_sensitive = FALSE;
4580 if (ok_sensitive && (moved_folder == folder_store)) {
4581 /* Do not allow to move to itself */
4582 ok_sensitive = FALSE;
4584 g_object_unref (moved_folder);
4586 TnyFolder *src_folder = NULL;
4588 /* Moving a message */
4589 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
4591 TnyHeader *header = NULL;
4592 header = modest_msg_view_window_get_header
4593 (MODEST_MSG_VIEW_WINDOW (user_data));
4594 if (!TNY_IS_HEADER(header))
4595 g_warning ("%s: could not get source header", __FUNCTION__);
4597 src_folder = tny_header_get_folder (header);
4600 g_object_unref (header);
4603 TNY_FOLDER (modest_folder_view_get_selected
4604 (MODEST_FOLDER_VIEW (folder_view)));
4607 if (TNY_IS_FOLDER(src_folder)) {
4608 /* Do not allow to move the msg to the same folder */
4609 /* Do not allow to move the msg to an account */
4610 if ((gpointer) src_folder == (gpointer) folder_store ||
4611 TNY_IS_ACCOUNT (folder_store))
4612 ok_sensitive = FALSE;
4613 g_object_unref (src_folder);
4615 g_warning ("%s: could not get source folder", __FUNCTION__);
4619 /* Set sensitivity of the OK button */
4620 gtk_widget_set_sensitive (ok_button, ok_sensitive);
4621 /* Set sensitivity of the NEW button */
4622 gtk_widget_set_sensitive (new_button, new_sensitive);
4626 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
4629 get_folder_view_from_move_to_dialog (GtkWidget *move_to_dialog)
4631 return GTK_WIDGET(g_object_get_data (G_OBJECT(move_to_dialog),
4632 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4636 create_move_to_dialog (GtkWindow *win,
4637 GtkWidget *folder_view,
4638 GtkWidget **tree_view)
4641 #ifdef MODEST_TOOLKIT_HILDON2
4642 GtkWidget *pannable;
4646 GtkWidget *new_button, *ok_button;
4648 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
4650 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
4653 #ifndef MODEST_TOOLKIT_GTK
4654 ok_button = gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
4655 /* We do this manually so GTK+ does not associate a response ID for
4657 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
4658 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
4659 gtk_widget_show (new_button);
4660 #ifndef MODEST_TOOLKIT_HILDON2
4661 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
4664 /* We do this manually so GTK+ does not associate a response ID for
4666 new_button = gtk_button_new_with_label (_("mcen_ti_new_folder"));
4667 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
4668 gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (GTK_DIALOG (dialog)->action_area), new_button, TRUE);
4669 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
4670 ok_button = gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
4671 gtk_container_set_border_width (GTK_CONTAINER (dialog), 12);
4672 gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 24);
4674 g_object_set_data (G_OBJECT (dialog), MOVE_FOLDER_OK_BUTTON, ok_button);
4675 g_object_set_data (G_OBJECT (dialog), MOVE_FOLDER_NEW_BUTTON, new_button);
4677 /* Create scrolled window */
4678 #ifdef MODEST_TOOLKIT_HILDON2
4679 pannable = hildon_pannable_area_new ();
4681 scroll = gtk_scrolled_window_new (NULL, NULL);
4682 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
4683 GTK_POLICY_AUTOMATIC,
4684 GTK_POLICY_AUTOMATIC);
4687 #ifdef MODEST_TOOLKIT_GTK
4688 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN);
4691 /* Create folder view */
4692 *tree_view = modest_platform_create_folder_view (NULL);
4694 /* Track changes in the selection to
4695 * disable the OK button whenever "Move to" is not possible
4696 * disbale NEW button whenever New is not possible */
4697 g_signal_connect (*tree_view,
4698 "folder_selection_changed",
4699 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
4702 /* Listen to clicks on New button */
4703 g_signal_connect (G_OBJECT (new_button),
4705 G_CALLBACK(create_move_to_dialog_on_new_folder),
4708 /* It could happen that we're trying to move a message from a
4709 window (msg window for example) after the main window was
4710 closed, so we can not just get the model of the folder
4712 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4713 const gchar *visible_id = NULL;
4715 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4716 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4717 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4718 MODEST_FOLDER_VIEW(*tree_view));
4721 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4723 /* Show the same account than the one that is shown in the main window */
4724 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
4727 const gchar *active_account_name = NULL;
4728 ModestAccountMgr *mgr = NULL;
4729 ModestAccountSettings *settings = NULL;
4730 ModestServerAccountSettings *store_settings = NULL;
4732 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4733 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4734 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
4735 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
4737 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4738 mgr = modest_runtime_get_account_mgr ();
4739 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4742 const gchar *store_account_name;
4743 store_settings = modest_account_settings_get_store_settings (settings);
4744 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4746 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
4747 store_account_name);
4748 g_object_unref (store_settings);
4749 g_object_unref (settings);
4753 /* we keep a pointer to the embedded folder view, so we can retrieve it with
4754 * get_folder_view_from_move_to_dialog
4755 * (see above) later (needed for focus handling)
4757 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, *tree_view);
4760 /* Hide special folders */
4761 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
4763 #ifdef MODEST_TOOLKIT_HILDON2
4764 gtk_container_add (GTK_CONTAINER (pannable), *tree_view);
4765 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
4766 pannable, TRUE, TRUE, 0);
4768 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
4769 /* Add scroll to dialog */
4770 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
4771 scroll, TRUE, TRUE, 0);
4775 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4776 #ifndef MODEST_TOOLKIT_GTK
4777 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
4779 gtk_window_set_default_size (GTK_WINDOW (dialog), 600, 400);
4788 * Shows a confirmation dialog to the user when we're moving messages
4789 * from a remote server to the local storage. Returns the dialog
4790 * response. If it's other kind of movement then it always returns
4793 * This one is used by the next functions:
4794 * modest_ui_actions_on_paste - commented out
4795 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4798 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4799 TnyFolder *dest_folder,
4803 gint response = GTK_RESPONSE_OK;
4804 TnyAccount *account = NULL;
4805 TnyFolder *src_folder = NULL;
4806 TnyIterator *iter = NULL;
4807 TnyHeader *header = NULL;
4809 /* return with OK if the destination is a remote folder */
4810 if (modest_tny_folder_is_remote_folder (dest_folder))
4811 return GTK_RESPONSE_OK;
4813 /* Get source folder */
4814 iter = tny_list_create_iterator (headers);
4815 header = TNY_HEADER (tny_iterator_get_current (iter));
4817 src_folder = tny_header_get_folder (header);
4818 g_object_unref (header);
4820 g_object_unref (iter);
4822 /* if no src_folder, message may be an attahcment */
4823 if (src_folder == NULL)
4824 return GTK_RESPONSE_CANCEL;
4826 /* If the source is a local or MMC folder */
4827 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4828 g_object_unref (src_folder);
4829 return GTK_RESPONSE_OK;
4832 /* Get the account */
4833 account = tny_folder_get_account (src_folder);
4835 /* now if offline we ask the user */
4836 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4837 response = GTK_RESPONSE_OK;
4839 response = GTK_RESPONSE_CANCEL;
4842 g_object_unref (src_folder);
4843 g_object_unref (account);
4849 move_to_helper_destroyer (gpointer user_data)
4851 MoveToHelper *helper = (MoveToHelper *) user_data;
4853 /* Close the "Pasting" information banner */
4854 if (helper->banner) {
4855 gtk_widget_destroy (GTK_WIDGET (helper->banner));
4856 g_object_unref (helper->banner);
4858 if (gtk_tree_row_reference_valid (helper->reference)) {
4859 gtk_tree_row_reference_free (helper->reference);
4860 helper->reference = NULL;
4866 move_to_cb (ModestMailOperation *mail_op,
4869 MoveToHelper *helper = (MoveToHelper *) user_data;
4871 /* Note that the operation could have failed, in that case do
4873 if (modest_mail_operation_get_status (mail_op) ==
4874 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
4876 GObject *object = modest_mail_operation_get_source (mail_op);
4877 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4878 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4880 if (!modest_msg_view_window_select_next_message (self) &&
4881 !modest_msg_view_window_select_previous_message (self)) {
4882 /* No more messages to view, so close this window */
4883 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4885 } else if (MODEST_IS_MAIN_WINDOW (object) &&
4886 gtk_tree_row_reference_valid (helper->reference)) {
4887 GtkWidget *header_view;
4889 GtkTreeSelection *sel;
4891 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4892 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4893 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
4894 path = gtk_tree_row_reference_get_path (helper->reference);
4895 /* We need to unselect the previous one
4896 because we could be copying instead of
4898 gtk_tree_selection_unselect_all (sel);
4899 gtk_tree_selection_select_path (sel, path);
4900 gtk_tree_path_free (path);
4902 g_object_unref (object);
4904 /* Destroy the helper */
4905 move_to_helper_destroyer (helper);
4909 folder_move_to_cb (ModestMailOperation *mail_op,
4910 TnyFolder *new_folder,
4913 GtkWidget *folder_view;
4916 object = modest_mail_operation_get_source (mail_op);
4917 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4918 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4919 g_object_ref (folder_view);
4920 g_object_unref (object);
4921 move_to_cb (mail_op, user_data);
4922 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
4923 g_object_unref (folder_view);
4927 msgs_move_to_cb (ModestMailOperation *mail_op,
4930 move_to_cb (mail_op, user_data);
4934 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
4937 ModestWindow *main_window = NULL;
4939 /* Disable next automatic folder selection */
4940 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
4941 FALSE); /* don't create */
4943 GObject *win = NULL;
4944 GtkWidget *folder_view = NULL;
4946 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
4947 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4948 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
4950 if (user_data && TNY_IS_FOLDER (user_data)) {
4951 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
4952 TNY_FOLDER (user_data), FALSE);
4955 /* Show notification dialog only if the main window exists */
4956 win = modest_mail_operation_get_source (mail_op);
4957 modest_platform_run_information_dialog ((GtkWindow *) win,
4958 _("mail_in_ui_folder_move_target_error"),
4961 g_object_unref (win);
4966 open_msg_for_purge_cb (ModestMailOperation *mail_op,
4975 gint pending_purges = 0;
4976 gboolean some_purged = FALSE;
4977 ModestWindow *win = MODEST_WINDOW (user_data);
4978 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
4980 /* If there was any error */
4981 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
4982 modest_window_mgr_unregister_header (mgr, header);
4986 /* Once the message has been retrieved for purging, we check if
4987 * it's all ok for purging */
4989 parts = tny_simple_list_new ();
4990 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
4991 iter = tny_list_create_iterator (parts);
4993 while (!tny_iterator_is_done (iter)) {
4995 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4996 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
4997 if (tny_mime_part_is_purged (part))
5004 g_object_unref (part);
5006 tny_iterator_next (iter);
5008 g_object_unref (iter);
5011 if (pending_purges>0) {
5013 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5015 if (response == GTK_RESPONSE_OK) {
5018 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_ib_removing_attachment"));
5019 iter = tny_list_create_iterator (parts);
5020 while (!tny_iterator_is_done (iter)) {
5023 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5024 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5025 tny_mime_part_set_purged (part);
5028 g_object_unref (part);
5030 tny_iterator_next (iter);
5032 g_object_unref (iter);
5034 tny_msg_rewrite_cache (msg);
5036 gtk_widget_destroy (info);
5040 modest_window_mgr_unregister_header (mgr, header);
5042 g_object_unref (parts);
5046 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5047 ModestMainWindow *win)
5049 GtkWidget *header_view;
5050 TnyList *header_list;
5052 TnyHeaderFlags flags;
5053 ModestWindow *msg_view_window = NULL;
5056 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5058 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5059 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5061 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5063 g_warning ("%s: no header selected", __FUNCTION__);
5067 if (tny_list_get_length (header_list) == 1) {
5068 TnyIterator *iter = tny_list_create_iterator (header_list);
5069 header = TNY_HEADER (tny_iterator_get_current (iter));
5070 g_object_unref (iter);
5074 if (!header || !TNY_IS_HEADER(header)) {
5075 g_warning ("%s: header is not valid", __FUNCTION__);
5079 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5080 header, &msg_view_window);
5081 flags = tny_header_get_flags (header);
5082 if (!(flags & TNY_HEADER_FLAG_CACHED))
5085 if (msg_view_window != NULL)
5086 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5088 /* do nothing; uid was registered before, so window is probably on it's way */
5089 g_warning ("debug: header %p has already been registered", header);
5092 ModestMailOperation *mail_op = NULL;
5093 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5094 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5095 modest_ui_actions_disk_operations_error_handler,
5097 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5098 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5100 g_object_unref (mail_op);
5103 g_object_unref (header);
5105 g_object_unref (header_list);
5109 * Checks if we need a connection to do the transfer and if the user
5110 * wants to connect to complete it
5113 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5114 TnyFolderStore *src_folder,
5116 TnyFolder *dst_folder,
5117 gboolean delete_originals,
5118 gboolean *need_connection,
5121 TnyAccount *src_account;
5122 gint uncached_msgs = 0;
5124 uncached_msgs = header_list_count_uncached_msgs (headers);
5126 /* We don't need any further check if
5128 * 1- the source folder is local OR
5129 * 2- the device is already online
5131 if (!modest_tny_folder_store_is_remote (src_folder) ||
5132 tny_device_is_online (modest_runtime_get_device())) {
5133 *need_connection = FALSE;
5138 /* We must ask for a connection when
5140 * - the message(s) is not already cached OR
5141 * - the message(s) is cached but the leave_on_server setting
5142 * is FALSE (because we need to sync the source folder to
5143 * delete the message from the server (for IMAP we could do it
5144 * offline, it'll take place the next time we get a
5147 src_account = get_account_from_folder_store (src_folder);
5148 if (uncached_msgs > 0) {
5152 *need_connection = TRUE;
5153 num_headers = tny_list_get_length (headers);
5154 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5156 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5157 GTK_RESPONSE_CANCEL) {
5163 /* The transfer is possible and the user wants to */
5166 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5167 const gchar *account_name;
5168 gboolean leave_on_server;
5170 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5171 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5174 if (leave_on_server == TRUE) {
5175 *need_connection = FALSE;
5177 *need_connection = TRUE;
5180 *need_connection = FALSE;
5185 g_object_unref (src_account);
5189 xfer_messages_error_handler (ModestMailOperation *mail_op,
5192 ModestWindow *main_window = NULL;
5194 /* Disable next automatic folder selection */
5195 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5196 FALSE); /* don't create */
5198 GObject *win = modest_mail_operation_get_source (mail_op);
5199 modest_platform_run_information_dialog ((GtkWindow *) win,
5200 _("mail_in_ui_folder_move_target_error"),
5203 g_object_unref (win);
5205 move_to_helper_destroyer (user_data);
5209 TnyFolderStore *dst_folder;
5214 * Utility function that transfer messages from both the main window
5215 * and the msg view window when using the "Move to" dialog
5218 xfer_messages_performer (gboolean canceled,
5220 GtkWindow *parent_window,
5221 TnyAccount *account,
5224 ModestWindow *win = MODEST_WINDOW (parent_window);
5225 TnyAccount *dst_account = NULL;
5226 gboolean dst_forbids_message_add = FALSE;
5227 XferMsgsHelper *helper;
5228 MoveToHelper *movehelper;
5229 ModestMailOperation *mail_op;
5231 helper = (XferMsgsHelper *) user_data;
5233 if (canceled || err) {
5234 if (!check_memory_full_error ((GtkWidget *) parent_window, err)) {
5235 /* Show the proper error message */
5236 modest_ui_actions_on_account_connection_error (parent_window, account);
5241 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5243 /* tinymail will return NULL for local folders it seems */
5244 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5245 modest_tny_account_get_protocol_type (dst_account),
5246 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_MESSAGE_ADD);
5247 g_object_unref (dst_account);
5249 if (dst_forbids_message_add) {
5250 modest_platform_information_banner (GTK_WIDGET (win),
5252 ngettext("mail_in_ui_folder_move_target_error",
5253 "mail_in_ui_folder_move_targets_error",
5254 tny_list_get_length (helper->headers)));
5258 movehelper = g_new0 (MoveToHelper, 1);
5259 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5260 _CS("ckct_nw_pasting"));
5261 if (movehelper->banner != NULL) {
5262 g_object_ref (movehelper->banner);
5263 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5266 if (MODEST_IS_MAIN_WINDOW (win)) {
5267 GtkWidget *header_view =
5268 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5269 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5270 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5273 /* Perform the mail operation */
5274 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5275 xfer_messages_error_handler,
5277 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5280 modest_mail_operation_xfer_msgs (mail_op,
5282 TNY_FOLDER (helper->dst_folder),
5287 g_object_unref (G_OBJECT (mail_op));
5289 g_object_unref (helper->dst_folder);
5290 g_object_unref (helper->headers);
5291 g_slice_free (XferMsgsHelper, helper);
5295 TnyFolder *src_folder;
5296 TnyFolderStore *dst_folder;
5297 gboolean delete_original;
5298 GtkWidget *folder_view;
5302 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
5303 TnyAccount *account, gpointer user_data)
5305 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5306 GtkTreeSelection *sel;
5307 ModestMailOperation *mail_op = NULL;
5309 if (canceled || err || !MODEST_IS_MAIN_WINDOW (parent_window)) {
5310 g_object_unref (G_OBJECT (info->src_folder));
5311 g_object_unref (G_OBJECT (info->dst_folder));
5316 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5317 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5318 _CS("ckct_nw_pasting"));
5319 if (helper->banner != NULL) {
5320 g_object_ref (helper->banner);
5321 gtk_widget_show (GTK_WIDGET(helper->banner));
5323 /* Clean folder on header view before moving it */
5324 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5325 gtk_tree_selection_unselect_all (sel);
5327 /* Let gtk events run. We need that the folder
5328 view frees its reference to the source
5329 folder *before* issuing the mail operation
5330 so we need the signal handler of selection
5331 changed to happen before the mail
5333 while (gtk_events_pending ())
5334 gtk_main_iteration (); */
5337 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5338 modest_ui_actions_move_folder_error_handler,
5339 info->src_folder, NULL);
5340 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5343 /* Select *after* the changes */
5344 /* TODO: this function hangs UI after transfer */
5345 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
5346 /* TNY_FOLDER (src_folder), TRUE); */
5348 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5349 TNY_FOLDER (info->dst_folder), TRUE);
5350 modest_mail_operation_xfer_folder (mail_op,
5351 TNY_FOLDER (info->src_folder),
5353 info->delete_original,
5356 g_object_unref (G_OBJECT (info->src_folder));
5358 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5361 /* Unref mail operation */
5362 g_object_unref (G_OBJECT (mail_op));
5363 g_object_unref (G_OBJECT (info->dst_folder));
5368 get_account_from_folder_store (TnyFolderStore *folder_store)
5370 if (TNY_IS_ACCOUNT (folder_store))
5371 return g_object_ref (folder_store);
5373 return tny_folder_get_account (TNY_FOLDER (folder_store));
5377 * UI handler for the "Move to" action when invoked from the
5381 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5382 GtkWidget *folder_view,
5383 TnyFolderStore *dst_folder,
5384 ModestMainWindow *win)
5386 ModestHeaderView *header_view = NULL;
5387 TnyFolderStore *src_folder = NULL;
5389 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5391 /* Get the source folder */
5392 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5394 /* Get header view */
5395 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
5397 /* Get folder or messages to transfer */
5398 if (gtk_widget_is_focus (folder_view)) {
5399 gboolean do_xfer = TRUE;
5401 /* Allow only to transfer folders to the local root folder */
5402 if (TNY_IS_ACCOUNT (dst_folder) &&
5403 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5404 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5406 } else if (!TNY_IS_FOLDER (src_folder)) {
5407 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5412 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5413 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5415 info->src_folder = g_object_ref (src_folder);
5416 info->dst_folder = g_object_ref (dst_folder);
5417 info->delete_original = TRUE;
5418 info->folder_view = folder_view;
5420 connect_info->callback = on_move_folder_cb;
5421 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5422 connect_info->data = info;
5424 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5425 TNY_FOLDER_STORE (src_folder),
5428 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5431 headers = modest_header_view_get_selected_headers(header_view);
5433 /* Transfer the messages */
5434 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
5435 headers, TNY_FOLDER (dst_folder));
5437 g_object_unref (headers);
5441 g_object_unref (src_folder);
5446 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
5447 TnyFolder *src_folder,
5449 TnyFolder *dst_folder)
5451 gboolean need_connection = TRUE;
5452 gboolean do_xfer = TRUE;
5453 XferMsgsHelper *helper;
5455 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5456 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5457 g_return_if_fail (TNY_IS_LIST (headers));
5459 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5460 headers, TNY_FOLDER (dst_folder),
5461 TRUE, &need_connection,
5464 /* If we don't want to transfer just return */
5468 /* Create the helper */
5469 helper = g_slice_new (XferMsgsHelper);
5470 helper->dst_folder = g_object_ref (dst_folder);
5471 helper->headers = g_object_ref (headers);
5473 if (need_connection) {
5474 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5475 connect_info->callback = xfer_messages_performer;
5476 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5477 connect_info->data = helper;
5479 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5480 TNY_FOLDER_STORE (src_folder),
5483 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5484 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
5485 src_account, helper);
5486 g_object_unref (src_account);
5491 * UI handler for the "Move to" action when invoked from the
5492 * ModestMsgViewWindow
5495 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
5496 TnyFolderStore *dst_folder,
5497 ModestMsgViewWindow *win)
5499 TnyList *headers = NULL;
5500 TnyHeader *header = NULL;
5501 TnyFolder *src_folder = NULL;
5503 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5505 /* Create header list */
5506 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
5507 src_folder = TNY_FOLDER (tny_header_get_folder(header));
5508 headers = tny_simple_list_new ();
5509 tny_list_append (headers, G_OBJECT (header));
5511 /* Transfer the messages */
5512 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder, headers,
5513 TNY_FOLDER (dst_folder));
5516 g_object_unref (src_folder);
5517 g_object_unref (header);
5518 g_object_unref (headers);
5522 modest_ui_actions_on_move_to (GtkAction *action,
5525 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
5527 TnyFolderStore *dst_folder = NULL;
5528 ModestMainWindow *main_window;
5530 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
5531 MODEST_IS_MSG_VIEW_WINDOW (win));
5533 /* Get the main window if exists */
5534 if (MODEST_IS_MAIN_WINDOW (win))
5535 main_window = MODEST_MAIN_WINDOW (win);
5538 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5539 FALSE)); /* don't create */
5541 /* Get the folder view widget if exists */
5543 folder_view = modest_main_window_get_child_widget (main_window,
5544 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5548 /* Create and run the dialog */
5549 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
5550 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5551 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog), (GtkWindow *) win);
5552 result = gtk_dialog_run (GTK_DIALOG(dialog));
5553 g_object_ref (tree_view);
5554 gtk_widget_destroy (dialog);
5556 if (result != GTK_RESPONSE_ACCEPT)
5559 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
5560 /* Do window specific stuff */
5561 if (MODEST_IS_MAIN_WINDOW (win)) {
5562 modest_ui_actions_on_main_window_move_to (action,
5565 MODEST_MAIN_WINDOW (win));
5567 modest_ui_actions_on_msg_view_window_move_to (action,
5569 MODEST_MSG_VIEW_WINDOW (win));
5573 g_object_unref (dst_folder);
5577 * Calls #HeadersFunc for each header already selected in the main
5578 * window or the message currently being shown in the msg view window
5581 do_headers_action (ModestWindow *win,
5585 TnyList *headers_list = NULL;
5586 TnyIterator *iter = NULL;
5587 TnyHeader *header = NULL;
5588 TnyFolder *folder = NULL;
5591 headers_list = get_selected_headers (win);
5595 /* Get the folder */
5596 iter = tny_list_create_iterator (headers_list);
5597 header = TNY_HEADER (tny_iterator_get_current (iter));
5599 folder = tny_header_get_folder (header);
5600 g_object_unref (header);
5603 /* Call the function for each header */
5604 while (!tny_iterator_is_done (iter)) {
5605 header = TNY_HEADER (tny_iterator_get_current (iter));
5606 func (header, win, user_data);
5607 g_object_unref (header);
5608 tny_iterator_next (iter);
5611 /* Trick: do a poke status in order to speed up the signaling
5613 tny_folder_poke_status (folder);
5616 g_object_unref (folder);
5617 g_object_unref (iter);
5618 g_object_unref (headers_list);
5622 modest_ui_actions_view_attachment (GtkAction *action,
5623 ModestWindow *window)
5625 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5626 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5628 /* not supported window for this action */
5629 g_return_if_reached ();
5634 modest_ui_actions_save_attachments (GtkAction *action,
5635 ModestWindow *window)
5637 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5639 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5642 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5644 /* not supported window for this action */
5645 g_return_if_reached ();
5650 modest_ui_actions_remove_attachments (GtkAction *action,
5651 ModestWindow *window)
5653 if (MODEST_IS_MAIN_WINDOW (window)) {
5654 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
5655 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5656 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5658 /* not supported window for this action */
5659 g_return_if_reached ();
5664 modest_ui_actions_on_settings (GtkAction *action,
5669 dialog = modest_platform_get_global_settings_dialog ();
5670 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
5671 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5672 gtk_widget_show_all (dialog);
5674 gtk_dialog_run (GTK_DIALOG (dialog));
5676 gtk_widget_destroy (dialog);
5680 modest_ui_actions_on_help (GtkAction *action,
5683 const gchar *help_id;
5685 g_return_if_fail (win && GTK_IS_WINDOW(win));
5687 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5690 modest_platform_show_help (GTK_WINDOW (win), help_id);
5694 modest_ui_actions_on_csm_help (GtkAction *action,
5697 const gchar* help_id = NULL;
5698 GtkWidget *folder_view;
5699 TnyFolderStore *folder_store;
5701 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
5703 /* Get selected folder */
5704 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5705 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5706 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5708 /* Switch help_id */
5709 if (folder_store && TNY_IS_FOLDER (folder_store))
5710 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
5713 g_object_unref (folder_store);
5716 modest_platform_show_help (GTK_WINDOW (win), help_id);
5718 modest_ui_actions_on_help (action, win);
5722 retrieve_contents_cb (ModestMailOperation *mail_op,
5729 /* We only need this callback to show an error in case of
5730 memory low condition */
5731 modest_ui_actions_msg_retrieval_check (mail_op, header, msg);
5735 retrieve_msg_contents_performer (gboolean canceled,
5737 GtkWindow *parent_window,
5738 TnyAccount *account,
5741 ModestMailOperation *mail_op;
5742 TnyList *headers = TNY_LIST (user_data);
5744 if (err || canceled) {
5745 check_memory_full_error ((GtkWidget *) parent_window, err);
5749 /* Create mail operation */
5750 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5751 modest_ui_actions_disk_operations_error_handler,
5753 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5754 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
5757 g_object_unref (mail_op);
5759 g_object_unref (headers);
5760 g_object_unref (account);
5764 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5765 ModestWindow *window)
5767 TnyList *headers = NULL;
5768 TnyAccount *account = NULL;
5769 TnyIterator *iter = NULL;
5770 TnyHeader *header = NULL;
5771 TnyFolder *folder = NULL;
5774 headers = get_selected_headers (window);
5778 /* Pick the account */
5779 iter = tny_list_create_iterator (headers);
5780 header = TNY_HEADER (tny_iterator_get_current (iter));
5781 folder = tny_header_get_folder (header);
5782 account = tny_folder_get_account (folder);
5783 g_object_unref (folder);
5784 g_object_unref (header);
5785 g_object_unref (iter);
5787 /* Connect and perform the message retrieval */
5788 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
5789 g_object_ref (account),
5790 retrieve_msg_contents_performer,
5791 g_object_ref (headers));
5794 g_object_unref (account);
5795 g_object_unref (headers);
5799 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
5801 g_return_if_fail (MODEST_IS_WINDOW (window));
5804 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
5808 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
5810 g_return_if_fail (MODEST_IS_WINDOW (window));
5813 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
5817 modest_ui_actions_on_email_menu_activated (GtkAction *action,
5818 ModestWindow *window)
5820 g_return_if_fail (MODEST_IS_WINDOW (window));
5823 modest_ui_actions_check_menu_dimming_rules (window);
5827 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
5828 ModestWindow *window)
5830 g_return_if_fail (MODEST_IS_WINDOW (window));
5833 modest_ui_actions_check_menu_dimming_rules (window);
5837 modest_ui_actions_on_view_menu_activated (GtkAction *action,
5838 ModestWindow *window)
5840 g_return_if_fail (MODEST_IS_WINDOW (window));
5843 modest_ui_actions_check_menu_dimming_rules (window);
5847 modest_ui_actions_on_format_menu_activated (GtkAction *action,
5848 ModestWindow *window)
5850 g_return_if_fail (MODEST_IS_WINDOW (window));
5853 modest_ui_actions_check_menu_dimming_rules (window);
5857 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
5858 ModestWindow *window)
5860 g_return_if_fail (MODEST_IS_WINDOW (window));
5863 modest_ui_actions_check_menu_dimming_rules (window);
5867 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
5868 ModestWindow *window)
5870 g_return_if_fail (MODEST_IS_WINDOW (window));
5873 modest_ui_actions_check_menu_dimming_rules (window);
5877 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
5878 ModestWindow *window)
5880 g_return_if_fail (MODEST_IS_WINDOW (window));
5883 modest_ui_actions_check_menu_dimming_rules (window);
5887 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
5888 ModestWindow *window)
5890 g_return_if_fail (MODEST_IS_WINDOW (window));
5893 modest_ui_actions_check_menu_dimming_rules (window);
5897 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
5898 ModestWindow *window)
5900 g_return_if_fail (MODEST_IS_WINDOW (window));
5903 modest_ui_actions_check_menu_dimming_rules (window);
5907 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
5909 g_return_if_fail (MODEST_IS_WINDOW (window));
5911 /* we check for low-mem; in that case, show a warning, and don't allow
5914 if (modest_platform_check_memory_low (window, TRUE))
5917 modest_platform_show_search_messages (GTK_WINDOW (window));
5921 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
5923 g_return_if_fail (MODEST_IS_WINDOW (win));
5926 /* we check for low-mem; in that case, show a warning, and don't allow
5927 * for the addressbook
5929 if (modest_platform_check_memory_low (win, TRUE))
5933 modest_platform_show_addressbook (GTK_WINDOW (win));
5938 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
5939 ModestWindow *window)
5941 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5943 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
5947 on_send_receive_finished (ModestMailOperation *mail_op,
5950 GtkWidget *header_view, *folder_view;
5951 TnyFolderStore *folder_store;
5952 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
5954 /* Set send/receive operation finished */
5955 modest_main_window_notify_send_receive_completed (main_win);
5957 /* Don't refresh the current folder if there were any errors */
5958 if (modest_mail_operation_get_status (mail_op) !=
5959 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5962 /* Refresh the current folder if we're viewing a window. We do
5963 this because the user won't be able to see the new mails in
5964 the selected folder after a Send&Receive because it only
5965 performs a poke_status, i.e, only the number of read/unread
5966 messages is updated, but the new headers are not
5968 folder_view = modest_main_window_get_child_widget (main_win,
5969 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5973 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5975 /* Do not need to refresh INBOX again because the
5976 update_account does it always automatically */
5977 if (folder_store && TNY_IS_FOLDER (folder_store) &&
5978 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
5979 ModestMailOperation *refresh_op;
5981 header_view = modest_main_window_get_child_widget (main_win,
5982 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5984 /* We do not need to set the contents style
5985 because it hasn't changed. We also do not
5986 need to save the widget status. Just force
5988 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
5989 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
5990 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
5991 folder_refreshed_cb, main_win);
5992 g_object_unref (refresh_op);
5996 g_object_unref (folder_store);
6001 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6007 const gchar* server_name = NULL;
6008 TnyTransportAccount *server_account;
6009 gchar *message = NULL;
6011 /* Don't show anything if the user cancelled something or the
6012 * send receive request is not interactive. Authentication
6013 * errors are managed by the account store so no need to show
6014 * a dialog here again */
6015 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6016 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6017 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6021 /* Get the server name: */
6023 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
6025 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
6027 g_return_if_reached ();
6029 /* Show the appropriate message text for the GError: */
6030 switch (err->code) {
6031 case TNY_SERVICE_ERROR_CONNECT:
6032 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6034 case TNY_SERVICE_ERROR_SEND:
6035 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
6037 case TNY_SERVICE_ERROR_UNAVAILABLE:
6038 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6041 g_warning ("%s: unexpected ERROR %d",
6042 __FUNCTION__, err->code);
6043 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
6047 modest_platform_run_information_dialog (NULL, message, FALSE);
6049 g_object_unref (server_account);
6053 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6058 ModestMainWindow *main_window = NULL;
6059 ModestWindowMgr *mgr = NULL;
6060 GtkWidget *folder_view = NULL, *header_view = NULL;
6061 TnyFolderStore *selected_folder = NULL;
6062 TnyFolderType folder_type;
6064 mgr = modest_runtime_get_window_mgr ();
6065 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr,
6066 FALSE));/* don't create */
6070 /* Check if selected folder is OUTBOX */
6071 folder_view = modest_main_window_get_child_widget (main_window,
6072 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6073 header_view = modest_main_window_get_child_widget (main_window,
6074 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6076 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6077 if (!TNY_IS_FOLDER (selected_folder))
6080 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6081 #if GTK_CHECK_VERSION(2, 8, 0)
6082 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
6083 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6084 GtkTreeViewColumn *tree_column;
6086 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6087 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6089 gtk_tree_view_column_queue_resize (tree_column);
6092 gtk_widget_queue_draw (header_view);
6095 /* Rerun dimming rules, because the message could become deletable for example */
6096 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6097 MODEST_DIMMING_RULES_TOOLBAR);
6098 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6099 MODEST_DIMMING_RULES_MENU);
6103 if (selected_folder != NULL)
6104 g_object_unref (selected_folder);
6108 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6109 TnyAccount *account)
6111 ModestProtocolType protocol_type;
6112 ModestProtocol *protocol;
6113 gchar *error_note = NULL;
6115 protocol_type = modest_tny_account_get_protocol_type (account);
6116 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6119 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6120 if (error_note == NULL) {
6121 g_warning ("%s: This should not be reached", __FUNCTION__);
6123 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6124 g_free (error_note);
6129 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6133 TnyFolderStore *folder = NULL;
6134 TnyAccount *account = NULL;
6135 ModestProtocolType proto;
6136 ModestProtocol *protocol;
6137 TnyHeader *header = NULL;
6139 if (MODEST_IS_MAIN_WINDOW (win)) {
6140 GtkWidget *header_view;
6141 TnyList* headers = NULL;
6143 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6144 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6145 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6146 if (!headers || tny_list_get_length (headers) == 0) {
6148 g_object_unref (headers);
6151 iter = tny_list_create_iterator (headers);
6152 header = TNY_HEADER (tny_iterator_get_current (iter));
6153 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6154 g_object_unref (iter);
6155 g_object_unref (headers);
6156 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6157 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6158 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6161 /* Get the account type */
6162 account = tny_folder_get_account (TNY_FOLDER (folder));
6163 proto = modest_tny_account_get_protocol_type (account);
6164 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6167 subject = tny_header_dup_subject (header);
6168 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6172 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6176 g_object_unref (account);
6177 g_object_unref (folder);
6178 g_object_unref (header);