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"
76 #include <modest-widget-memory.h>
77 #include <tny-error.h>
78 #include <tny-simple-list.h>
79 #include <tny-msg-view.h>
80 #include <tny-device.h>
81 #include <tny-merge-folder.h>
83 #include <gtkhtml/gtkhtml.h>
85 #define MIN_FREE_SPACE 5 * 1024 * 1024
86 #define MOVE_FOLDER_OK_BUTTON "ok-button"
87 #define MOVE_FOLDER_NEW_BUTTON "new-button"
89 typedef struct _GetMsgAsyncHelper {
91 ModestMailOperation *mail_op;
98 typedef enum _ReplyForwardAction {
102 } ReplyForwardAction;
104 typedef struct _ReplyForwardHelper {
105 guint reply_forward_type;
106 ReplyForwardAction action;
108 GtkWidget *parent_window;
110 } ReplyForwardHelper;
112 typedef struct _MoveToHelper {
113 GtkTreeRowReference *reference;
117 typedef struct _PasteAsAttachmentHelper {
118 ModestMsgEditWindow *window;
120 } PasteAsAttachmentHelper;
124 * The do_headers_action uses this kind of functions to perform some
125 * action to each member of a list of headers
127 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
129 static void do_headers_action (ModestWindow *win,
133 static void open_msg_cb (ModestMailOperation *mail_op,
140 static void reply_forward_cb (ModestMailOperation *mail_op,
147 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
149 static void folder_refreshed_cb (ModestMailOperation *mail_op,
153 static void on_send_receive_finished (ModestMailOperation *mail_op,
156 static gint header_list_count_uncached_msgs (TnyList *header_list);
158 static gboolean connect_to_get_msg (ModestWindow *win,
159 gint num_of_uncached_msgs,
160 TnyAccount *account);
162 static gboolean remote_folder_has_leave_on_server (TnyFolderStore *folder);
164 static void do_create_folder (GtkWindow *window,
165 TnyFolderStore *parent_folder,
166 const gchar *suggested_name);
168 static GtkWidget* get_folder_view_from_move_to_dialog (GtkWidget *move_to_dialog);
170 static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store);
173 * This function checks whether a TnyFolderStore is a pop account
176 remote_folder_has_leave_on_server (TnyFolderStore *folder)
181 g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
183 account = get_account_from_folder_store (folder);
184 result = (modest_protocol_registry_protocol_type_has_leave_on_server (modest_runtime_get_protocol_registry (),
185 modest_tny_account_get_protocol_type (account)));
186 g_object_unref (account);
191 /* FIXME: this should be merged with the similar code in modest-account-view-window */
192 /* Show the account creation wizard dialog.
193 * returns: TRUE if an account was created. FALSE if the user cancelled.
196 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
198 gboolean result = FALSE;
200 gint dialog_response;
202 /* there is no such wizard yet */
203 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
204 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (wizard), (GtkWindow *) win);
206 /* always present a main window in the background
207 * we do it here, so we cannot end up with two wizards (as this
208 * function might be called in modest_window_mgr_get_main_window as well */
210 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
211 TRUE); /* create if not existent */
213 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
215 /* make sure the mainwindow is visible. We need to present the
216 wizard again to give it the focus back. show_all are needed
217 in order to get the widgets properly drawn (MainWindow main
218 paned won't be in its right position and the dialog will be
220 #ifndef MODEST_TOOLKIT_HILDON2
221 gtk_widget_show_all (GTK_WIDGET (win));
222 gtk_widget_show_all (GTK_WIDGET (wizard));
223 gtk_window_present (GTK_WINDOW (win));
224 gtk_window_present (GTK_WINDOW (wizard));
227 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
228 gtk_widget_destroy (GTK_WIDGET (wizard));
229 if (gtk_events_pending ())
230 gtk_main_iteration ();
232 if (dialog_response == GTK_RESPONSE_CANCEL) {
235 /* Check whether an account was created: */
236 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
243 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
246 const gchar *authors[] = {
247 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
250 about = gtk_about_dialog_new ();
251 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
252 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
253 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
254 _("Copyright (c) 2006, Nokia Corporation\n"
255 "All rights reserved."));
256 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
257 _("a modest e-mail client\n\n"
258 "design and implementation: Dirk-Jan C. Binnema\n"
259 "contributions from the fine people at KC and Ig\n"
260 "uses the tinymail email framework written by Philip van Hoof"));
261 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
262 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
263 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
264 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
266 gtk_dialog_run (GTK_DIALOG (about));
267 gtk_widget_destroy(about);
271 * Gets the list of currently selected messages. If the win is the
272 * main window, then it returns a newly allocated list of the headers
273 * selected in the header view. If win is the msg view window, then
274 * the value returned is a list with just a single header.
276 * The caller of this funcion must free the list.
279 get_selected_headers (ModestWindow *win)
281 if (MODEST_IS_MAIN_WINDOW(win)) {
282 GtkWidget *header_view;
284 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
285 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
286 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
288 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
289 /* for MsgViewWindows, we simply return a list with one element */
291 TnyList *list = NULL;
293 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
294 if (header != NULL) {
295 list = tny_simple_list_new ();
296 tny_list_prepend (list, G_OBJECT(header));
297 g_object_unref (G_OBJECT(header));
306 static GtkTreeRowReference *
307 get_next_after_selected_headers (ModestHeaderView *header_view)
309 GtkTreeSelection *sel;
310 GList *selected_rows, *node;
312 GtkTreeRowReference *result;
315 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
316 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
317 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
319 if (selected_rows == NULL)
322 node = g_list_last (selected_rows);
323 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
324 gtk_tree_path_next (path);
326 result = gtk_tree_row_reference_new (model, path);
328 gtk_tree_path_free (path);
329 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
330 g_list_free (selected_rows);
336 headers_action_mark_as_read (TnyHeader *header,
340 TnyHeaderFlags flags;
342 g_return_if_fail (TNY_IS_HEADER(header));
344 flags = tny_header_get_flags (header);
345 if (flags & TNY_HEADER_FLAG_SEEN) return;
346 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
350 headers_action_mark_as_unread (TnyHeader *header,
354 TnyHeaderFlags flags;
356 g_return_if_fail (TNY_IS_HEADER(header));
358 flags = tny_header_get_flags (header);
359 if (flags & TNY_HEADER_FLAG_SEEN) {
360 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
364 /** After deleing a message that is currently visible in a window,
365 * show the next message from the list, or close the window if there are no more messages.
368 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
370 /* Close msg view window or select next */
371 if (!modest_msg_view_window_select_next_message (win) &&
372 !modest_msg_view_window_select_previous_message (win)) {
374 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
380 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
382 TnyList *header_list = NULL;
383 TnyIterator *iter = NULL;
384 TnyHeader *header = NULL;
385 gchar *message = NULL;
388 ModestWindowMgr *mgr;
389 GtkWidget *header_view = NULL;
391 g_return_if_fail (MODEST_IS_WINDOW(win));
393 /* Check first if the header view has the focus */
394 if (MODEST_IS_MAIN_WINDOW (win)) {
396 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
397 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
398 if (!gtk_widget_is_focus (header_view))
402 /* Get the headers, either from the header view (if win is the main window),
403 * or from the message view window: */
404 header_list = get_selected_headers (win);
405 if (!header_list) return;
407 /* Check if any of the headers are already opened, or in the process of being opened */
408 if (MODEST_IS_MAIN_WINDOW (win)) {
409 gint opened_headers = 0;
411 iter = tny_list_create_iterator (header_list);
412 mgr = modest_runtime_get_window_mgr ();
413 while (!tny_iterator_is_done (iter)) {
414 header = TNY_HEADER (tny_iterator_get_current (iter));
416 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
418 g_object_unref (header);
420 tny_iterator_next (iter);
422 g_object_unref (iter);
424 if (opened_headers > 0) {
427 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
430 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg, FALSE);
433 g_object_unref (header_list);
439 if (tny_list_get_length(header_list) == 1) {
440 iter = tny_list_create_iterator (header_list);
441 header = TNY_HEADER (tny_iterator_get_current (iter));
444 subject = tny_header_dup_subject (header);
446 subject = g_strdup (_("mail_va_no_subject"));
447 desc = g_strdup_printf ("%s", subject);
449 g_object_unref (header);
452 g_object_unref (iter);
454 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
455 tny_list_get_length(header_list)), desc);
457 /* Confirmation dialog */
458 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
462 if (response == GTK_RESPONSE_OK) {
463 ModestWindow *main_window = NULL;
464 ModestWindowMgr *mgr = NULL;
465 GtkTreeModel *model = NULL;
466 GtkTreeSelection *sel = NULL;
467 GList *sel_list = NULL, *tmp = NULL;
468 GtkTreeRowReference *next_row_reference = NULL;
469 GtkTreeRowReference *prev_row_reference = NULL;
470 GtkTreePath *next_path = NULL;
471 GtkTreePath *prev_path = NULL;
472 ModestMailOperation *mail_op = NULL;
474 /* Find last selected row */
475 if (MODEST_IS_MAIN_WINDOW (win)) {
476 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
477 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
478 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
479 for (tmp=sel_list; tmp; tmp=tmp->next) {
480 if (tmp->next == NULL) {
481 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
482 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
484 gtk_tree_path_prev (prev_path);
485 gtk_tree_path_next (next_path);
487 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
488 next_row_reference = gtk_tree_row_reference_new (model, next_path);
493 /* Disable window dimming management */
494 modest_window_disable_dimming (MODEST_WINDOW(win));
496 /* Remove each header. If it's a view window header_view == NULL */
497 mail_op = modest_mail_operation_new ((GObject *) win);
498 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
500 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
501 g_object_unref (mail_op);
503 /* Enable window dimming management */
505 gtk_tree_selection_unselect_all (sel);
507 modest_window_enable_dimming (MODEST_WINDOW(win));
509 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
510 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
512 /* Get main window */
513 mgr = modest_runtime_get_window_mgr ();
514 main_window = modest_window_mgr_get_main_window (mgr, FALSE); /* don't create */
516 /* Move cursor to next row */
519 /* Select next or previous row */
520 if (gtk_tree_row_reference_valid (next_row_reference)) {
521 gtk_tree_selection_select_path (sel, next_path);
523 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
524 gtk_tree_selection_select_path (sel, prev_path);
528 if (gtk_tree_row_reference_valid (next_row_reference))
529 gtk_tree_row_reference_free (next_row_reference);
530 if (next_path != NULL)
531 gtk_tree_path_free (next_path);
532 if (gtk_tree_row_reference_valid (prev_row_reference))
533 gtk_tree_row_reference_free (prev_row_reference);
534 if (prev_path != NULL)
535 gtk_tree_path_free (prev_path);
538 /* Update toolbar dimming state */
540 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
541 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
545 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
546 g_list_free (sel_list);
552 g_object_unref (header_list);
558 /* delete either message or folder, based on where we are */
560 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
562 g_return_if_fail (MODEST_IS_WINDOW(win));
564 /* Check first if the header view has the focus */
565 if (MODEST_IS_MAIN_WINDOW (win)) {
567 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
568 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
569 if (gtk_widget_is_focus (w)) {
570 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
574 modest_ui_actions_on_delete_message (action, win);
578 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
580 ModestWindowMgr *mgr = NULL;
582 #ifdef MODEST_PLATFORM_MAEMO
583 modest_osso_save_state();
584 #endif /* MODEST_PLATFORM_MAEMO */
586 g_debug ("closing down, clearing %d item(s) from operation queue",
587 modest_mail_operation_queue_num_elements
588 (modest_runtime_get_mail_operation_queue()));
590 /* cancel all outstanding operations */
591 modest_mail_operation_queue_cancel_all
592 (modest_runtime_get_mail_operation_queue());
594 g_debug ("queue has been cleared");
597 /* Check if there are opened editing windows */
598 mgr = modest_runtime_get_window_mgr ();
599 modest_window_mgr_close_all_windows (mgr);
601 /* note: when modest-tny-account-store is finalized,
602 it will automatically set all network connections
605 /* gtk_main_quit (); */
609 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
613 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
615 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
616 /* gtk_widget_destroy (GTK_WIDGET (win)); */
617 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
618 /* gboolean ret_value; */
619 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
620 /* } else if (MODEST_IS_WINDOW (win)) { */
621 /* gtk_widget_destroy (GTK_WIDGET (win)); */
623 /* g_return_if_reached (); */
628 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
630 GtkClipboard *clipboard = NULL;
631 gchar *selection = NULL;
633 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
634 selection = gtk_clipboard_wait_for_text (clipboard);
636 /* Question: why is the clipboard being used here?
637 * It doesn't really make a lot of sense. */
641 modest_address_book_add_address (selection);
647 modest_ui_actions_on_accounts (GtkAction *action,
650 /* This is currently only implemented for Maemo */
651 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
652 if (!modest_ui_actions_run_account_setup_wizard (win))
653 g_debug ("%s: wizard was already running", __FUNCTION__);
657 /* Show the list of accounts */
658 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
660 /* The accounts dialog must be modal */
661 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
662 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
667 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
669 /* This is currently only implemented for Maemo,
670 * because it requires an API (libconic) to detect different connection
673 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
675 /* Create the window if necessary: */
676 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
677 modest_connection_specific_smtp_window_fill_with_connections (
678 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
679 modest_runtime_get_account_mgr());
681 /* Show the window: */
682 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
683 GTK_WINDOW (specific_window), (GtkWindow *) win);
684 gtk_widget_show (specific_window);
685 #endif /* !MODEST_TOOLKIT_GTK */
689 modest_ui_actions_compose_msg(ModestWindow *win,
692 const gchar *bcc_str,
693 const gchar *subject_str,
694 const gchar *body_str,
696 gboolean set_as_modified)
698 gchar *account_name = NULL;
700 TnyAccount *account = NULL;
701 TnyFolder *folder = NULL;
702 gchar *from_str = NULL, *signature = NULL, *body = NULL;
703 gboolean use_signature = FALSE;
704 ModestWindow *msg_win = NULL;
705 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
706 ModestTnyAccountStore *store = modest_runtime_get_account_store();
707 GnomeVFSFileSize total_size, allowed_size;
709 /* we check for low-mem */
710 if (modest_platform_check_memory_low (win, TRUE))
713 #ifdef MODEST_TOOLKIT_HILDON2
714 account_name = g_strdup (modest_window_get_active_account(win));
717 account_name = modest_account_mgr_get_default_account(mgr);
720 g_printerr ("modest: no account found\n");
723 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
725 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
728 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
730 g_printerr ("modest: failed to find Drafts folder\n");
733 from_str = modest_account_mgr_get_from_string (mgr, account_name);
735 g_printerr ("modest: failed get from string for '%s'\n", account_name);
739 signature = modest_account_mgr_get_signature (mgr, account_name, &use_signature);
740 if (body_str != NULL) {
741 body = use_signature ? g_strconcat(body_str, "\n--\n", signature, NULL) : g_strdup(body_str);
743 body = use_signature ? g_strconcat("\n--\n", signature, NULL) : g_strdup("");
746 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, body, NULL, NULL, NULL);
748 g_printerr ("modest: failed to create new msg\n");
752 /* Create and register edit window */
753 /* This is destroyed by TODO. */
755 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
756 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
758 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, NULL)) {
759 gtk_widget_destroy (GTK_WIDGET (msg_win));
762 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
763 gtk_widget_show_all (GTK_WIDGET (msg_win));
765 while (attachments) {
767 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
768 attachments->data, allowed_size);
770 if (total_size > allowed_size) {
771 g_warning ("%s: total size: %u",
772 __FUNCTION__, (unsigned int)total_size);
775 allowed_size -= total_size;
777 attachments = g_slist_next(attachments);
784 g_free (account_name);
786 g_object_unref (G_OBJECT(account));
788 g_object_unref (G_OBJECT(folder));
790 g_object_unref (G_OBJECT(msg));
794 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
796 /* if there are no accounts yet, just show the wizard */
797 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
798 if (!modest_ui_actions_run_account_setup_wizard (win))
801 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
806 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
810 ModestMailOperationStatus status;
812 /* If there is no message or the operation was not successful */
813 status = modest_mail_operation_get_status (mail_op);
814 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
817 /* If it's a memory low issue, then show a banner */
818 error = modest_mail_operation_get_error (mail_op);
819 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
820 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
821 GObject *source = modest_mail_operation_get_source (mail_op);
822 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
823 dgettext("ke-recv","memr_ib_operation_disabled"),
825 g_object_unref (source);
828 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
829 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
830 gchar *subject, *msg;
831 subject = tny_header_dup_subject (header);
833 subject = g_strdup (_("mail_va_no_subject"));;
834 msg = g_strdup_printf (_("emev_ni_ui_imap_message_not_available_in_server"),
836 modest_platform_run_information_dialog (NULL, msg, FALSE);
841 /* Remove the header from the preregistered uids */
842 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
860 OpenMsgBannerInfo *banner_info;
861 GtkTreeRowReference *rowref;
865 open_msg_banner_idle (gpointer userdata)
867 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
869 gdk_threads_enter ();
870 banner_info->idle_handler = 0;
871 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
873 g_object_ref (banner_info->banner);
875 gdk_threads_leave ();
882 get_header_view_from_window (ModestWindow *window)
884 GtkWidget *header_view;
886 if (MODEST_IS_MAIN_WINDOW (window)) {
887 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
888 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
889 #ifdef MODEST_TOOLKIT_HILDON2
890 } else if (MODEST_IS_HEADER_WINDOW (window)){
891 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
901 get_info_from_header (TnyHeader *header, gboolean *is_draft)
904 gchar *account = NULL;
905 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
909 folder = tny_header_get_folder (header);
910 /* Gets folder type (OUTBOX headers will be opened in edit window */
911 if (modest_tny_folder_is_local_folder (folder)) {
912 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
913 if (folder_type == TNY_FOLDER_TYPE_INVALID)
914 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
917 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
918 TnyTransportAccount *traccount = NULL;
919 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
920 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
922 ModestTnySendQueue *send_queue = NULL;
923 ModestTnySendQueueStatus status;
925 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
926 TNY_ACCOUNT(traccount)));
927 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
928 if (TNY_IS_SEND_QUEUE (send_queue)) {
929 msg_id = modest_tny_send_queue_get_msg_id (header);
930 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
931 /* Only open messages in outbox with the editor if they are in Failed state */
932 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
937 g_object_unref(traccount);
939 g_warning("Cannot get transport account for message in outbox!!");
941 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
942 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
945 g_object_unref (folder);
951 open_msg_cb (ModestMailOperation *mail_op,
958 ModestWindowMgr *mgr = NULL;
959 ModestWindow *parent_win = NULL;
960 ModestWindow *win = NULL;
961 gchar *account = NULL;
962 gboolean open_in_editor = FALSE;
963 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
965 /* Do nothing if there was any problem with the mail
966 operation. The error will be shown by the error_handler of
967 the mail operation */
968 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
971 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
973 /* Mark header as read */
974 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
976 account = get_info_from_header (header, &open_in_editor);
980 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
982 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
984 if (open_in_editor) {
985 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
986 gchar *from_header = NULL, *acc_name;
988 from_header = tny_header_dup_from (header);
990 /* we cannot edit without a valid account... */
991 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
992 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
993 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
995 g_free (from_header);
1000 acc_name = modest_utils_get_account_name_from_recipient (from_header);
1001 g_free (from_header);
1007 win = modest_msg_edit_window_new (msg, account, TRUE);
1009 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1011 if (helper->rowref && helper->model) {
1012 win = modest_msg_view_window_new_with_header_model (msg, account, (const gchar*) uid,
1013 helper->model, helper->rowref);
1015 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
1020 /* Register and show new window */
1022 mgr = modest_runtime_get_window_mgr ();
1023 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1024 gtk_widget_destroy (GTK_WIDGET (win));
1027 gtk_widget_show_all (GTK_WIDGET(win));
1030 /* Update toolbar dimming state */
1031 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1032 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1038 g_object_unref (parent_win);
1042 is_memory_full_error (GError *error)
1044 gboolean enough_free_space = TRUE;
1045 GnomeVFSURI *cache_dir_uri;
1046 const gchar *cache_dir;
1047 GnomeVFSFileSize free_space;
1049 cache_dir = tny_account_store_get_cache_dir (TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
1050 cache_dir_uri = gnome_vfs_uri_new (cache_dir);
1051 if (gnome_vfs_get_volume_free_space (cache_dir_uri, &free_space) == GNOME_VFS_OK) {
1052 if (free_space < MIN_FREE_SPACE)
1053 enough_free_space = FALSE;
1055 gnome_vfs_uri_unref (cache_dir_uri);
1057 if ((error->code == TNY_SYSTEM_ERROR_MEMORY ||
1058 /* When asking for a mail and no space left on device
1059 tinymail returns this error */
1060 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE ||
1061 /* When the folder summary could not be read or
1063 error->code == TNY_IO_ERROR_WRITE ||
1064 error->code == TNY_IO_ERROR_READ) &&
1065 !enough_free_space) {
1073 check_memory_full_error (GtkWidget *parent_window, GError *err)
1078 if (is_memory_full_error (err))
1079 modest_platform_information_banner (parent_window,
1080 NULL, dgettext("ke-recv",
1081 "cerm_device_memory_full"));
1082 else if (err->code == TNY_SYSTEM_ERROR_MEMORY)
1083 /* If the account was created in memory full
1084 conditions then tinymail won't be able to
1085 connect so it'll return this error code */
1086 modest_platform_information_banner (parent_window,
1087 NULL, _("emev_ui_imap_inbox_select_error"));
1095 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1098 const GError *error;
1099 GObject *win = NULL;
1100 ModestMailOperationStatus status;
1102 win = modest_mail_operation_get_source (mail_op);
1103 error = modest_mail_operation_get_error (mail_op);
1104 status = modest_mail_operation_get_status (mail_op);
1106 /* If the mail op has been cancelled then it's not an error:
1107 don't show any message */
1108 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1109 if (is_memory_full_error ((GError *) error)) {
1110 modest_platform_information_banner ((GtkWidget *) win,
1111 NULL, dgettext("ke-recv",
1112 "cerm_device_memory_full"));
1113 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1114 modest_platform_information_banner ((GtkWidget *) win,
1115 NULL, _("emev_ui_imap_inbox_select_error"));
1116 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1117 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1118 modest_platform_information_banner ((GtkWidget *) win,
1119 NULL, dgettext ("hildon-common-strings", "sfil_ni_unable_to_open_file_not_found"));
1120 } else if (user_data) {
1121 modest_platform_information_banner ((GtkWidget *) win,
1127 g_object_unref (win);
1131 * Returns the account a list of headers belongs to. It returns a
1132 * *new* reference so don't forget to unref it
1135 get_account_from_header_list (TnyList *headers)
1137 TnyAccount *account = NULL;
1139 if (tny_list_get_length (headers) > 0) {
1140 TnyIterator *iter = tny_list_create_iterator (headers);
1141 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1142 TnyFolder *folder = tny_header_get_folder (header);
1145 g_object_unref (header);
1147 while (!tny_iterator_is_done (iter)) {
1148 header = TNY_HEADER (tny_iterator_get_current (iter));
1149 folder = tny_header_get_folder (header);
1152 g_object_unref (header);
1154 tny_iterator_next (iter);
1159 account = tny_folder_get_account (folder);
1160 g_object_unref (folder);
1164 g_object_unref (header);
1166 g_object_unref (iter);
1172 get_account_from_header (TnyHeader *header)
1174 TnyAccount *account = NULL;
1177 folder = tny_header_get_folder (header);
1180 account = tny_folder_get_account (folder);
1181 g_object_unref (folder);
1188 open_msg_helper_destroyer (gpointer user_data)
1190 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1192 if (helper->banner_info) {
1193 g_free (helper->banner_info->message);
1194 if (helper->banner_info->idle_handler > 0) {
1195 g_source_remove (helper->banner_info->idle_handler);
1196 helper->banner_info->idle_handler = 0;
1198 if (helper->banner_info->banner != NULL) {
1199 gtk_widget_destroy (helper->banner_info->banner);
1200 g_object_unref (helper->banner_info->banner);
1201 helper->banner_info->banner = NULL;
1203 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1204 helper->banner_info = NULL;
1206 g_object_unref (helper->model);
1207 g_object_unref (helper->header);
1208 gtk_tree_row_reference_free (helper->rowref);
1209 g_slice_free (OpenMsgHelper, helper);
1213 open_msg_performer(gboolean canceled,
1215 GtkWindow *parent_window,
1216 TnyAccount *account,
1219 ModestMailOperation *mail_op = NULL;
1221 ModestProtocolType proto;
1222 TnyConnectionStatus status;
1223 gboolean show_open_draft = FALSE;
1224 OpenMsgHelper *helper = NULL;
1226 helper = (OpenMsgHelper *) user_data;
1228 status = tny_account_get_connection_status (account);
1229 if (err || canceled) {
1230 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1231 /* Free the helper */
1232 open_msg_helper_destroyer (helper);
1234 /* In memory full conditions we could get this error here */
1235 check_memory_full_error ((GtkWidget *) parent_window, err);
1240 /* Get the error message depending on the protocol */
1241 proto = modest_tny_account_get_protocol_type (account);
1242 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1243 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1246 ModestProtocol *protocol;
1247 ModestProtocolRegistry *protocol_registry;
1250 protocol_registry = modest_runtime_get_protocol_registry ();
1251 subject = tny_header_dup_subject (helper->header);
1253 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1254 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1258 if (error_msg == NULL) {
1259 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1262 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1264 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1266 TnyFolderType folder_type;
1268 folder = tny_header_get_folder (helper->header);
1269 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1270 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1271 g_object_unref (folder);
1274 #ifdef MODEST_TOOLKIT_HILDON2
1276 gchar *account_name = get_info_from_header (helper->header, &is_draft);
1279 ModestWindow *window;
1280 GtkWidget *header_view;
1283 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1284 uid = modest_tny_folder_get_header_unique_id (helper->header);
1286 window = modest_msg_view_window_new_from_header_view
1287 (MODEST_HEADER_VIEW (header_view), account_name, uid, helper->rowref);
1288 if (window != NULL) {
1289 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1291 gtk_widget_destroy (GTK_WIDGET (window));
1293 gtk_widget_show_all (GTK_WIDGET(window));
1297 g_free (account_name);
1299 open_msg_helper_destroyer (helper);
1302 g_free (account_name);
1304 /* Create the mail operation */
1306 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1307 modest_ui_actions_disk_operations_error_handler,
1309 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1312 if (show_open_draft) {
1313 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1314 #ifdef MODEST_TOOLKIT_HILDON2
1315 helper->banner_info->message = g_strdup (_("mail_me_opening"));
1317 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1319 helper->banner_info->banner = NULL;
1320 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1321 helper->banner_info);
1325 headers = TNY_LIST (tny_simple_list_new ());
1326 tny_list_prepend (headers, G_OBJECT (helper->header));
1327 modest_mail_operation_get_msgs_full (mail_op,
1331 open_msg_helper_destroyer);
1332 g_object_unref (headers);
1337 g_object_unref (mail_op);
1338 g_object_unref (account);
1342 * This function is used by both modest_ui_actions_on_open and
1343 * modest_ui_actions_on_header_activated. This way we always do the
1344 * same when trying to open messages.
1347 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1349 ModestWindowMgr *mgr = NULL;
1350 TnyAccount *account;
1351 gboolean cached = FALSE;
1353 GtkWidget *header_view = NULL;
1354 OpenMsgHelper *helper;
1355 ModestWindow *window;
1357 g_return_if_fail (header != NULL && rowref != NULL);
1359 mgr = modest_runtime_get_window_mgr ();
1362 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1363 if (header_view == NULL)
1366 /* Get the account */
1367 account = get_account_from_header (header);
1372 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1374 /* Do not open again the message and present the
1375 window to the user */
1378 #ifndef MODEST_TOOLKIT_HILDON2
1379 gtk_window_present (GTK_WINDOW (window));
1382 /* the header has been registered already, we don't do
1383 * anything but wait for the window to come up*/
1384 g_debug ("header %p already registered, waiting for window", header);
1389 /* Open each message */
1390 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1392 /* Allways download if we are online. */
1393 if (!tny_device_is_online (modest_runtime_get_device ())) {
1396 /* If ask for user permission to download the messages */
1397 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1398 _("mcen_nc_get_msg"));
1400 /* End if the user does not want to continue */
1401 if (response == GTK_RESPONSE_CANCEL) {
1407 /* We register the window for opening */
1408 modest_window_mgr_register_header (mgr, header, NULL);
1410 /* Create the helper. We need to get a reference to the model
1411 here because it could change while the message is readed
1412 (the user could switch between folders) */
1413 helper = g_slice_new (OpenMsgHelper);
1414 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1415 helper->header = g_object_ref (header);
1416 helper->rowref = gtk_tree_row_reference_copy (rowref);
1417 helper->banner_info = NULL;
1419 /* Connect to the account and perform */
1421 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1422 open_msg_performer, helper);
1424 /* Call directly the performer, do not need to connect */
1425 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1426 g_object_ref (account), helper);
1431 g_object_unref (account);
1435 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1442 /* we check for low-mem; in that case, show a warning, and don't allow
1445 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1449 headers = get_selected_headers (win);
1453 headers_count = tny_list_get_length (headers);
1454 if (headers_count != 1) {
1455 if (headers_count > 1) {
1456 /* Don't allow activation if there are more than one message selected */
1457 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1460 g_object_unref (headers);
1464 iter = tny_list_create_iterator (headers);
1465 header = TNY_HEADER (tny_iterator_get_current (iter));
1466 g_object_unref (iter);
1470 open_msg_from_header (header, NULL, win);
1471 g_object_unref (header);
1474 g_object_unref(headers);
1477 static ReplyForwardHelper*
1478 create_reply_forward_helper (ReplyForwardAction action,
1480 guint reply_forward_type,
1483 ReplyForwardHelper *rf_helper = NULL;
1484 const gchar *active_acc = modest_window_get_active_account (win);
1486 rf_helper = g_slice_new0 (ReplyForwardHelper);
1487 rf_helper->reply_forward_type = reply_forward_type;
1488 rf_helper->action = action;
1489 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1490 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1491 rf_helper->account_name = (active_acc) ?
1492 g_strdup (active_acc) :
1493 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1499 free_reply_forward_helper (gpointer data)
1501 ReplyForwardHelper *helper;
1503 helper = (ReplyForwardHelper *) data;
1504 g_free (helper->account_name);
1506 g_object_unref (helper->header);
1507 g_slice_free (ReplyForwardHelper, helper);
1511 reply_forward_cb (ModestMailOperation *mail_op,
1518 TnyMsg *new_msg = NULL;
1519 ReplyForwardHelper *rf_helper;
1520 ModestWindow *msg_win = NULL;
1521 ModestEditType edit_type;
1523 TnyAccount *account = NULL;
1524 ModestWindowMgr *mgr = NULL;
1525 gchar *signature = NULL;
1526 gboolean use_signature;
1528 /* If there was any error. The mail operation could be NULL,
1529 this means that we already have the message downloaded and
1530 that we didn't do a mail operation to retrieve it */
1531 rf_helper = (ReplyForwardHelper *) user_data;
1532 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1535 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1536 rf_helper->account_name);
1537 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr(),
1538 rf_helper->account_name,
1541 /* Create reply mail */
1542 switch (rf_helper->action) {
1545 modest_tny_msg_create_reply_msg (msg, header, from,
1546 (use_signature) ? signature : NULL,
1547 rf_helper->reply_forward_type,
1548 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1550 case ACTION_REPLY_TO_ALL:
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_ALL);
1556 edit_type = MODEST_EDIT_TYPE_REPLY;
1558 case ACTION_FORWARD:
1560 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1561 rf_helper->reply_forward_type);
1562 edit_type = MODEST_EDIT_TYPE_FORWARD;
1565 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1567 g_return_if_reached ();
1575 g_warning ("%s: failed to create message\n", __FUNCTION__);
1579 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1580 rf_helper->account_name,
1581 TNY_ACCOUNT_TYPE_STORE);
1583 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1587 /* Create and register the windows */
1588 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1589 mgr = modest_runtime_get_window_mgr ();
1590 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1592 if (rf_helper->parent_window != NULL) {
1593 gdouble parent_zoom;
1595 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1596 modest_window_set_zoom (msg_win, parent_zoom);
1599 /* Show edit window */
1600 gtk_widget_show_all (GTK_WIDGET (msg_win));
1603 /* We always unregister the header because the message is
1604 forwarded or replied so the original one is no longer
1606 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1609 g_object_unref (G_OBJECT (new_msg));
1611 g_object_unref (G_OBJECT (account));
1612 free_reply_forward_helper (rf_helper);
1615 /* Checks a list of headers. If any of them are not currently
1616 * downloaded (CACHED) then returns TRUE else returns FALSE.
1619 header_list_count_uncached_msgs (TnyList *header_list)
1622 gint uncached_messages = 0;
1624 iter = tny_list_create_iterator (header_list);
1625 while (!tny_iterator_is_done (iter)) {
1628 header = TNY_HEADER (tny_iterator_get_current (iter));
1630 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1631 uncached_messages ++;
1632 g_object_unref (header);
1635 tny_iterator_next (iter);
1637 g_object_unref (iter);
1639 return uncached_messages;
1642 /* Returns FALSE if the user does not want to download the
1643 * messages. Returns TRUE if the user allowed the download.
1646 connect_to_get_msg (ModestWindow *win,
1647 gint num_of_uncached_msgs,
1648 TnyAccount *account)
1650 GtkResponseType response;
1652 /* Allways download if we are online. */
1653 if (tny_device_is_online (modest_runtime_get_device ()))
1656 /* If offline, then ask for user permission to download the messages */
1657 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1658 ngettext("mcen_nc_get_msg",
1660 num_of_uncached_msgs));
1662 if (response == GTK_RESPONSE_CANCEL)
1665 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1669 reply_forward_performer (gboolean canceled,
1671 GtkWindow *parent_window,
1672 TnyAccount *account,
1675 ReplyForwardHelper *rf_helper = NULL;
1676 ModestMailOperation *mail_op;
1678 rf_helper = (ReplyForwardHelper *) user_data;
1680 if (canceled || err) {
1681 free_reply_forward_helper (rf_helper);
1685 /* Retrieve the message */
1686 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1687 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1688 modest_ui_actions_disk_operations_error_handler,
1690 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1691 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1694 g_object_unref(mail_op);
1698 * Common code for the reply and forward actions
1701 reply_forward (ReplyForwardAction action, ModestWindow *win)
1703 ReplyForwardHelper *rf_helper = NULL;
1704 guint reply_forward_type;
1706 g_return_if_fail (MODEST_IS_WINDOW(win));
1708 /* we check for low-mem; in that case, show a warning, and don't allow
1709 * reply/forward (because it could potentially require a lot of memory */
1710 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1714 /* we need an account when editing */
1715 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1716 if (!modest_ui_actions_run_account_setup_wizard (win))
1720 reply_forward_type =
1721 modest_conf_get_int (modest_runtime_get_conf (),
1722 (action == ACTION_FORWARD) ?
1723 MODEST_CONF_FORWARD_TYPE :
1724 MODEST_CONF_REPLY_TYPE,
1727 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1729 TnyHeader *header = NULL;
1730 /* Get header and message. Do not free them here, the
1731 reply_forward_cb must do it */
1732 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1733 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1735 if (msg && header) {
1737 rf_helper = create_reply_forward_helper (action, win,
1738 reply_forward_type, header);
1739 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1741 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1745 g_object_unref (msg);
1747 g_object_unref (header);
1749 TnyHeader *header = NULL;
1751 gboolean do_retrieve = TRUE;
1752 TnyList *header_list = NULL;
1754 header_list = get_selected_headers (win);
1757 /* Check that only one message is selected for replying */
1758 if (tny_list_get_length (header_list) != 1) {
1759 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1760 NULL, _("mcen_ib_select_one_message"));
1761 g_object_unref (header_list);
1765 /* Only reply/forward to one message */
1766 iter = tny_list_create_iterator (header_list);
1767 header = TNY_HEADER (tny_iterator_get_current (iter));
1768 g_object_unref (iter);
1770 /* Retrieve messages */
1771 do_retrieve = (action == ACTION_FORWARD) ||
1772 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1775 TnyAccount *account = NULL;
1776 TnyFolder *folder = NULL;
1777 gdouble download = TRUE;
1778 guint uncached_msgs = 0;
1780 folder = tny_header_get_folder (header);
1782 goto do_retrieve_frees;
1783 account = tny_folder_get_account (folder);
1785 goto do_retrieve_frees;
1787 uncached_msgs = header_list_count_uncached_msgs (header_list);
1789 if (uncached_msgs > 0) {
1790 /* Allways download if we are online. */
1791 if (!tny_device_is_online (modest_runtime_get_device ())) {
1794 /* If ask for user permission to download the messages */
1795 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1796 ngettext("mcen_nc_get_msg",
1800 /* End if the user does not want to continue */
1801 if (response == GTK_RESPONSE_CANCEL)
1808 rf_helper = create_reply_forward_helper (action, win,
1809 reply_forward_type, header);
1810 if (uncached_msgs > 0) {
1811 modest_platform_connect_and_perform (GTK_WINDOW (win),
1813 reply_forward_performer,
1816 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
1817 account, rf_helper);
1822 g_object_unref (account);
1824 g_object_unref (folder);
1826 reply_forward_cb (NULL, header, FALSE, NULL, NULL, rf_helper);
1829 g_object_unref (header_list);
1830 g_object_unref (header);
1835 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1837 g_return_if_fail (MODEST_IS_WINDOW(win));
1839 reply_forward (ACTION_REPLY, win);
1843 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1845 g_return_if_fail (MODEST_IS_WINDOW(win));
1847 reply_forward (ACTION_FORWARD, win);
1851 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1853 g_return_if_fail (MODEST_IS_WINDOW(win));
1855 reply_forward (ACTION_REPLY_TO_ALL, win);
1859 modest_ui_actions_on_next (GtkAction *action,
1860 ModestWindow *window)
1862 if (MODEST_IS_MAIN_WINDOW (window)) {
1863 GtkWidget *header_view;
1865 header_view = modest_main_window_get_child_widget (
1866 MODEST_MAIN_WINDOW(window),
1867 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1871 modest_header_view_select_next (
1872 MODEST_HEADER_VIEW(header_view));
1873 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1874 modest_msg_view_window_select_next_message (
1875 MODEST_MSG_VIEW_WINDOW (window));
1877 g_return_if_reached ();
1882 modest_ui_actions_on_prev (GtkAction *action,
1883 ModestWindow *window)
1885 g_return_if_fail (MODEST_IS_WINDOW(window));
1887 if (MODEST_IS_MAIN_WINDOW (window)) {
1888 GtkWidget *header_view;
1889 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1890 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1894 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1895 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1896 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1898 g_return_if_reached ();
1903 modest_ui_actions_on_sort (GtkAction *action,
1904 ModestWindow *window)
1906 GtkWidget *header_view = NULL;
1908 g_return_if_fail (MODEST_IS_WINDOW(window));
1910 if (MODEST_IS_MAIN_WINDOW (window)) {
1911 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1912 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1913 #ifdef MODEST_TOOLKIT_HILDON2
1914 } else if (MODEST_IS_HEADER_WINDOW (window)) {
1915 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
1920 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1925 /* Show sorting dialog */
1926 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1930 new_messages_arrived (ModestMailOperation *self,
1931 TnyList *new_headers,
1935 gboolean show_visual_notifications;
1937 source = modest_mail_operation_get_source (self);
1938 show_visual_notifications = (source) ? FALSE : TRUE;
1940 g_object_unref (source);
1942 /* Notify new messages have been downloaded. If the
1943 send&receive was invoked by the user then do not show any
1944 visual notification, only play a sound and activate the LED
1945 (for the Maemo version) */
1946 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0)
1947 modest_platform_on_new_headers_received (new_headers,
1948 show_visual_notifications);
1953 retrieve_all_messages_cb (GObject *source,
1955 guint retrieve_limit)
1961 window = GTK_WINDOW (source);
1962 msg = g_strdup_printf (_("mail_nc_msg_count_limit_exceeded"),
1963 num_msgs, retrieve_limit);
1965 /* Ask the user if they want to retrieve all the messages */
1967 modest_platform_run_confirmation_dialog_with_buttons (window, msg,
1968 _("mcen_bd_get_all"),
1969 _("mcen_bd_newest_only"));
1970 /* Free and return */
1972 return (response == GTK_RESPONSE_ACCEPT) ? TRUE : FALSE;
1976 TnyAccount *account;
1978 gchar *account_name;
1979 gboolean poke_status;
1980 gboolean interactive;
1981 ModestMailOperation *mail_op;
1985 do_send_receive_performer (gboolean canceled,
1987 GtkWindow *parent_window,
1988 TnyAccount *account,
1991 SendReceiveInfo *info;
1993 info = (SendReceiveInfo *) user_data;
1995 if (err || canceled) {
1996 /* In memory full conditions we could get this error here */
1997 check_memory_full_error ((GtkWidget *) parent_window, err);
1999 if (info->mail_op) {
2000 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2006 /* Set send/receive operation in progress */
2007 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2008 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2011 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2012 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2013 G_CALLBACK (on_send_receive_finished),
2016 /* Send & receive. */
2017 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2018 (info->win) ? retrieve_all_messages_cb : NULL,
2019 new_messages_arrived, info->win);
2024 g_object_unref (G_OBJECT (info->mail_op));
2025 if (info->account_name)
2026 g_free (info->account_name);
2028 g_object_unref (info->win);
2030 g_object_unref (info->account);
2031 g_slice_free (SendReceiveInfo, info);
2035 * This function performs the send & receive required actions. The
2036 * window is used to create the mail operation. Typically it should
2037 * always be the main window, but we pass it as argument in order to
2041 modest_ui_actions_do_send_receive (const gchar *account_name,
2042 gboolean force_connection,
2043 gboolean poke_status,
2044 gboolean interactive,
2047 gchar *acc_name = NULL;
2048 SendReceiveInfo *info;
2049 ModestTnyAccountStore *acc_store;
2051 /* If no account name was provided then get the current account, and if
2052 there is no current account then pick the default one: */
2053 if (!account_name) {
2055 acc_name = g_strdup (modest_window_get_active_account (win));
2057 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2059 g_printerr ("modest: cannot get default account\n");
2063 acc_name = g_strdup (account_name);
2066 acc_store = modest_runtime_get_account_store ();
2068 /* Create the info for the connect and perform */
2069 info = g_slice_new (SendReceiveInfo);
2070 info->account_name = acc_name;
2071 info->win = (win) ? g_object_ref (win) : NULL;
2072 info->poke_status = poke_status;
2073 info->interactive = interactive;
2074 info->account = modest_tny_account_store_get_server_account (acc_store, acc_name,
2075 TNY_ACCOUNT_TYPE_STORE);
2076 /* We need to create the operation here, because otherwise it
2077 could happen that the queue emits the queue-empty signal
2078 while we're trying to connect the account */
2079 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2080 modest_ui_actions_disk_operations_error_handler,
2082 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2084 /* Invoke the connect and perform */
2085 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2086 force_connection, info->account,
2087 do_send_receive_performer, info);
2092 modest_ui_actions_do_cancel_send (const gchar *account_name,
2095 TnyTransportAccount *transport_account;
2096 TnySendQueue *send_queue = NULL;
2097 GError *error = NULL;
2099 /* Get transport account */
2101 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2102 (modest_runtime_get_account_store(),
2104 TNY_ACCOUNT_TYPE_TRANSPORT));
2105 if (!transport_account) {
2106 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2111 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2112 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2113 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2114 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2115 "modest: could not find send queue for account\n");
2117 /* Cancel the current send */
2118 tny_account_cancel (TNY_ACCOUNT (transport_account));
2120 /* Suspend all pending messages */
2121 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2125 if (transport_account != NULL)
2126 g_object_unref (G_OBJECT (transport_account));
2130 modest_ui_actions_cancel_send_all (ModestWindow *win)
2132 GSList *account_names, *iter;
2134 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2137 iter = account_names;
2139 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2140 iter = g_slist_next (iter);
2143 modest_account_mgr_free_account_names (account_names);
2144 account_names = NULL;
2148 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2151 /* Check if accounts exist */
2152 gboolean accounts_exist =
2153 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2155 /* If not, allow the user to create an account before trying to send/receive. */
2156 if (!accounts_exist)
2157 modest_ui_actions_on_accounts (NULL, win);
2159 /* Cancel all sending operaitons */
2160 modest_ui_actions_cancel_send_all (win);
2164 * Refreshes all accounts. This function will be used by automatic
2168 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2169 gboolean force_connection,
2170 gboolean poke_status,
2171 gboolean interactive)
2173 GSList *account_names, *iter;
2175 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2178 iter = account_names;
2180 modest_ui_actions_do_send_receive ((const char*) iter->data,
2182 poke_status, interactive, win);
2183 iter = g_slist_next (iter);
2186 modest_account_mgr_free_account_names (account_names);
2187 account_names = NULL;
2191 * Handler of the click on Send&Receive button in the main toolbar
2194 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2196 /* Check if accounts exist */
2197 gboolean accounts_exist;
2200 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2202 /* If not, allow the user to create an account before trying to send/receive. */
2203 if (!accounts_exist)
2204 modest_ui_actions_on_accounts (NULL, win);
2206 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2207 if (MODEST_IS_MAIN_WINDOW (win)) {
2208 GtkWidget *folder_view;
2209 TnyFolderStore *folder_store;
2212 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2213 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2217 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2220 g_object_unref (folder_store);
2221 /* Refresh the active account. Force the connection if needed
2222 and poke the status of all folders */
2223 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2225 const gchar *active_account;
2226 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2228 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2235 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2238 GtkWidget *header_view;
2240 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2242 header_view = modest_main_window_get_child_widget (main_window,
2243 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2247 conf = modest_runtime_get_conf ();
2249 /* what is saved/restored is depending on the style; thus; we save with
2250 * old style, then update the style, and restore for this new style
2252 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2254 if (modest_header_view_get_style
2255 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2256 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2257 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2259 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2260 MODEST_HEADER_VIEW_STYLE_DETAILS);
2262 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2263 MODEST_CONF_HEADER_VIEW_KEY);
2268 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2270 ModestMainWindow *main_window)
2272 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2273 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2275 /* in the case the folder is empty, show the empty folder message and focus
2277 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2278 if (modest_header_view_is_empty (header_view)) {
2279 TnyFolder *folder = modest_header_view_get_folder (header_view);
2280 GtkWidget *folder_view =
2281 modest_main_window_get_child_widget (main_window,
2282 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2283 if (folder != NULL) {
2284 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2285 g_object_unref (folder);
2287 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2291 /* If no header has been selected then exit */
2296 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2297 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2299 /* Update toolbar dimming state */
2300 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2301 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2305 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2308 ModestWindow *window)
2310 GtkWidget *open_widget;
2311 GtkTreeRowReference *rowref;
2313 g_return_if_fail (MODEST_IS_WINDOW(window));
2314 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2315 g_return_if_fail (TNY_IS_HEADER (header));
2317 if (modest_header_view_count_selected_headers (header_view) > 1) {
2318 /* Don't allow activation if there are more than one message selected */
2319 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2323 /* we check for low-mem; in that case, show a warning, and don't allow
2324 * activating headers
2326 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2329 if (MODEST_IS_MAIN_WINDOW (window)) {
2330 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2331 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2332 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2336 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2337 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2338 gtk_tree_row_reference_free (rowref);
2342 set_active_account_from_tny_account (TnyAccount *account,
2343 ModestWindow *window)
2345 const gchar *server_acc_name = tny_account_get_id (account);
2347 /* We need the TnyAccount provided by the
2348 account store because that is the one that
2349 knows the name of the Modest account */
2350 TnyAccount *modest_server_account = modest_server_account =
2351 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2352 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2354 if (!modest_server_account) {
2355 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2359 /* Update active account, but only if it's not a pseudo-account */
2360 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2361 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2362 const gchar *modest_acc_name =
2363 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2364 if (modest_acc_name)
2365 modest_window_set_active_account (window, modest_acc_name);
2368 g_object_unref (modest_server_account);
2373 folder_refreshed_cb (ModestMailOperation *mail_op,
2377 ModestMainWindow *win = NULL;
2378 GtkWidget *folder_view;
2379 const GError *error;
2381 g_return_if_fail (TNY_IS_FOLDER (folder));
2383 win = MODEST_MAIN_WINDOW (user_data);
2385 /* Check if the operation failed due to memory low conditions */
2386 error = modest_mail_operation_get_error (mail_op);
2387 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2388 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2389 modest_platform_run_information_dialog (GTK_WINDOW (win),
2390 dgettext("ke-recv","memr_ib_operation_disabled"),
2396 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2399 TnyFolderStore *current_folder;
2401 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2402 if (current_folder) {
2403 gboolean different = ((TnyFolderStore *) folder != current_folder);
2404 g_object_unref (current_folder);
2410 /* Check if folder is empty and set headers view contents style */
2411 if (tny_folder_get_all_count (folder) == 0)
2412 modest_main_window_set_contents_style (win,
2413 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2418 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2419 TnyFolderStore *folder_store,
2421 ModestMainWindow *main_window)
2424 GtkWidget *header_view;
2426 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2428 header_view = modest_main_window_get_child_widget(main_window,
2429 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2433 conf = modest_runtime_get_conf ();
2435 if (TNY_IS_ACCOUNT (folder_store)) {
2437 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2439 /* Show account details */
2440 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2443 if (TNY_IS_FOLDER (folder_store) && selected) {
2444 TnyAccount *account;
2445 const gchar *account_name = NULL;
2447 /* Update the active account */
2448 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2450 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2452 modest_tny_account_get_parent_modest_account_name_for_server_account (account);
2453 g_object_unref (account);
2457 /* Set the header style by default, it could
2458 be changed later by the refresh callback to
2460 modest_main_window_set_contents_style (main_window,
2461 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2463 /* Set folder on header view. This function
2464 will call tny_folder_refresh_async so we
2465 pass a callback that will be called when
2466 finished. We use that callback to set the
2467 empty view if there are no messages */
2468 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2469 TNY_FOLDER (folder_store),
2471 MODEST_WINDOW (main_window),
2472 folder_refreshed_cb,
2475 /* Restore configuration. We need to do this
2476 *after* the set_folder because the widget
2477 memory asks the header view about its
2479 modest_widget_memory_restore (modest_runtime_get_conf (),
2480 G_OBJECT(header_view),
2481 MODEST_CONF_HEADER_VIEW_KEY);
2483 /* No need to save the header view
2484 configuration for Maemo because it only
2485 saves the sorting stuff and that it's
2486 already being done by the sort
2487 dialog. Remove it when the GNOME version
2488 has the same behaviour */
2489 #ifdef MODEST_TOOLKIT_GTK
2490 if (modest_main_window_get_contents_style (main_window) ==
2491 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2492 modest_widget_memory_save (conf, G_OBJECT (header_view),
2493 MODEST_CONF_HEADER_VIEW_KEY);
2495 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2499 /* Update dimming state */
2500 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2501 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2505 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2512 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2514 online = tny_device_is_online (modest_runtime_get_device());
2517 /* already online -- the item is simply not there... */
2518 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2520 GTK_MESSAGE_WARNING,
2522 _("The %s you selected cannot be found"),
2524 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2525 gtk_dialog_run (GTK_DIALOG(dialog));
2527 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2530 _("mcen_bd_dialog_cancel"),
2531 GTK_RESPONSE_REJECT,
2532 _("mcen_bd_dialog_ok"),
2533 GTK_RESPONSE_ACCEPT,
2535 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2536 "Do you want to get online?"), item);
2537 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2538 gtk_label_new (txt), FALSE, FALSE, 0);
2539 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2542 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2543 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2544 /* TODO: Comment about why is this commented out: */
2545 /* modest_platform_connect_and_wait (); */
2548 gtk_widget_destroy (dialog);
2552 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2555 /* g_message ("%s %s", __FUNCTION__, link); */
2560 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2563 modest_platform_activate_uri (link);
2567 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2570 modest_platform_show_uri_popup (link);
2574 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2577 /* we check for low-mem; in that case, show a warning, and don't allow
2578 * viewing attachments
2580 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2583 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2587 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2588 const gchar *address,
2591 /* g_message ("%s %s", __FUNCTION__, address); */
2595 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2596 TnyMsg *saved_draft,
2599 ModestMsgEditWindow *edit_window;
2601 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2602 #ifndef MODEST_TOOLKIT_HILDON2
2603 ModestMainWindow *win;
2605 /* FIXME. Make the header view sensitive again. This is a
2606 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2608 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2609 modest_runtime_get_window_mgr(), FALSE));
2611 GtkWidget *hdrview = modest_main_window_get_child_widget(
2612 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2613 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2617 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2619 /* Set draft is there was no error */
2620 if (!modest_mail_operation_get_error (mail_op))
2621 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2623 g_object_unref(edit_window);
2627 enough_space_for_message (ModestMsgEditWindow *edit_window,
2630 TnyAccountStore *acc_store;
2631 guint64 available_disk, expected_size;
2636 acc_store = TNY_ACCOUNT_STORE (modest_runtime_get_account_store());
2637 available_disk = modest_utils_get_available_space (NULL);
2638 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2639 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2644 /* Double check: memory full condition or message too big */
2645 if (available_disk < MIN_FREE_SPACE ||
2646 expected_size > available_disk) {
2648 modest_platform_information_banner (NULL, NULL,
2650 "cerm_device_memory_full"));
2655 * djcb: if we're in low-memory state, we only allow for
2656 * saving messages smaller than
2657 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2658 * should still allow for sending anything critical...
2660 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2661 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2665 * djcb: we also make sure that the attachments are smaller than the max size
2666 * this is for the case where we'd try to forward a message with attachments
2667 * bigger than our max allowed size, or sending an message from drafts which
2668 * somehow got past our checks when attaching.
2670 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2671 modest_platform_run_information_dialog (
2672 GTK_WINDOW(edit_window),
2673 dgettext("ke-recv","memr_ib_operation_disabled"),
2682 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2684 TnyTransportAccount *transport_account;
2685 ModestMailOperation *mail_operation;
2687 gchar *account_name, *from;
2688 ModestAccountMgr *account_mgr;
2689 gboolean had_error = FALSE;
2690 ModestMainWindow *win = NULL;
2692 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2694 data = modest_msg_edit_window_get_msg_data (edit_window);
2697 if (!enough_space_for_message (edit_window, data)) {
2698 modest_msg_edit_window_free_msg_data (edit_window, data);
2702 account_name = g_strdup (data->account_name);
2703 account_mgr = modest_runtime_get_account_mgr();
2705 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2707 account_name = modest_account_mgr_get_default_account (account_mgr);
2708 if (!account_name) {
2709 g_printerr ("modest: no account found\n");
2710 modest_msg_edit_window_free_msg_data (edit_window, data);
2714 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2715 account_name = g_strdup (data->account_name);
2719 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2720 (modest_runtime_get_account_store (),
2722 TNY_ACCOUNT_TYPE_TRANSPORT));
2723 if (!transport_account) {
2724 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2725 g_free (account_name);
2726 modest_msg_edit_window_free_msg_data (edit_window, data);
2729 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2731 /* Create the mail operation */
2732 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
2734 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2736 modest_mail_operation_save_to_drafts (mail_operation,
2748 data->priority_flags,
2749 on_save_to_drafts_cb,
2750 g_object_ref(edit_window));
2752 #ifdef MODEST_TOOLKIT_HILDON2
2753 /* In hildon2 we always show the information banner on saving to drafts.
2754 * It will be a system information banner in this case.
2756 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2757 modest_platform_information_banner (NULL, NULL, text);
2760 /* Use the main window as the parent of the banner, if the
2761 main window does not exist it won't be shown, if the parent
2762 window exists then it's properly shown. We don't use the
2763 editor window because it could be closed (save to drafts
2764 could happen after closing the window */
2765 win = (ModestMainWindow *)
2766 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
2768 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2769 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
2773 modest_msg_edit_window_set_modified (edit_window, FALSE);
2777 g_free (account_name);
2778 g_object_unref (G_OBJECT (transport_account));
2779 g_object_unref (G_OBJECT (mail_operation));
2781 modest_msg_edit_window_free_msg_data (edit_window, data);
2784 * If the drafts folder is selected then make the header view
2785 * insensitive while the message is being saved to drafts
2786 * (it'll be sensitive again in on_save_to_drafts_cb()). This
2787 * is not very clean but it avoids letting the drafts folder
2788 * in an inconsistent state: the user could edit the message
2789 * being saved and undesirable things would happen.
2790 * In the average case the user won't notice anything at
2791 * all. In the worst case (the user is editing a really big
2792 * file from Drafts) the header view will be insensitive
2793 * during the saving process (10 or 20 seconds, depending on
2794 * the message). Anyway this is just a quick workaround: once
2795 * we find a better solution it should be removed
2796 * See NB#65125 (commend #18) for details.
2798 if (!had_error && win != NULL) {
2799 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
2800 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
2802 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
2804 if (modest_tny_folder_is_local_folder(folder)) {
2805 TnyFolderType folder_type;
2806 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
2807 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
2808 GtkWidget *hdrview = modest_main_window_get_child_widget(
2809 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2810 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
2814 if (folder != NULL) g_object_unref(folder);
2821 /* For instance, when clicking the Send toolbar button when editing a message: */
2823 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2825 TnyTransportAccount *transport_account = NULL;
2826 gboolean had_error = FALSE;
2828 ModestAccountMgr *account_mgr;
2829 gchar *account_name;
2831 ModestMailOperation *mail_operation;
2833 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
2835 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2838 data = modest_msg_edit_window_get_msg_data (edit_window);
2841 if (!enough_space_for_message (edit_window, data)) {
2842 modest_msg_edit_window_free_msg_data (edit_window, data);
2846 account_mgr = modest_runtime_get_account_mgr();
2847 account_name = g_strdup (data->account_name);
2849 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2852 account_name = modest_account_mgr_get_default_account (account_mgr);
2854 if (!account_name) {
2855 modest_msg_edit_window_free_msg_data (edit_window, data);
2856 /* Run account setup wizard */
2857 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
2862 /* Get the currently-active transport account for this modest account: */
2863 if (strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
2865 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2866 (modest_runtime_get_account_store (),
2867 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
2870 if (!transport_account) {
2871 modest_msg_edit_window_free_msg_data (edit_window, data);
2872 /* Run account setup wizard */
2873 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2878 /* Create the mail operation */
2879 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2880 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
2881 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2883 modest_mail_operation_send_new_mail (mail_operation,
2895 data->priority_flags);
2897 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
2898 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2901 if (modest_mail_operation_get_error (mail_operation) != NULL) {
2902 const GError *error = modest_mail_operation_get_error (mail_operation);
2903 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
2904 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
2905 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
2906 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
2913 g_free (account_name);
2914 g_object_unref (G_OBJECT (transport_account));
2915 g_object_unref (G_OBJECT (mail_operation));
2917 modest_msg_edit_window_free_msg_data (edit_window, data);
2920 modest_msg_edit_window_set_sent (edit_window, TRUE);
2922 /* Save settings and close the window: */
2923 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2930 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2931 ModestMsgEditWindow *window)
2933 ModestMsgEditFormatState *format_state = NULL;
2935 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2936 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2938 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2941 format_state = modest_msg_edit_window_get_format_state (window);
2942 g_return_if_fail (format_state != NULL);
2944 format_state->bold = gtk_toggle_action_get_active (action);
2945 modest_msg_edit_window_set_format_state (window, format_state);
2946 g_free (format_state);
2951 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2952 ModestMsgEditWindow *window)
2954 ModestMsgEditFormatState *format_state = NULL;
2956 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2957 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2959 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2962 format_state = modest_msg_edit_window_get_format_state (window);
2963 g_return_if_fail (format_state != NULL);
2965 format_state->italics = gtk_toggle_action_get_active (action);
2966 modest_msg_edit_window_set_format_state (window, format_state);
2967 g_free (format_state);
2972 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2973 ModestMsgEditWindow *window)
2975 ModestMsgEditFormatState *format_state = NULL;
2977 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2978 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2980 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2983 format_state = modest_msg_edit_window_get_format_state (window);
2984 g_return_if_fail (format_state != NULL);
2986 format_state->bullet = gtk_toggle_action_get_active (action);
2987 modest_msg_edit_window_set_format_state (window, format_state);
2988 g_free (format_state);
2993 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2994 GtkRadioAction *selected,
2995 ModestMsgEditWindow *window)
2997 ModestMsgEditFormatState *format_state = NULL;
2998 GtkJustification value;
3000 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3002 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3005 value = gtk_radio_action_get_current_value (selected);
3007 format_state = modest_msg_edit_window_get_format_state (window);
3008 g_return_if_fail (format_state != NULL);
3010 format_state->justification = value;
3011 modest_msg_edit_window_set_format_state (window, format_state);
3012 g_free (format_state);
3016 modest_ui_actions_on_select_editor_color (GtkAction *action,
3017 ModestMsgEditWindow *window)
3019 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3020 g_return_if_fail (GTK_IS_ACTION (action));
3022 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3025 modest_msg_edit_window_select_color (window);
3029 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3030 ModestMsgEditWindow *window)
3032 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3033 g_return_if_fail (GTK_IS_ACTION (action));
3035 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3038 modest_msg_edit_window_select_background_color (window);
3042 modest_ui_actions_on_insert_image (GtkAction *action,
3043 ModestMsgEditWindow *window)
3045 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3046 g_return_if_fail (GTK_IS_ACTION (action));
3049 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3052 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3055 modest_msg_edit_window_insert_image (window);
3059 modest_ui_actions_on_attach_file (GtkAction *action,
3060 ModestMsgEditWindow *window)
3062 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3063 g_return_if_fail (GTK_IS_ACTION (action));
3065 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3068 modest_msg_edit_window_offer_attach_file (window);
3072 modest_ui_actions_on_remove_attachments (GtkAction *action,
3073 ModestMsgEditWindow *window)
3075 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3076 g_return_if_fail (GTK_IS_ACTION (action));
3078 modest_msg_edit_window_remove_attachments (window, NULL);
3082 #ifndef MODEST_TOOLKIT_GTK
3087 TnyFolderStore *folder;
3088 } CreateFolderHelper;
3091 show_create_folder_in_timeout (gpointer data)
3093 CreateFolderHelper *helper = (CreateFolderHelper *) data;
3095 /* Remove the timeout ASAP, we can not wait until the dialog
3096 is shown because it could take a lot of time and so the
3097 timeout could be called twice or more times */
3098 g_source_remove (helper->handler);
3100 gdk_threads_enter ();
3101 do_create_folder (helper->win, helper->folder, helper->name);
3102 gdk_threads_leave ();
3104 g_object_unref (helper->win);
3105 g_object_unref (helper->folder);
3106 g_free (helper->name);
3107 g_slice_free (CreateFolderHelper, helper);
3114 do_create_folder_cb (ModestMailOperation *mail_op,
3115 TnyFolderStore *parent_folder,
3116 TnyFolder *new_folder,
3119 gchar *suggested_name = (gchar *) user_data;
3120 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3122 if (modest_mail_operation_get_error (mail_op)) {
3124 /* Show an error. If there was some problem writing to
3125 disk, show it, otherwise show the generic folder
3126 create error. We do it here and not in an error
3127 handler because the call to do_create_folder will
3128 stop the main loop in a gtk_dialog_run and then,
3129 the message won't be shown until that dialog is
3131 modest_ui_actions_disk_operations_error_handler (mail_op,
3132 _("mail_in_ui_folder_create_error"));
3134 /* Try again. Do *NOT* show any error because the mail
3135 operations system will do it for us because we
3136 created the mail_op with new_with_error_handler */
3137 #ifndef MODEST_TOOLKIT_GTK
3138 CreateFolderHelper *helper;
3139 helper = g_slice_new0 (CreateFolderHelper);
3140 helper->name = g_strdup (suggested_name);
3141 helper->folder = g_object_ref (parent_folder);
3142 helper->win = g_object_ref (source_win);
3144 /* Ugly but neccesary stuff. The problem is that the
3145 dialog when is shown calls a function that destroys
3146 all the temporary windows, so the banner is
3148 helper->handler = g_timeout_add (2000, show_create_folder_in_timeout, helper);
3150 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3153 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3154 * FIXME: any other? */
3155 GtkWidget *folder_view;
3157 if (MODEST_IS_MAIN_WINDOW(source_win))
3159 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3160 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3163 get_folder_view_from_move_to_dialog (GTK_WIDGET(source_win));
3165 /* Select the newly created folder. It could happen
3166 that the widget is no longer there (i.e. the window
3167 has been destroyed, so we need to check this */
3169 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3171 g_object_unref (new_folder);
3173 /* Free. Note that the first time it'll be NULL so noop */
3174 g_free (suggested_name);
3175 g_object_unref (source_win);
3179 do_create_folder (GtkWindow *parent_window,
3180 TnyFolderStore *parent_folder,
3181 const gchar *suggested_name)
3184 gchar *folder_name = NULL;
3186 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3188 (gchar *) suggested_name,
3191 if (result == GTK_RESPONSE_ACCEPT) {
3192 ModestMailOperation *mail_op;
3194 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3195 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3197 modest_mail_operation_create_folder (mail_op,
3199 (const gchar *) folder_name,
3200 do_create_folder_cb,
3202 g_object_unref (mail_op);
3207 create_folder_performer (gboolean canceled,
3209 GtkWindow *parent_window,
3210 TnyAccount *account,
3213 TnyFolderStore *parent_folder = TNY_FOLDER_STORE (user_data);
3215 if (canceled || err) {
3216 /* In memory full conditions we could get this error here */
3217 check_memory_full_error ((GtkWidget *) parent_window, err);
3221 /* Run the new folder dialog */
3222 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3225 g_object_unref (parent_folder);
3229 modest_ui_actions_create_folder(GtkWidget *parent_window,
3230 GtkWidget *folder_view)
3232 TnyFolderStore *parent_folder;
3234 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3236 if (parent_folder) {
3237 /* The parent folder will be freed in the callback */
3238 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3241 create_folder_performer,
3247 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
3249 GtkWidget *folder_view;
3251 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3253 folder_view = modest_main_window_get_child_widget (main_window,
3254 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3258 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
3262 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3265 const GError *error = NULL;
3266 const gchar *message = NULL;
3268 /* Get error message */
3269 error = modest_mail_operation_get_error (mail_op);
3271 g_return_if_reached ();
3273 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3274 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3275 message = _CS("ckdg_ib_folder_already_exists");
3276 } else if (error->domain == TNY_ERROR_DOMAIN &&
3277 error->code == TNY_SERVICE_ERROR_STATE) {
3278 /* This means that the folder is already in use (a
3279 message is opened for example */
3280 message = _("emev_ni_internal_error");
3282 message = _("emev_ib_ui_imap_unable_to_rename");
3285 /* We don't set a parent for the dialog because the dialog
3286 will be destroyed so the banner won't appear */
3287 modest_platform_information_banner (NULL, NULL, message);
3291 TnyFolderStore *folder;
3296 on_rename_folder_cb (ModestMailOperation *mail_op,
3297 TnyFolder *new_folder,
3300 ModestFolderView *folder_view;
3302 /* If the window was closed when renaming a folder this could
3304 if (!MODEST_IS_FOLDER_VIEW (user_data))
3307 folder_view = MODEST_FOLDER_VIEW (user_data);
3308 /* Note that if the rename fails new_folder will be NULL */
3310 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3312 modest_folder_view_select_first_inbox_or_local (folder_view);
3314 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3318 on_rename_folder_performer (gboolean canceled,
3320 GtkWindow *parent_window,
3321 TnyAccount *account,
3324 ModestMailOperation *mail_op = NULL;
3325 GtkTreeSelection *sel = NULL;
3326 GtkWidget *folder_view = NULL;
3327 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3329 if (canceled || err) {
3330 /* In memory full conditions we could get this error here */
3331 check_memory_full_error ((GtkWidget *) parent_window, err);
3332 } else if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3334 folder_view = modest_main_window_get_child_widget (
3335 MODEST_MAIN_WINDOW (parent_window),
3336 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3339 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3340 modest_ui_actions_rename_folder_error_handler,
3341 parent_window, NULL);
3343 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3346 /* Clear the headers view */
3347 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3348 gtk_tree_selection_unselect_all (sel);
3350 /* Actually rename the folder */
3351 modest_mail_operation_rename_folder (mail_op,
3352 TNY_FOLDER (data->folder),
3353 (const gchar *) (data->new_name),
3354 on_rename_folder_cb,
3356 g_object_unref (data->folder);
3357 g_object_unref (mail_op);
3360 g_free (data->new_name);
3365 modest_ui_actions_on_rename_folder (GtkAction *action,
3366 ModestMainWindow *main_window)
3368 TnyFolderStore *folder;
3369 GtkWidget *folder_view;
3370 GtkWidget *header_view;
3372 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3374 folder_view = modest_main_window_get_child_widget (main_window,
3375 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3379 header_view = modest_main_window_get_child_widget (main_window,
3380 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3385 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3390 if (TNY_IS_FOLDER (folder)) {
3391 gchar *folder_name = NULL;
3393 const gchar *current_name;
3394 TnyFolderStore *parent;
3395 gboolean do_rename = TRUE;
3397 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3398 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3399 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
3400 parent, current_name,
3402 g_object_unref (parent);
3404 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3407 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3408 rename_folder_data->folder = g_object_ref (folder);
3409 rename_folder_data->new_name = folder_name;
3410 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(main_window), TRUE,
3411 folder, on_rename_folder_performer, rename_folder_data);
3414 g_object_unref (folder);
3418 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3421 GObject *win = modest_mail_operation_get_source (mail_op);
3423 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3424 _("mail_in_ui_folder_delete_error"),
3426 g_object_unref (win);
3430 TnyFolderStore *folder;
3431 gboolean move_to_trash;
3435 on_delete_folder_cb (gboolean canceled,
3437 GtkWindow *parent_window,
3438 TnyAccount *account,
3441 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3442 GtkWidget *folder_view;
3443 ModestMailOperation *mail_op;
3444 GtkTreeSelection *sel;
3446 if (!MODEST_IS_MAIN_WINDOW(parent_window) || canceled || (err!=NULL)) {
3447 g_object_unref (G_OBJECT (info->folder));
3452 folder_view = modest_main_window_get_child_widget (
3453 MODEST_MAIN_WINDOW (parent_window),
3454 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3456 /* Unselect the folder before deleting it to free the headers */
3457 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3458 gtk_tree_selection_unselect_all (sel);
3460 /* Create the mail operation */
3462 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3463 modest_ui_actions_delete_folder_error_handler,
3466 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3468 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3470 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3472 g_object_unref (G_OBJECT (mail_op));
3473 g_object_unref (G_OBJECT (info->folder));
3478 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
3480 TnyFolderStore *folder;
3481 GtkWidget *folder_view;
3485 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3487 folder_view = modest_main_window_get_child_widget (main_window,
3488 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3492 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3494 /* Show an error if it's an account */
3495 if (!TNY_IS_FOLDER (folder)) {
3496 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
3497 _("mail_in_ui_folder_delete_error"),
3499 g_object_unref (G_OBJECT (folder));
3504 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3505 tny_folder_get_name (TNY_FOLDER (folder)));
3506 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
3507 (const gchar *) message);
3510 if (response == GTK_RESPONSE_OK) {
3511 DeleteFolderInfo *info;
3512 info = g_new0(DeleteFolderInfo, 1);
3513 info->folder = folder;
3514 info->move_to_trash = move_to_trash;
3515 g_object_ref (G_OBJECT (info->folder));
3516 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder));
3517 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (main_window),
3519 TNY_FOLDER_STORE (account),
3520 on_delete_folder_cb, info);
3521 g_object_unref (account);
3523 g_object_unref (G_OBJECT (folder));
3527 modest_ui_actions_on_delete_folder (GtkAction *action,
3528 ModestMainWindow *main_window)
3530 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3532 delete_folder (main_window, FALSE);
3536 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3538 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3540 delete_folder (main_window, TRUE);
3544 typedef struct _PasswordDialogFields {
3545 GtkWidget *username;
3546 GtkWidget *password;
3548 } PasswordDialogFields;
3551 password_dialog_check_field (GtkEditable *editable,
3552 PasswordDialogFields *fields)
3555 gboolean any_value_empty = FALSE;
3557 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
3558 if ((value == NULL) || value[0] == '\0') {
3559 any_value_empty = TRUE;
3561 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
3562 if ((value == NULL) || value[0] == '\0') {
3563 any_value_empty = TRUE;
3565 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3569 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3570 const gchar* server_account_name,
3575 ModestMainWindow *main_window)
3577 g_return_if_fail(server_account_name);
3578 gboolean completed = FALSE;
3579 PasswordDialogFields *fields = NULL;
3581 /* Initalize output parameters: */
3588 #ifndef MODEST_TOOLKIT_GTK
3589 /* Maemo uses a different (awkward) button order,
3590 * It should probably just use gtk_alternative_dialog_button_order ().
3592 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3595 _("mcen_bd_dialog_ok"),
3596 GTK_RESPONSE_ACCEPT,
3597 _("mcen_bd_dialog_cancel"),
3598 GTK_RESPONSE_REJECT,
3601 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3605 GTK_RESPONSE_REJECT,
3607 GTK_RESPONSE_ACCEPT,
3609 #endif /* !MODEST_TOOLKIT_GTK */
3611 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3613 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3614 modest_runtime_get_account_mgr(), server_account_name);
3615 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3616 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3619 gtk_widget_destroy (dialog);
3623 /* This causes a warning because the logical ID has no %s in it,
3624 * though the translation does, but there is not much we can do about that: */
3625 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3626 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
3629 g_free (server_name);
3633 gchar *initial_username = modest_account_mgr_get_server_account_username (
3634 modest_runtime_get_account_mgr(), server_account_name);
3636 GtkWidget *entry_username = gtk_entry_new ();
3637 if (initial_username)
3638 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
3639 /* Dim this if a connection has ever succeeded with this username,
3640 * as per the UI spec: */
3641 /* const gboolean username_known = */
3642 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3643 /* modest_runtime_get_account_mgr(), server_account_name); */
3644 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3646 /* We drop the username sensitive code and disallow changing it here
3647 * as tinymail does not support really changing the username in the callback
3649 gtk_widget_set_sensitive (entry_username, FALSE);
3651 #ifndef MODEST_TOOLKIT_GTK
3652 /* Auto-capitalization is the default, so let's turn it off: */
3653 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3655 /* Create a size group to be used by all captions.
3656 * Note that HildonCaption does not create a default size group if we do not specify one.
3657 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3658 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3660 GtkWidget *caption = hildon_caption_new (sizegroup,
3661 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
3662 gtk_widget_show (entry_username);
3663 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3664 FALSE, FALSE, MODEST_MARGIN_HALF);
3665 gtk_widget_show (caption);
3667 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
3669 #endif /* !MODEST_TOOLKIT_GTK */
3672 GtkWidget *entry_password = gtk_entry_new ();
3673 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3674 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3676 #ifndef MODEST_TOOLKIT_GTK
3677 /* Auto-capitalization is the default, so let's turn it off: */
3678 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3679 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3681 caption = hildon_caption_new (sizegroup,
3682 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
3683 gtk_widget_show (entry_password);
3684 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3685 FALSE, FALSE, MODEST_MARGIN_HALF);
3686 gtk_widget_show (caption);
3687 g_object_unref (sizegroup);
3689 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
3691 #endif /* !MODEST_TOOLKIT_GTK */
3693 if (initial_username != NULL)
3694 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3696 /* This is not in the Maemo UI spec:
3697 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3698 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3702 fields = g_slice_new0 (PasswordDialogFields);
3703 fields->username = entry_username;
3704 fields->password = entry_password;
3705 fields->dialog = dialog;
3707 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3708 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3709 password_dialog_check_field (NULL, fields);
3711 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3713 while (!completed) {
3715 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3717 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
3719 /* Note that an empty field becomes the "" string */
3720 if (*username && strlen (*username) > 0) {
3721 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
3722 server_account_name,
3726 const gboolean username_was_changed =
3727 (strcmp (*username, initial_username) != 0);
3728 if (username_was_changed) {
3729 g_warning ("%s: tinymail does not yet support changing the "
3730 "username in the get_password() callback.\n", __FUNCTION__);
3736 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
3737 _("mcen_ib_username_pw_incorrect"));
3743 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
3745 /* We do not save the password in the configuration,
3746 * because this function is only called for passwords that should
3747 * not be remembered:
3748 modest_server_account_set_password (
3749 modest_runtime_get_account_mgr(), server_account_name,
3756 /* Set parent to NULL or the banner will disappear with its parent dialog */
3757 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
3768 /* This is not in the Maemo UI spec:
3769 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3775 g_free (initial_username);
3776 gtk_widget_destroy (dialog);
3777 g_slice_free (PasswordDialogFields, fields);
3779 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3783 modest_ui_actions_on_cut (GtkAction *action,
3784 ModestWindow *window)
3786 GtkWidget *focused_widget;
3787 GtkClipboard *clipboard;
3789 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3790 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3791 if (GTK_IS_EDITABLE (focused_widget)) {
3792 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3793 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3794 gtk_clipboard_store (clipboard);
3795 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3796 GtkTextBuffer *buffer;
3798 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3799 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3800 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3801 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3802 gtk_clipboard_store (clipboard);
3804 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3805 TnyList *header_list = modest_header_view_get_selected_headers (
3806 MODEST_HEADER_VIEW (focused_widget));
3807 gboolean continue_download = FALSE;
3808 gint num_of_unc_msgs;
3810 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3812 if (num_of_unc_msgs) {
3813 TnyAccount *account = get_account_from_header_list (header_list);
3815 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3816 g_object_unref (account);
3820 if (num_of_unc_msgs == 0 || continue_download) {
3821 /* modest_platform_information_banner (
3822 NULL, NULL, _CS("mcen_ib_getting_items"));*/
3823 modest_header_view_cut_selection (
3824 MODEST_HEADER_VIEW (focused_widget));
3827 g_object_unref (header_list);
3828 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3829 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3834 modest_ui_actions_on_copy (GtkAction *action,
3835 ModestWindow *window)
3837 GtkClipboard *clipboard;
3838 GtkWidget *focused_widget;
3839 gboolean copied = TRUE;
3841 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3842 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3844 if (GTK_IS_LABEL (focused_widget)) {
3846 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
3847 gtk_clipboard_set_text (clipboard, selection, -1);
3849 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3850 gtk_clipboard_store (clipboard);
3851 } else if (GTK_IS_EDITABLE (focused_widget)) {
3852 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3853 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3854 gtk_clipboard_store (clipboard);
3855 } else if (GTK_IS_HTML (focused_widget)) {
3858 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
3859 if ((sel == NULL) || (sel[0] == '\0')) {
3862 gtk_html_copy (GTK_HTML (focused_widget));
3863 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3864 gtk_clipboard_store (clipboard);
3866 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3867 GtkTextBuffer *buffer;
3868 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3869 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3870 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3871 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3872 gtk_clipboard_store (clipboard);
3874 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3875 TnyList *header_list = modest_header_view_get_selected_headers (
3876 MODEST_HEADER_VIEW (focused_widget));
3877 gboolean continue_download = FALSE;
3878 gint num_of_unc_msgs;
3880 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3882 if (num_of_unc_msgs) {
3883 TnyAccount *account = get_account_from_header_list (header_list);
3885 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3886 g_object_unref (account);
3890 if (num_of_unc_msgs == 0 || continue_download) {
3891 modest_platform_information_banner (
3892 NULL, NULL, _CS("mcen_ib_getting_items"));
3893 modest_header_view_copy_selection (
3894 MODEST_HEADER_VIEW (focused_widget));
3898 g_object_unref (header_list);
3900 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3901 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3904 /* Show information banner if there was a copy to clipboard */
3906 modest_platform_information_banner (
3907 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3911 modest_ui_actions_on_undo (GtkAction *action,
3912 ModestWindow *window)
3914 ModestEmailClipboard *clipboard = NULL;
3916 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3917 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3918 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3919 /* Clear clipboard source */
3920 clipboard = modest_runtime_get_email_clipboard ();
3921 modest_email_clipboard_clear (clipboard);
3924 g_return_if_reached ();
3929 modest_ui_actions_on_redo (GtkAction *action,
3930 ModestWindow *window)
3932 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3933 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3936 g_return_if_reached ();
3942 destroy_information_note (ModestMailOperation *mail_op,
3945 /* destroy information note */
3946 gtk_widget_destroy (GTK_WIDGET(user_data));
3950 destroy_folder_information_note (ModestMailOperation *mail_op,
3951 TnyFolder *new_folder,
3954 /* destroy information note */
3955 gtk_widget_destroy (GTK_WIDGET(user_data));
3960 paste_as_attachment_free (gpointer data)
3962 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3964 if (helper->banner) {
3965 gtk_widget_destroy (helper->banner);
3966 g_object_unref (helper->banner);
3972 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3977 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3978 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3983 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3988 modest_ui_actions_on_paste (GtkAction *action,
3989 ModestWindow *window)
3991 GtkWidget *focused_widget = NULL;
3992 GtkWidget *inf_note = NULL;
3993 ModestMailOperation *mail_op = NULL;
3995 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3996 if (GTK_IS_EDITABLE (focused_widget)) {
3997 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3998 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3999 ModestEmailClipboard *e_clipboard = NULL;
4000 e_clipboard = modest_runtime_get_email_clipboard ();
4001 if (modest_email_clipboard_cleared (e_clipboard)) {
4002 GtkTextBuffer *buffer;
4003 GtkClipboard *clipboard;
4005 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4006 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4007 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4008 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4009 ModestMailOperation *mail_op;
4010 TnyFolder *src_folder = NULL;
4011 TnyList *data = NULL;
4013 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4014 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4015 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4016 _CS("ckct_nw_pasting"));
4017 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4018 mail_op = modest_mail_operation_new (G_OBJECT (window));
4019 if (helper->banner != NULL) {
4020 g_object_ref (G_OBJECT (helper->banner));
4021 gtk_widget_show (GTK_WIDGET (helper->banner));
4025 modest_mail_operation_get_msgs_full (mail_op,
4027 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4029 paste_as_attachment_free);
4033 g_object_unref (data);
4035 g_object_unref (src_folder);
4038 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4039 ModestEmailClipboard *clipboard = NULL;
4040 TnyFolder *src_folder = NULL;
4041 TnyFolderStore *folder_store = NULL;
4042 TnyList *data = NULL;
4043 gboolean delete = FALSE;
4045 /* Check clipboard source */
4046 clipboard = modest_runtime_get_email_clipboard ();
4047 if (modest_email_clipboard_cleared (clipboard))
4050 /* Get elements to paste */
4051 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4053 /* Create a new mail operation */
4054 mail_op = modest_mail_operation_new (G_OBJECT(window));
4056 /* Get destination folder */
4057 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4059 /* transfer messages */
4063 /* Ask for user confirmation */
4065 modest_ui_actions_msgs_move_to_confirmation (window,
4066 TNY_FOLDER (folder_store),
4070 if (response == GTK_RESPONSE_OK) {
4071 /* Launch notification */
4072 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4073 _CS("ckct_nw_pasting"));
4074 if (inf_note != NULL) {
4075 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4076 gtk_widget_show (GTK_WIDGET(inf_note));
4079 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4080 modest_mail_operation_xfer_msgs (mail_op,
4082 TNY_FOLDER (folder_store),
4084 destroy_information_note,
4087 g_object_unref (mail_op);
4090 } else if (src_folder != NULL) {
4091 /* Launch notification */
4092 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4093 _CS("ckct_nw_pasting"));
4094 if (inf_note != NULL) {
4095 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4096 gtk_widget_show (GTK_WIDGET(inf_note));
4099 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4100 modest_mail_operation_xfer_folder (mail_op,
4104 destroy_folder_information_note,
4110 g_object_unref (data);
4111 if (src_folder != NULL)
4112 g_object_unref (src_folder);
4113 if (folder_store != NULL)
4114 g_object_unref (folder_store);
4120 modest_ui_actions_on_select_all (GtkAction *action,
4121 ModestWindow *window)
4123 GtkWidget *focused_widget;
4125 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4126 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4127 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4128 } else if (GTK_IS_LABEL (focused_widget)) {
4129 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4130 } else if (GTK_IS_EDITABLE (focused_widget)) {
4131 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4132 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4133 GtkTextBuffer *buffer;
4134 GtkTextIter start, end;
4136 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4137 gtk_text_buffer_get_start_iter (buffer, &start);
4138 gtk_text_buffer_get_end_iter (buffer, &end);
4139 gtk_text_buffer_select_range (buffer, &start, &end);
4140 } else if (GTK_IS_HTML (focused_widget)) {
4141 gtk_html_select_all (GTK_HTML (focused_widget));
4142 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4143 GtkWidget *header_view = focused_widget;
4144 GtkTreeSelection *selection = NULL;
4146 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4147 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4148 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4151 /* Disable window dimming management */
4152 modest_window_disable_dimming (MODEST_WINDOW(window));
4154 /* Select all messages */
4155 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4156 gtk_tree_selection_select_all (selection);
4158 /* Set focuse on header view */
4159 gtk_widget_grab_focus (header_view);
4161 /* Enable window dimming management */
4162 modest_window_enable_dimming (MODEST_WINDOW(window));
4163 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4164 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4170 modest_ui_actions_on_mark_as_read (GtkAction *action,
4171 ModestWindow *window)
4173 g_return_if_fail (MODEST_IS_WINDOW(window));
4175 /* Mark each header as read */
4176 do_headers_action (window, headers_action_mark_as_read, NULL);
4180 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4181 ModestWindow *window)
4183 g_return_if_fail (MODEST_IS_WINDOW(window));
4185 /* Mark each header as read */
4186 do_headers_action (window, headers_action_mark_as_unread, NULL);
4190 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4191 GtkRadioAction *selected,
4192 ModestWindow *window)
4196 value = gtk_radio_action_get_current_value (selected);
4197 if (MODEST_IS_WINDOW (window)) {
4198 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4203 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4204 GtkRadioAction *selected,
4205 ModestWindow *window)
4207 TnyHeaderFlags flags;
4208 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4210 flags = gtk_radio_action_get_current_value (selected);
4211 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4215 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4216 GtkRadioAction *selected,
4217 ModestWindow *window)
4221 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4223 file_format = gtk_radio_action_get_current_value (selected);
4224 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4229 modest_ui_actions_on_zoom_plus (GtkAction *action,
4230 ModestWindow *window)
4232 g_return_if_fail (MODEST_IS_WINDOW (window));
4234 modest_window_zoom_plus (MODEST_WINDOW (window));
4238 modest_ui_actions_on_zoom_minus (GtkAction *action,
4239 ModestWindow *window)
4241 g_return_if_fail (MODEST_IS_WINDOW (window));
4243 modest_window_zoom_minus (MODEST_WINDOW (window));
4247 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4248 ModestWindow *window)
4250 ModestWindowMgr *mgr;
4251 gboolean fullscreen, active;
4252 g_return_if_fail (MODEST_IS_WINDOW (window));
4254 mgr = modest_runtime_get_window_mgr ();
4256 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4257 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4259 if (active != fullscreen) {
4260 modest_window_mgr_set_fullscreen_mode (mgr, active);
4261 #ifndef MODEST_TOOLKIT_HILDON2
4262 gtk_window_present (GTK_WINDOW (window));
4268 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4269 ModestWindow *window)
4271 ModestWindowMgr *mgr;
4272 gboolean fullscreen;
4274 g_return_if_fail (MODEST_IS_WINDOW (window));
4276 mgr = modest_runtime_get_window_mgr ();
4277 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4278 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4280 #ifndef MODEST_TOOLKIT_HILDON2
4281 gtk_window_present (GTK_WINDOW (window));
4286 * Used by modest_ui_actions_on_details to call do_headers_action
4289 headers_action_show_details (TnyHeader *header,
4290 ModestWindow *window,
4294 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header);
4298 * Show the header details in a ModestDetailsDialog widget
4301 modest_ui_actions_on_details (GtkAction *action,
4304 TnyList * headers_list;
4308 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4311 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4314 g_object_unref (msg);
4316 headers_list = get_selected_headers (win);
4320 iter = tny_list_create_iterator (headers_list);
4322 header = TNY_HEADER (tny_iterator_get_current (iter));
4324 headers_action_show_details (header, win, NULL);
4325 g_object_unref (header);
4328 g_object_unref (iter);
4329 g_object_unref (headers_list);
4331 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4332 GtkWidget *folder_view, *header_view;
4334 /* Check which widget has the focus */
4335 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4336 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4337 if (gtk_widget_is_focus (folder_view)) {
4338 TnyFolderStore *folder_store
4339 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4340 if (!folder_store) {
4341 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4344 /* Show only when it's a folder */
4345 /* This function should not be called for account items,
4346 * because we dim the menu item for them. */
4347 if (TNY_IS_FOLDER (folder_store)) {
4348 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4349 TNY_FOLDER (folder_store));
4352 g_object_unref (folder_store);
4355 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4356 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4357 /* Show details of each header */
4358 do_headers_action (win, headers_action_show_details, header_view);
4360 #ifdef MODEST_TOOLKIT_HILDON2
4361 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4363 GtkWidget *header_view;
4365 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4366 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4368 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4370 g_object_unref (folder);
4377 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4378 ModestMsgEditWindow *window)
4380 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4382 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4386 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4387 ModestMsgEditWindow *window)
4389 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4391 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4395 modest_ui_actions_toggle_folders_view (GtkAction *action,
4396 ModestMainWindow *main_window)
4398 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4400 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4401 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4403 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4407 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4408 ModestWindow *window)
4410 gboolean active, fullscreen = FALSE;
4411 ModestWindowMgr *mgr;
4413 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4415 /* Check if we want to toggle the toolbar view in fullscreen
4417 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4418 "ViewShowToolbarFullScreen")) {
4422 /* Toggle toolbar */
4423 mgr = modest_runtime_get_window_mgr ();
4424 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4428 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4429 ModestMsgEditWindow *window)
4431 modest_msg_edit_window_select_font (window);
4436 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4437 const gchar *display_name,
4440 /* don't update the display name if it was already set;
4441 * updating the display name apparently is expensive */
4442 const gchar* old_name = gtk_window_get_title (window);
4444 if (display_name == NULL)
4447 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4448 return; /* don't do anything */
4450 /* This is usually used to change the title of the main window, which
4451 * is the one that holds the folder view. Note that this change can
4452 * happen even when the widget doesn't have the focus. */
4453 gtk_window_set_title (window, display_name);
4458 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4460 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4461 modest_msg_edit_window_select_contacts (window);
4465 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4467 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4468 modest_msg_edit_window_check_names (window, FALSE);
4472 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
4474 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
4475 GTK_WIDGET (user_data));
4479 * This function is used to track changes in the selection of the
4480 * folder view that is inside the "move to" dialog to enable/disable
4481 * the OK button because we do not want the user to select a disallowed
4482 * destination for a folder.
4483 * The user also not desired to be able to use NEW button on items where
4484 * folder creation is not possibel.
4487 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4488 TnyFolderStore *folder_store,
4492 GtkWidget *dialog = NULL;
4493 GtkWidget *ok_button = NULL, *new_button = NULL;
4494 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4495 gboolean moving_folder = FALSE;
4496 gboolean is_local_account = TRUE;
4497 GtkWidget *folder_view = NULL;
4498 ModestTnyFolderRules rules;
4500 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
4505 /* Get the OK button */
4506 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
4510 ok_button = g_object_get_data (G_OBJECT (dialog), MOVE_FOLDER_OK_BUTTON);
4511 new_button = g_object_get_data (G_OBJECT (dialog), MOVE_FOLDER_NEW_BUTTON);
4513 /* check if folder_store is an remote account */
4514 if (TNY_IS_ACCOUNT (folder_store)) {
4515 TnyAccount *local_account = NULL;
4516 TnyAccount *mmc_account = NULL;
4517 ModestTnyAccountStore *account_store = NULL;
4519 account_store = modest_runtime_get_account_store ();
4520 local_account = modest_tny_account_store_get_local_folders_account (account_store);
4521 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
4523 if ((gpointer) local_account != (gpointer) folder_store &&
4524 (gpointer) mmc_account != (gpointer) folder_store) {
4525 ModestProtocolType proto;
4526 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
4527 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
4528 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
4530 is_local_account = FALSE;
4531 /* New button should be dimmed on remote
4533 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4535 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
4537 g_object_unref (local_account);
4539 /* It could not exist */
4541 g_object_unref (mmc_account);
4544 /* Check the target folder rules */
4545 if (TNY_IS_FOLDER (folder_store)) {
4546 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
4547 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
4548 ok_sensitive = FALSE;
4549 new_sensitive = FALSE;
4554 /* Check if we're moving a folder */
4555 if (MODEST_IS_MAIN_WINDOW (user_data)) {
4556 /* Get the widgets */
4557 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
4558 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4559 if (gtk_widget_is_focus (folder_view))
4560 moving_folder = TRUE;
4563 if (moving_folder) {
4564 TnyFolderStore *moved_folder = NULL, *parent = NULL;
4566 /* Get the folder to move */
4567 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4569 /* Check that we're not moving to the same folder */
4570 if (TNY_IS_FOLDER (moved_folder)) {
4571 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
4572 if (parent == folder_store)
4573 ok_sensitive = FALSE;
4574 g_object_unref (parent);
4577 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
4578 /* Do not allow to move to an account unless it's the
4579 local folders account */
4580 if (!is_local_account)
4581 ok_sensitive = FALSE;
4584 if (ok_sensitive && (moved_folder == folder_store)) {
4585 /* Do not allow to move to itself */
4586 ok_sensitive = FALSE;
4588 g_object_unref (moved_folder);
4590 TnyFolder *src_folder = NULL;
4592 /* Moving a message */
4593 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
4595 TnyHeader *header = NULL;
4596 header = modest_msg_view_window_get_header
4597 (MODEST_MSG_VIEW_WINDOW (user_data));
4598 if (!TNY_IS_HEADER(header))
4599 g_warning ("%s: could not get source header", __FUNCTION__);
4601 src_folder = tny_header_get_folder (header);
4604 g_object_unref (header);
4607 TNY_FOLDER (modest_folder_view_get_selected
4608 (MODEST_FOLDER_VIEW (folder_view)));
4611 if (TNY_IS_FOLDER(src_folder)) {
4612 /* Do not allow to move the msg to the same folder */
4613 /* Do not allow to move the msg to an account */
4614 if ((gpointer) src_folder == (gpointer) folder_store ||
4615 TNY_IS_ACCOUNT (folder_store))
4616 ok_sensitive = FALSE;
4617 g_object_unref (src_folder);
4619 g_warning ("%s: could not get source folder", __FUNCTION__);
4623 /* Set sensitivity of the OK button */
4624 gtk_widget_set_sensitive (ok_button, ok_sensitive);
4625 /* Set sensitivity of the NEW button */
4626 gtk_widget_set_sensitive (new_button, new_sensitive);
4630 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
4633 get_folder_view_from_move_to_dialog (GtkWidget *move_to_dialog)
4635 return GTK_WIDGET(g_object_get_data (G_OBJECT(move_to_dialog),
4636 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4640 create_move_to_dialog (GtkWindow *win,
4641 GtkWidget *folder_view,
4642 GtkWidget **tree_view)
4645 #ifdef MODEST_TOOLKIT_HILDON2
4646 GtkWidget *pannable;
4650 GtkWidget *new_button, *ok_button;
4652 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
4654 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
4657 #ifndef MODEST_TOOLKIT_GTK
4658 ok_button = gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
4659 /* We do this manually so GTK+ does not associate a response ID for
4661 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
4662 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
4663 gtk_widget_show (new_button);
4664 #ifndef MODEST_TOOLKIT_HILDON2
4665 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
4668 /* We do this manually so GTK+ does not associate a response ID for
4670 new_button = gtk_button_new_with_label (_("mcen_ti_new_folder"));
4671 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
4672 gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (GTK_DIALOG (dialog)->action_area), new_button, TRUE);
4673 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
4674 ok_button = gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
4675 gtk_container_set_border_width (GTK_CONTAINER (dialog), 12);
4676 gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 24);
4678 g_object_set_data (G_OBJECT (dialog), MOVE_FOLDER_OK_BUTTON, ok_button);
4679 g_object_set_data (G_OBJECT (dialog), MOVE_FOLDER_NEW_BUTTON, new_button);
4681 /* Create scrolled window */
4682 #ifdef MODEST_TOOLKIT_HILDON2
4683 pannable = hildon_pannable_area_new ();
4685 scroll = gtk_scrolled_window_new (NULL, NULL);
4686 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
4687 GTK_POLICY_AUTOMATIC,
4688 GTK_POLICY_AUTOMATIC);
4691 #ifdef MODEST_TOOLKIT_GTK
4692 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN);
4695 /* Create folder view */
4696 *tree_view = modest_platform_create_folder_view (NULL);
4698 /* Track changes in the selection to
4699 * disable the OK button whenever "Move to" is not possible
4700 * disbale NEW button whenever New is not possible */
4701 g_signal_connect (*tree_view,
4702 "folder_selection_changed",
4703 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
4706 /* Listen to clicks on New button */
4707 g_signal_connect (G_OBJECT (new_button),
4709 G_CALLBACK(create_move_to_dialog_on_new_folder),
4712 /* It could happen that we're trying to move a message from a
4713 window (msg window for example) after the main window was
4714 closed, so we can not just get the model of the folder
4716 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4717 const gchar *visible_id = NULL;
4719 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4720 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4721 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4722 MODEST_FOLDER_VIEW(*tree_view));
4725 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4727 /* Show the same account than the one that is shown in the main window */
4728 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
4731 const gchar *active_account_name = NULL;
4732 ModestAccountMgr *mgr = NULL;
4733 ModestAccountSettings *settings = NULL;
4734 ModestServerAccountSettings *store_settings = NULL;
4736 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4737 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4738 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
4739 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
4741 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4742 mgr = modest_runtime_get_account_mgr ();
4743 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4746 const gchar *store_account_name;
4747 store_settings = modest_account_settings_get_store_settings (settings);
4748 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4750 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
4751 store_account_name);
4752 g_object_unref (store_settings);
4753 g_object_unref (settings);
4757 /* we keep a pointer to the embedded folder view, so we can retrieve it with
4758 * get_folder_view_from_move_to_dialog
4759 * (see above) later (needed for focus handling)
4761 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, *tree_view);
4764 /* Hide special folders */
4765 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
4767 #ifdef MODEST_TOOLKIT_HILDON2
4768 gtk_container_add (GTK_CONTAINER (pannable), *tree_view);
4769 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
4770 pannable, TRUE, TRUE, 0);
4772 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
4773 /* Add scroll to dialog */
4774 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
4775 scroll, TRUE, TRUE, 0);
4779 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4780 #ifndef MODEST_TOOLKIT_GTK
4781 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
4783 gtk_window_set_default_size (GTK_WINDOW (dialog), 600, 400);
4792 * Shows a confirmation dialog to the user when we're moving messages
4793 * from a remote server to the local storage. Returns the dialog
4794 * response. If it's other kind of movement then it always returns
4797 * This one is used by the next functions:
4798 * modest_ui_actions_on_paste - commented out
4799 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4802 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4803 TnyFolder *dest_folder,
4807 gint response = GTK_RESPONSE_OK;
4808 TnyAccount *account = NULL;
4809 TnyFolder *src_folder = NULL;
4810 TnyIterator *iter = NULL;
4811 TnyHeader *header = NULL;
4813 /* return with OK if the destination is a remote folder */
4814 if (modest_tny_folder_is_remote_folder (dest_folder))
4815 return GTK_RESPONSE_OK;
4817 /* Get source folder */
4818 iter = tny_list_create_iterator (headers);
4819 header = TNY_HEADER (tny_iterator_get_current (iter));
4821 src_folder = tny_header_get_folder (header);
4822 g_object_unref (header);
4824 g_object_unref (iter);
4826 /* if no src_folder, message may be an attahcment */
4827 if (src_folder == NULL)
4828 return GTK_RESPONSE_CANCEL;
4830 /* If the source is a local or MMC folder */
4831 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4832 g_object_unref (src_folder);
4833 return GTK_RESPONSE_OK;
4836 /* Get the account */
4837 account = tny_folder_get_account (src_folder);
4839 /* now if offline we ask the user */
4840 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4841 response = GTK_RESPONSE_OK;
4843 response = GTK_RESPONSE_CANCEL;
4846 g_object_unref (src_folder);
4847 g_object_unref (account);
4853 move_to_helper_destroyer (gpointer user_data)
4855 MoveToHelper *helper = (MoveToHelper *) user_data;
4857 /* Close the "Pasting" information banner */
4858 if (helper->banner) {
4859 gtk_widget_destroy (GTK_WIDGET (helper->banner));
4860 g_object_unref (helper->banner);
4862 if (gtk_tree_row_reference_valid (helper->reference)) {
4863 gtk_tree_row_reference_free (helper->reference);
4864 helper->reference = NULL;
4870 move_to_cb (ModestMailOperation *mail_op,
4873 MoveToHelper *helper = (MoveToHelper *) user_data;
4875 /* Note that the operation could have failed, in that case do
4877 if (modest_mail_operation_get_status (mail_op) ==
4878 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
4880 GObject *object = modest_mail_operation_get_source (mail_op);
4881 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4882 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4884 if (!modest_msg_view_window_select_next_message (self) &&
4885 !modest_msg_view_window_select_previous_message (self)) {
4886 /* No more messages to view, so close this window */
4887 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4889 } else if (MODEST_IS_MAIN_WINDOW (object) &&
4890 gtk_tree_row_reference_valid (helper->reference)) {
4891 GtkWidget *header_view;
4893 GtkTreeSelection *sel;
4895 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4896 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4897 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
4898 path = gtk_tree_row_reference_get_path (helper->reference);
4899 /* We need to unselect the previous one
4900 because we could be copying instead of
4902 gtk_tree_selection_unselect_all (sel);
4903 gtk_tree_selection_select_path (sel, path);
4904 gtk_tree_path_free (path);
4906 g_object_unref (object);
4908 /* Destroy the helper */
4909 move_to_helper_destroyer (helper);
4913 folder_move_to_cb (ModestMailOperation *mail_op,
4914 TnyFolder *new_folder,
4917 GtkWidget *folder_view;
4920 object = modest_mail_operation_get_source (mail_op);
4921 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4922 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4923 g_object_ref (folder_view);
4924 g_object_unref (object);
4925 move_to_cb (mail_op, user_data);
4926 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
4927 g_object_unref (folder_view);
4931 msgs_move_to_cb (ModestMailOperation *mail_op,
4934 move_to_cb (mail_op, user_data);
4938 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
4941 ModestWindow *main_window = NULL;
4943 /* Disable next automatic folder selection */
4944 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
4945 FALSE); /* don't create */
4947 GObject *win = NULL;
4948 GtkWidget *folder_view = NULL;
4950 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
4951 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4952 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
4954 if (user_data && TNY_IS_FOLDER (user_data)) {
4955 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
4956 TNY_FOLDER (user_data), FALSE);
4959 /* Show notification dialog only if the main window exists */
4960 win = modest_mail_operation_get_source (mail_op);
4961 modest_platform_run_information_dialog ((GtkWindow *) win,
4962 _("mail_in_ui_folder_move_target_error"),
4965 g_object_unref (win);
4970 open_msg_for_purge_cb (ModestMailOperation *mail_op,
4979 gint pending_purges = 0;
4980 gboolean some_purged = FALSE;
4981 ModestWindow *win = MODEST_WINDOW (user_data);
4982 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
4984 /* If there was any error */
4985 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
4986 modest_window_mgr_unregister_header (mgr, header);
4990 /* Once the message has been retrieved for purging, we check if
4991 * it's all ok for purging */
4993 parts = tny_simple_list_new ();
4994 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
4995 iter = tny_list_create_iterator (parts);
4997 while (!tny_iterator_is_done (iter)) {
4999 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5000 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5001 if (tny_mime_part_is_purged (part))
5008 g_object_unref (part);
5010 tny_iterator_next (iter);
5012 g_object_unref (iter);
5015 if (pending_purges>0) {
5017 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5019 if (response == GTK_RESPONSE_OK) {
5022 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_ib_removing_attachment"));
5023 iter = tny_list_create_iterator (parts);
5024 while (!tny_iterator_is_done (iter)) {
5027 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5028 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5029 tny_mime_part_set_purged (part);
5032 g_object_unref (part);
5034 tny_iterator_next (iter);
5036 g_object_unref (iter);
5038 tny_msg_rewrite_cache (msg);
5040 gtk_widget_destroy (info);
5044 modest_window_mgr_unregister_header (mgr, header);
5046 g_object_unref (parts);
5050 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5051 ModestMainWindow *win)
5053 GtkWidget *header_view;
5054 TnyList *header_list;
5056 TnyHeaderFlags flags;
5057 ModestWindow *msg_view_window = NULL;
5060 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5062 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5063 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5065 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5067 g_warning ("%s: no header selected", __FUNCTION__);
5071 if (tny_list_get_length (header_list) == 1) {
5072 TnyIterator *iter = tny_list_create_iterator (header_list);
5073 header = TNY_HEADER (tny_iterator_get_current (iter));
5074 g_object_unref (iter);
5078 if (!header || !TNY_IS_HEADER(header)) {
5079 g_warning ("%s: header is not valid", __FUNCTION__);
5083 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5084 header, &msg_view_window);
5085 flags = tny_header_get_flags (header);
5086 if (!(flags & TNY_HEADER_FLAG_CACHED))
5089 if (msg_view_window != NULL)
5090 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5092 /* do nothing; uid was registered before, so window is probably on it's way */
5093 g_warning ("debug: header %p has already been registered", header);
5096 ModestMailOperation *mail_op = NULL;
5097 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5098 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5099 modest_ui_actions_disk_operations_error_handler,
5101 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5102 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5104 g_object_unref (mail_op);
5107 g_object_unref (header);
5109 g_object_unref (header_list);
5113 * Checks if we need a connection to do the transfer and if the user
5114 * wants to connect to complete it
5117 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5118 TnyFolderStore *src_folder,
5120 TnyFolder *dst_folder,
5121 gboolean delete_originals,
5122 gboolean *need_connection,
5125 TnyAccount *src_account;
5126 gint uncached_msgs = 0;
5128 uncached_msgs = header_list_count_uncached_msgs (headers);
5130 /* We don't need any further check if
5132 * 1- the source folder is local OR
5133 * 2- the device is already online
5135 if (!modest_tny_folder_store_is_remote (src_folder) ||
5136 tny_device_is_online (modest_runtime_get_device())) {
5137 *need_connection = FALSE;
5142 /* We must ask for a connection when
5144 * - the message(s) is not already cached OR
5145 * - the message(s) is cached but the leave_on_server setting
5146 * is FALSE (because we need to sync the source folder to
5147 * delete the message from the server (for IMAP we could do it
5148 * offline, it'll take place the next time we get a
5151 src_account = get_account_from_folder_store (src_folder);
5152 if (uncached_msgs > 0) {
5156 *need_connection = TRUE;
5157 num_headers = tny_list_get_length (headers);
5158 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5160 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5161 GTK_RESPONSE_CANCEL) {
5167 /* The transfer is possible and the user wants to */
5170 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5171 const gchar *account_name;
5172 gboolean leave_on_server;
5174 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5175 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5178 if (leave_on_server == TRUE) {
5179 *need_connection = FALSE;
5181 *need_connection = TRUE;
5184 *need_connection = FALSE;
5189 g_object_unref (src_account);
5193 xfer_messages_error_handler (ModestMailOperation *mail_op,
5196 ModestWindow *main_window = NULL;
5198 /* Disable next automatic folder selection */
5199 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5200 FALSE); /* don't create */
5202 GObject *win = modest_mail_operation_get_source (mail_op);
5203 modest_platform_run_information_dialog ((GtkWindow *) win,
5204 _("mail_in_ui_folder_move_target_error"),
5207 g_object_unref (win);
5209 move_to_helper_destroyer (user_data);
5213 TnyFolderStore *dst_folder;
5218 * Utility function that transfer messages from both the main window
5219 * and the msg view window when using the "Move to" dialog
5222 xfer_messages_performer (gboolean canceled,
5224 GtkWindow *parent_window,
5225 TnyAccount *account,
5228 ModestWindow *win = MODEST_WINDOW (parent_window);
5229 TnyAccount *dst_account = NULL;
5230 gboolean dst_forbids_message_add = FALSE;
5231 XferMsgsHelper *helper;
5232 MoveToHelper *movehelper;
5233 ModestMailOperation *mail_op;
5235 helper = (XferMsgsHelper *) user_data;
5237 if (canceled || err) {
5238 if (!check_memory_full_error ((GtkWidget *) parent_window, err)) {
5239 /* Show the proper error message */
5240 modest_ui_actions_on_account_connection_error (parent_window, account);
5245 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5247 /* tinymail will return NULL for local folders it seems */
5248 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5249 modest_tny_account_get_protocol_type (dst_account),
5250 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_MESSAGE_ADD);
5251 g_object_unref (dst_account);
5253 if (dst_forbids_message_add) {
5254 modest_platform_information_banner (GTK_WIDGET (win),
5256 ngettext("mail_in_ui_folder_move_target_error",
5257 "mail_in_ui_folder_move_targets_error",
5258 tny_list_get_length (helper->headers)));
5262 movehelper = g_new0 (MoveToHelper, 1);
5263 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5264 _CS("ckct_nw_pasting"));
5265 if (movehelper->banner != NULL) {
5266 g_object_ref (movehelper->banner);
5267 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5270 if (MODEST_IS_MAIN_WINDOW (win)) {
5271 GtkWidget *header_view =
5272 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5273 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5274 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5277 /* Perform the mail operation */
5278 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5279 xfer_messages_error_handler,
5281 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5284 modest_mail_operation_xfer_msgs (mail_op,
5286 TNY_FOLDER (helper->dst_folder),
5291 g_object_unref (G_OBJECT (mail_op));
5293 g_object_unref (helper->dst_folder);
5294 g_object_unref (helper->headers);
5295 g_slice_free (XferMsgsHelper, helper);
5299 TnyFolder *src_folder;
5300 TnyFolderStore *dst_folder;
5301 gboolean delete_original;
5302 GtkWidget *folder_view;
5306 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
5307 TnyAccount *account, gpointer user_data)
5309 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5310 GtkTreeSelection *sel;
5311 ModestMailOperation *mail_op = NULL;
5313 if (canceled || err || !MODEST_IS_MAIN_WINDOW (parent_window)) {
5314 g_object_unref (G_OBJECT (info->src_folder));
5315 g_object_unref (G_OBJECT (info->dst_folder));
5320 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5321 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5322 _CS("ckct_nw_pasting"));
5323 if (helper->banner != NULL) {
5324 g_object_ref (helper->banner);
5325 gtk_widget_show (GTK_WIDGET(helper->banner));
5327 /* Clean folder on header view before moving it */
5328 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5329 gtk_tree_selection_unselect_all (sel);
5331 /* Let gtk events run. We need that the folder
5332 view frees its reference to the source
5333 folder *before* issuing the mail operation
5334 so we need the signal handler of selection
5335 changed to happen before the mail
5337 while (gtk_events_pending ())
5338 gtk_main_iteration (); */
5341 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5342 modest_ui_actions_move_folder_error_handler,
5343 info->src_folder, NULL);
5344 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5347 /* Select *after* the changes */
5348 /* TODO: this function hangs UI after transfer */
5349 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
5350 /* TNY_FOLDER (src_folder), TRUE); */
5352 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5353 TNY_FOLDER (info->dst_folder), TRUE);
5354 modest_mail_operation_xfer_folder (mail_op,
5355 TNY_FOLDER (info->src_folder),
5357 info->delete_original,
5360 g_object_unref (G_OBJECT (info->src_folder));
5362 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5365 /* Unref mail operation */
5366 g_object_unref (G_OBJECT (mail_op));
5367 g_object_unref (G_OBJECT (info->dst_folder));
5372 get_account_from_folder_store (TnyFolderStore *folder_store)
5374 if (TNY_IS_ACCOUNT (folder_store))
5375 return g_object_ref (folder_store);
5377 return tny_folder_get_account (TNY_FOLDER (folder_store));
5381 * UI handler for the "Move to" action when invoked from the
5385 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5386 GtkWidget *folder_view,
5387 TnyFolderStore *dst_folder,
5388 ModestMainWindow *win)
5390 ModestHeaderView *header_view = NULL;
5391 TnyFolderStore *src_folder = NULL;
5393 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5395 /* Get the source folder */
5396 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5398 /* Get header view */
5399 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
5401 /* Get folder or messages to transfer */
5402 if (gtk_widget_is_focus (folder_view)) {
5403 gboolean do_xfer = TRUE;
5405 /* Allow only to transfer folders to the local root folder */
5406 if (TNY_IS_ACCOUNT (dst_folder) &&
5407 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5408 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5410 } else if (!TNY_IS_FOLDER (src_folder)) {
5411 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5416 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5417 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5419 info->src_folder = g_object_ref (src_folder);
5420 info->dst_folder = g_object_ref (dst_folder);
5421 info->delete_original = TRUE;
5422 info->folder_view = folder_view;
5424 connect_info->callback = on_move_folder_cb;
5425 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5426 connect_info->data = info;
5428 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5429 TNY_FOLDER_STORE (src_folder),
5432 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5435 headers = modest_header_view_get_selected_headers(header_view);
5437 /* Transfer the messages */
5438 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
5439 headers, TNY_FOLDER (dst_folder));
5441 g_object_unref (headers);
5445 g_object_unref (src_folder);
5450 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
5451 TnyFolder *src_folder,
5453 TnyFolder *dst_folder)
5455 gboolean need_connection = TRUE;
5456 gboolean do_xfer = TRUE;
5457 XferMsgsHelper *helper;
5459 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5460 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5461 g_return_if_fail (TNY_IS_LIST (headers));
5463 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5464 headers, TNY_FOLDER (dst_folder),
5465 TRUE, &need_connection,
5468 /* If we don't want to transfer just return */
5472 /* Create the helper */
5473 helper = g_slice_new (XferMsgsHelper);
5474 helper->dst_folder = g_object_ref (dst_folder);
5475 helper->headers = g_object_ref (headers);
5477 if (need_connection) {
5478 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5479 connect_info->callback = xfer_messages_performer;
5480 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5481 connect_info->data = helper;
5483 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5484 TNY_FOLDER_STORE (src_folder),
5487 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5488 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
5489 src_account, helper);
5490 g_object_unref (src_account);
5495 * UI handler for the "Move to" action when invoked from the
5496 * ModestMsgViewWindow
5499 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
5500 TnyFolderStore *dst_folder,
5501 ModestMsgViewWindow *win)
5503 TnyList *headers = NULL;
5504 TnyHeader *header = NULL;
5505 TnyFolder *src_folder = NULL;
5507 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5509 /* Create header list */
5510 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
5511 src_folder = TNY_FOLDER (tny_header_get_folder(header));
5512 headers = tny_simple_list_new ();
5513 tny_list_append (headers, G_OBJECT (header));
5515 /* Transfer the messages */
5516 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder, headers,
5517 TNY_FOLDER (dst_folder));
5520 g_object_unref (src_folder);
5521 g_object_unref (header);
5522 g_object_unref (headers);
5526 modest_ui_actions_on_move_to (GtkAction *action,
5529 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
5531 TnyFolderStore *dst_folder = NULL;
5532 ModestMainWindow *main_window;
5534 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
5535 MODEST_IS_MSG_VIEW_WINDOW (win));
5537 /* Get the main window if exists */
5538 if (MODEST_IS_MAIN_WINDOW (win))
5539 main_window = MODEST_MAIN_WINDOW (win);
5542 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5543 FALSE)); /* don't create */
5545 /* Get the folder view widget if exists */
5547 folder_view = modest_main_window_get_child_widget (main_window,
5548 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5552 /* Create and run the dialog */
5553 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
5554 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5555 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog), (GtkWindow *) win);
5556 result = gtk_dialog_run (GTK_DIALOG(dialog));
5557 g_object_ref (tree_view);
5558 gtk_widget_destroy (dialog);
5560 if (result != GTK_RESPONSE_ACCEPT)
5563 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
5564 /* Do window specific stuff */
5565 if (MODEST_IS_MAIN_WINDOW (win)) {
5566 modest_ui_actions_on_main_window_move_to (action,
5569 MODEST_MAIN_WINDOW (win));
5571 modest_ui_actions_on_msg_view_window_move_to (action,
5573 MODEST_MSG_VIEW_WINDOW (win));
5577 g_object_unref (dst_folder);
5581 * Calls #HeadersFunc for each header already selected in the main
5582 * window or the message currently being shown in the msg view window
5585 do_headers_action (ModestWindow *win,
5589 TnyList *headers_list = NULL;
5590 TnyIterator *iter = NULL;
5591 TnyHeader *header = NULL;
5592 TnyFolder *folder = NULL;
5595 headers_list = get_selected_headers (win);
5599 /* Get the folder */
5600 iter = tny_list_create_iterator (headers_list);
5601 header = TNY_HEADER (tny_iterator_get_current (iter));
5603 folder = tny_header_get_folder (header);
5604 g_object_unref (header);
5607 /* Call the function for each header */
5608 while (!tny_iterator_is_done (iter)) {
5609 header = TNY_HEADER (tny_iterator_get_current (iter));
5610 func (header, win, user_data);
5611 g_object_unref (header);
5612 tny_iterator_next (iter);
5615 /* Trick: do a poke status in order to speed up the signaling
5617 tny_folder_poke_status (folder);
5620 g_object_unref (folder);
5621 g_object_unref (iter);
5622 g_object_unref (headers_list);
5626 modest_ui_actions_view_attachment (GtkAction *action,
5627 ModestWindow *window)
5629 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5630 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5632 /* not supported window for this action */
5633 g_return_if_reached ();
5638 modest_ui_actions_save_attachments (GtkAction *action,
5639 ModestWindow *window)
5641 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5643 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5646 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5648 /* not supported window for this action */
5649 g_return_if_reached ();
5654 modest_ui_actions_remove_attachments (GtkAction *action,
5655 ModestWindow *window)
5657 if (MODEST_IS_MAIN_WINDOW (window)) {
5658 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
5659 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5660 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5662 /* not supported window for this action */
5663 g_return_if_reached ();
5668 modest_ui_actions_on_settings (GtkAction *action,
5673 dialog = modest_platform_get_global_settings_dialog ();
5674 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
5675 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5676 gtk_widget_show_all (dialog);
5678 gtk_dialog_run (GTK_DIALOG (dialog));
5680 gtk_widget_destroy (dialog);
5684 modest_ui_actions_on_help (GtkAction *action,
5687 /* Help app is not available at all in fremantle */
5688 #ifndef MODEST_TOOLKIT_HILDON2
5689 const gchar *help_id;
5691 g_return_if_fail (win && GTK_IS_WINDOW(win));
5693 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5696 modest_platform_show_help (GTK_WINDOW (win), help_id);
5701 modest_ui_actions_on_csm_help (GtkAction *action,
5704 /* Help app is not available at all in fremantle */
5705 #ifndef MODEST_TOOLKIT_HILDON2
5707 const gchar* help_id = NULL;
5708 GtkWidget *folder_view;
5709 TnyFolderStore *folder_store;
5711 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
5713 /* Get selected folder */
5714 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5715 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5716 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5718 /* Switch help_id */
5719 if (folder_store && TNY_IS_FOLDER (folder_store))
5720 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
5723 g_object_unref (folder_store);
5726 modest_platform_show_help (GTK_WINDOW (win), help_id);
5728 modest_ui_actions_on_help (action, win);
5733 retrieve_contents_cb (ModestMailOperation *mail_op,
5740 /* We only need this callback to show an error in case of
5741 memory low condition */
5742 modest_ui_actions_msg_retrieval_check (mail_op, header, msg);
5746 retrieve_msg_contents_performer (gboolean canceled,
5748 GtkWindow *parent_window,
5749 TnyAccount *account,
5752 ModestMailOperation *mail_op;
5753 TnyList *headers = TNY_LIST (user_data);
5755 if (err || canceled) {
5756 check_memory_full_error ((GtkWidget *) parent_window, err);
5760 /* Create mail operation */
5761 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5762 modest_ui_actions_disk_operations_error_handler,
5764 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5765 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
5768 g_object_unref (mail_op);
5770 g_object_unref (headers);
5771 g_object_unref (account);
5775 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5776 ModestWindow *window)
5778 TnyList *headers = NULL;
5779 TnyAccount *account = NULL;
5780 TnyIterator *iter = NULL;
5781 TnyHeader *header = NULL;
5782 TnyFolder *folder = NULL;
5785 headers = get_selected_headers (window);
5789 /* Pick the account */
5790 iter = tny_list_create_iterator (headers);
5791 header = TNY_HEADER (tny_iterator_get_current (iter));
5792 folder = tny_header_get_folder (header);
5793 account = tny_folder_get_account (folder);
5794 g_object_unref (folder);
5795 g_object_unref (header);
5796 g_object_unref (iter);
5798 /* Connect and perform the message retrieval */
5799 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
5800 g_object_ref (account),
5801 retrieve_msg_contents_performer,
5802 g_object_ref (headers));
5805 g_object_unref (account);
5806 g_object_unref (headers);
5810 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
5812 g_return_if_fail (MODEST_IS_WINDOW (window));
5815 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
5819 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
5821 g_return_if_fail (MODEST_IS_WINDOW (window));
5824 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
5828 modest_ui_actions_on_email_menu_activated (GtkAction *action,
5829 ModestWindow *window)
5831 g_return_if_fail (MODEST_IS_WINDOW (window));
5834 modest_ui_actions_check_menu_dimming_rules (window);
5838 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
5839 ModestWindow *window)
5841 g_return_if_fail (MODEST_IS_WINDOW (window));
5844 modest_ui_actions_check_menu_dimming_rules (window);
5848 modest_ui_actions_on_view_menu_activated (GtkAction *action,
5849 ModestWindow *window)
5851 g_return_if_fail (MODEST_IS_WINDOW (window));
5854 modest_ui_actions_check_menu_dimming_rules (window);
5858 modest_ui_actions_on_format_menu_activated (GtkAction *action,
5859 ModestWindow *window)
5861 g_return_if_fail (MODEST_IS_WINDOW (window));
5864 modest_ui_actions_check_menu_dimming_rules (window);
5868 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
5869 ModestWindow *window)
5871 g_return_if_fail (MODEST_IS_WINDOW (window));
5874 modest_ui_actions_check_menu_dimming_rules (window);
5878 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
5879 ModestWindow *window)
5881 g_return_if_fail (MODEST_IS_WINDOW (window));
5884 modest_ui_actions_check_menu_dimming_rules (window);
5888 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
5889 ModestWindow *window)
5891 g_return_if_fail (MODEST_IS_WINDOW (window));
5894 modest_ui_actions_check_menu_dimming_rules (window);
5898 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
5899 ModestWindow *window)
5901 g_return_if_fail (MODEST_IS_WINDOW (window));
5904 modest_ui_actions_check_menu_dimming_rules (window);
5908 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
5909 ModestWindow *window)
5911 g_return_if_fail (MODEST_IS_WINDOW (window));
5914 modest_ui_actions_check_menu_dimming_rules (window);
5918 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
5920 g_return_if_fail (MODEST_IS_WINDOW (window));
5922 /* we check for low-mem; in that case, show a warning, and don't allow
5925 if (modest_platform_check_memory_low (window, TRUE))
5928 modest_platform_show_search_messages (GTK_WINDOW (window));
5932 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
5934 g_return_if_fail (MODEST_IS_WINDOW (win));
5937 /* we check for low-mem; in that case, show a warning, and don't allow
5938 * for the addressbook
5940 if (modest_platform_check_memory_low (win, TRUE))
5944 modest_platform_show_addressbook (GTK_WINDOW (win));
5949 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
5950 ModestWindow *window)
5952 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5954 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
5958 on_send_receive_finished (ModestMailOperation *mail_op,
5961 GtkWidget *header_view, *folder_view;
5962 TnyFolderStore *folder_store;
5963 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
5965 /* Set send/receive operation finished */
5966 modest_main_window_notify_send_receive_completed (main_win);
5968 /* Don't refresh the current folder if there were any errors */
5969 if (modest_mail_operation_get_status (mail_op) !=
5970 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5973 /* Refresh the current folder if we're viewing a window. We do
5974 this because the user won't be able to see the new mails in
5975 the selected folder after a Send&Receive because it only
5976 performs a poke_status, i.e, only the number of read/unread
5977 messages is updated, but the new headers are not
5979 folder_view = modest_main_window_get_child_widget (main_win,
5980 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5984 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5986 /* Do not need to refresh INBOX again because the
5987 update_account does it always automatically */
5988 if (folder_store && TNY_IS_FOLDER (folder_store) &&
5989 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
5990 ModestMailOperation *refresh_op;
5992 header_view = modest_main_window_get_child_widget (main_win,
5993 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5995 /* We do not need to set the contents style
5996 because it hasn't changed. We also do not
5997 need to save the widget status. Just force
5999 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6000 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6001 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6002 folder_refreshed_cb, main_win);
6003 g_object_unref (refresh_op);
6007 g_object_unref (folder_store);
6012 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6018 const gchar* server_name = NULL;
6019 TnyTransportAccount *server_account;
6020 gchar *message = NULL;
6022 /* Don't show anything if the user cancelled something or the
6023 * send receive request is not interactive. Authentication
6024 * errors are managed by the account store so no need to show
6025 * a dialog here again */
6026 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6027 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6028 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6032 /* Get the server name: */
6034 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
6036 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
6038 g_return_if_reached ();
6040 /* Show the appropriate message text for the GError: */
6041 switch (err->code) {
6042 case TNY_SERVICE_ERROR_CONNECT:
6043 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6045 case TNY_SERVICE_ERROR_SEND:
6046 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
6048 case TNY_SERVICE_ERROR_UNAVAILABLE:
6049 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6052 g_warning ("%s: unexpected ERROR %d",
6053 __FUNCTION__, err->code);
6054 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
6058 modest_platform_run_information_dialog (NULL, message, FALSE);
6060 g_object_unref (server_account);
6064 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6069 ModestMainWindow *main_window = NULL;
6070 ModestWindowMgr *mgr = NULL;
6071 GtkWidget *folder_view = NULL, *header_view = NULL;
6072 TnyFolderStore *selected_folder = NULL;
6073 TnyFolderType folder_type;
6075 mgr = modest_runtime_get_window_mgr ();
6076 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr,
6077 FALSE));/* don't create */
6081 /* Check if selected folder is OUTBOX */
6082 folder_view = modest_main_window_get_child_widget (main_window,
6083 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6084 header_view = modest_main_window_get_child_widget (main_window,
6085 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6087 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6088 if (!TNY_IS_FOLDER (selected_folder))
6091 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6092 #if GTK_CHECK_VERSION(2, 8, 0)
6093 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
6094 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6095 GtkTreeViewColumn *tree_column;
6097 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6098 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6100 gtk_tree_view_column_queue_resize (tree_column);
6103 gtk_widget_queue_draw (header_view);
6106 /* Rerun dimming rules, because the message could become deletable for example */
6107 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6108 MODEST_DIMMING_RULES_TOOLBAR);
6109 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6110 MODEST_DIMMING_RULES_MENU);
6114 if (selected_folder != NULL)
6115 g_object_unref (selected_folder);
6119 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6120 TnyAccount *account)
6122 ModestProtocolType protocol_type;
6123 ModestProtocol *protocol;
6124 gchar *error_note = NULL;
6126 protocol_type = modest_tny_account_get_protocol_type (account);
6127 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6130 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6131 if (error_note == NULL) {
6132 g_warning ("%s: This should not be reached", __FUNCTION__);
6134 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6135 g_free (error_note);
6140 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6144 TnyFolderStore *folder = NULL;
6145 TnyAccount *account = NULL;
6146 ModestProtocolType proto;
6147 ModestProtocol *protocol;
6148 TnyHeader *header = NULL;
6150 if (MODEST_IS_MAIN_WINDOW (win)) {
6151 GtkWidget *header_view;
6152 TnyList* headers = NULL;
6154 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6155 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6156 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6157 if (!headers || tny_list_get_length (headers) == 0) {
6159 g_object_unref (headers);
6162 iter = tny_list_create_iterator (headers);
6163 header = TNY_HEADER (tny_iterator_get_current (iter));
6164 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6165 g_object_unref (iter);
6166 g_object_unref (headers);
6167 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6168 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6169 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6172 /* Get the account type */
6173 account = tny_folder_get_account (TNY_FOLDER (folder));
6174 proto = modest_tny_account_get_protocol_type (account);
6175 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6178 subject = tny_header_dup_subject (header);
6179 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6183 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6187 g_object_unref (account);
6188 g_object_unref (folder);
6189 g_object_unref (header);
6195 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6196 const gchar *account_name,
6197 const gchar *account_title)
6199 ModestAccountMgr *account_mgr;
6202 ModestProtocol *protocol;
6203 gboolean removed = FALSE;
6205 g_return_val_if_fail (account_name, FALSE);
6206 g_return_val_if_fail (account_title, FALSE);
6208 account_mgr = modest_runtime_get_account_mgr();
6210 /* The warning text depends on the account type: */
6211 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6212 modest_account_mgr_get_store_protocol (account_mgr,
6214 txt = modest_protocol_get_translation (protocol,
6215 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6218 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6220 response = modest_platform_run_confirmation_dialog (parent_window, txt);
6224 if (response == GTK_RESPONSE_OK) {
6225 /* Remove account. If it succeeds then it also removes
6226 the account from the ModestAccountView: */
6227 gboolean is_default = FALSE;
6228 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6229 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6231 g_free (default_account_name);
6233 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6235 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);