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_add_to_contacts (GtkAction *action, ModestWindow *win)
630 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
632 modest_msg_view_window_add_to_contacts (MODEST_MSG_VIEW_WINDOW (win));
636 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
638 GtkClipboard *clipboard = NULL;
639 gchar *selection = NULL;
641 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
642 selection = gtk_clipboard_wait_for_text (clipboard);
644 /* Question: why is the clipboard being used here?
645 * It doesn't really make a lot of sense. */
649 modest_address_book_add_address (selection);
655 modest_ui_actions_on_accounts (GtkAction *action,
658 /* This is currently only implemented for Maemo */
659 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
660 if (!modest_ui_actions_run_account_setup_wizard (win))
661 g_debug ("%s: wizard was already running", __FUNCTION__);
665 /* Show the list of accounts */
666 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
668 /* The accounts dialog must be modal */
669 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
670 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
675 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
677 /* This is currently only implemented for Maemo,
678 * because it requires an API (libconic) to detect different connection
681 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
683 /* Create the window if necessary: */
684 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
685 modest_connection_specific_smtp_window_fill_with_connections (
686 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
687 modest_runtime_get_account_mgr());
689 /* Show the window: */
690 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
691 GTK_WINDOW (specific_window), (GtkWindow *) win);
692 gtk_widget_show (specific_window);
693 #endif /* !MODEST_TOOLKIT_GTK */
697 modest_ui_actions_compose_msg(ModestWindow *win,
700 const gchar *bcc_str,
701 const gchar *subject_str,
702 const gchar *body_str,
704 gboolean set_as_modified)
706 gchar *account_name = NULL;
708 TnyAccount *account = NULL;
709 TnyFolder *folder = NULL;
710 gchar *from_str = NULL, *signature = NULL, *body = NULL;
711 gboolean use_signature = FALSE;
712 ModestWindow *msg_win = NULL;
713 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
714 ModestTnyAccountStore *store = modest_runtime_get_account_store();
715 GnomeVFSFileSize total_size, allowed_size;
717 /* we check for low-mem */
718 if (modest_platform_check_memory_low (win, TRUE))
721 #ifdef MODEST_TOOLKIT_HILDON2
722 account_name = g_strdup (modest_window_get_active_account(win));
725 account_name = modest_account_mgr_get_default_account(mgr);
728 g_printerr ("modest: no account found\n");
731 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
733 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
736 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
738 g_printerr ("modest: failed to find Drafts folder\n");
741 from_str = modest_account_mgr_get_from_string (mgr, account_name);
743 g_printerr ("modest: failed get from string for '%s'\n", account_name);
747 signature = modest_account_mgr_get_signature (mgr, account_name, &use_signature);
748 if (body_str != NULL) {
749 body = use_signature ? g_strconcat(body_str, "\n--\n", signature, NULL) : g_strdup(body_str);
751 body = use_signature ? g_strconcat("\n--\n", signature, NULL) : g_strdup("");
754 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, body, NULL, NULL, NULL);
756 g_printerr ("modest: failed to create new msg\n");
760 /* Create and register edit window */
761 /* This is destroyed by TODO. */
763 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
764 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
766 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, NULL)) {
767 gtk_widget_destroy (GTK_WIDGET (msg_win));
770 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
771 gtk_widget_show_all (GTK_WIDGET (msg_win));
773 while (attachments) {
775 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
776 attachments->data, allowed_size);
778 if (total_size > allowed_size) {
779 g_warning ("%s: total size: %u",
780 __FUNCTION__, (unsigned int)total_size);
783 allowed_size -= total_size;
785 attachments = g_slist_next(attachments);
792 g_free (account_name);
794 g_object_unref (G_OBJECT(account));
796 g_object_unref (G_OBJECT(folder));
798 g_object_unref (G_OBJECT(msg));
802 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
804 /* if there are no accounts yet, just show the wizard */
805 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
806 if (!modest_ui_actions_run_account_setup_wizard (win))
809 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
814 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
818 ModestMailOperationStatus status;
820 /* If there is no message or the operation was not successful */
821 status = modest_mail_operation_get_status (mail_op);
822 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
825 /* If it's a memory low issue, then show a banner */
826 error = modest_mail_operation_get_error (mail_op);
827 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
828 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
829 GObject *source = modest_mail_operation_get_source (mail_op);
830 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
831 dgettext("ke-recv","memr_ib_operation_disabled"),
833 g_object_unref (source);
836 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
837 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
838 gchar *subject, *msg;
839 subject = tny_header_dup_subject (header);
841 subject = g_strdup (_("mail_va_no_subject"));;
842 msg = g_strdup_printf (_("emev_ni_ui_imap_message_not_available_in_server"),
844 modest_platform_run_information_dialog (NULL, msg, FALSE);
849 /* Remove the header from the preregistered uids */
850 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
868 OpenMsgBannerInfo *banner_info;
869 GtkTreeRowReference *rowref;
873 open_msg_banner_idle (gpointer userdata)
875 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
877 gdk_threads_enter ();
878 banner_info->idle_handler = 0;
879 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
881 g_object_ref (banner_info->banner);
883 gdk_threads_leave ();
890 get_header_view_from_window (ModestWindow *window)
892 GtkWidget *header_view;
894 if (MODEST_IS_MAIN_WINDOW (window)) {
895 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
896 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
897 #ifdef MODEST_TOOLKIT_HILDON2
898 } else if (MODEST_IS_HEADER_WINDOW (window)){
899 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
909 get_info_from_header (TnyHeader *header, gboolean *is_draft)
912 gchar *account = NULL;
913 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
917 folder = tny_header_get_folder (header);
918 /* Gets folder type (OUTBOX headers will be opened in edit window */
919 if (modest_tny_folder_is_local_folder (folder)) {
920 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
921 if (folder_type == TNY_FOLDER_TYPE_INVALID)
922 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
925 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
926 TnyTransportAccount *traccount = NULL;
927 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
928 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
930 ModestTnySendQueue *send_queue = NULL;
931 ModestTnySendQueueStatus status;
933 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
934 TNY_ACCOUNT(traccount)));
935 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
936 if (TNY_IS_SEND_QUEUE (send_queue)) {
937 msg_id = modest_tny_send_queue_get_msg_id (header);
938 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
940 /* Only open messages in outbox with the editor if they are in Failed state */
941 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
944 #ifdef MODEST_TOOLKIT_HILDON2
946 /* In Fremantle we can not
947 open any message from
948 outbox which is not in
950 g_object_unref(traccount);
954 g_object_unref(traccount);
956 g_warning("Cannot get transport account for message in outbox!!");
958 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
959 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
962 g_object_unref (folder);
968 open_msg_cb (ModestMailOperation *mail_op,
975 ModestWindowMgr *mgr = NULL;
976 ModestWindow *parent_win = NULL;
977 ModestWindow *win = NULL;
978 gchar *account = NULL;
979 gboolean open_in_editor = FALSE;
980 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
982 /* Do nothing if there was any problem with the mail
983 operation. The error will be shown by the error_handler of
984 the mail operation */
985 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
988 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
990 /* Mark header as read */
991 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
993 account = get_info_from_header (header, &open_in_editor);
997 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
999 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1001 if (open_in_editor) {
1002 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1003 gchar *from_header = NULL, *acc_name;
1005 from_header = tny_header_dup_from (header);
1007 /* we cannot edit without a valid account... */
1008 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1009 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1010 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1012 g_free (from_header);
1017 acc_name = modest_utils_get_account_name_from_recipient (from_header);
1018 g_free (from_header);
1024 win = modest_msg_edit_window_new (msg, account, TRUE);
1026 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1028 if (helper->rowref && helper->model) {
1029 win = modest_msg_view_window_new_with_header_model (msg, account, (const gchar*) uid,
1030 helper->model, helper->rowref);
1032 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
1037 /* Register and show new window */
1039 mgr = modest_runtime_get_window_mgr ();
1040 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1041 gtk_widget_destroy (GTK_WIDGET (win));
1044 gtk_widget_show_all (GTK_WIDGET(win));
1047 /* Update toolbar dimming state */
1048 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1049 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1055 g_object_unref (parent_win);
1059 is_memory_full_error (GError *error)
1061 gboolean enough_free_space = TRUE;
1062 GnomeVFSURI *cache_dir_uri;
1063 const gchar *cache_dir;
1064 GnomeVFSFileSize free_space;
1066 cache_dir = tny_account_store_get_cache_dir (TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
1067 cache_dir_uri = gnome_vfs_uri_new (cache_dir);
1068 if (gnome_vfs_get_volume_free_space (cache_dir_uri, &free_space) == GNOME_VFS_OK) {
1069 if (free_space < MIN_FREE_SPACE)
1070 enough_free_space = FALSE;
1072 gnome_vfs_uri_unref (cache_dir_uri);
1074 if ((error->code == TNY_SYSTEM_ERROR_MEMORY ||
1075 /* When asking for a mail and no space left on device
1076 tinymail returns this error */
1077 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE ||
1078 /* When the folder summary could not be read or
1080 error->code == TNY_IO_ERROR_WRITE ||
1081 error->code == TNY_IO_ERROR_READ) &&
1082 !enough_free_space) {
1090 check_memory_full_error (GtkWidget *parent_window, GError *err)
1095 if (is_memory_full_error (err))
1096 modest_platform_information_banner (parent_window,
1097 NULL, dgettext("ke-recv",
1098 "cerm_device_memory_full"));
1099 else if (err->code == TNY_SYSTEM_ERROR_MEMORY)
1100 /* If the account was created in memory full
1101 conditions then tinymail won't be able to
1102 connect so it'll return this error code */
1103 modest_platform_information_banner (parent_window,
1104 NULL, _("emev_ui_imap_inbox_select_error"));
1112 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1115 const GError *error;
1116 GObject *win = NULL;
1117 ModestMailOperationStatus status;
1119 win = modest_mail_operation_get_source (mail_op);
1120 error = modest_mail_operation_get_error (mail_op);
1121 status = modest_mail_operation_get_status (mail_op);
1123 /* If the mail op has been cancelled then it's not an error:
1124 don't show any message */
1125 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1126 if (is_memory_full_error ((GError *) error)) {
1127 modest_platform_information_banner ((GtkWidget *) win,
1128 NULL, dgettext("ke-recv",
1129 "cerm_device_memory_full"));
1130 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1131 modest_platform_information_banner ((GtkWidget *) win,
1132 NULL, _("emev_ui_imap_inbox_select_error"));
1133 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1134 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1135 modest_platform_information_banner ((GtkWidget *) win,
1136 NULL, dgettext ("hildon-common-strings", "sfil_ni_unable_to_open_file_not_found"));
1137 } else if (user_data) {
1138 modest_platform_information_banner ((GtkWidget *) win,
1144 g_object_unref (win);
1148 * Returns the account a list of headers belongs to. It returns a
1149 * *new* reference so don't forget to unref it
1152 get_account_from_header_list (TnyList *headers)
1154 TnyAccount *account = NULL;
1156 if (tny_list_get_length (headers) > 0) {
1157 TnyIterator *iter = tny_list_create_iterator (headers);
1158 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1159 TnyFolder *folder = tny_header_get_folder (header);
1162 g_object_unref (header);
1164 while (!tny_iterator_is_done (iter)) {
1165 header = TNY_HEADER (tny_iterator_get_current (iter));
1166 folder = tny_header_get_folder (header);
1169 g_object_unref (header);
1171 tny_iterator_next (iter);
1176 account = tny_folder_get_account (folder);
1177 g_object_unref (folder);
1181 g_object_unref (header);
1183 g_object_unref (iter);
1189 get_account_from_header (TnyHeader *header)
1191 TnyAccount *account = NULL;
1194 folder = tny_header_get_folder (header);
1197 account = tny_folder_get_account (folder);
1198 g_object_unref (folder);
1205 open_msg_helper_destroyer (gpointer user_data)
1207 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1209 if (helper->banner_info) {
1210 g_free (helper->banner_info->message);
1211 if (helper->banner_info->idle_handler > 0) {
1212 g_source_remove (helper->banner_info->idle_handler);
1213 helper->banner_info->idle_handler = 0;
1215 if (helper->banner_info->banner != NULL) {
1216 gtk_widget_destroy (helper->banner_info->banner);
1217 g_object_unref (helper->banner_info->banner);
1218 helper->banner_info->banner = NULL;
1220 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1221 helper->banner_info = NULL;
1223 g_object_unref (helper->model);
1224 g_object_unref (helper->header);
1225 gtk_tree_row_reference_free (helper->rowref);
1226 g_slice_free (OpenMsgHelper, helper);
1230 open_msg_performer(gboolean canceled,
1232 GtkWindow *parent_window,
1233 TnyAccount *account,
1236 ModestMailOperation *mail_op = NULL;
1238 ModestProtocolType proto;
1239 TnyConnectionStatus status;
1240 gboolean show_open_draft = FALSE;
1241 OpenMsgHelper *helper = NULL;
1243 helper = (OpenMsgHelper *) user_data;
1245 status = tny_account_get_connection_status (account);
1246 if (err || canceled) {
1247 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1248 /* Free the helper */
1249 open_msg_helper_destroyer (helper);
1251 /* In memory full conditions we could get this error here */
1252 check_memory_full_error ((GtkWidget *) parent_window, err);
1257 /* Get the error message depending on the protocol */
1258 proto = modest_tny_account_get_protocol_type (account);
1259 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1260 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1263 ModestProtocol *protocol;
1264 ModestProtocolRegistry *protocol_registry;
1267 protocol_registry = modest_runtime_get_protocol_registry ();
1268 subject = tny_header_dup_subject (helper->header);
1270 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1271 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1275 if (error_msg == NULL) {
1276 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1279 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1281 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1283 TnyFolderType folder_type;
1285 folder = tny_header_get_folder (helper->header);
1286 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1287 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1288 g_object_unref (folder);
1291 #ifdef MODEST_TOOLKIT_HILDON2
1293 gchar *account_name = get_info_from_header (helper->header, &is_draft);
1296 ModestWindow *window;
1297 GtkWidget *header_view;
1300 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1301 uid = modest_tny_folder_get_header_unique_id (helper->header);
1303 window = modest_msg_view_window_new_from_header_view
1304 (MODEST_HEADER_VIEW (header_view), account_name, uid, helper->rowref);
1305 if (window != NULL) {
1306 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1308 gtk_widget_destroy (GTK_WIDGET (window));
1310 gtk_widget_show_all (GTK_WIDGET(window));
1314 g_free (account_name);
1316 open_msg_helper_destroyer (helper);
1319 g_free (account_name);
1321 /* Create the mail operation */
1323 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1324 modest_ui_actions_disk_operations_error_handler,
1326 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1329 if (show_open_draft) {
1330 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1331 #ifdef MODEST_TOOLKIT_HILDON2
1332 helper->banner_info->message = g_strdup (_("mail_me_opening"));
1334 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1336 helper->banner_info->banner = NULL;
1337 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1338 helper->banner_info);
1342 headers = TNY_LIST (tny_simple_list_new ());
1343 tny_list_prepend (headers, G_OBJECT (helper->header));
1344 modest_mail_operation_get_msgs_full (mail_op,
1348 open_msg_helper_destroyer);
1349 g_object_unref (headers);
1354 g_object_unref (mail_op);
1355 g_object_unref (account);
1359 * This function is used by both modest_ui_actions_on_open and
1360 * modest_ui_actions_on_header_activated. This way we always do the
1361 * same when trying to open messages.
1364 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1366 ModestWindowMgr *mgr = NULL;
1367 TnyAccount *account;
1368 gboolean cached = FALSE;
1370 GtkWidget *header_view = NULL;
1371 OpenMsgHelper *helper;
1372 ModestWindow *window;
1374 g_return_if_fail (header != NULL && rowref != NULL);
1376 mgr = modest_runtime_get_window_mgr ();
1379 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1380 if (header_view == NULL)
1383 /* Get the account */
1384 account = get_account_from_header (header);
1389 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1391 /* Do not open again the message and present the
1392 window to the user */
1395 #ifndef MODEST_TOOLKIT_HILDON2
1396 gtk_window_present (GTK_WINDOW (window));
1399 /* the header has been registered already, we don't do
1400 * anything but wait for the window to come up*/
1401 g_debug ("header %p already registered, waiting for window", header);
1406 /* Open each message */
1407 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1409 /* Allways download if we are online. */
1410 if (!tny_device_is_online (modest_runtime_get_device ())) {
1413 /* If ask for user permission to download the messages */
1414 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1415 _("mcen_nc_get_msg"));
1417 /* End if the user does not want to continue */
1418 if (response == GTK_RESPONSE_CANCEL) {
1424 /* We register the window for opening */
1425 modest_window_mgr_register_header (mgr, header, NULL);
1427 /* Create the helper. We need to get a reference to the model
1428 here because it could change while the message is readed
1429 (the user could switch between folders) */
1430 helper = g_slice_new (OpenMsgHelper);
1431 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1432 helper->header = g_object_ref (header);
1433 helper->rowref = gtk_tree_row_reference_copy (rowref);
1434 helper->banner_info = NULL;
1436 /* Connect to the account and perform */
1438 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1439 open_msg_performer, helper);
1441 /* Call directly the performer, do not need to connect */
1442 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1443 g_object_ref (account), helper);
1448 g_object_unref (account);
1452 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1459 /* we check for low-mem; in that case, show a warning, and don't allow
1462 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1466 headers = get_selected_headers (win);
1470 headers_count = tny_list_get_length (headers);
1471 if (headers_count != 1) {
1472 if (headers_count > 1) {
1473 /* Don't allow activation if there are more than one message selected */
1474 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1477 g_object_unref (headers);
1481 iter = tny_list_create_iterator (headers);
1482 header = TNY_HEADER (tny_iterator_get_current (iter));
1483 g_object_unref (iter);
1487 open_msg_from_header (header, NULL, win);
1488 g_object_unref (header);
1491 g_object_unref(headers);
1494 static ReplyForwardHelper*
1495 create_reply_forward_helper (ReplyForwardAction action,
1497 guint reply_forward_type,
1500 ReplyForwardHelper *rf_helper = NULL;
1501 const gchar *active_acc = modest_window_get_active_account (win);
1503 rf_helper = g_slice_new0 (ReplyForwardHelper);
1504 rf_helper->reply_forward_type = reply_forward_type;
1505 rf_helper->action = action;
1506 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1507 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1508 rf_helper->account_name = (active_acc) ?
1509 g_strdup (active_acc) :
1510 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1516 free_reply_forward_helper (gpointer data)
1518 ReplyForwardHelper *helper;
1520 helper = (ReplyForwardHelper *) data;
1521 g_free (helper->account_name);
1523 g_object_unref (helper->header);
1524 g_slice_free (ReplyForwardHelper, helper);
1528 reply_forward_cb (ModestMailOperation *mail_op,
1535 TnyMsg *new_msg = NULL;
1536 ReplyForwardHelper *rf_helper;
1537 ModestWindow *msg_win = NULL;
1538 ModestEditType edit_type;
1540 TnyAccount *account = NULL;
1541 ModestWindowMgr *mgr = NULL;
1542 gchar *signature = NULL;
1543 gboolean use_signature;
1545 /* If there was any error. The mail operation could be NULL,
1546 this means that we already have the message downloaded and
1547 that we didn't do a mail operation to retrieve it */
1548 rf_helper = (ReplyForwardHelper *) user_data;
1549 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1552 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1553 rf_helper->account_name);
1554 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr(),
1555 rf_helper->account_name,
1558 /* Create reply mail */
1559 switch (rf_helper->action) {
1562 modest_tny_msg_create_reply_msg (msg, header, from,
1563 (use_signature) ? signature : NULL,
1564 rf_helper->reply_forward_type,
1565 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1567 case ACTION_REPLY_TO_ALL:
1569 modest_tny_msg_create_reply_msg (msg, header, from,
1570 (use_signature) ? signature : NULL,
1571 rf_helper->reply_forward_type,
1572 MODEST_TNY_MSG_REPLY_MODE_ALL);
1573 edit_type = MODEST_EDIT_TYPE_REPLY;
1575 case ACTION_FORWARD:
1577 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1578 rf_helper->reply_forward_type);
1579 edit_type = MODEST_EDIT_TYPE_FORWARD;
1582 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1584 g_return_if_reached ();
1592 g_warning ("%s: failed to create message\n", __FUNCTION__);
1596 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1597 rf_helper->account_name,
1598 TNY_ACCOUNT_TYPE_STORE);
1600 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1604 /* Create and register the windows */
1605 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1606 mgr = modest_runtime_get_window_mgr ();
1607 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1609 if (rf_helper->parent_window != NULL) {
1610 gdouble parent_zoom;
1612 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1613 modest_window_set_zoom (msg_win, parent_zoom);
1616 /* Show edit window */
1617 gtk_widget_show_all (GTK_WIDGET (msg_win));
1620 /* We always unregister the header because the message is
1621 forwarded or replied so the original one is no longer
1623 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1626 g_object_unref (G_OBJECT (new_msg));
1628 g_object_unref (G_OBJECT (account));
1629 free_reply_forward_helper (rf_helper);
1632 /* Checks a list of headers. If any of them are not currently
1633 * downloaded (CACHED) then returns TRUE else returns FALSE.
1636 header_list_count_uncached_msgs (TnyList *header_list)
1639 gint uncached_messages = 0;
1641 iter = tny_list_create_iterator (header_list);
1642 while (!tny_iterator_is_done (iter)) {
1645 header = TNY_HEADER (tny_iterator_get_current (iter));
1647 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1648 uncached_messages ++;
1649 g_object_unref (header);
1652 tny_iterator_next (iter);
1654 g_object_unref (iter);
1656 return uncached_messages;
1659 /* Returns FALSE if the user does not want to download the
1660 * messages. Returns TRUE if the user allowed the download.
1663 connect_to_get_msg (ModestWindow *win,
1664 gint num_of_uncached_msgs,
1665 TnyAccount *account)
1667 GtkResponseType response;
1669 /* Allways download if we are online. */
1670 if (tny_device_is_online (modest_runtime_get_device ()))
1673 /* If offline, then ask for user permission to download the messages */
1674 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1675 ngettext("mcen_nc_get_msg",
1677 num_of_uncached_msgs));
1679 if (response == GTK_RESPONSE_CANCEL)
1682 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1686 reply_forward_performer (gboolean canceled,
1688 GtkWindow *parent_window,
1689 TnyAccount *account,
1692 ReplyForwardHelper *rf_helper = NULL;
1693 ModestMailOperation *mail_op;
1695 rf_helper = (ReplyForwardHelper *) user_data;
1697 if (canceled || err) {
1698 free_reply_forward_helper (rf_helper);
1702 /* Retrieve the message */
1703 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1704 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1705 modest_ui_actions_disk_operations_error_handler,
1707 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1708 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1711 g_object_unref(mail_op);
1715 * Common code for the reply and forward actions
1718 reply_forward (ReplyForwardAction action, ModestWindow *win)
1720 ReplyForwardHelper *rf_helper = NULL;
1721 guint reply_forward_type;
1723 g_return_if_fail (MODEST_IS_WINDOW(win));
1725 /* we check for low-mem; in that case, show a warning, and don't allow
1726 * reply/forward (because it could potentially require a lot of memory */
1727 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1731 /* we need an account when editing */
1732 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1733 if (!modest_ui_actions_run_account_setup_wizard (win))
1737 reply_forward_type =
1738 modest_conf_get_int (modest_runtime_get_conf (),
1739 (action == ACTION_FORWARD) ?
1740 MODEST_CONF_FORWARD_TYPE :
1741 MODEST_CONF_REPLY_TYPE,
1744 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1746 TnyHeader *header = NULL;
1747 /* Get header and message. Do not free them here, the
1748 reply_forward_cb must do it */
1749 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1750 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1752 if (msg && header) {
1754 rf_helper = create_reply_forward_helper (action, win,
1755 reply_forward_type, header);
1756 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1758 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1762 g_object_unref (msg);
1764 g_object_unref (header);
1766 TnyHeader *header = NULL;
1768 gboolean do_retrieve = TRUE;
1769 TnyList *header_list = NULL;
1771 header_list = get_selected_headers (win);
1774 /* Check that only one message is selected for replying */
1775 if (tny_list_get_length (header_list) != 1) {
1776 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1777 NULL, _("mcen_ib_select_one_message"));
1778 g_object_unref (header_list);
1782 /* Only reply/forward to one message */
1783 iter = tny_list_create_iterator (header_list);
1784 header = TNY_HEADER (tny_iterator_get_current (iter));
1785 g_object_unref (iter);
1787 /* Retrieve messages */
1788 do_retrieve = (action == ACTION_FORWARD) ||
1789 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1792 TnyAccount *account = NULL;
1793 TnyFolder *folder = NULL;
1794 gdouble download = TRUE;
1795 guint uncached_msgs = 0;
1797 folder = tny_header_get_folder (header);
1799 goto do_retrieve_frees;
1800 account = tny_folder_get_account (folder);
1802 goto do_retrieve_frees;
1804 uncached_msgs = header_list_count_uncached_msgs (header_list);
1806 if (uncached_msgs > 0) {
1807 /* Allways download if we are online. */
1808 if (!tny_device_is_online (modest_runtime_get_device ())) {
1811 /* If ask for user permission to download the messages */
1812 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1813 ngettext("mcen_nc_get_msg",
1817 /* End if the user does not want to continue */
1818 if (response == GTK_RESPONSE_CANCEL)
1825 rf_helper = create_reply_forward_helper (action, win,
1826 reply_forward_type, header);
1827 if (uncached_msgs > 0) {
1828 modest_platform_connect_and_perform (GTK_WINDOW (win),
1830 reply_forward_performer,
1833 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
1834 account, rf_helper);
1839 g_object_unref (account);
1841 g_object_unref (folder);
1843 reply_forward_cb (NULL, header, FALSE, NULL, NULL, rf_helper);
1846 g_object_unref (header_list);
1847 g_object_unref (header);
1852 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1854 g_return_if_fail (MODEST_IS_WINDOW(win));
1856 reply_forward (ACTION_REPLY, win);
1860 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1862 g_return_if_fail (MODEST_IS_WINDOW(win));
1864 reply_forward (ACTION_FORWARD, win);
1868 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1870 g_return_if_fail (MODEST_IS_WINDOW(win));
1872 reply_forward (ACTION_REPLY_TO_ALL, win);
1876 modest_ui_actions_on_next (GtkAction *action,
1877 ModestWindow *window)
1879 if (MODEST_IS_MAIN_WINDOW (window)) {
1880 GtkWidget *header_view;
1882 header_view = modest_main_window_get_child_widget (
1883 MODEST_MAIN_WINDOW(window),
1884 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1888 modest_header_view_select_next (
1889 MODEST_HEADER_VIEW(header_view));
1890 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1891 modest_msg_view_window_select_next_message (
1892 MODEST_MSG_VIEW_WINDOW (window));
1894 g_return_if_reached ();
1899 modest_ui_actions_on_prev (GtkAction *action,
1900 ModestWindow *window)
1902 g_return_if_fail (MODEST_IS_WINDOW(window));
1904 if (MODEST_IS_MAIN_WINDOW (window)) {
1905 GtkWidget *header_view;
1906 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1907 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1911 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1912 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1913 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1915 g_return_if_reached ();
1920 modest_ui_actions_on_sort (GtkAction *action,
1921 ModestWindow *window)
1923 GtkWidget *header_view = NULL;
1925 g_return_if_fail (MODEST_IS_WINDOW(window));
1927 if (MODEST_IS_MAIN_WINDOW (window)) {
1928 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1929 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1930 #ifdef MODEST_TOOLKIT_HILDON2
1931 } else if (MODEST_IS_HEADER_WINDOW (window)) {
1932 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
1937 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1942 /* Show sorting dialog */
1943 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1947 new_messages_arrived (ModestMailOperation *self,
1948 TnyList *new_headers,
1952 gboolean show_visual_notifications;
1954 source = modest_mail_operation_get_source (self);
1955 show_visual_notifications = (source) ? FALSE : TRUE;
1957 g_object_unref (source);
1959 /* Notify new messages have been downloaded. If the
1960 send&receive was invoked by the user then do not show any
1961 visual notification, only play a sound and activate the LED
1962 (for the Maemo version) */
1963 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0)
1964 modest_platform_on_new_headers_received (new_headers,
1965 show_visual_notifications);
1970 retrieve_all_messages_cb (GObject *source,
1972 guint retrieve_limit)
1978 window = GTK_WINDOW (source);
1979 msg = g_strdup_printf (_("mail_nc_msg_count_limit_exceeded"),
1980 num_msgs, retrieve_limit);
1982 /* Ask the user if they want to retrieve all the messages */
1984 modest_platform_run_confirmation_dialog_with_buttons (window, msg,
1985 _("mcen_bd_get_all"),
1986 _("mcen_bd_newest_only"));
1987 /* Free and return */
1989 return (response == GTK_RESPONSE_ACCEPT) ? TRUE : FALSE;
1993 TnyAccount *account;
1995 gchar *account_name;
1996 gboolean poke_status;
1997 gboolean interactive;
1998 ModestMailOperation *mail_op;
2002 do_send_receive_performer (gboolean canceled,
2004 GtkWindow *parent_window,
2005 TnyAccount *account,
2008 SendReceiveInfo *info;
2010 info = (SendReceiveInfo *) user_data;
2012 if (err || canceled) {
2013 /* In memory full conditions we could get this error here */
2014 check_memory_full_error ((GtkWidget *) parent_window, err);
2016 if (info->mail_op) {
2017 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2023 /* Set send/receive operation in progress */
2024 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2025 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2028 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2029 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2030 G_CALLBACK (on_send_receive_finished),
2033 /* Send & receive. */
2034 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2035 (info->win) ? retrieve_all_messages_cb : NULL,
2036 new_messages_arrived, info->win);
2041 g_object_unref (G_OBJECT (info->mail_op));
2042 if (info->account_name)
2043 g_free (info->account_name);
2045 g_object_unref (info->win);
2047 g_object_unref (info->account);
2048 g_slice_free (SendReceiveInfo, info);
2052 * This function performs the send & receive required actions. The
2053 * window is used to create the mail operation. Typically it should
2054 * always be the main window, but we pass it as argument in order to
2058 modest_ui_actions_do_send_receive (const gchar *account_name,
2059 gboolean force_connection,
2060 gboolean poke_status,
2061 gboolean interactive,
2064 gchar *acc_name = NULL;
2065 SendReceiveInfo *info;
2066 ModestTnyAccountStore *acc_store;
2068 /* If no account name was provided then get the current account, and if
2069 there is no current account then pick the default one: */
2070 if (!account_name) {
2072 acc_name = g_strdup (modest_window_get_active_account (win));
2074 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2076 g_printerr ("modest: cannot get default account\n");
2080 acc_name = g_strdup (account_name);
2083 acc_store = modest_runtime_get_account_store ();
2085 /* Create the info for the connect and perform */
2086 info = g_slice_new (SendReceiveInfo);
2087 info->account_name = acc_name;
2088 info->win = (win) ? g_object_ref (win) : NULL;
2089 info->poke_status = poke_status;
2090 info->interactive = interactive;
2091 info->account = modest_tny_account_store_get_server_account (acc_store, acc_name,
2092 TNY_ACCOUNT_TYPE_STORE);
2093 /* We need to create the operation here, because otherwise it
2094 could happen that the queue emits the queue-empty signal
2095 while we're trying to connect the account */
2096 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2097 modest_ui_actions_disk_operations_error_handler,
2099 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2101 /* Invoke the connect and perform */
2102 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2103 force_connection, info->account,
2104 do_send_receive_performer, info);
2109 modest_ui_actions_do_cancel_send (const gchar *account_name,
2112 TnyTransportAccount *transport_account;
2113 TnySendQueue *send_queue = NULL;
2114 GError *error = NULL;
2116 /* Get transport account */
2118 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2119 (modest_runtime_get_account_store(),
2121 TNY_ACCOUNT_TYPE_TRANSPORT));
2122 if (!transport_account) {
2123 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2128 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2129 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2130 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2131 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2132 "modest: could not find send queue for account\n");
2134 /* Cancel the current send */
2135 tny_account_cancel (TNY_ACCOUNT (transport_account));
2137 /* Suspend all pending messages */
2138 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2142 if (transport_account != NULL)
2143 g_object_unref (G_OBJECT (transport_account));
2147 modest_ui_actions_cancel_send_all (ModestWindow *win)
2149 GSList *account_names, *iter;
2151 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2154 iter = account_names;
2156 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2157 iter = g_slist_next (iter);
2160 modest_account_mgr_free_account_names (account_names);
2161 account_names = NULL;
2165 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2168 /* Check if accounts exist */
2169 gboolean accounts_exist =
2170 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2172 /* If not, allow the user to create an account before trying to send/receive. */
2173 if (!accounts_exist)
2174 modest_ui_actions_on_accounts (NULL, win);
2176 /* Cancel all sending operaitons */
2177 modest_ui_actions_cancel_send_all (win);
2181 * Refreshes all accounts. This function will be used by automatic
2185 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2186 gboolean force_connection,
2187 gboolean poke_status,
2188 gboolean interactive)
2190 GSList *account_names, *iter;
2192 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2195 iter = account_names;
2197 modest_ui_actions_do_send_receive ((const char*) iter->data,
2199 poke_status, interactive, win);
2200 iter = g_slist_next (iter);
2203 modest_account_mgr_free_account_names (account_names);
2204 account_names = NULL;
2208 * Handler of the click on Send&Receive button in the main toolbar
2211 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2213 /* Check if accounts exist */
2214 gboolean accounts_exist;
2217 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2219 /* If not, allow the user to create an account before trying to send/receive. */
2220 if (!accounts_exist)
2221 modest_ui_actions_on_accounts (NULL, win);
2223 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2224 if (MODEST_IS_MAIN_WINDOW (win)) {
2225 GtkWidget *folder_view;
2226 TnyFolderStore *folder_store;
2229 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2230 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2234 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2237 g_object_unref (folder_store);
2238 /* Refresh the active account. Force the connection if needed
2239 and poke the status of all folders */
2240 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2242 const gchar *active_account;
2243 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2245 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2252 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2255 GtkWidget *header_view;
2257 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2259 header_view = modest_main_window_get_child_widget (main_window,
2260 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2264 conf = modest_runtime_get_conf ();
2266 /* what is saved/restored is depending on the style; thus; we save with
2267 * old style, then update the style, and restore for this new style
2269 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2271 if (modest_header_view_get_style
2272 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2273 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2274 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2276 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2277 MODEST_HEADER_VIEW_STYLE_DETAILS);
2279 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2280 MODEST_CONF_HEADER_VIEW_KEY);
2285 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2287 ModestMainWindow *main_window)
2289 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2290 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2292 /* in the case the folder is empty, show the empty folder message and focus
2294 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2295 if (modest_header_view_is_empty (header_view)) {
2296 TnyFolder *folder = modest_header_view_get_folder (header_view);
2297 GtkWidget *folder_view =
2298 modest_main_window_get_child_widget (main_window,
2299 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2300 if (folder != NULL) {
2301 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2302 g_object_unref (folder);
2304 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2308 /* If no header has been selected then exit */
2313 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2314 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2316 /* Update toolbar dimming state */
2317 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2318 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2322 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2325 ModestWindow *window)
2327 GtkWidget *open_widget;
2328 GtkTreeRowReference *rowref;
2330 g_return_if_fail (MODEST_IS_WINDOW(window));
2331 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2332 g_return_if_fail (TNY_IS_HEADER (header));
2334 if (modest_header_view_count_selected_headers (header_view) > 1) {
2335 /* Don't allow activation if there are more than one message selected */
2336 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2340 /* we check for low-mem; in that case, show a warning, and don't allow
2341 * activating headers
2343 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2346 if (MODEST_IS_MAIN_WINDOW (window)) {
2347 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2348 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2349 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2353 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2354 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2355 gtk_tree_row_reference_free (rowref);
2359 set_active_account_from_tny_account (TnyAccount *account,
2360 ModestWindow *window)
2362 const gchar *server_acc_name = tny_account_get_id (account);
2364 /* We need the TnyAccount provided by the
2365 account store because that is the one that
2366 knows the name of the Modest account */
2367 TnyAccount *modest_server_account = modest_server_account =
2368 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2369 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2371 if (!modest_server_account) {
2372 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2376 /* Update active account, but only if it's not a pseudo-account */
2377 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2378 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2379 const gchar *modest_acc_name =
2380 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2381 if (modest_acc_name)
2382 modest_window_set_active_account (window, modest_acc_name);
2385 g_object_unref (modest_server_account);
2390 folder_refreshed_cb (ModestMailOperation *mail_op,
2394 ModestMainWindow *win = NULL;
2395 GtkWidget *folder_view;
2396 const GError *error;
2398 g_return_if_fail (TNY_IS_FOLDER (folder));
2400 win = MODEST_MAIN_WINDOW (user_data);
2402 /* Check if the operation failed due to memory low conditions */
2403 error = modest_mail_operation_get_error (mail_op);
2404 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2405 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2406 modest_platform_run_information_dialog (GTK_WINDOW (win),
2407 dgettext("ke-recv","memr_ib_operation_disabled"),
2413 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2416 TnyFolderStore *current_folder;
2418 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2419 if (current_folder) {
2420 gboolean different = ((TnyFolderStore *) folder != current_folder);
2421 g_object_unref (current_folder);
2427 /* Check if folder is empty and set headers view contents style */
2428 if (tny_folder_get_all_count (folder) == 0)
2429 modest_main_window_set_contents_style (win,
2430 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2435 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2436 TnyFolderStore *folder_store,
2438 ModestMainWindow *main_window)
2441 GtkWidget *header_view;
2443 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2445 header_view = modest_main_window_get_child_widget(main_window,
2446 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2450 conf = modest_runtime_get_conf ();
2452 if (TNY_IS_ACCOUNT (folder_store)) {
2454 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2456 /* Show account details */
2457 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2460 if (TNY_IS_FOLDER (folder_store) && selected) {
2461 TnyAccount *account;
2462 const gchar *account_name = NULL;
2464 /* Update the active account */
2465 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2467 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2469 modest_tny_account_get_parent_modest_account_name_for_server_account (account);
2470 g_object_unref (account);
2474 /* Set the header style by default, it could
2475 be changed later by the refresh callback to
2477 modest_main_window_set_contents_style (main_window,
2478 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2480 /* Set folder on header view. This function
2481 will call tny_folder_refresh_async so we
2482 pass a callback that will be called when
2483 finished. We use that callback to set the
2484 empty view if there are no messages */
2485 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2486 TNY_FOLDER (folder_store),
2488 MODEST_WINDOW (main_window),
2489 folder_refreshed_cb,
2492 /* Restore configuration. We need to do this
2493 *after* the set_folder because the widget
2494 memory asks the header view about its
2496 modest_widget_memory_restore (modest_runtime_get_conf (),
2497 G_OBJECT(header_view),
2498 MODEST_CONF_HEADER_VIEW_KEY);
2500 /* No need to save the header view
2501 configuration for Maemo because it only
2502 saves the sorting stuff and that it's
2503 already being done by the sort
2504 dialog. Remove it when the GNOME version
2505 has the same behaviour */
2506 #ifdef MODEST_TOOLKIT_GTK
2507 if (modest_main_window_get_contents_style (main_window) ==
2508 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2509 modest_widget_memory_save (conf, G_OBJECT (header_view),
2510 MODEST_CONF_HEADER_VIEW_KEY);
2512 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2516 /* Update dimming state */
2517 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2518 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2522 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2529 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2531 online = tny_device_is_online (modest_runtime_get_device());
2534 /* already online -- the item is simply not there... */
2535 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2537 GTK_MESSAGE_WARNING,
2539 _("The %s you selected cannot be found"),
2541 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2542 gtk_dialog_run (GTK_DIALOG(dialog));
2544 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2547 _("mcen_bd_dialog_cancel"),
2548 GTK_RESPONSE_REJECT,
2549 _("mcen_bd_dialog_ok"),
2550 GTK_RESPONSE_ACCEPT,
2552 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2553 "Do you want to get online?"), item);
2554 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2555 gtk_label_new (txt), FALSE, FALSE, 0);
2556 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2559 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2560 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2561 /* TODO: Comment about why is this commented out: */
2562 /* modest_platform_connect_and_wait (); */
2565 gtk_widget_destroy (dialog);
2569 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2572 /* g_message ("%s %s", __FUNCTION__, link); */
2577 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2580 modest_platform_activate_uri (link);
2584 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2587 modest_platform_show_uri_popup (link);
2591 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2594 /* we check for low-mem; in that case, show a warning, and don't allow
2595 * viewing attachments
2597 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2600 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2604 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2605 const gchar *address,
2608 /* g_message ("%s %s", __FUNCTION__, address); */
2612 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2613 TnyMsg *saved_draft,
2616 ModestMsgEditWindow *edit_window;
2618 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2619 #ifndef MODEST_TOOLKIT_HILDON2
2620 ModestMainWindow *win;
2622 /* FIXME. Make the header view sensitive again. This is a
2623 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2625 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2626 modest_runtime_get_window_mgr(), FALSE));
2628 GtkWidget *hdrview = modest_main_window_get_child_widget(
2629 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2630 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2634 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2636 /* Set draft is there was no error */
2637 if (!modest_mail_operation_get_error (mail_op))
2638 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2640 g_object_unref(edit_window);
2644 enough_space_for_message (ModestMsgEditWindow *edit_window,
2647 TnyAccountStore *acc_store;
2648 guint64 available_disk, expected_size;
2653 acc_store = TNY_ACCOUNT_STORE (modest_runtime_get_account_store());
2654 available_disk = modest_utils_get_available_space (NULL);
2655 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2656 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2661 /* Double check: memory full condition or message too big */
2662 if (available_disk < MIN_FREE_SPACE ||
2663 expected_size > available_disk) {
2665 modest_platform_information_banner (NULL, NULL,
2667 "cerm_device_memory_full"));
2672 * djcb: if we're in low-memory state, we only allow for
2673 * saving messages smaller than
2674 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2675 * should still allow for sending anything critical...
2677 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2678 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2682 * djcb: we also make sure that the attachments are smaller than the max size
2683 * this is for the case where we'd try to forward a message with attachments
2684 * bigger than our max allowed size, or sending an message from drafts which
2685 * somehow got past our checks when attaching.
2687 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2688 modest_platform_run_information_dialog (
2689 GTK_WINDOW(edit_window),
2690 dgettext("ke-recv","memr_ib_operation_disabled"),
2699 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2701 TnyTransportAccount *transport_account;
2702 ModestMailOperation *mail_operation;
2704 gchar *account_name, *from;
2705 ModestAccountMgr *account_mgr;
2706 gboolean had_error = FALSE;
2707 ModestMainWindow *win = NULL;
2709 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2711 data = modest_msg_edit_window_get_msg_data (edit_window);
2714 if (!enough_space_for_message (edit_window, data)) {
2715 modest_msg_edit_window_free_msg_data (edit_window, data);
2719 account_name = g_strdup (data->account_name);
2720 account_mgr = modest_runtime_get_account_mgr();
2722 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2724 account_name = modest_account_mgr_get_default_account (account_mgr);
2725 if (!account_name) {
2726 g_printerr ("modest: no account found\n");
2727 modest_msg_edit_window_free_msg_data (edit_window, data);
2731 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2732 account_name = g_strdup (data->account_name);
2736 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2737 (modest_runtime_get_account_store (),
2739 TNY_ACCOUNT_TYPE_TRANSPORT));
2740 if (!transport_account) {
2741 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2742 g_free (account_name);
2743 modest_msg_edit_window_free_msg_data (edit_window, data);
2746 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2748 /* Create the mail operation */
2749 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
2751 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2753 modest_mail_operation_save_to_drafts (mail_operation,
2765 data->priority_flags,
2766 on_save_to_drafts_cb,
2767 g_object_ref(edit_window));
2769 #ifdef MODEST_TOOLKIT_HILDON2
2770 /* In hildon2 we always show the information banner on saving to drafts.
2771 * It will be a system information banner in this case.
2773 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2774 modest_platform_information_banner (NULL, NULL, text);
2777 /* Use the main window as the parent of the banner, if the
2778 main window does not exist it won't be shown, if the parent
2779 window exists then it's properly shown. We don't use the
2780 editor window because it could be closed (save to drafts
2781 could happen after closing the window */
2782 win = (ModestMainWindow *)
2783 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
2785 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2786 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
2790 modest_msg_edit_window_set_modified (edit_window, FALSE);
2794 g_free (account_name);
2795 g_object_unref (G_OBJECT (transport_account));
2796 g_object_unref (G_OBJECT (mail_operation));
2798 modest_msg_edit_window_free_msg_data (edit_window, data);
2801 * If the drafts folder is selected then make the header view
2802 * insensitive while the message is being saved to drafts
2803 * (it'll be sensitive again in on_save_to_drafts_cb()). This
2804 * is not very clean but it avoids letting the drafts folder
2805 * in an inconsistent state: the user could edit the message
2806 * being saved and undesirable things would happen.
2807 * In the average case the user won't notice anything at
2808 * all. In the worst case (the user is editing a really big
2809 * file from Drafts) the header view will be insensitive
2810 * during the saving process (10 or 20 seconds, depending on
2811 * the message). Anyway this is just a quick workaround: once
2812 * we find a better solution it should be removed
2813 * See NB#65125 (commend #18) for details.
2815 if (!had_error && win != NULL) {
2816 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
2817 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
2819 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
2821 if (modest_tny_folder_is_local_folder(folder)) {
2822 TnyFolderType folder_type;
2823 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
2824 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
2825 GtkWidget *hdrview = modest_main_window_get_child_widget(
2826 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2827 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
2831 if (folder != NULL) g_object_unref(folder);
2838 /* For instance, when clicking the Send toolbar button when editing a message: */
2840 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2842 TnyTransportAccount *transport_account = NULL;
2843 gboolean had_error = FALSE;
2845 ModestAccountMgr *account_mgr;
2846 gchar *account_name;
2848 ModestMailOperation *mail_operation;
2850 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
2852 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2855 data = modest_msg_edit_window_get_msg_data (edit_window);
2858 if (!enough_space_for_message (edit_window, data)) {
2859 modest_msg_edit_window_free_msg_data (edit_window, data);
2863 account_mgr = modest_runtime_get_account_mgr();
2864 account_name = g_strdup (data->account_name);
2866 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2869 account_name = modest_account_mgr_get_default_account (account_mgr);
2871 if (!account_name) {
2872 modest_msg_edit_window_free_msg_data (edit_window, data);
2873 /* Run account setup wizard */
2874 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
2879 /* Get the currently-active transport account for this modest account: */
2880 if (strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
2882 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2883 (modest_runtime_get_account_store (),
2884 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
2887 if (!transport_account) {
2888 modest_msg_edit_window_free_msg_data (edit_window, data);
2889 /* Run account setup wizard */
2890 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2895 /* Create the mail operation */
2896 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2897 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
2898 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2900 modest_mail_operation_send_new_mail (mail_operation,
2912 data->priority_flags);
2914 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
2915 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2918 if (modest_mail_operation_get_error (mail_operation) != NULL) {
2919 const GError *error = modest_mail_operation_get_error (mail_operation);
2920 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
2921 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
2922 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
2923 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
2930 g_free (account_name);
2931 g_object_unref (G_OBJECT (transport_account));
2932 g_object_unref (G_OBJECT (mail_operation));
2934 modest_msg_edit_window_free_msg_data (edit_window, data);
2937 modest_msg_edit_window_set_sent (edit_window, TRUE);
2939 /* Save settings and close the window: */
2940 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2947 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2948 ModestMsgEditWindow *window)
2950 ModestMsgEditFormatState *format_state = NULL;
2952 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2953 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2955 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2958 format_state = modest_msg_edit_window_get_format_state (window);
2959 g_return_if_fail (format_state != NULL);
2961 format_state->bold = gtk_toggle_action_get_active (action);
2962 modest_msg_edit_window_set_format_state (window, format_state);
2963 g_free (format_state);
2968 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2969 ModestMsgEditWindow *window)
2971 ModestMsgEditFormatState *format_state = NULL;
2973 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2974 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2976 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2979 format_state = modest_msg_edit_window_get_format_state (window);
2980 g_return_if_fail (format_state != NULL);
2982 format_state->italics = gtk_toggle_action_get_active (action);
2983 modest_msg_edit_window_set_format_state (window, format_state);
2984 g_free (format_state);
2989 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2990 ModestMsgEditWindow *window)
2992 ModestMsgEditFormatState *format_state = NULL;
2994 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2995 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2997 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3000 format_state = modest_msg_edit_window_get_format_state (window);
3001 g_return_if_fail (format_state != NULL);
3003 format_state->bullet = gtk_toggle_action_get_active (action);
3004 modest_msg_edit_window_set_format_state (window, format_state);
3005 g_free (format_state);
3010 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3011 GtkRadioAction *selected,
3012 ModestMsgEditWindow *window)
3014 ModestMsgEditFormatState *format_state = NULL;
3015 GtkJustification value;
3017 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3019 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3022 value = gtk_radio_action_get_current_value (selected);
3024 format_state = modest_msg_edit_window_get_format_state (window);
3025 g_return_if_fail (format_state != NULL);
3027 format_state->justification = value;
3028 modest_msg_edit_window_set_format_state (window, format_state);
3029 g_free (format_state);
3033 modest_ui_actions_on_select_editor_color (GtkAction *action,
3034 ModestMsgEditWindow *window)
3036 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3037 g_return_if_fail (GTK_IS_ACTION (action));
3039 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3042 modest_msg_edit_window_select_color (window);
3046 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3047 ModestMsgEditWindow *window)
3049 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3050 g_return_if_fail (GTK_IS_ACTION (action));
3052 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3055 modest_msg_edit_window_select_background_color (window);
3059 modest_ui_actions_on_insert_image (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));
3066 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3069 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3072 modest_msg_edit_window_insert_image (window);
3076 modest_ui_actions_on_attach_file (GtkAction *action,
3077 ModestMsgEditWindow *window)
3079 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3080 g_return_if_fail (GTK_IS_ACTION (action));
3082 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3085 modest_msg_edit_window_offer_attach_file (window);
3089 modest_ui_actions_on_remove_attachments (GtkAction *action,
3090 ModestMsgEditWindow *window)
3092 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3093 g_return_if_fail (GTK_IS_ACTION (action));
3095 modest_msg_edit_window_remove_attachments (window, NULL);
3099 #ifndef MODEST_TOOLKIT_GTK
3104 TnyFolderStore *folder;
3105 } CreateFolderHelper;
3108 show_create_folder_in_timeout (gpointer data)
3110 CreateFolderHelper *helper = (CreateFolderHelper *) data;
3112 /* Remove the timeout ASAP, we can not wait until the dialog
3113 is shown because it could take a lot of time and so the
3114 timeout could be called twice or more times */
3115 g_source_remove (helper->handler);
3117 gdk_threads_enter ();
3118 do_create_folder (helper->win, helper->folder, helper->name);
3119 gdk_threads_leave ();
3121 g_object_unref (helper->win);
3122 g_object_unref (helper->folder);
3123 g_free (helper->name);
3124 g_slice_free (CreateFolderHelper, helper);
3131 do_create_folder_cb (ModestMailOperation *mail_op,
3132 TnyFolderStore *parent_folder,
3133 TnyFolder *new_folder,
3136 gchar *suggested_name = (gchar *) user_data;
3137 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3139 if (modest_mail_operation_get_error (mail_op)) {
3141 /* Show an error. If there was some problem writing to
3142 disk, show it, otherwise show the generic folder
3143 create error. We do it here and not in an error
3144 handler because the call to do_create_folder will
3145 stop the main loop in a gtk_dialog_run and then,
3146 the message won't be shown until that dialog is
3148 modest_ui_actions_disk_operations_error_handler (mail_op,
3149 _("mail_in_ui_folder_create_error"));
3151 /* Try again. Do *NOT* show any error because the mail
3152 operations system will do it for us because we
3153 created the mail_op with new_with_error_handler */
3154 #ifndef MODEST_TOOLKIT_GTK
3155 CreateFolderHelper *helper;
3156 helper = g_slice_new0 (CreateFolderHelper);
3157 helper->name = g_strdup (suggested_name);
3158 helper->folder = g_object_ref (parent_folder);
3159 helper->win = g_object_ref (source_win);
3161 /* Ugly but neccesary stuff. The problem is that the
3162 dialog when is shown calls a function that destroys
3163 all the temporary windows, so the banner is
3165 helper->handler = g_timeout_add (2000, show_create_folder_in_timeout, helper);
3167 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3170 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3171 * FIXME: any other? */
3172 GtkWidget *folder_view;
3174 if (MODEST_IS_MAIN_WINDOW(source_win))
3176 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3177 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3180 get_folder_view_from_move_to_dialog (GTK_WIDGET(source_win));
3182 /* Select the newly created folder. It could happen
3183 that the widget is no longer there (i.e. the window
3184 has been destroyed, so we need to check this */
3186 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3188 g_object_unref (new_folder);
3190 /* Free. Note that the first time it'll be NULL so noop */
3191 g_free (suggested_name);
3192 g_object_unref (source_win);
3196 do_create_folder (GtkWindow *parent_window,
3197 TnyFolderStore *parent_folder,
3198 const gchar *suggested_name)
3201 gchar *folder_name = NULL;
3203 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3205 (gchar *) suggested_name,
3208 if (result == GTK_RESPONSE_ACCEPT) {
3209 ModestMailOperation *mail_op;
3211 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3212 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3214 modest_mail_operation_create_folder (mail_op,
3216 (const gchar *) folder_name,
3217 do_create_folder_cb,
3219 g_object_unref (mail_op);
3224 create_folder_performer (gboolean canceled,
3226 GtkWindow *parent_window,
3227 TnyAccount *account,
3230 TnyFolderStore *parent_folder = TNY_FOLDER_STORE (user_data);
3232 if (canceled || err) {
3233 /* In memory full conditions we could get this error here */
3234 check_memory_full_error ((GtkWidget *) parent_window, err);
3238 /* Run the new folder dialog */
3239 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3242 g_object_unref (parent_folder);
3246 modest_ui_actions_create_folder(GtkWidget *parent_window,
3247 GtkWidget *folder_view)
3249 TnyFolderStore *parent_folder;
3251 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3253 if (parent_folder) {
3254 /* The parent folder will be freed in the callback */
3255 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3258 create_folder_performer,
3264 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
3266 GtkWidget *folder_view;
3268 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3270 folder_view = modest_main_window_get_child_widget (main_window,
3271 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3275 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
3279 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3282 const GError *error = NULL;
3283 const gchar *message = NULL;
3285 /* Get error message */
3286 error = modest_mail_operation_get_error (mail_op);
3288 g_return_if_reached ();
3290 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3291 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3292 message = _CS("ckdg_ib_folder_already_exists");
3293 } else if (error->domain == TNY_ERROR_DOMAIN &&
3294 error->code == TNY_SERVICE_ERROR_STATE) {
3295 /* This means that the folder is already in use (a
3296 message is opened for example */
3297 message = _("emev_ni_internal_error");
3299 message = _("emev_ib_ui_imap_unable_to_rename");
3302 /* We don't set a parent for the dialog because the dialog
3303 will be destroyed so the banner won't appear */
3304 modest_platform_information_banner (NULL, NULL, message);
3308 TnyFolderStore *folder;
3313 on_rename_folder_cb (ModestMailOperation *mail_op,
3314 TnyFolder *new_folder,
3317 ModestFolderView *folder_view;
3319 /* If the window was closed when renaming a folder this could
3321 if (!MODEST_IS_FOLDER_VIEW (user_data))
3324 folder_view = MODEST_FOLDER_VIEW (user_data);
3325 /* Note that if the rename fails new_folder will be NULL */
3327 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3329 modest_folder_view_select_first_inbox_or_local (folder_view);
3331 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3335 on_rename_folder_performer (gboolean canceled,
3337 GtkWindow *parent_window,
3338 TnyAccount *account,
3341 ModestMailOperation *mail_op = NULL;
3342 GtkTreeSelection *sel = NULL;
3343 GtkWidget *folder_view = NULL;
3344 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3346 if (canceled || err) {
3347 /* In memory full conditions we could get this error here */
3348 check_memory_full_error ((GtkWidget *) parent_window, err);
3349 } else if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3351 folder_view = modest_main_window_get_child_widget (
3352 MODEST_MAIN_WINDOW (parent_window),
3353 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3356 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3357 modest_ui_actions_rename_folder_error_handler,
3358 parent_window, NULL);
3360 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3363 /* Clear the headers view */
3364 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3365 gtk_tree_selection_unselect_all (sel);
3367 /* Actually rename the folder */
3368 modest_mail_operation_rename_folder (mail_op,
3369 TNY_FOLDER (data->folder),
3370 (const gchar *) (data->new_name),
3371 on_rename_folder_cb,
3373 g_object_unref (data->folder);
3374 g_object_unref (mail_op);
3377 g_free (data->new_name);
3382 modest_ui_actions_on_rename_folder (GtkAction *action,
3383 ModestMainWindow *main_window)
3385 TnyFolderStore *folder;
3386 GtkWidget *folder_view;
3387 GtkWidget *header_view;
3389 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3391 folder_view = modest_main_window_get_child_widget (main_window,
3392 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3396 header_view = modest_main_window_get_child_widget (main_window,
3397 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3402 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3407 if (TNY_IS_FOLDER (folder)) {
3408 gchar *folder_name = NULL;
3410 const gchar *current_name;
3411 TnyFolderStore *parent;
3412 gboolean do_rename = TRUE;
3414 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3415 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3416 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
3417 parent, current_name,
3419 g_object_unref (parent);
3421 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3424 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3425 rename_folder_data->folder = g_object_ref (folder);
3426 rename_folder_data->new_name = folder_name;
3427 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(main_window), TRUE,
3428 folder, on_rename_folder_performer, rename_folder_data);
3431 g_object_unref (folder);
3435 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3438 GObject *win = modest_mail_operation_get_source (mail_op);
3440 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3441 _("mail_in_ui_folder_delete_error"),
3443 g_object_unref (win);
3447 TnyFolderStore *folder;
3448 gboolean move_to_trash;
3452 on_delete_folder_cb (gboolean canceled,
3454 GtkWindow *parent_window,
3455 TnyAccount *account,
3458 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3459 GtkWidget *folder_view;
3460 ModestMailOperation *mail_op;
3461 GtkTreeSelection *sel;
3463 if (!MODEST_IS_MAIN_WINDOW(parent_window) || canceled || (err!=NULL)) {
3464 g_object_unref (G_OBJECT (info->folder));
3469 folder_view = modest_main_window_get_child_widget (
3470 MODEST_MAIN_WINDOW (parent_window),
3471 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3473 /* Unselect the folder before deleting it to free the headers */
3474 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3475 gtk_tree_selection_unselect_all (sel);
3477 /* Create the mail operation */
3479 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3480 modest_ui_actions_delete_folder_error_handler,
3483 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3485 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3487 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3489 g_object_unref (G_OBJECT (mail_op));
3490 g_object_unref (G_OBJECT (info->folder));
3495 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
3497 TnyFolderStore *folder;
3498 GtkWidget *folder_view;
3502 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3504 folder_view = modest_main_window_get_child_widget (main_window,
3505 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3509 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3511 /* Show an error if it's an account */
3512 if (!TNY_IS_FOLDER (folder)) {
3513 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
3514 _("mail_in_ui_folder_delete_error"),
3516 g_object_unref (G_OBJECT (folder));
3521 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3522 tny_folder_get_name (TNY_FOLDER (folder)));
3523 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
3524 (const gchar *) message);
3527 if (response == GTK_RESPONSE_OK) {
3528 DeleteFolderInfo *info;
3529 info = g_new0(DeleteFolderInfo, 1);
3530 info->folder = folder;
3531 info->move_to_trash = move_to_trash;
3532 g_object_ref (G_OBJECT (info->folder));
3533 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder));
3534 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (main_window),
3536 TNY_FOLDER_STORE (account),
3537 on_delete_folder_cb, info);
3538 g_object_unref (account);
3540 g_object_unref (G_OBJECT (folder));
3544 modest_ui_actions_on_delete_folder (GtkAction *action,
3545 ModestMainWindow *main_window)
3547 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3549 delete_folder (main_window, FALSE);
3553 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3555 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3557 delete_folder (main_window, TRUE);
3561 typedef struct _PasswordDialogFields {
3562 GtkWidget *username;
3563 GtkWidget *password;
3565 } PasswordDialogFields;
3568 password_dialog_check_field (GtkEditable *editable,
3569 PasswordDialogFields *fields)
3572 gboolean any_value_empty = FALSE;
3574 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
3575 if ((value == NULL) || value[0] == '\0') {
3576 any_value_empty = TRUE;
3578 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
3579 if ((value == NULL) || value[0] == '\0') {
3580 any_value_empty = TRUE;
3582 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3586 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3587 const gchar* server_account_name,
3592 ModestMainWindow *main_window)
3594 g_return_if_fail(server_account_name);
3595 gboolean completed = FALSE;
3596 PasswordDialogFields *fields = NULL;
3598 /* Initalize output parameters: */
3605 #ifndef MODEST_TOOLKIT_GTK
3606 /* Maemo uses a different (awkward) button order,
3607 * It should probably just use gtk_alternative_dialog_button_order ().
3609 #ifdef MODEST_TOOLKIT_HILDON2
3611 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3614 _HL("wdgt_bd_done"),
3615 GTK_RESPONSE_ACCEPT,
3619 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3622 _("mcen_bd_dialog_ok"),
3623 GTK_RESPONSE_ACCEPT,
3624 _("mcen_bd_dialog_cancel"),
3625 GTK_RESPONSE_REJECT,
3627 #endif /* MODEST_TOOLKIT_HILDON2 */
3630 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3634 GTK_RESPONSE_REJECT,
3636 GTK_RESPONSE_ACCEPT,
3638 #endif /* MODEST_TOOLKIT_GTK */
3640 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3642 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3643 modest_runtime_get_account_mgr(), server_account_name);
3644 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3645 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3648 gtk_widget_destroy (dialog);
3652 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3653 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
3656 g_free (server_name);
3660 gchar *initial_username = modest_account_mgr_get_server_account_username (
3661 modest_runtime_get_account_mgr(), server_account_name);
3663 GtkWidget *entry_username = gtk_entry_new ();
3664 if (initial_username)
3665 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
3666 /* Dim this if a connection has ever succeeded with this username,
3667 * as per the UI spec: */
3668 /* const gboolean username_known = */
3669 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3670 /* modest_runtime_get_account_mgr(), server_account_name); */
3671 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3673 /* We drop the username sensitive code and disallow changing it here
3674 * as tinymail does not support really changing the username in the callback
3676 gtk_widget_set_sensitive (entry_username, FALSE);
3678 #ifndef MODEST_TOOLKIT_GTK
3679 /* Auto-capitalization is the default, so let's turn it off: */
3680 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3682 /* Create a size group to be used by all captions.
3683 * Note that HildonCaption does not create a default size group if we do not specify one.
3684 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3685 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3687 GtkWidget *caption = hildon_caption_new (sizegroup,
3688 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
3689 gtk_widget_show (entry_username);
3690 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3691 FALSE, FALSE, MODEST_MARGIN_HALF);
3692 gtk_widget_show (caption);
3694 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
3696 #endif /* !MODEST_TOOLKIT_GTK */
3699 GtkWidget *entry_password = gtk_entry_new ();
3700 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3701 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3703 #ifndef MODEST_TOOLKIT_GTK
3704 /* Auto-capitalization is the default, so let's turn it off: */
3705 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3706 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3708 caption = hildon_caption_new (sizegroup,
3709 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
3710 gtk_widget_show (entry_password);
3711 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3712 FALSE, FALSE, MODEST_MARGIN_HALF);
3713 gtk_widget_show (caption);
3714 g_object_unref (sizegroup);
3716 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
3718 #endif /* !MODEST_TOOLKIT_GTK */
3720 if (initial_username != NULL)
3721 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3723 /* This is not in the Maemo UI spec:
3724 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3725 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3729 fields = g_slice_new0 (PasswordDialogFields);
3730 fields->username = entry_username;
3731 fields->password = entry_password;
3732 fields->dialog = dialog;
3734 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3735 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3736 password_dialog_check_field (NULL, fields);
3738 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3740 while (!completed) {
3742 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3744 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
3746 /* Note that an empty field becomes the "" string */
3747 if (*username && strlen (*username) > 0) {
3748 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
3749 server_account_name,
3753 const gboolean username_was_changed =
3754 (strcmp (*username, initial_username) != 0);
3755 if (username_was_changed) {
3756 g_warning ("%s: tinymail does not yet support changing the "
3757 "username in the get_password() callback.\n", __FUNCTION__);
3763 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
3764 _("mcen_ib_username_pw_incorrect"));
3770 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
3772 /* We do not save the password in the configuration,
3773 * because this function is only called for passwords that should
3774 * not be remembered:
3775 modest_server_account_set_password (
3776 modest_runtime_get_account_mgr(), server_account_name,
3783 #ifndef MODEST_TOOLKIT_HILDON2
3784 /* Set parent to NULL or the banner will disappear with its parent dialog */
3785 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
3797 /* This is not in the Maemo UI spec:
3798 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3804 g_free (initial_username);
3805 gtk_widget_destroy (dialog);
3806 g_slice_free (PasswordDialogFields, fields);
3808 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3812 modest_ui_actions_on_cut (GtkAction *action,
3813 ModestWindow *window)
3815 GtkWidget *focused_widget;
3816 GtkClipboard *clipboard;
3818 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3819 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3820 if (GTK_IS_EDITABLE (focused_widget)) {
3821 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3822 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3823 gtk_clipboard_store (clipboard);
3824 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3825 GtkTextBuffer *buffer;
3827 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3828 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3829 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3830 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3831 gtk_clipboard_store (clipboard);
3833 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3834 TnyList *header_list = modest_header_view_get_selected_headers (
3835 MODEST_HEADER_VIEW (focused_widget));
3836 gboolean continue_download = FALSE;
3837 gint num_of_unc_msgs;
3839 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3841 if (num_of_unc_msgs) {
3842 TnyAccount *account = get_account_from_header_list (header_list);
3844 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3845 g_object_unref (account);
3849 if (num_of_unc_msgs == 0 || continue_download) {
3850 /* modest_platform_information_banner (
3851 NULL, NULL, _CS("mcen_ib_getting_items"));*/
3852 modest_header_view_cut_selection (
3853 MODEST_HEADER_VIEW (focused_widget));
3856 g_object_unref (header_list);
3857 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3858 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3863 modest_ui_actions_on_copy (GtkAction *action,
3864 ModestWindow *window)
3866 GtkClipboard *clipboard;
3867 GtkWidget *focused_widget;
3868 gboolean copied = TRUE;
3870 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3871 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3873 if (GTK_IS_LABEL (focused_widget)) {
3875 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
3876 gtk_clipboard_set_text (clipboard, selection, -1);
3878 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3879 gtk_clipboard_store (clipboard);
3880 } else if (GTK_IS_EDITABLE (focused_widget)) {
3881 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3882 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3883 gtk_clipboard_store (clipboard);
3884 } else if (GTK_IS_HTML (focused_widget)) {
3887 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
3888 if ((sel == NULL) || (sel[0] == '\0')) {
3891 gtk_html_copy (GTK_HTML (focused_widget));
3892 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3893 gtk_clipboard_store (clipboard);
3895 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3896 GtkTextBuffer *buffer;
3897 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3898 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3899 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3900 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3901 gtk_clipboard_store (clipboard);
3903 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3904 TnyList *header_list = modest_header_view_get_selected_headers (
3905 MODEST_HEADER_VIEW (focused_widget));
3906 gboolean continue_download = FALSE;
3907 gint num_of_unc_msgs;
3909 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3911 if (num_of_unc_msgs) {
3912 TnyAccount *account = get_account_from_header_list (header_list);
3914 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3915 g_object_unref (account);
3919 if (num_of_unc_msgs == 0 || continue_download) {
3920 modest_platform_information_banner (
3921 NULL, NULL, _CS("mcen_ib_getting_items"));
3922 modest_header_view_copy_selection (
3923 MODEST_HEADER_VIEW (focused_widget));
3927 g_object_unref (header_list);
3929 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3930 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3933 /* Show information banner if there was a copy to clipboard */
3935 modest_platform_information_banner (
3936 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3940 modest_ui_actions_on_undo (GtkAction *action,
3941 ModestWindow *window)
3943 ModestEmailClipboard *clipboard = NULL;
3945 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3946 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3947 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3948 /* Clear clipboard source */
3949 clipboard = modest_runtime_get_email_clipboard ();
3950 modest_email_clipboard_clear (clipboard);
3953 g_return_if_reached ();
3958 modest_ui_actions_on_redo (GtkAction *action,
3959 ModestWindow *window)
3961 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3962 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3965 g_return_if_reached ();
3971 destroy_information_note (ModestMailOperation *mail_op,
3974 /* destroy information note */
3975 gtk_widget_destroy (GTK_WIDGET(user_data));
3979 destroy_folder_information_note (ModestMailOperation *mail_op,
3980 TnyFolder *new_folder,
3983 /* destroy information note */
3984 gtk_widget_destroy (GTK_WIDGET(user_data));
3989 paste_as_attachment_free (gpointer data)
3991 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3993 if (helper->banner) {
3994 gtk_widget_destroy (helper->banner);
3995 g_object_unref (helper->banner);
4001 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4006 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4007 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4012 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4017 modest_ui_actions_on_paste (GtkAction *action,
4018 ModestWindow *window)
4020 GtkWidget *focused_widget = NULL;
4021 GtkWidget *inf_note = NULL;
4022 ModestMailOperation *mail_op = NULL;
4024 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4025 if (GTK_IS_EDITABLE (focused_widget)) {
4026 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4027 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4028 ModestEmailClipboard *e_clipboard = NULL;
4029 e_clipboard = modest_runtime_get_email_clipboard ();
4030 if (modest_email_clipboard_cleared (e_clipboard)) {
4031 GtkTextBuffer *buffer;
4032 GtkClipboard *clipboard;
4034 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4035 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4036 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4037 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4038 ModestMailOperation *mail_op;
4039 TnyFolder *src_folder = NULL;
4040 TnyList *data = NULL;
4042 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4043 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4044 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4045 _CS("ckct_nw_pasting"));
4046 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4047 mail_op = modest_mail_operation_new (G_OBJECT (window));
4048 if (helper->banner != NULL) {
4049 g_object_ref (G_OBJECT (helper->banner));
4050 gtk_widget_show (GTK_WIDGET (helper->banner));
4054 modest_mail_operation_get_msgs_full (mail_op,
4056 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4058 paste_as_attachment_free);
4062 g_object_unref (data);
4064 g_object_unref (src_folder);
4067 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4068 ModestEmailClipboard *clipboard = NULL;
4069 TnyFolder *src_folder = NULL;
4070 TnyFolderStore *folder_store = NULL;
4071 TnyList *data = NULL;
4072 gboolean delete = FALSE;
4074 /* Check clipboard source */
4075 clipboard = modest_runtime_get_email_clipboard ();
4076 if (modest_email_clipboard_cleared (clipboard))
4079 /* Get elements to paste */
4080 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4082 /* Create a new mail operation */
4083 mail_op = modest_mail_operation_new (G_OBJECT(window));
4085 /* Get destination folder */
4086 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4088 /* transfer messages */
4092 /* Ask for user confirmation */
4094 modest_ui_actions_msgs_move_to_confirmation (window,
4095 TNY_FOLDER (folder_store),
4099 if (response == GTK_RESPONSE_OK) {
4100 /* Launch notification */
4101 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4102 _CS("ckct_nw_pasting"));
4103 if (inf_note != NULL) {
4104 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4105 gtk_widget_show (GTK_WIDGET(inf_note));
4108 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4109 modest_mail_operation_xfer_msgs (mail_op,
4111 TNY_FOLDER (folder_store),
4113 destroy_information_note,
4116 g_object_unref (mail_op);
4119 } else if (src_folder != NULL) {
4120 /* Launch notification */
4121 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4122 _CS("ckct_nw_pasting"));
4123 if (inf_note != NULL) {
4124 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4125 gtk_widget_show (GTK_WIDGET(inf_note));
4128 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4129 modest_mail_operation_xfer_folder (mail_op,
4133 destroy_folder_information_note,
4139 g_object_unref (data);
4140 if (src_folder != NULL)
4141 g_object_unref (src_folder);
4142 if (folder_store != NULL)
4143 g_object_unref (folder_store);
4149 modest_ui_actions_on_select_all (GtkAction *action,
4150 ModestWindow *window)
4152 GtkWidget *focused_widget;
4154 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4155 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4156 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4157 } else if (GTK_IS_LABEL (focused_widget)) {
4158 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4159 } else if (GTK_IS_EDITABLE (focused_widget)) {
4160 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4161 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4162 GtkTextBuffer *buffer;
4163 GtkTextIter start, end;
4165 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4166 gtk_text_buffer_get_start_iter (buffer, &start);
4167 gtk_text_buffer_get_end_iter (buffer, &end);
4168 gtk_text_buffer_select_range (buffer, &start, &end);
4169 } else if (GTK_IS_HTML (focused_widget)) {
4170 gtk_html_select_all (GTK_HTML (focused_widget));
4171 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4172 GtkWidget *header_view = focused_widget;
4173 GtkTreeSelection *selection = NULL;
4175 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4176 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4177 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4180 /* Disable window dimming management */
4181 modest_window_disable_dimming (MODEST_WINDOW(window));
4183 /* Select all messages */
4184 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4185 gtk_tree_selection_select_all (selection);
4187 /* Set focuse on header view */
4188 gtk_widget_grab_focus (header_view);
4190 /* Enable window dimming management */
4191 modest_window_enable_dimming (MODEST_WINDOW(window));
4192 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4193 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4199 modest_ui_actions_on_mark_as_read (GtkAction *action,
4200 ModestWindow *window)
4202 g_return_if_fail (MODEST_IS_WINDOW(window));
4204 /* Mark each header as read */
4205 do_headers_action (window, headers_action_mark_as_read, NULL);
4209 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4210 ModestWindow *window)
4212 g_return_if_fail (MODEST_IS_WINDOW(window));
4214 /* Mark each header as read */
4215 do_headers_action (window, headers_action_mark_as_unread, NULL);
4219 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4220 GtkRadioAction *selected,
4221 ModestWindow *window)
4225 value = gtk_radio_action_get_current_value (selected);
4226 if (MODEST_IS_WINDOW (window)) {
4227 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4232 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4233 GtkRadioAction *selected,
4234 ModestWindow *window)
4236 TnyHeaderFlags flags;
4237 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4239 flags = gtk_radio_action_get_current_value (selected);
4240 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4244 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4245 GtkRadioAction *selected,
4246 ModestWindow *window)
4250 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4252 file_format = gtk_radio_action_get_current_value (selected);
4253 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4258 modest_ui_actions_on_zoom_plus (GtkAction *action,
4259 ModestWindow *window)
4261 g_return_if_fail (MODEST_IS_WINDOW (window));
4263 modest_window_zoom_plus (MODEST_WINDOW (window));
4267 modest_ui_actions_on_zoom_minus (GtkAction *action,
4268 ModestWindow *window)
4270 g_return_if_fail (MODEST_IS_WINDOW (window));
4272 modest_window_zoom_minus (MODEST_WINDOW (window));
4276 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4277 ModestWindow *window)
4279 ModestWindowMgr *mgr;
4280 gboolean fullscreen, active;
4281 g_return_if_fail (MODEST_IS_WINDOW (window));
4283 mgr = modest_runtime_get_window_mgr ();
4285 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4286 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4288 if (active != fullscreen) {
4289 modest_window_mgr_set_fullscreen_mode (mgr, active);
4290 #ifndef MODEST_TOOLKIT_HILDON2
4291 gtk_window_present (GTK_WINDOW (window));
4297 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4298 ModestWindow *window)
4300 ModestWindowMgr *mgr;
4301 gboolean fullscreen;
4303 g_return_if_fail (MODEST_IS_WINDOW (window));
4305 mgr = modest_runtime_get_window_mgr ();
4306 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4307 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4309 #ifndef MODEST_TOOLKIT_HILDON2
4310 gtk_window_present (GTK_WINDOW (window));
4315 * Used by modest_ui_actions_on_details to call do_headers_action
4318 headers_action_show_details (TnyHeader *header,
4319 ModestWindow *window,
4323 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header);
4327 * Show the header details in a ModestDetailsDialog widget
4330 modest_ui_actions_on_details (GtkAction *action,
4333 TnyList * headers_list;
4337 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4340 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4343 g_object_unref (msg);
4345 headers_list = get_selected_headers (win);
4349 iter = tny_list_create_iterator (headers_list);
4351 header = TNY_HEADER (tny_iterator_get_current (iter));
4353 headers_action_show_details (header, win, NULL);
4354 g_object_unref (header);
4357 g_object_unref (iter);
4358 g_object_unref (headers_list);
4360 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4361 GtkWidget *folder_view, *header_view;
4363 /* Check which widget has the focus */
4364 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4365 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4366 if (gtk_widget_is_focus (folder_view)) {
4367 TnyFolderStore *folder_store
4368 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4369 if (!folder_store) {
4370 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4373 /* Show only when it's a folder */
4374 /* This function should not be called for account items,
4375 * because we dim the menu item for them. */
4376 if (TNY_IS_FOLDER (folder_store)) {
4377 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4378 TNY_FOLDER (folder_store));
4381 g_object_unref (folder_store);
4384 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4385 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4386 /* Show details of each header */
4387 do_headers_action (win, headers_action_show_details, header_view);
4389 #ifdef MODEST_TOOLKIT_HILDON2
4390 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4392 GtkWidget *header_view;
4394 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4395 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4397 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4399 g_object_unref (folder);
4406 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4407 ModestMsgEditWindow *window)
4409 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4411 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4415 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4416 ModestMsgEditWindow *window)
4418 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4420 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4424 modest_ui_actions_toggle_folders_view (GtkAction *action,
4425 ModestMainWindow *main_window)
4427 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4429 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4430 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4432 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4436 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4437 ModestWindow *window)
4439 gboolean active, fullscreen = FALSE;
4440 ModestWindowMgr *mgr;
4442 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4444 /* Check if we want to toggle the toolbar view in fullscreen
4446 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4447 "ViewShowToolbarFullScreen")) {
4451 /* Toggle toolbar */
4452 mgr = modest_runtime_get_window_mgr ();
4453 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4457 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4458 ModestMsgEditWindow *window)
4460 modest_msg_edit_window_select_font (window);
4465 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4466 const gchar *display_name,
4469 /* don't update the display name if it was already set;
4470 * updating the display name apparently is expensive */
4471 const gchar* old_name = gtk_window_get_title (window);
4473 if (display_name == NULL)
4476 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4477 return; /* don't do anything */
4479 /* This is usually used to change the title of the main window, which
4480 * is the one that holds the folder view. Note that this change can
4481 * happen even when the widget doesn't have the focus. */
4482 gtk_window_set_title (window, display_name);
4487 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4489 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4490 modest_msg_edit_window_select_contacts (window);
4494 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4496 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4497 modest_msg_edit_window_check_names (window, FALSE);
4501 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
4503 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
4504 GTK_WIDGET (user_data));
4508 * This function is used to track changes in the selection of the
4509 * folder view that is inside the "move to" dialog to enable/disable
4510 * the OK button because we do not want the user to select a disallowed
4511 * destination for a folder.
4512 * The user also not desired to be able to use NEW button on items where
4513 * folder creation is not possibel.
4516 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4517 TnyFolderStore *folder_store,
4521 GtkWidget *dialog = NULL;
4522 GtkWidget *ok_button = NULL, *new_button = NULL;
4523 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4524 gboolean moving_folder = FALSE;
4525 gboolean is_local_account = TRUE;
4526 GtkWidget *folder_view = NULL;
4527 ModestTnyFolderRules rules;
4529 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
4534 /* Get the OK button */
4535 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
4539 ok_button = g_object_get_data (G_OBJECT (dialog), MOVE_FOLDER_OK_BUTTON);
4540 new_button = g_object_get_data (G_OBJECT (dialog), MOVE_FOLDER_NEW_BUTTON);
4542 /* check if folder_store is an remote account */
4543 if (TNY_IS_ACCOUNT (folder_store)) {
4544 TnyAccount *local_account = NULL;
4545 TnyAccount *mmc_account = NULL;
4546 ModestTnyAccountStore *account_store = NULL;
4548 account_store = modest_runtime_get_account_store ();
4549 local_account = modest_tny_account_store_get_local_folders_account (account_store);
4550 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
4552 if ((gpointer) local_account != (gpointer) folder_store &&
4553 (gpointer) mmc_account != (gpointer) folder_store) {
4554 ModestProtocolType proto;
4555 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
4556 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
4557 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
4559 is_local_account = FALSE;
4560 /* New button should be dimmed on remote
4562 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4564 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
4566 g_object_unref (local_account);
4568 /* It could not exist */
4570 g_object_unref (mmc_account);
4573 /* Check the target folder rules */
4574 if (TNY_IS_FOLDER (folder_store)) {
4575 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
4576 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
4577 ok_sensitive = FALSE;
4578 new_sensitive = FALSE;
4583 /* Check if we're moving a folder */
4584 if (MODEST_IS_MAIN_WINDOW (user_data)) {
4585 /* Get the widgets */
4586 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
4587 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4588 if (gtk_widget_is_focus (folder_view))
4589 moving_folder = TRUE;
4592 if (moving_folder) {
4593 TnyFolderStore *moved_folder = NULL, *parent = NULL;
4595 /* Get the folder to move */
4596 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4598 /* Check that we're not moving to the same folder */
4599 if (TNY_IS_FOLDER (moved_folder)) {
4600 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
4601 if (parent == folder_store)
4602 ok_sensitive = FALSE;
4603 g_object_unref (parent);
4606 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
4607 /* Do not allow to move to an account unless it's the
4608 local folders account */
4609 if (!is_local_account)
4610 ok_sensitive = FALSE;
4613 if (ok_sensitive && (moved_folder == folder_store)) {
4614 /* Do not allow to move to itself */
4615 ok_sensitive = FALSE;
4617 g_object_unref (moved_folder);
4619 TnyFolder *src_folder = NULL;
4621 /* Moving a message */
4622 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
4624 TnyHeader *header = NULL;
4625 header = modest_msg_view_window_get_header
4626 (MODEST_MSG_VIEW_WINDOW (user_data));
4627 if (!TNY_IS_HEADER(header))
4628 g_warning ("%s: could not get source header", __FUNCTION__);
4630 src_folder = tny_header_get_folder (header);
4633 g_object_unref (header);
4636 TNY_FOLDER (modest_folder_view_get_selected
4637 (MODEST_FOLDER_VIEW (folder_view)));
4640 if (TNY_IS_FOLDER(src_folder)) {
4641 /* Do not allow to move the msg to the same folder */
4642 /* Do not allow to move the msg to an account */
4643 if ((gpointer) src_folder == (gpointer) folder_store ||
4644 TNY_IS_ACCOUNT (folder_store))
4645 ok_sensitive = FALSE;
4646 g_object_unref (src_folder);
4648 g_warning ("%s: could not get source folder", __FUNCTION__);
4652 /* Set sensitivity of the OK button */
4653 gtk_widget_set_sensitive (ok_button, ok_sensitive);
4654 /* Set sensitivity of the NEW button */
4655 gtk_widget_set_sensitive (new_button, new_sensitive);
4659 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
4662 get_folder_view_from_move_to_dialog (GtkWidget *move_to_dialog)
4664 return GTK_WIDGET(g_object_get_data (G_OBJECT(move_to_dialog),
4665 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4669 create_move_to_dialog (GtkWindow *win,
4670 GtkWidget *folder_view,
4671 GtkWidget **tree_view)
4674 #ifdef MODEST_TOOLKIT_HILDON2
4675 GtkWidget *pannable;
4679 GtkWidget *new_button, *ok_button;
4681 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
4683 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
4686 #ifndef MODEST_TOOLKIT_GTK
4687 ok_button = gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
4688 /* We do this manually so GTK+ does not associate a response ID for
4690 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
4691 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
4692 gtk_widget_show (new_button);
4693 #ifndef MODEST_TOOLKIT_HILDON2
4694 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
4697 /* We do this manually so GTK+ does not associate a response ID for
4699 new_button = gtk_button_new_with_label (_("mcen_ti_new_folder"));
4700 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
4701 gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (GTK_DIALOG (dialog)->action_area), new_button, TRUE);
4702 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
4703 ok_button = gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
4704 gtk_container_set_border_width (GTK_CONTAINER (dialog), 12);
4705 gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 24);
4707 g_object_set_data (G_OBJECT (dialog), MOVE_FOLDER_OK_BUTTON, ok_button);
4708 g_object_set_data (G_OBJECT (dialog), MOVE_FOLDER_NEW_BUTTON, new_button);
4710 /* Create scrolled window */
4711 #ifdef MODEST_TOOLKIT_HILDON2
4712 pannable = hildon_pannable_area_new ();
4714 scroll = gtk_scrolled_window_new (NULL, NULL);
4715 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
4716 GTK_POLICY_AUTOMATIC,
4717 GTK_POLICY_AUTOMATIC);
4720 #ifdef MODEST_TOOLKIT_GTK
4721 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN);
4724 /* Create folder view */
4725 *tree_view = modest_platform_create_folder_view (NULL);
4727 /* Track changes in the selection to
4728 * disable the OK button whenever "Move to" is not possible
4729 * disbale NEW button whenever New is not possible */
4730 g_signal_connect (*tree_view,
4731 "folder_selection_changed",
4732 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
4735 /* Listen to clicks on New button */
4736 g_signal_connect (G_OBJECT (new_button),
4738 G_CALLBACK(create_move_to_dialog_on_new_folder),
4741 /* It could happen that we're trying to move a message from a
4742 window (msg window for example) after the main window was
4743 closed, so we can not just get the model of the folder
4745 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4746 const gchar *visible_id = NULL;
4748 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4749 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4750 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4751 MODEST_FOLDER_VIEW(*tree_view));
4754 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4756 /* Show the same account than the one that is shown in the main window */
4757 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
4760 const gchar *active_account_name = NULL;
4761 ModestAccountMgr *mgr = NULL;
4762 ModestAccountSettings *settings = NULL;
4763 ModestServerAccountSettings *store_settings = NULL;
4765 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4766 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4767 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
4768 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
4770 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4771 mgr = modest_runtime_get_account_mgr ();
4772 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4775 const gchar *store_account_name;
4776 store_settings = modest_account_settings_get_store_settings (settings);
4777 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4779 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
4780 store_account_name);
4781 g_object_unref (store_settings);
4782 g_object_unref (settings);
4786 /* we keep a pointer to the embedded folder view, so we can retrieve it with
4787 * get_folder_view_from_move_to_dialog
4788 * (see above) later (needed for focus handling)
4790 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, *tree_view);
4793 /* Hide special folders */
4794 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
4796 #ifdef MODEST_TOOLKIT_HILDON2
4797 gtk_container_add (GTK_CONTAINER (pannable), *tree_view);
4798 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
4799 pannable, TRUE, TRUE, 0);
4801 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
4802 /* Add scroll to dialog */
4803 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
4804 scroll, TRUE, TRUE, 0);
4808 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4809 #ifndef MODEST_TOOLKIT_GTK
4810 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
4812 gtk_window_set_default_size (GTK_WINDOW (dialog), 600, 400);
4821 * Shows a confirmation dialog to the user when we're moving messages
4822 * from a remote server to the local storage. Returns the dialog
4823 * response. If it's other kind of movement then it always returns
4826 * This one is used by the next functions:
4827 * modest_ui_actions_on_paste - commented out
4828 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4831 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4832 TnyFolder *dest_folder,
4836 gint response = GTK_RESPONSE_OK;
4837 TnyAccount *account = NULL;
4838 TnyFolder *src_folder = NULL;
4839 TnyIterator *iter = NULL;
4840 TnyHeader *header = NULL;
4842 /* return with OK if the destination is a remote folder */
4843 if (modest_tny_folder_is_remote_folder (dest_folder))
4844 return GTK_RESPONSE_OK;
4846 /* Get source folder */
4847 iter = tny_list_create_iterator (headers);
4848 header = TNY_HEADER (tny_iterator_get_current (iter));
4850 src_folder = tny_header_get_folder (header);
4851 g_object_unref (header);
4853 g_object_unref (iter);
4855 /* if no src_folder, message may be an attahcment */
4856 if (src_folder == NULL)
4857 return GTK_RESPONSE_CANCEL;
4859 /* If the source is a local or MMC folder */
4860 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4861 g_object_unref (src_folder);
4862 return GTK_RESPONSE_OK;
4865 /* Get the account */
4866 account = tny_folder_get_account (src_folder);
4868 /* now if offline we ask the user */
4869 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4870 response = GTK_RESPONSE_OK;
4872 response = GTK_RESPONSE_CANCEL;
4875 g_object_unref (src_folder);
4876 g_object_unref (account);
4882 move_to_helper_destroyer (gpointer user_data)
4884 MoveToHelper *helper = (MoveToHelper *) user_data;
4886 /* Close the "Pasting" information banner */
4887 if (helper->banner) {
4888 gtk_widget_destroy (GTK_WIDGET (helper->banner));
4889 g_object_unref (helper->banner);
4891 if (gtk_tree_row_reference_valid (helper->reference)) {
4892 gtk_tree_row_reference_free (helper->reference);
4893 helper->reference = NULL;
4899 move_to_cb (ModestMailOperation *mail_op,
4902 MoveToHelper *helper = (MoveToHelper *) user_data;
4904 /* Note that the operation could have failed, in that case do
4906 if (modest_mail_operation_get_status (mail_op) ==
4907 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
4909 GObject *object = modest_mail_operation_get_source (mail_op);
4910 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4911 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4913 if (!modest_msg_view_window_select_next_message (self) &&
4914 !modest_msg_view_window_select_previous_message (self)) {
4915 /* No more messages to view, so close this window */
4916 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4918 } else if (MODEST_IS_MAIN_WINDOW (object) &&
4919 gtk_tree_row_reference_valid (helper->reference)) {
4920 GtkWidget *header_view;
4922 GtkTreeSelection *sel;
4924 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4925 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4926 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
4927 path = gtk_tree_row_reference_get_path (helper->reference);
4928 /* We need to unselect the previous one
4929 because we could be copying instead of
4931 gtk_tree_selection_unselect_all (sel);
4932 gtk_tree_selection_select_path (sel, path);
4933 gtk_tree_path_free (path);
4935 g_object_unref (object);
4937 /* Destroy the helper */
4938 move_to_helper_destroyer (helper);
4942 folder_move_to_cb (ModestMailOperation *mail_op,
4943 TnyFolder *new_folder,
4946 GtkWidget *folder_view;
4949 object = modest_mail_operation_get_source (mail_op);
4950 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4951 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4952 g_object_ref (folder_view);
4953 g_object_unref (object);
4954 move_to_cb (mail_op, user_data);
4955 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
4956 g_object_unref (folder_view);
4960 msgs_move_to_cb (ModestMailOperation *mail_op,
4963 move_to_cb (mail_op, user_data);
4967 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
4970 ModestWindow *main_window = NULL;
4972 /* Disable next automatic folder selection */
4973 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
4974 FALSE); /* don't create */
4976 GObject *win = NULL;
4977 GtkWidget *folder_view = NULL;
4979 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
4980 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4981 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
4983 if (user_data && TNY_IS_FOLDER (user_data)) {
4984 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
4985 TNY_FOLDER (user_data), FALSE);
4988 /* Show notification dialog only if the main window exists */
4989 win = modest_mail_operation_get_source (mail_op);
4990 modest_platform_run_information_dialog ((GtkWindow *) win,
4991 _("mail_in_ui_folder_move_target_error"),
4994 g_object_unref (win);
4999 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5008 gint pending_purges = 0;
5009 gboolean some_purged = FALSE;
5010 ModestWindow *win = MODEST_WINDOW (user_data);
5011 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5013 /* If there was any error */
5014 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5015 modest_window_mgr_unregister_header (mgr, header);
5019 /* Once the message has been retrieved for purging, we check if
5020 * it's all ok for purging */
5022 parts = tny_simple_list_new ();
5023 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5024 iter = tny_list_create_iterator (parts);
5026 while (!tny_iterator_is_done (iter)) {
5028 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5029 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5030 if (tny_mime_part_is_purged (part))
5037 g_object_unref (part);
5039 tny_iterator_next (iter);
5041 g_object_unref (iter);
5044 if (pending_purges>0) {
5046 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5048 if (response == GTK_RESPONSE_OK) {
5051 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5052 iter = tny_list_create_iterator (parts);
5053 while (!tny_iterator_is_done (iter)) {
5056 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5057 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5058 tny_mime_part_set_purged (part);
5061 g_object_unref (part);
5063 tny_iterator_next (iter);
5065 g_object_unref (iter);
5067 tny_msg_rewrite_cache (msg);
5069 gtk_widget_destroy (info);
5073 modest_window_mgr_unregister_header (mgr, header);
5075 g_object_unref (parts);
5079 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5080 ModestMainWindow *win)
5082 GtkWidget *header_view;
5083 TnyList *header_list;
5085 TnyHeaderFlags flags;
5086 ModestWindow *msg_view_window = NULL;
5089 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5091 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5092 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5094 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5096 g_warning ("%s: no header selected", __FUNCTION__);
5100 if (tny_list_get_length (header_list) == 1) {
5101 TnyIterator *iter = tny_list_create_iterator (header_list);
5102 header = TNY_HEADER (tny_iterator_get_current (iter));
5103 g_object_unref (iter);
5107 if (!header || !TNY_IS_HEADER(header)) {
5108 g_warning ("%s: header is not valid", __FUNCTION__);
5112 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5113 header, &msg_view_window);
5114 flags = tny_header_get_flags (header);
5115 if (!(flags & TNY_HEADER_FLAG_CACHED))
5118 if (msg_view_window != NULL)
5119 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5121 /* do nothing; uid was registered before, so window is probably on it's way */
5122 g_warning ("debug: header %p has already been registered", header);
5125 ModestMailOperation *mail_op = NULL;
5126 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5127 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5128 modest_ui_actions_disk_operations_error_handler,
5130 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5131 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5133 g_object_unref (mail_op);
5136 g_object_unref (header);
5138 g_object_unref (header_list);
5142 * Checks if we need a connection to do the transfer and if the user
5143 * wants to connect to complete it
5146 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5147 TnyFolderStore *src_folder,
5149 TnyFolder *dst_folder,
5150 gboolean delete_originals,
5151 gboolean *need_connection,
5154 TnyAccount *src_account;
5155 gint uncached_msgs = 0;
5157 uncached_msgs = header_list_count_uncached_msgs (headers);
5159 /* We don't need any further check if
5161 * 1- the source folder is local OR
5162 * 2- the device is already online
5164 if (!modest_tny_folder_store_is_remote (src_folder) ||
5165 tny_device_is_online (modest_runtime_get_device())) {
5166 *need_connection = FALSE;
5171 /* We must ask for a connection when
5173 * - the message(s) is not already cached OR
5174 * - the message(s) is cached but the leave_on_server setting
5175 * is FALSE (because we need to sync the source folder to
5176 * delete the message from the server (for IMAP we could do it
5177 * offline, it'll take place the next time we get a
5180 src_account = get_account_from_folder_store (src_folder);
5181 if (uncached_msgs > 0) {
5185 *need_connection = TRUE;
5186 num_headers = tny_list_get_length (headers);
5187 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5189 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5190 GTK_RESPONSE_CANCEL) {
5196 /* The transfer is possible and the user wants to */
5199 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5200 const gchar *account_name;
5201 gboolean leave_on_server;
5203 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5204 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5207 if (leave_on_server == TRUE) {
5208 *need_connection = FALSE;
5210 *need_connection = TRUE;
5213 *need_connection = FALSE;
5218 g_object_unref (src_account);
5222 xfer_messages_error_handler (ModestMailOperation *mail_op,
5225 ModestWindow *main_window = NULL;
5227 /* Disable next automatic folder selection */
5228 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5229 FALSE); /* don't create */
5231 GObject *win = modest_mail_operation_get_source (mail_op);
5232 modest_platform_run_information_dialog ((GtkWindow *) win,
5233 _("mail_in_ui_folder_move_target_error"),
5236 g_object_unref (win);
5238 move_to_helper_destroyer (user_data);
5242 TnyFolderStore *dst_folder;
5247 * Utility function that transfer messages from both the main window
5248 * and the msg view window when using the "Move to" dialog
5251 xfer_messages_performer (gboolean canceled,
5253 GtkWindow *parent_window,
5254 TnyAccount *account,
5257 ModestWindow *win = MODEST_WINDOW (parent_window);
5258 TnyAccount *dst_account = NULL;
5259 gboolean dst_forbids_message_add = FALSE;
5260 XferMsgsHelper *helper;
5261 MoveToHelper *movehelper;
5262 ModestMailOperation *mail_op;
5264 helper = (XferMsgsHelper *) user_data;
5266 if (canceled || err) {
5267 if (!check_memory_full_error ((GtkWidget *) parent_window, err)) {
5268 /* Show the proper error message */
5269 modest_ui_actions_on_account_connection_error (parent_window, account);
5274 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5276 /* tinymail will return NULL for local folders it seems */
5277 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5278 modest_tny_account_get_protocol_type (dst_account),
5279 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_MESSAGE_ADD);
5280 g_object_unref (dst_account);
5282 if (dst_forbids_message_add) {
5283 modest_platform_information_banner (GTK_WIDGET (win),
5285 ngettext("mail_in_ui_folder_move_target_error",
5286 "mail_in_ui_folder_move_targets_error",
5287 tny_list_get_length (helper->headers)));
5291 movehelper = g_new0 (MoveToHelper, 1);
5292 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5293 _CS("ckct_nw_pasting"));
5294 if (movehelper->banner != NULL) {
5295 g_object_ref (movehelper->banner);
5296 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5299 if (MODEST_IS_MAIN_WINDOW (win)) {
5300 GtkWidget *header_view =
5301 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5302 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5303 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5306 /* Perform the mail operation */
5307 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5308 xfer_messages_error_handler,
5310 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5313 modest_mail_operation_xfer_msgs (mail_op,
5315 TNY_FOLDER (helper->dst_folder),
5320 g_object_unref (G_OBJECT (mail_op));
5322 g_object_unref (helper->dst_folder);
5323 g_object_unref (helper->headers);
5324 g_slice_free (XferMsgsHelper, helper);
5328 TnyFolder *src_folder;
5329 TnyFolderStore *dst_folder;
5330 gboolean delete_original;
5331 GtkWidget *folder_view;
5335 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
5336 TnyAccount *account, gpointer user_data)
5338 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5339 GtkTreeSelection *sel;
5340 ModestMailOperation *mail_op = NULL;
5342 if (canceled || err || !MODEST_IS_MAIN_WINDOW (parent_window)) {
5343 g_object_unref (G_OBJECT (info->src_folder));
5344 g_object_unref (G_OBJECT (info->dst_folder));
5349 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5350 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5351 _CS("ckct_nw_pasting"));
5352 if (helper->banner != NULL) {
5353 g_object_ref (helper->banner);
5354 gtk_widget_show (GTK_WIDGET(helper->banner));
5356 /* Clean folder on header view before moving it */
5357 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5358 gtk_tree_selection_unselect_all (sel);
5360 /* Let gtk events run. We need that the folder
5361 view frees its reference to the source
5362 folder *before* issuing the mail operation
5363 so we need the signal handler of selection
5364 changed to happen before the mail
5366 while (gtk_events_pending ())
5367 gtk_main_iteration (); */
5370 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5371 modest_ui_actions_move_folder_error_handler,
5372 info->src_folder, NULL);
5373 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5376 /* Select *after* the changes */
5377 /* TODO: this function hangs UI after transfer */
5378 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
5379 /* TNY_FOLDER (src_folder), TRUE); */
5381 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5382 TNY_FOLDER (info->dst_folder), TRUE);
5383 modest_mail_operation_xfer_folder (mail_op,
5384 TNY_FOLDER (info->src_folder),
5386 info->delete_original,
5389 g_object_unref (G_OBJECT (info->src_folder));
5391 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5394 /* Unref mail operation */
5395 g_object_unref (G_OBJECT (mail_op));
5396 g_object_unref (G_OBJECT (info->dst_folder));
5401 get_account_from_folder_store (TnyFolderStore *folder_store)
5403 if (TNY_IS_ACCOUNT (folder_store))
5404 return g_object_ref (folder_store);
5406 return tny_folder_get_account (TNY_FOLDER (folder_store));
5410 * UI handler for the "Move to" action when invoked from the
5414 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5415 GtkWidget *folder_view,
5416 TnyFolderStore *dst_folder,
5417 ModestMainWindow *win)
5419 ModestHeaderView *header_view = NULL;
5420 TnyFolderStore *src_folder = NULL;
5422 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5424 /* Get the source folder */
5425 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5427 /* Get header view */
5428 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
5430 /* Get folder or messages to transfer */
5431 if (gtk_widget_is_focus (folder_view)) {
5432 gboolean do_xfer = TRUE;
5434 /* Allow only to transfer folders to the local root folder */
5435 if (TNY_IS_ACCOUNT (dst_folder) &&
5436 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5437 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5439 } else if (!TNY_IS_FOLDER (src_folder)) {
5440 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5445 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5446 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5448 info->src_folder = g_object_ref (src_folder);
5449 info->dst_folder = g_object_ref (dst_folder);
5450 info->delete_original = TRUE;
5451 info->folder_view = folder_view;
5453 connect_info->callback = on_move_folder_cb;
5454 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5455 connect_info->data = info;
5457 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5458 TNY_FOLDER_STORE (src_folder),
5461 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5464 headers = modest_header_view_get_selected_headers(header_view);
5466 /* Transfer the messages */
5467 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
5468 headers, TNY_FOLDER (dst_folder));
5470 g_object_unref (headers);
5474 g_object_unref (src_folder);
5479 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
5480 TnyFolder *src_folder,
5482 TnyFolder *dst_folder)
5484 gboolean need_connection = TRUE;
5485 gboolean do_xfer = TRUE;
5486 XferMsgsHelper *helper;
5488 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5489 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5490 g_return_if_fail (TNY_IS_LIST (headers));
5492 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5493 headers, TNY_FOLDER (dst_folder),
5494 TRUE, &need_connection,
5497 /* If we don't want to transfer just return */
5501 /* Create the helper */
5502 helper = g_slice_new (XferMsgsHelper);
5503 helper->dst_folder = g_object_ref (dst_folder);
5504 helper->headers = g_object_ref (headers);
5506 if (need_connection) {
5507 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5508 connect_info->callback = xfer_messages_performer;
5509 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5510 connect_info->data = helper;
5512 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5513 TNY_FOLDER_STORE (src_folder),
5516 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5517 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
5518 src_account, helper);
5519 g_object_unref (src_account);
5524 * UI handler for the "Move to" action when invoked from the
5525 * ModestMsgViewWindow
5528 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
5529 TnyFolderStore *dst_folder,
5530 ModestMsgViewWindow *win)
5532 TnyList *headers = NULL;
5533 TnyHeader *header = NULL;
5534 TnyFolder *src_folder = NULL;
5536 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5538 /* Create header list */
5539 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
5540 src_folder = TNY_FOLDER (tny_header_get_folder(header));
5541 headers = tny_simple_list_new ();
5542 tny_list_append (headers, G_OBJECT (header));
5544 /* Transfer the messages */
5545 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder, headers,
5546 TNY_FOLDER (dst_folder));
5549 g_object_unref (src_folder);
5550 g_object_unref (header);
5551 g_object_unref (headers);
5555 modest_ui_actions_on_move_to (GtkAction *action,
5558 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
5560 TnyFolderStore *dst_folder = NULL;
5561 ModestMainWindow *main_window;
5563 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
5564 MODEST_IS_MSG_VIEW_WINDOW (win));
5566 /* Get the main window if exists */
5567 if (MODEST_IS_MAIN_WINDOW (win))
5568 main_window = MODEST_MAIN_WINDOW (win);
5571 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5572 FALSE)); /* don't create */
5574 /* Get the folder view widget if exists */
5576 folder_view = modest_main_window_get_child_widget (main_window,
5577 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5581 /* Create and run the dialog */
5582 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
5583 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5584 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog), (GtkWindow *) win);
5585 result = gtk_dialog_run (GTK_DIALOG(dialog));
5586 g_object_ref (tree_view);
5587 gtk_widget_destroy (dialog);
5589 if (result != GTK_RESPONSE_ACCEPT)
5592 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
5593 /* Do window specific stuff */
5594 if (MODEST_IS_MAIN_WINDOW (win)) {
5595 modest_ui_actions_on_main_window_move_to (action,
5598 MODEST_MAIN_WINDOW (win));
5600 modest_ui_actions_on_msg_view_window_move_to (action,
5602 MODEST_MSG_VIEW_WINDOW (win));
5606 g_object_unref (dst_folder);
5610 * Calls #HeadersFunc for each header already selected in the main
5611 * window or the message currently being shown in the msg view window
5614 do_headers_action (ModestWindow *win,
5618 TnyList *headers_list = NULL;
5619 TnyIterator *iter = NULL;
5620 TnyHeader *header = NULL;
5621 TnyFolder *folder = NULL;
5624 headers_list = get_selected_headers (win);
5628 /* Get the folder */
5629 iter = tny_list_create_iterator (headers_list);
5630 header = TNY_HEADER (tny_iterator_get_current (iter));
5632 folder = tny_header_get_folder (header);
5633 g_object_unref (header);
5636 /* Call the function for each header */
5637 while (!tny_iterator_is_done (iter)) {
5638 header = TNY_HEADER (tny_iterator_get_current (iter));
5639 func (header, win, user_data);
5640 g_object_unref (header);
5641 tny_iterator_next (iter);
5644 /* Trick: do a poke status in order to speed up the signaling
5646 tny_folder_poke_status (folder);
5649 g_object_unref (folder);
5650 g_object_unref (iter);
5651 g_object_unref (headers_list);
5655 modest_ui_actions_view_attachment (GtkAction *action,
5656 ModestWindow *window)
5658 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5659 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5661 /* not supported window for this action */
5662 g_return_if_reached ();
5667 modest_ui_actions_save_attachments (GtkAction *action,
5668 ModestWindow *window)
5670 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5672 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5675 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5677 /* not supported window for this action */
5678 g_return_if_reached ();
5683 modest_ui_actions_remove_attachments (GtkAction *action,
5684 ModestWindow *window)
5686 if (MODEST_IS_MAIN_WINDOW (window)) {
5687 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
5688 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5689 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5691 /* not supported window for this action */
5692 g_return_if_reached ();
5697 modest_ui_actions_on_settings (GtkAction *action,
5702 dialog = modest_platform_get_global_settings_dialog ();
5703 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
5704 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5705 gtk_widget_show_all (dialog);
5707 gtk_dialog_run (GTK_DIALOG (dialog));
5709 gtk_widget_destroy (dialog);
5713 modest_ui_actions_on_help (GtkAction *action,
5716 /* Help app is not available at all in fremantle */
5717 #ifndef MODEST_TOOLKIT_HILDON2
5718 const gchar *help_id;
5720 g_return_if_fail (win && GTK_IS_WINDOW(win));
5722 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5725 modest_platform_show_help (GTK_WINDOW (win), help_id);
5730 modest_ui_actions_on_csm_help (GtkAction *action,
5733 /* Help app is not available at all in fremantle */
5734 #ifndef MODEST_TOOLKIT_HILDON2
5736 const gchar* help_id = NULL;
5737 GtkWidget *folder_view;
5738 TnyFolderStore *folder_store;
5740 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
5742 /* Get selected folder */
5743 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5744 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5745 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5747 /* Switch help_id */
5748 if (folder_store && TNY_IS_FOLDER (folder_store))
5749 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
5752 g_object_unref (folder_store);
5755 modest_platform_show_help (GTK_WINDOW (win), help_id);
5757 modest_ui_actions_on_help (action, win);
5762 retrieve_contents_cb (ModestMailOperation *mail_op,
5769 /* We only need this callback to show an error in case of
5770 memory low condition */
5771 modest_ui_actions_msg_retrieval_check (mail_op, header, msg);
5775 retrieve_msg_contents_performer (gboolean canceled,
5777 GtkWindow *parent_window,
5778 TnyAccount *account,
5781 ModestMailOperation *mail_op;
5782 TnyList *headers = TNY_LIST (user_data);
5784 if (err || canceled) {
5785 check_memory_full_error ((GtkWidget *) parent_window, err);
5789 /* Create mail operation */
5790 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5791 modest_ui_actions_disk_operations_error_handler,
5793 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5794 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
5797 g_object_unref (mail_op);
5799 g_object_unref (headers);
5800 g_object_unref (account);
5804 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5805 ModestWindow *window)
5807 TnyList *headers = NULL;
5808 TnyAccount *account = NULL;
5809 TnyIterator *iter = NULL;
5810 TnyHeader *header = NULL;
5811 TnyFolder *folder = NULL;
5814 headers = get_selected_headers (window);
5818 /* Pick the account */
5819 iter = tny_list_create_iterator (headers);
5820 header = TNY_HEADER (tny_iterator_get_current (iter));
5821 folder = tny_header_get_folder (header);
5822 account = tny_folder_get_account (folder);
5823 g_object_unref (folder);
5824 g_object_unref (header);
5825 g_object_unref (iter);
5827 /* Connect and perform the message retrieval */
5828 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
5829 g_object_ref (account),
5830 retrieve_msg_contents_performer,
5831 g_object_ref (headers));
5834 g_object_unref (account);
5835 g_object_unref (headers);
5839 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
5841 g_return_if_fail (MODEST_IS_WINDOW (window));
5844 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
5848 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
5850 g_return_if_fail (MODEST_IS_WINDOW (window));
5853 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
5857 modest_ui_actions_on_email_menu_activated (GtkAction *action,
5858 ModestWindow *window)
5860 g_return_if_fail (MODEST_IS_WINDOW (window));
5863 modest_ui_actions_check_menu_dimming_rules (window);
5867 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
5868 ModestWindow *window)
5870 g_return_if_fail (MODEST_IS_WINDOW (window));
5873 modest_ui_actions_check_menu_dimming_rules (window);
5877 modest_ui_actions_on_view_menu_activated (GtkAction *action,
5878 ModestWindow *window)
5880 g_return_if_fail (MODEST_IS_WINDOW (window));
5883 modest_ui_actions_check_menu_dimming_rules (window);
5887 modest_ui_actions_on_format_menu_activated (GtkAction *action,
5888 ModestWindow *window)
5890 g_return_if_fail (MODEST_IS_WINDOW (window));
5893 modest_ui_actions_check_menu_dimming_rules (window);
5897 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
5898 ModestWindow *window)
5900 g_return_if_fail (MODEST_IS_WINDOW (window));
5903 modest_ui_actions_check_menu_dimming_rules (window);
5907 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
5908 ModestWindow *window)
5910 g_return_if_fail (MODEST_IS_WINDOW (window));
5913 modest_ui_actions_check_menu_dimming_rules (window);
5917 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
5918 ModestWindow *window)
5920 g_return_if_fail (MODEST_IS_WINDOW (window));
5923 modest_ui_actions_check_menu_dimming_rules (window);
5927 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
5928 ModestWindow *window)
5930 g_return_if_fail (MODEST_IS_WINDOW (window));
5933 modest_ui_actions_check_menu_dimming_rules (window);
5937 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
5938 ModestWindow *window)
5940 g_return_if_fail (MODEST_IS_WINDOW (window));
5943 modest_ui_actions_check_menu_dimming_rules (window);
5947 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
5949 g_return_if_fail (MODEST_IS_WINDOW (window));
5951 /* we check for low-mem; in that case, show a warning, and don't allow
5954 if (modest_platform_check_memory_low (window, TRUE))
5957 modest_platform_show_search_messages (GTK_WINDOW (window));
5961 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
5963 g_return_if_fail (MODEST_IS_WINDOW (win));
5966 /* we check for low-mem; in that case, show a warning, and don't allow
5967 * for the addressbook
5969 if (modest_platform_check_memory_low (win, TRUE))
5973 modest_platform_show_addressbook (GTK_WINDOW (win));
5978 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
5979 ModestWindow *window)
5981 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5983 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
5987 on_send_receive_finished (ModestMailOperation *mail_op,
5990 GtkWidget *header_view, *folder_view;
5991 TnyFolderStore *folder_store;
5992 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
5994 /* Set send/receive operation finished */
5995 modest_main_window_notify_send_receive_completed (main_win);
5997 /* Don't refresh the current folder if there were any errors */
5998 if (modest_mail_operation_get_status (mail_op) !=
5999 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6002 /* Refresh the current folder if we're viewing a window. We do
6003 this because the user won't be able to see the new mails in
6004 the selected folder after a Send&Receive because it only
6005 performs a poke_status, i.e, only the number of read/unread
6006 messages is updated, but the new headers are not
6008 folder_view = modest_main_window_get_child_widget (main_win,
6009 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6013 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6015 /* Do not need to refresh INBOX again because the
6016 update_account does it always automatically */
6017 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6018 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6019 ModestMailOperation *refresh_op;
6021 header_view = modest_main_window_get_child_widget (main_win,
6022 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6024 /* We do not need to set the contents style
6025 because it hasn't changed. We also do not
6026 need to save the widget status. Just force
6028 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6029 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6030 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6031 folder_refreshed_cb, main_win);
6032 g_object_unref (refresh_op);
6036 g_object_unref (folder_store);
6041 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6047 const gchar* server_name = NULL;
6048 TnyTransportAccount *server_account;
6049 gchar *message = NULL;
6051 /* Don't show anything if the user cancelled something or the
6052 * send receive request is not interactive. Authentication
6053 * errors are managed by the account store so no need to show
6054 * a dialog here again */
6055 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6056 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6057 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6061 /* Get the server name: */
6063 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
6065 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
6067 g_return_if_reached ();
6069 /* Show the appropriate message text for the GError: */
6070 switch (err->code) {
6071 case TNY_SERVICE_ERROR_CONNECT:
6072 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6074 case TNY_SERVICE_ERROR_SEND:
6075 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
6077 case TNY_SERVICE_ERROR_UNAVAILABLE:
6078 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6081 g_warning ("%s: unexpected ERROR %d",
6082 __FUNCTION__, err->code);
6083 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
6087 modest_platform_run_information_dialog (NULL, message, FALSE);
6089 g_object_unref (server_account);
6093 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6098 ModestMainWindow *main_window = NULL;
6099 ModestWindowMgr *mgr = NULL;
6100 GtkWidget *folder_view = NULL, *header_view = NULL;
6101 TnyFolderStore *selected_folder = NULL;
6102 TnyFolderType folder_type;
6104 mgr = modest_runtime_get_window_mgr ();
6105 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr,
6106 FALSE));/* don't create */
6110 /* Check if selected folder is OUTBOX */
6111 folder_view = modest_main_window_get_child_widget (main_window,
6112 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6113 header_view = modest_main_window_get_child_widget (main_window,
6114 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6116 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6117 if (!TNY_IS_FOLDER (selected_folder))
6120 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6121 #if GTK_CHECK_VERSION(2, 8, 0)
6122 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
6123 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6124 GtkTreeViewColumn *tree_column;
6126 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6127 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6129 gtk_tree_view_column_queue_resize (tree_column);
6132 gtk_widget_queue_draw (header_view);
6135 /* Rerun dimming rules, because the message could become deletable for example */
6136 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6137 MODEST_DIMMING_RULES_TOOLBAR);
6138 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6139 MODEST_DIMMING_RULES_MENU);
6143 if (selected_folder != NULL)
6144 g_object_unref (selected_folder);
6148 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6149 TnyAccount *account)
6151 ModestProtocolType protocol_type;
6152 ModestProtocol *protocol;
6153 gchar *error_note = NULL;
6155 protocol_type = modest_tny_account_get_protocol_type (account);
6156 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6159 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6160 if (error_note == NULL) {
6161 g_warning ("%s: This should not be reached", __FUNCTION__);
6163 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6164 g_free (error_note);
6169 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6173 TnyFolderStore *folder = NULL;
6174 TnyAccount *account = NULL;
6175 ModestProtocolType proto;
6176 ModestProtocol *protocol;
6177 TnyHeader *header = NULL;
6179 if (MODEST_IS_MAIN_WINDOW (win)) {
6180 GtkWidget *header_view;
6181 TnyList* headers = NULL;
6183 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6184 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6185 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6186 if (!headers || tny_list_get_length (headers) == 0) {
6188 g_object_unref (headers);
6191 iter = tny_list_create_iterator (headers);
6192 header = TNY_HEADER (tny_iterator_get_current (iter));
6193 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6194 g_object_unref (iter);
6195 g_object_unref (headers);
6196 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6197 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6198 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6201 /* Get the account type */
6202 account = tny_folder_get_account (TNY_FOLDER (folder));
6203 proto = modest_tny_account_get_protocol_type (account);
6204 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6207 subject = tny_header_dup_subject (header);
6208 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6212 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6216 g_object_unref (account);
6217 g_object_unref (folder);
6218 g_object_unref (header);
6224 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6225 const gchar *account_name,
6226 const gchar *account_title)
6228 ModestAccountMgr *account_mgr;
6231 ModestProtocol *protocol;
6232 gboolean removed = FALSE;
6234 g_return_val_if_fail (account_name, FALSE);
6235 g_return_val_if_fail (account_title, FALSE);
6237 account_mgr = modest_runtime_get_account_mgr();
6239 /* The warning text depends on the account type: */
6240 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6241 modest_account_mgr_get_store_protocol (account_mgr,
6243 txt = modest_protocol_get_translation (protocol,
6244 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6247 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6249 response = modest_platform_run_confirmation_dialog (parent_window, txt);
6253 if (response == GTK_RESPONSE_OK) {
6254 /* Remove account. If it succeeds then it also removes
6255 the account from the ModestAccountView: */
6256 gboolean is_default = FALSE;
6257 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6258 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6260 g_free (default_account_name);
6262 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6264 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);