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 <modest-accounts-window.h>
53 #include <hildon/hildon-pannable-area.h>
54 #include <hildon/hildon-gtk.h>
55 #include <modest-header-window.h>
56 #include <modest-folder-window.h>
59 #ifdef MODEST_PLATFORM_MAEMO
60 #include "maemo/modest-osso-state-saving.h"
61 #endif /* MODEST_PLATFORM_MAEMO */
62 #ifndef MODEST_TOOLKIT_GTK
63 #include "maemo/modest-hildon-includes.h"
64 #include "maemo/modest-connection-specific-smtp-window.h"
65 #endif /* !MODEST_TOOLKIT_GTK */
66 #include <modest-utils.h>
68 #include "widgets/modest-ui-constants.h"
69 #include <widgets/modest-main-window.h>
70 #include <widgets/modest-msg-view-window.h>
71 #include <widgets/modest-account-view-window.h>
72 #include <widgets/modest-details-dialog.h>
73 #include <widgets/modest-attachments-view.h>
74 #include "widgets/modest-folder-view.h"
75 #include "widgets/modest-global-settings-dialog.h"
76 #include "modest-account-mgr-helpers.h"
77 #include "modest-mail-operation.h"
78 #include "modest-text-utils.h"
79 #include <modest-widget-memory.h>
80 #include <tny-error.h>
81 #include <tny-simple-list.h>
82 #include <tny-msg-view.h>
83 #include <tny-device.h>
84 #include <tny-merge-folder.h>
86 #include <gtkhtml/gtkhtml.h>
88 #define MIN_FREE_SPACE 5 * 1024 * 1024
89 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
91 typedef struct _GetMsgAsyncHelper {
93 ModestMailOperation *mail_op;
100 typedef enum _ReplyForwardAction {
104 } ReplyForwardAction;
106 typedef struct _ReplyForwardHelper {
107 guint reply_forward_type;
108 ReplyForwardAction action;
110 GtkWidget *parent_window;
112 } ReplyForwardHelper;
114 typedef struct _MoveToHelper {
115 GtkTreeRowReference *reference;
119 typedef struct _PasteAsAttachmentHelper {
120 ModestMsgEditWindow *window;
122 } PasteAsAttachmentHelper;
130 * The do_headers_action uses this kind of functions to perform some
131 * action to each member of a list of headers
133 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
135 static void do_headers_action (ModestWindow *win,
139 static void open_msg_cb (ModestMailOperation *mail_op,
146 static void reply_forward_cb (ModestMailOperation *mail_op,
153 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
155 static void folder_refreshed_cb (ModestMailOperation *mail_op,
159 static void on_send_receive_finished (ModestMailOperation *mail_op,
162 static gint header_list_count_uncached_msgs (TnyList *header_list);
164 static gboolean connect_to_get_msg (ModestWindow *win,
165 gint num_of_uncached_msgs,
166 TnyAccount *account);
168 static gboolean remote_folder_has_leave_on_server (TnyFolderStore *folder);
170 static void do_create_folder (GtkWindow *window,
171 TnyFolderStore *parent_folder,
172 const gchar *suggested_name);
174 static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store);
176 static void modest_ui_actions_on_main_window_move_to (GtkAction *action,
177 GtkWidget *folder_view,
178 TnyFolderStore *dst_folder,
179 ModestMainWindow *win);
181 static void modest_ui_actions_on_window_move_to (GtkAction *action,
182 TnyList *list_to_move,
183 TnyFolderStore *dst_folder,
187 * This function checks whether a TnyFolderStore is a pop account
190 remote_folder_has_leave_on_server (TnyFolderStore *folder)
195 g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
197 account = get_account_from_folder_store (folder);
198 result = (modest_protocol_registry_protocol_type_has_leave_on_server (modest_runtime_get_protocol_registry (),
199 modest_tny_account_get_protocol_type (account)));
200 g_object_unref (account);
205 /* FIXME: this should be merged with the similar code in modest-account-view-window */
206 /* Show the account creation wizard dialog.
207 * returns: TRUE if an account was created. FALSE if the user cancelled.
210 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
212 gboolean result = FALSE;
214 gint dialog_response;
216 /* there is no such wizard yet */
217 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
218 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (wizard), (GtkWindow *) win);
220 /* always present a main window in the background
221 * we do it here, so we cannot end up with two wizards (as this
222 * function might be called in modest_window_mgr_get_main_window as well */
224 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
225 TRUE); /* create if not existent */
227 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
229 /* make sure the mainwindow is visible. We need to present the
230 wizard again to give it the focus back. show_all are needed
231 in order to get the widgets properly drawn (MainWindow main
232 paned won't be in its right position and the dialog will be
234 #ifndef MODEST_TOOLKIT_HILDON2
235 gtk_widget_show_all (GTK_WIDGET (win));
236 gtk_widget_show_all (GTK_WIDGET (wizard));
237 gtk_window_present (GTK_WINDOW (win));
238 gtk_window_present (GTK_WINDOW (wizard));
241 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
242 gtk_widget_destroy (GTK_WIDGET (wizard));
243 if (gtk_events_pending ())
244 gtk_main_iteration ();
246 if (dialog_response == GTK_RESPONSE_CANCEL) {
249 /* Check whether an account was created: */
250 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
257 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
260 const gchar *authors[] = {
261 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
264 about = gtk_about_dialog_new ();
265 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
266 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
267 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
268 _("Copyright (c) 2006, Nokia Corporation\n"
269 "All rights reserved."));
270 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
271 _("a modest e-mail client\n\n"
272 "design and implementation: Dirk-Jan C. Binnema\n"
273 "contributions from the fine people at KC and Ig\n"
274 "uses the tinymail email framework written by Philip van Hoof"));
275 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
276 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
277 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
278 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
280 gtk_dialog_run (GTK_DIALOG (about));
281 gtk_widget_destroy(about);
285 * Gets the list of currently selected messages. If the win is the
286 * main window, then it returns a newly allocated list of the headers
287 * selected in the header view. If win is the msg view window, then
288 * the value returned is a list with just a single header.
290 * The caller of this funcion must free the list.
293 get_selected_headers (ModestWindow *win)
295 if (MODEST_IS_MAIN_WINDOW(win)) {
296 GtkWidget *header_view;
298 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
299 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
300 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
302 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
303 /* for MsgViewWindows, we simply return a list with one element */
305 TnyList *list = NULL;
307 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
308 if (header != NULL) {
309 list = tny_simple_list_new ();
310 tny_list_prepend (list, G_OBJECT(header));
311 g_object_unref (G_OBJECT(header));
316 #ifdef MODEST_TOOLKIT_HILDON2
317 } else if (MODEST_IS_HEADER_WINDOW (win)) {
318 GtkWidget *header_view;
320 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
321 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
327 static GtkTreeRowReference *
328 get_next_after_selected_headers (ModestHeaderView *header_view)
330 GtkTreeSelection *sel;
331 GList *selected_rows, *node;
333 GtkTreeRowReference *result;
336 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
337 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
338 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
340 if (selected_rows == NULL)
343 node = g_list_last (selected_rows);
344 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
345 gtk_tree_path_next (path);
347 result = gtk_tree_row_reference_new (model, path);
349 gtk_tree_path_free (path);
350 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
351 g_list_free (selected_rows);
357 headers_action_mark_as_read (TnyHeader *header,
361 TnyHeaderFlags flags;
363 g_return_if_fail (TNY_IS_HEADER(header));
365 flags = tny_header_get_flags (header);
366 if (flags & TNY_HEADER_FLAG_SEEN) return;
367 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
371 headers_action_mark_as_unread (TnyHeader *header,
375 TnyHeaderFlags flags;
377 g_return_if_fail (TNY_IS_HEADER(header));
379 flags = tny_header_get_flags (header);
380 if (flags & TNY_HEADER_FLAG_SEEN) {
381 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
385 /** After deleing a message that is currently visible in a window,
386 * show the next message from the list, or close the window if there are no more messages.
389 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
391 /* Close msg view window or select next */
392 if (!modest_msg_view_window_select_next_message (win) &&
393 !modest_msg_view_window_select_previous_message (win)) {
395 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
401 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
403 modest_ui_actions_on_edit_mode_delete_message (win);
407 modest_ui_actions_on_edit_mode_delete_message (ModestWindow *win)
409 TnyList *header_list = NULL;
410 TnyIterator *iter = NULL;
411 TnyHeader *header = NULL;
412 gchar *message = NULL;
415 ModestWindowMgr *mgr;
416 GtkWidget *header_view = NULL;
417 gboolean retval = TRUE;
419 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
421 /* Check first if the header view has the focus */
422 if (MODEST_IS_MAIN_WINDOW (win)) {
424 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
425 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
426 if (!gtk_widget_is_focus (header_view))
430 /* Get the headers, either from the header view (if win is the main window),
431 * or from the message view window: */
432 header_list = get_selected_headers (win);
433 if (!header_list) return FALSE;
435 /* Check if any of the headers are already opened, or in the process of being opened */
436 if (MODEST_IS_MAIN_WINDOW (win)) {
437 gint opened_headers = 0;
439 iter = tny_list_create_iterator (header_list);
440 mgr = modest_runtime_get_window_mgr ();
441 while (!tny_iterator_is_done (iter)) {
442 header = TNY_HEADER (tny_iterator_get_current (iter));
444 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
446 g_object_unref (header);
448 tny_iterator_next (iter);
450 g_object_unref (iter);
452 if (opened_headers > 0) {
455 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
458 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg, FALSE);
461 g_object_unref (header_list);
467 if (tny_list_get_length(header_list) == 1) {
468 iter = tny_list_create_iterator (header_list);
469 header = TNY_HEADER (tny_iterator_get_current (iter));
472 subject = tny_header_dup_subject (header);
474 subject = g_strdup (_("mail_va_no_subject"));
475 desc = g_strdup_printf ("%s", subject);
477 g_object_unref (header);
480 g_object_unref (iter);
482 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
483 tny_list_get_length(header_list)), desc);
485 /* Confirmation dialog */
486 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
490 if (response == GTK_RESPONSE_OK) {
491 ModestWindow *main_window = NULL;
492 ModestWindowMgr *mgr = NULL;
493 GtkTreeModel *model = NULL;
494 GtkTreeSelection *sel = NULL;
495 GList *sel_list = NULL, *tmp = NULL;
496 GtkTreeRowReference *next_row_reference = NULL;
497 GtkTreeRowReference *prev_row_reference = NULL;
498 GtkTreePath *next_path = NULL;
499 GtkTreePath *prev_path = NULL;
500 ModestMailOperation *mail_op = NULL;
502 /* Find last selected row */
503 if (MODEST_IS_MAIN_WINDOW (win)) {
504 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
505 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
506 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
507 for (tmp=sel_list; tmp; tmp=tmp->next) {
508 if (tmp->next == NULL) {
509 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
510 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
512 gtk_tree_path_prev (prev_path);
513 gtk_tree_path_next (next_path);
515 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
516 next_row_reference = gtk_tree_row_reference_new (model, next_path);
521 /* Disable window dimming management */
522 modest_window_disable_dimming (MODEST_WINDOW(win));
524 /* Remove each header. If it's a view window header_view == NULL */
525 mail_op = modest_mail_operation_new ((GObject *) win);
526 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
528 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
529 g_object_unref (mail_op);
531 /* Enable window dimming management */
533 gtk_tree_selection_unselect_all (sel);
535 modest_window_enable_dimming (MODEST_WINDOW(win));
537 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
538 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
540 /* Get main window */
541 mgr = modest_runtime_get_window_mgr ();
542 main_window = modest_window_mgr_get_main_window (mgr, FALSE); /* don't create */
543 } else if (MODEST_IS_MAIN_WINDOW (win)) {
544 /* Move cursor to next row */
547 /* Select next or previous row */
548 if (gtk_tree_row_reference_valid (next_row_reference)) {
549 gtk_tree_selection_select_path (sel, next_path);
551 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
552 gtk_tree_selection_select_path (sel, prev_path);
556 if (gtk_tree_row_reference_valid (next_row_reference))
557 gtk_tree_row_reference_free (next_row_reference);
558 if (next_path != NULL)
559 gtk_tree_path_free (next_path);
560 if (gtk_tree_row_reference_valid (prev_row_reference))
561 gtk_tree_row_reference_free (prev_row_reference);
562 if (prev_path != NULL)
563 gtk_tree_path_free (prev_path);
566 /* Update toolbar dimming state */
568 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
569 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
573 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
574 g_list_free (sel_list);
583 g_object_unref (header_list);
591 /* delete either message or folder, based on where we are */
593 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
595 g_return_if_fail (MODEST_IS_WINDOW(win));
597 /* Check first if the header view has the focus */
598 if (MODEST_IS_MAIN_WINDOW (win)) {
600 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
601 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
602 if (gtk_widget_is_focus (w)) {
603 modest_ui_actions_on_delete_folder (action, MODEST_WINDOW(win));
607 modest_ui_actions_on_delete_message (action, win);
611 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
613 ModestWindowMgr *mgr = NULL;
615 #ifdef MODEST_PLATFORM_MAEMO
616 modest_osso_save_state();
617 #endif /* MODEST_PLATFORM_MAEMO */
619 g_debug ("closing down, clearing %d item(s) from operation queue",
620 modest_mail_operation_queue_num_elements
621 (modest_runtime_get_mail_operation_queue()));
623 /* cancel all outstanding operations */
624 modest_mail_operation_queue_cancel_all
625 (modest_runtime_get_mail_operation_queue());
627 g_debug ("queue has been cleared");
630 /* Check if there are opened editing windows */
631 mgr = modest_runtime_get_window_mgr ();
632 modest_window_mgr_close_all_windows (mgr);
634 /* note: when modest-tny-account-store is finalized,
635 it will automatically set all network connections
638 /* gtk_main_quit (); */
642 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
646 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
648 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
649 /* gtk_widget_destroy (GTK_WIDGET (win)); */
650 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
651 /* gboolean ret_value; */
652 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
653 /* } else if (MODEST_IS_WINDOW (win)) { */
654 /* gtk_widget_destroy (GTK_WIDGET (win)); */
656 /* g_return_if_reached (); */
661 modest_ui_actions_add_to_contacts (GtkAction *action, ModestWindow *win)
663 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
665 modest_msg_view_window_add_to_contacts (MODEST_MSG_VIEW_WINDOW (win));
669 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
671 GtkClipboard *clipboard = NULL;
672 gchar *selection = NULL;
674 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
675 selection = gtk_clipboard_wait_for_text (clipboard);
677 /* Question: why is the clipboard being used here?
678 * It doesn't really make a lot of sense. */
682 modest_address_book_add_address (selection);
688 modest_ui_actions_on_new_account (GtkAction *action,
689 ModestWindow *window)
691 modest_ui_actions_run_account_setup_wizard (window);
695 modest_ui_actions_on_accounts (GtkAction *action,
698 /* This is currently only implemented for Maemo */
699 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
700 if (!modest_ui_actions_run_account_setup_wizard (win))
701 g_debug ("%s: wizard was already running", __FUNCTION__);
705 /* Show the list of accounts */
706 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
708 /* The accounts dialog must be modal */
709 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
710 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
715 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
717 /* This is currently only implemented for Maemo,
718 * because it requires an API (libconic) to detect different connection
721 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
723 /* Create the window if necessary: */
724 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
725 modest_connection_specific_smtp_window_fill_with_connections (
726 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
727 modest_runtime_get_account_mgr());
729 /* Show the window: */
730 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
731 GTK_WINDOW (specific_window), (GtkWindow *) win);
732 gtk_widget_show (specific_window);
733 #endif /* !MODEST_TOOLKIT_GTK */
737 modest_ui_actions_compose_msg(ModestWindow *win,
740 const gchar *bcc_str,
741 const gchar *subject_str,
742 const gchar *body_str,
744 gboolean set_as_modified)
746 gchar *account_name = NULL;
748 TnyAccount *account = NULL;
749 TnyFolder *folder = NULL;
750 gchar *from_str = NULL, *signature = NULL, *body = NULL;
751 gboolean use_signature = FALSE;
752 ModestWindow *msg_win = NULL;
753 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
754 ModestTnyAccountStore *store = modest_runtime_get_account_store();
755 GnomeVFSFileSize total_size, allowed_size;
757 /* we check for low-mem */
758 if (modest_platform_check_memory_low (win, TRUE))
761 #ifdef MODEST_TOOLKIT_HILDON2
762 account_name = g_strdup (modest_window_get_active_account(win));
765 account_name = modest_account_mgr_get_default_account(mgr);
768 g_printerr ("modest: no account found\n");
771 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
773 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
776 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
778 g_printerr ("modest: failed to find Drafts folder\n");
781 from_str = modest_account_mgr_get_from_string (mgr, account_name);
783 g_printerr ("modest: failed get from string for '%s'\n", account_name);
787 signature = modest_account_mgr_get_signature (mgr, account_name, &use_signature);
788 if (body_str != NULL) {
789 body = use_signature ? g_strconcat(body_str, "\n--\n", signature, NULL) : g_strdup(body_str);
791 body = use_signature ? g_strconcat("\n--\n", signature, NULL) : g_strdup("");
794 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, body, NULL, NULL, NULL);
796 g_printerr ("modest: failed to create new msg\n");
800 /* Create and register edit window */
801 /* This is destroyed by TODO. */
803 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
804 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
806 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, win)) {
807 gtk_widget_destroy (GTK_WIDGET (msg_win));
810 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
811 gtk_widget_show_all (GTK_WIDGET (msg_win));
813 while (attachments) {
815 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
816 attachments->data, allowed_size);
818 if (total_size > allowed_size) {
819 g_warning ("%s: total size: %u",
820 __FUNCTION__, (unsigned int)total_size);
823 allowed_size -= total_size;
825 attachments = g_slist_next(attachments);
832 g_free (account_name);
834 g_object_unref (G_OBJECT(account));
836 g_object_unref (G_OBJECT(folder));
838 g_object_unref (G_OBJECT(msg));
842 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
844 /* if there are no accounts yet, just show the wizard */
845 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
846 if (!modest_ui_actions_run_account_setup_wizard (win))
849 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
854 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
858 ModestMailOperationStatus status;
860 /* If there is no message or the operation was not successful */
861 status = modest_mail_operation_get_status (mail_op);
862 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
865 /* If it's a memory low issue, then show a banner */
866 error = modest_mail_operation_get_error (mail_op);
867 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
868 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
869 GObject *source = modest_mail_operation_get_source (mail_op);
870 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
871 dgettext("ke-recv","memr_ib_operation_disabled"),
873 g_object_unref (source);
876 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
877 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
878 gchar *subject, *msg;
879 subject = tny_header_dup_subject (header);
881 subject = g_strdup (_("mail_va_no_subject"));;
882 msg = g_strdup_printf (_("emev_ni_ui_imap_message_not_available_in_server"),
884 modest_platform_run_information_dialog (NULL, msg, FALSE);
889 /* Remove the header from the preregistered uids */
890 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
908 OpenMsgBannerInfo *banner_info;
909 GtkTreeRowReference *rowref;
913 open_msg_banner_idle (gpointer userdata)
915 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
917 gdk_threads_enter ();
918 banner_info->idle_handler = 0;
919 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
921 g_object_ref (banner_info->banner);
923 gdk_threads_leave ();
930 get_header_view_from_window (ModestWindow *window)
932 GtkWidget *header_view;
934 if (MODEST_IS_MAIN_WINDOW (window)) {
935 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
936 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
937 #ifdef MODEST_TOOLKIT_HILDON2
938 } else if (MODEST_IS_HEADER_WINDOW (window)){
939 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
949 get_info_from_header (TnyHeader *header, gboolean *is_draft)
952 gchar *account = NULL;
953 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
957 folder = tny_header_get_folder (header);
958 /* Gets folder type (OUTBOX headers will be opened in edit window */
959 if (modest_tny_folder_is_local_folder (folder)) {
960 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
961 if (folder_type == TNY_FOLDER_TYPE_INVALID)
962 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
965 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
966 TnyTransportAccount *traccount = NULL;
967 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
968 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
970 ModestTnySendQueue *send_queue = NULL;
971 ModestTnySendQueueStatus status;
973 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
974 TNY_ACCOUNT(traccount)));
975 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
976 if (TNY_IS_SEND_QUEUE (send_queue)) {
977 msg_id = modest_tny_send_queue_get_msg_id (header);
978 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
980 /* Only open messages in outbox with the editor if they are in Failed state */
981 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
984 #ifdef MODEST_TOOLKIT_HILDON2
986 /* In Fremantle we can not
987 open any message from
988 outbox which is not in
990 g_object_unref(traccount);
994 g_object_unref(traccount);
996 g_warning("Cannot get transport account for message in outbox!!");
998 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
999 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
1002 g_object_unref (folder);
1008 open_msg_cb (ModestMailOperation *mail_op,
1015 ModestWindowMgr *mgr = NULL;
1016 ModestWindow *parent_win = NULL;
1017 ModestWindow *win = NULL;
1018 gchar *account = NULL;
1019 gboolean open_in_editor = FALSE;
1020 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1022 /* Do nothing if there was any problem with the mail
1023 operation. The error will be shown by the error_handler of
1024 the mail operation */
1025 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1028 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1030 /* Mark header as read */
1031 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1033 account = get_info_from_header (header, &open_in_editor);
1037 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1039 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1041 if (open_in_editor) {
1042 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1043 gchar *from_header = NULL, *acc_name;
1045 from_header = tny_header_dup_from (header);
1047 /* we cannot edit without a valid account... */
1048 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1049 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1050 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1052 g_free (from_header);
1057 acc_name = modest_utils_get_account_name_from_recipient (from_header);
1058 g_free (from_header);
1064 win = modest_msg_edit_window_new (msg, account, TRUE);
1066 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1068 if (helper->rowref && helper->model) {
1069 win = modest_msg_view_window_new_with_header_model (msg, account, (const gchar*) uid,
1070 helper->model, helper->rowref);
1072 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
1077 /* Register and show new window */
1079 mgr = modest_runtime_get_window_mgr ();
1080 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1081 gtk_widget_destroy (GTK_WIDGET (win));
1084 gtk_widget_show_all (GTK_WIDGET(win));
1087 /* Update toolbar dimming state */
1088 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1089 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1095 g_object_unref (parent_win);
1099 is_memory_full_error (GError *error)
1101 gboolean enough_free_space = TRUE;
1102 GnomeVFSURI *cache_dir_uri;
1103 const gchar *cache_dir;
1104 GnomeVFSFileSize free_space;
1106 cache_dir = tny_account_store_get_cache_dir (TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
1107 cache_dir_uri = gnome_vfs_uri_new (cache_dir);
1108 if (gnome_vfs_get_volume_free_space (cache_dir_uri, &free_space) == GNOME_VFS_OK) {
1109 if (free_space < MIN_FREE_SPACE)
1110 enough_free_space = FALSE;
1112 gnome_vfs_uri_unref (cache_dir_uri);
1114 if ((error->code == TNY_SYSTEM_ERROR_MEMORY ||
1115 /* When asking for a mail and no space left on device
1116 tinymail returns this error */
1117 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE ||
1118 /* When the folder summary could not be read or
1120 error->code == TNY_IO_ERROR_WRITE ||
1121 error->code == TNY_IO_ERROR_READ) &&
1122 !enough_free_space) {
1130 check_memory_full_error (GtkWidget *parent_window, GError *err)
1135 if (is_memory_full_error (err))
1136 modest_platform_information_banner (parent_window,
1137 NULL, dgettext("ke-recv",
1138 "cerm_device_memory_full"));
1139 else if (err->code == TNY_SYSTEM_ERROR_MEMORY)
1140 /* If the account was created in memory full
1141 conditions then tinymail won't be able to
1142 connect so it'll return this error code */
1143 modest_platform_information_banner (parent_window,
1144 NULL, _("emev_ui_imap_inbox_select_error"));
1152 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1155 const GError *error;
1156 GObject *win = NULL;
1157 ModestMailOperationStatus status;
1159 win = modest_mail_operation_get_source (mail_op);
1160 error = modest_mail_operation_get_error (mail_op);
1161 status = modest_mail_operation_get_status (mail_op);
1163 /* If the mail op has been cancelled then it's not an error:
1164 don't show any message */
1165 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1166 if (is_memory_full_error ((GError *) error)) {
1167 modest_platform_information_banner ((GtkWidget *) win,
1168 NULL, dgettext("ke-recv",
1169 "cerm_device_memory_full"));
1170 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1171 modest_platform_information_banner ((GtkWidget *) win,
1172 NULL, _("emev_ui_imap_inbox_select_error"));
1173 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1174 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1175 modest_platform_information_banner ((GtkWidget *) win,
1176 NULL, dgettext ("hildon-common-strings", "sfil_ni_unable_to_open_file_not_found"));
1177 } else if (user_data) {
1178 modest_platform_information_banner ((GtkWidget *) win,
1184 g_object_unref (win);
1188 * Returns the account a list of headers belongs to. It returns a
1189 * *new* reference so don't forget to unref it
1192 get_account_from_header_list (TnyList *headers)
1194 TnyAccount *account = NULL;
1196 if (tny_list_get_length (headers) > 0) {
1197 TnyIterator *iter = tny_list_create_iterator (headers);
1198 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1199 TnyFolder *folder = tny_header_get_folder (header);
1202 g_object_unref (header);
1204 while (!tny_iterator_is_done (iter)) {
1205 header = TNY_HEADER (tny_iterator_get_current (iter));
1206 folder = tny_header_get_folder (header);
1209 g_object_unref (header);
1211 tny_iterator_next (iter);
1216 account = tny_folder_get_account (folder);
1217 g_object_unref (folder);
1221 g_object_unref (header);
1223 g_object_unref (iter);
1229 get_account_from_header (TnyHeader *header)
1231 TnyAccount *account = NULL;
1234 folder = tny_header_get_folder (header);
1237 account = tny_folder_get_account (folder);
1238 g_object_unref (folder);
1245 open_msg_helper_destroyer (gpointer user_data)
1247 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1249 if (helper->banner_info) {
1250 g_free (helper->banner_info->message);
1251 if (helper->banner_info->idle_handler > 0) {
1252 g_source_remove (helper->banner_info->idle_handler);
1253 helper->banner_info->idle_handler = 0;
1255 if (helper->banner_info->banner != NULL) {
1256 gtk_widget_destroy (helper->banner_info->banner);
1257 g_object_unref (helper->banner_info->banner);
1258 helper->banner_info->banner = NULL;
1260 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1261 helper->banner_info = NULL;
1263 g_object_unref (helper->model);
1264 g_object_unref (helper->header);
1265 gtk_tree_row_reference_free (helper->rowref);
1266 g_slice_free (OpenMsgHelper, helper);
1270 open_msg_performer(gboolean canceled,
1272 GtkWindow *parent_window,
1273 TnyAccount *account,
1276 ModestMailOperation *mail_op = NULL;
1278 ModestProtocolType proto;
1279 TnyConnectionStatus status;
1280 gboolean show_open_draft = FALSE;
1281 OpenMsgHelper *helper = NULL;
1283 helper = (OpenMsgHelper *) user_data;
1285 status = tny_account_get_connection_status (account);
1286 if (err || canceled) {
1287 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1288 /* Free the helper */
1289 open_msg_helper_destroyer (helper);
1291 /* In memory full conditions we could get this error here */
1292 check_memory_full_error ((GtkWidget *) parent_window, err);
1297 /* Get the error message depending on the protocol */
1298 proto = modest_tny_account_get_protocol_type (account);
1299 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1300 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1303 ModestProtocol *protocol;
1304 ModestProtocolRegistry *protocol_registry;
1307 protocol_registry = modest_runtime_get_protocol_registry ();
1308 subject = tny_header_dup_subject (helper->header);
1310 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1311 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1315 if (error_msg == NULL) {
1316 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1319 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1321 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1323 TnyFolderType folder_type;
1325 folder = tny_header_get_folder (helper->header);
1326 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1327 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1328 g_object_unref (folder);
1331 #ifdef MODEST_TOOLKIT_HILDON2
1333 gchar *account_name = get_info_from_header (helper->header, &is_draft);
1336 ModestWindow *window;
1337 GtkWidget *header_view;
1340 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1341 uid = modest_tny_folder_get_header_unique_id (helper->header);
1343 window = modest_msg_view_window_new_from_header_view
1344 (MODEST_HEADER_VIEW (header_view), account_name, uid, helper->rowref);
1345 if (window != NULL) {
1346 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1348 gtk_widget_destroy (GTK_WIDGET (window));
1350 gtk_widget_show_all (GTK_WIDGET(window));
1354 g_free (account_name);
1356 open_msg_helper_destroyer (helper);
1359 g_free (account_name);
1361 /* Create the mail operation */
1363 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1364 modest_ui_actions_disk_operations_error_handler,
1366 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1369 if (show_open_draft) {
1370 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1371 #ifdef MODEST_TOOLKIT_HILDON2
1372 helper->banner_info->message = g_strdup (_("mail_me_opening"));
1374 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1376 helper->banner_info->banner = NULL;
1377 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1378 helper->banner_info);
1382 headers = TNY_LIST (tny_simple_list_new ());
1383 tny_list_prepend (headers, G_OBJECT (helper->header));
1384 modest_mail_operation_get_msgs_full (mail_op,
1388 open_msg_helper_destroyer);
1389 g_object_unref (headers);
1394 g_object_unref (mail_op);
1395 g_object_unref (account);
1399 * This function is used by both modest_ui_actions_on_open and
1400 * modest_ui_actions_on_header_activated. This way we always do the
1401 * same when trying to open messages.
1404 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1406 ModestWindowMgr *mgr = NULL;
1407 TnyAccount *account;
1408 gboolean cached = FALSE;
1410 GtkWidget *header_view = NULL;
1411 OpenMsgHelper *helper;
1412 ModestWindow *window;
1414 g_return_if_fail (header != NULL && rowref != NULL);
1416 mgr = modest_runtime_get_window_mgr ();
1419 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1420 if (header_view == NULL)
1423 /* Get the account */
1424 account = get_account_from_header (header);
1429 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1431 /* Do not open again the message and present the
1432 window to the user */
1435 #ifndef MODEST_TOOLKIT_HILDON2
1436 gtk_window_present (GTK_WINDOW (window));
1439 /* the header has been registered already, we don't do
1440 * anything but wait for the window to come up*/
1441 g_debug ("header %p already registered, waiting for window", header);
1446 /* Open each message */
1447 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1449 /* Allways download if we are online. */
1450 if (!tny_device_is_online (modest_runtime_get_device ())) {
1453 /* If ask for user permission to download the messages */
1454 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1455 _("mcen_nc_get_msg"));
1457 /* End if the user does not want to continue */
1458 if (response == GTK_RESPONSE_CANCEL) {
1464 /* We register the window for opening */
1465 modest_window_mgr_register_header (mgr, header, NULL);
1467 /* Create the helper. We need to get a reference to the model
1468 here because it could change while the message is readed
1469 (the user could switch between folders) */
1470 helper = g_slice_new (OpenMsgHelper);
1471 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1472 helper->header = g_object_ref (header);
1473 helper->rowref = gtk_tree_row_reference_copy (rowref);
1474 helper->banner_info = NULL;
1476 /* Connect to the account and perform */
1478 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1479 open_msg_performer, helper);
1481 /* Call directly the performer, do not need to connect */
1482 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1483 g_object_ref (account), helper);
1488 g_object_unref (account);
1492 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1499 /* we check for low-mem; in that case, show a warning, and don't allow
1502 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1506 headers = get_selected_headers (win);
1510 headers_count = tny_list_get_length (headers);
1511 if (headers_count != 1) {
1512 if (headers_count > 1) {
1513 /* Don't allow activation if there are more than one message selected */
1514 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1517 g_object_unref (headers);
1521 iter = tny_list_create_iterator (headers);
1522 header = TNY_HEADER (tny_iterator_get_current (iter));
1523 g_object_unref (iter);
1527 open_msg_from_header (header, NULL, win);
1528 g_object_unref (header);
1531 g_object_unref(headers);
1535 rf_helper_window_closed (gpointer data,
1538 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1540 helper->parent_window = NULL;
1543 static ReplyForwardHelper*
1544 create_reply_forward_helper (ReplyForwardAction action,
1546 guint reply_forward_type,
1549 ReplyForwardHelper *rf_helper = NULL;
1550 const gchar *active_acc = modest_window_get_active_account (win);
1552 rf_helper = g_slice_new0 (ReplyForwardHelper);
1553 rf_helper->reply_forward_type = reply_forward_type;
1554 rf_helper->action = action;
1555 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1556 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1557 rf_helper->account_name = (active_acc) ?
1558 g_strdup (active_acc) :
1559 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1561 /* Note that window could be destroyed just AFTER calling
1562 register_window so we must ensure that this pointer does
1563 not hold invalid references */
1564 if (rf_helper->parent_window)
1565 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1566 rf_helper_window_closed, rf_helper);
1572 free_reply_forward_helper (gpointer data)
1574 ReplyForwardHelper *helper;
1576 helper = (ReplyForwardHelper *) data;
1577 g_free (helper->account_name);
1579 g_object_unref (helper->header);
1580 if (helper->parent_window)
1581 g_object_weak_unref (G_OBJECT (helper->parent_window),
1582 rf_helper_window_closed, helper);
1583 g_slice_free (ReplyForwardHelper, helper);
1587 reply_forward_cb (ModestMailOperation *mail_op,
1594 TnyMsg *new_msg = NULL;
1595 ReplyForwardHelper *rf_helper;
1596 ModestWindow *msg_win = NULL;
1597 ModestEditType edit_type;
1599 TnyAccount *account = NULL;
1600 ModestWindowMgr *mgr = NULL;
1601 gchar *signature = NULL;
1602 gboolean use_signature;
1604 /* If there was any error. The mail operation could be NULL,
1605 this means that we already have the message downloaded and
1606 that we didn't do a mail operation to retrieve it */
1607 rf_helper = (ReplyForwardHelper *) user_data;
1608 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1611 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1612 rf_helper->account_name);
1613 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr(),
1614 rf_helper->account_name,
1617 /* Create reply mail */
1618 switch (rf_helper->action) {
1621 modest_tny_msg_create_reply_msg (msg, header, from,
1622 (use_signature) ? signature : NULL,
1623 rf_helper->reply_forward_type,
1624 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1626 case ACTION_REPLY_TO_ALL:
1628 modest_tny_msg_create_reply_msg (msg, header, from,
1629 (use_signature) ? signature : NULL,
1630 rf_helper->reply_forward_type,
1631 MODEST_TNY_MSG_REPLY_MODE_ALL);
1632 edit_type = MODEST_EDIT_TYPE_REPLY;
1634 case ACTION_FORWARD:
1636 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1637 rf_helper->reply_forward_type);
1638 edit_type = MODEST_EDIT_TYPE_FORWARD;
1641 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1643 g_return_if_reached ();
1651 g_warning ("%s: failed to create message\n", __FUNCTION__);
1655 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1656 rf_helper->account_name,
1657 TNY_ACCOUNT_TYPE_STORE);
1659 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1663 /* Create and register the windows */
1664 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1665 mgr = modest_runtime_get_window_mgr ();
1666 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1668 /* Note that register_window could have deleted the account */
1669 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1670 gdouble parent_zoom;
1672 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1673 modest_window_set_zoom (msg_win, parent_zoom);
1676 /* Show edit window */
1677 gtk_widget_show_all (GTK_WIDGET (msg_win));
1680 /* We always unregister the header because the message is
1681 forwarded or replied so the original one is no longer
1683 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1686 g_object_unref (G_OBJECT (new_msg));
1688 g_object_unref (G_OBJECT (account));
1689 free_reply_forward_helper (rf_helper);
1692 /* Checks a list of headers. If any of them are not currently
1693 * downloaded (CACHED) then returns TRUE else returns FALSE.
1696 header_list_count_uncached_msgs (TnyList *header_list)
1699 gint uncached_messages = 0;
1701 iter = tny_list_create_iterator (header_list);
1702 while (!tny_iterator_is_done (iter)) {
1705 header = TNY_HEADER (tny_iterator_get_current (iter));
1707 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1708 uncached_messages ++;
1709 g_object_unref (header);
1712 tny_iterator_next (iter);
1714 g_object_unref (iter);
1716 return uncached_messages;
1719 /* Returns FALSE if the user does not want to download the
1720 * messages. Returns TRUE if the user allowed the download.
1723 connect_to_get_msg (ModestWindow *win,
1724 gint num_of_uncached_msgs,
1725 TnyAccount *account)
1727 GtkResponseType response;
1729 /* Allways download if we are online. */
1730 if (tny_device_is_online (modest_runtime_get_device ()))
1733 /* If offline, then ask for user permission to download the messages */
1734 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1735 ngettext("mcen_nc_get_msg",
1737 num_of_uncached_msgs));
1739 if (response == GTK_RESPONSE_CANCEL)
1742 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1746 reply_forward_performer (gboolean canceled,
1748 GtkWindow *parent_window,
1749 TnyAccount *account,
1752 ReplyForwardHelper *rf_helper = NULL;
1753 ModestMailOperation *mail_op;
1755 rf_helper = (ReplyForwardHelper *) user_data;
1757 if (canceled || err) {
1758 free_reply_forward_helper (rf_helper);
1762 /* Retrieve the message */
1763 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1764 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1765 modest_ui_actions_disk_operations_error_handler,
1767 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1768 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1771 g_object_unref(mail_op);
1775 * Common code for the reply and forward actions
1778 reply_forward (ReplyForwardAction action, ModestWindow *win)
1780 ReplyForwardHelper *rf_helper = NULL;
1781 guint reply_forward_type;
1783 g_return_if_fail (MODEST_IS_WINDOW(win));
1785 /* we check for low-mem; in that case, show a warning, and don't allow
1786 * reply/forward (because it could potentially require a lot of memory */
1787 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1791 /* we need an account when editing */
1792 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1793 if (!modest_ui_actions_run_account_setup_wizard (win))
1797 reply_forward_type =
1798 modest_conf_get_int (modest_runtime_get_conf (),
1799 (action == ACTION_FORWARD) ?
1800 MODEST_CONF_FORWARD_TYPE :
1801 MODEST_CONF_REPLY_TYPE,
1804 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1806 TnyHeader *header = NULL;
1807 /* Get header and message. Do not free them here, the
1808 reply_forward_cb must do it */
1809 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1810 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1812 if (msg && header) {
1814 rf_helper = create_reply_forward_helper (action, win,
1815 reply_forward_type, header);
1816 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1818 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1822 g_object_unref (msg);
1824 g_object_unref (header);
1826 TnyHeader *header = NULL;
1828 gboolean do_retrieve = TRUE;
1829 TnyList *header_list = NULL;
1831 header_list = get_selected_headers (win);
1834 /* Check that only one message is selected for replying */
1835 if (tny_list_get_length (header_list) != 1) {
1836 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1837 NULL, _("mcen_ib_select_one_message"));
1838 g_object_unref (header_list);
1842 /* Only reply/forward to one message */
1843 iter = tny_list_create_iterator (header_list);
1844 header = TNY_HEADER (tny_iterator_get_current (iter));
1845 g_object_unref (iter);
1847 /* Retrieve messages */
1848 do_retrieve = (action == ACTION_FORWARD) ||
1849 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1852 TnyAccount *account = NULL;
1853 TnyFolder *folder = NULL;
1854 gdouble download = TRUE;
1855 guint uncached_msgs = 0;
1857 folder = tny_header_get_folder (header);
1859 goto do_retrieve_frees;
1860 account = tny_folder_get_account (folder);
1862 goto do_retrieve_frees;
1864 uncached_msgs = header_list_count_uncached_msgs (header_list);
1866 if (uncached_msgs > 0) {
1867 /* Allways download if we are online. */
1868 if (!tny_device_is_online (modest_runtime_get_device ())) {
1871 /* If ask for user permission to download the messages */
1872 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1873 ngettext("mcen_nc_get_msg",
1877 /* End if the user does not want to continue */
1878 if (response == GTK_RESPONSE_CANCEL)
1885 rf_helper = create_reply_forward_helper (action, win,
1886 reply_forward_type, header);
1887 if (uncached_msgs > 0) {
1888 modest_platform_connect_and_perform (GTK_WINDOW (win),
1890 reply_forward_performer,
1893 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
1894 account, rf_helper);
1899 g_object_unref (account);
1901 g_object_unref (folder);
1903 reply_forward_cb (NULL, header, FALSE, NULL, NULL, rf_helper);
1906 g_object_unref (header_list);
1907 g_object_unref (header);
1912 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1914 g_return_if_fail (MODEST_IS_WINDOW(win));
1916 reply_forward (ACTION_REPLY, win);
1920 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1922 g_return_if_fail (MODEST_IS_WINDOW(win));
1924 reply_forward (ACTION_FORWARD, win);
1928 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1930 g_return_if_fail (MODEST_IS_WINDOW(win));
1932 reply_forward (ACTION_REPLY_TO_ALL, win);
1936 modest_ui_actions_on_next (GtkAction *action,
1937 ModestWindow *window)
1939 if (MODEST_IS_MAIN_WINDOW (window)) {
1940 GtkWidget *header_view;
1942 header_view = modest_main_window_get_child_widget (
1943 MODEST_MAIN_WINDOW(window),
1944 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1948 modest_header_view_select_next (
1949 MODEST_HEADER_VIEW(header_view));
1950 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1951 modest_msg_view_window_select_next_message (
1952 MODEST_MSG_VIEW_WINDOW (window));
1954 g_return_if_reached ();
1959 modest_ui_actions_on_prev (GtkAction *action,
1960 ModestWindow *window)
1962 g_return_if_fail (MODEST_IS_WINDOW(window));
1964 if (MODEST_IS_MAIN_WINDOW (window)) {
1965 GtkWidget *header_view;
1966 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1967 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1971 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1972 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1973 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1975 g_return_if_reached ();
1980 modest_ui_actions_on_sort (GtkAction *action,
1981 ModestWindow *window)
1983 GtkWidget *header_view = NULL;
1985 g_return_if_fail (MODEST_IS_WINDOW(window));
1987 if (MODEST_IS_MAIN_WINDOW (window)) {
1988 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1989 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1990 #ifdef MODEST_TOOLKIT_HILDON2
1991 } else if (MODEST_IS_HEADER_WINDOW (window)) {
1992 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
1997 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
2002 /* Show sorting dialog */
2003 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
2007 new_messages_arrived (ModestMailOperation *self,
2008 TnyList *new_headers,
2012 gboolean show_visual_notifications;
2014 source = modest_mail_operation_get_source (self);
2015 show_visual_notifications = (source) ? FALSE : TRUE;
2017 g_object_unref (source);
2019 /* Notify new messages have been downloaded. If the
2020 send&receive was invoked by the user then do not show any
2021 visual notification, only play a sound and activate the LED
2022 (for the Maemo version) */
2023 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0)
2024 modest_platform_on_new_headers_received (new_headers,
2025 show_visual_notifications);
2030 retrieve_all_messages_cb (GObject *source,
2032 guint retrieve_limit)
2038 window = GTK_WINDOW (source);
2039 msg = g_strdup_printf (_("mail_nc_msg_count_limit_exceeded"),
2040 num_msgs, retrieve_limit);
2042 /* Ask the user if they want to retrieve all the messages */
2044 modest_platform_run_confirmation_dialog_with_buttons (window, msg,
2045 _("mcen_bd_get_all"),
2046 _("mcen_bd_newest_only"));
2047 /* Free and return */
2049 return (response == GTK_RESPONSE_ACCEPT) ? TRUE : FALSE;
2053 TnyAccount *account;
2055 gchar *account_name;
2056 gboolean poke_status;
2057 gboolean interactive;
2058 ModestMailOperation *mail_op;
2062 do_send_receive_performer (gboolean canceled,
2064 GtkWindow *parent_window,
2065 TnyAccount *account,
2068 SendReceiveInfo *info;
2070 info = (SendReceiveInfo *) user_data;
2072 if (err || canceled) {
2073 /* In memory full conditions we could get this error here */
2074 check_memory_full_error ((GtkWidget *) parent_window, err);
2076 if (info->mail_op) {
2077 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2083 /* Set send/receive operation in progress */
2084 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2085 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2088 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2089 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2090 G_CALLBACK (on_send_receive_finished),
2093 /* Send & receive. */
2094 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2095 (info->win) ? retrieve_all_messages_cb : NULL,
2096 new_messages_arrived, info->win);
2101 g_object_unref (G_OBJECT (info->mail_op));
2102 if (info->account_name)
2103 g_free (info->account_name);
2105 g_object_unref (info->win);
2107 g_object_unref (info->account);
2108 g_slice_free (SendReceiveInfo, info);
2112 * This function performs the send & receive required actions. The
2113 * window is used to create the mail operation. Typically it should
2114 * always be the main window, but we pass it as argument in order to
2118 modest_ui_actions_do_send_receive (const gchar *account_name,
2119 gboolean force_connection,
2120 gboolean poke_status,
2121 gboolean interactive,
2124 gchar *acc_name = NULL;
2125 SendReceiveInfo *info;
2126 ModestTnyAccountStore *acc_store;
2128 /* If no account name was provided then get the current account, and if
2129 there is no current account then pick the default one: */
2130 if (!account_name) {
2132 acc_name = g_strdup (modest_window_get_active_account (win));
2134 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2136 g_printerr ("modest: cannot get default account\n");
2140 acc_name = g_strdup (account_name);
2143 acc_store = modest_runtime_get_account_store ();
2145 /* Create the info for the connect and perform */
2146 info = g_slice_new (SendReceiveInfo);
2147 info->account_name = acc_name;
2148 info->win = (win) ? g_object_ref (win) : NULL;
2149 info->poke_status = poke_status;
2150 info->interactive = interactive;
2151 info->account = modest_tny_account_store_get_server_account (acc_store, acc_name,
2152 TNY_ACCOUNT_TYPE_STORE);
2153 /* We need to create the operation here, because otherwise it
2154 could happen that the queue emits the queue-empty signal
2155 while we're trying to connect the account */
2156 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2157 modest_ui_actions_disk_operations_error_handler,
2159 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2161 /* Invoke the connect and perform */
2162 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2163 force_connection, info->account,
2164 do_send_receive_performer, info);
2169 modest_ui_actions_do_cancel_send (const gchar *account_name,
2172 TnyTransportAccount *transport_account;
2173 TnySendQueue *send_queue = NULL;
2174 GError *error = NULL;
2176 /* Get transport account */
2178 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2179 (modest_runtime_get_account_store(),
2181 TNY_ACCOUNT_TYPE_TRANSPORT));
2182 if (!transport_account) {
2183 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2188 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2189 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2190 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2191 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2192 "modest: could not find send queue for account\n");
2194 /* Cancel the current send */
2195 tny_account_cancel (TNY_ACCOUNT (transport_account));
2197 /* Suspend all pending messages */
2198 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2202 if (transport_account != NULL)
2203 g_object_unref (G_OBJECT (transport_account));
2207 modest_ui_actions_cancel_send_all (ModestWindow *win)
2209 GSList *account_names, *iter;
2211 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2214 iter = account_names;
2216 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2217 iter = g_slist_next (iter);
2220 modest_account_mgr_free_account_names (account_names);
2221 account_names = NULL;
2225 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2228 /* Check if accounts exist */
2229 gboolean accounts_exist =
2230 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2232 /* If not, allow the user to create an account before trying to send/receive. */
2233 if (!accounts_exist)
2234 modest_ui_actions_on_accounts (NULL, win);
2236 /* Cancel all sending operaitons */
2237 modest_ui_actions_cancel_send_all (win);
2241 * Refreshes all accounts. This function will be used by automatic
2245 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2246 gboolean force_connection,
2247 gboolean poke_status,
2248 gboolean interactive)
2250 GSList *account_names, *iter;
2252 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2255 iter = account_names;
2257 modest_ui_actions_do_send_receive ((const char*) iter->data,
2259 poke_status, interactive, win);
2260 iter = g_slist_next (iter);
2263 modest_account_mgr_free_account_names (account_names);
2264 account_names = NULL;
2268 * Handler of the click on Send&Receive button in the main toolbar
2271 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2273 /* Check if accounts exist */
2274 gboolean accounts_exist;
2277 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2279 /* If not, allow the user to create an account before trying to send/receive. */
2280 if (!accounts_exist)
2281 modest_ui_actions_on_accounts (NULL, win);
2283 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2284 if (MODEST_IS_MAIN_WINDOW (win)) {
2285 GtkWidget *folder_view;
2286 TnyFolderStore *folder_store;
2289 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2290 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2294 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2297 g_object_unref (folder_store);
2298 /* Refresh the active account. Force the connection if needed
2299 and poke the status of all folders */
2300 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2301 #ifdef MODEST_TOOLKIT_HILDON2
2302 } else if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2303 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2306 const gchar *active_account;
2307 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2309 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2316 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2319 GtkWidget *header_view;
2321 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2323 header_view = modest_main_window_get_child_widget (main_window,
2324 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2328 conf = modest_runtime_get_conf ();
2330 /* what is saved/restored is depending on the style; thus; we save with
2331 * old style, then update the style, and restore for this new style
2333 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2335 if (modest_header_view_get_style
2336 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2337 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2338 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2340 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2341 MODEST_HEADER_VIEW_STYLE_DETAILS);
2343 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2344 MODEST_CONF_HEADER_VIEW_KEY);
2349 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2351 ModestMainWindow *main_window)
2353 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2354 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2356 /* in the case the folder is empty, show the empty folder message and focus
2358 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2359 if (modest_header_view_is_empty (header_view)) {
2360 TnyFolder *folder = modest_header_view_get_folder (header_view);
2361 GtkWidget *folder_view =
2362 modest_main_window_get_child_widget (main_window,
2363 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2364 if (folder != NULL) {
2365 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2366 g_object_unref (folder);
2368 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2372 /* If no header has been selected then exit */
2377 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2378 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2380 /* Update toolbar dimming state */
2381 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2382 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2386 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2389 ModestWindow *window)
2391 GtkWidget *open_widget;
2392 GtkTreeRowReference *rowref;
2394 g_return_if_fail (MODEST_IS_WINDOW(window));
2395 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2396 g_return_if_fail (TNY_IS_HEADER (header));
2398 if (modest_header_view_count_selected_headers (header_view) > 1) {
2399 /* Don't allow activation if there are more than one message selected */
2400 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2404 /* we check for low-mem; in that case, show a warning, and don't allow
2405 * activating headers
2407 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2410 if (MODEST_IS_MAIN_WINDOW (window)) {
2411 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2412 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2413 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2417 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2418 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2419 gtk_tree_row_reference_free (rowref);
2423 set_active_account_from_tny_account (TnyAccount *account,
2424 ModestWindow *window)
2426 const gchar *server_acc_name = tny_account_get_id (account);
2428 /* We need the TnyAccount provided by the
2429 account store because that is the one that
2430 knows the name of the Modest account */
2431 TnyAccount *modest_server_account = modest_server_account =
2432 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2433 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2435 if (!modest_server_account) {
2436 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2440 /* Update active account, but only if it's not a pseudo-account */
2441 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2442 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2443 const gchar *modest_acc_name =
2444 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2445 if (modest_acc_name)
2446 modest_window_set_active_account (window, modest_acc_name);
2449 g_object_unref (modest_server_account);
2454 folder_refreshed_cb (ModestMailOperation *mail_op,
2458 ModestMainWindow *win = NULL;
2459 GtkWidget *folder_view;
2460 const GError *error;
2462 g_return_if_fail (TNY_IS_FOLDER (folder));
2464 win = MODEST_MAIN_WINDOW (user_data);
2466 /* Check if the operation failed due to memory low conditions */
2467 error = modest_mail_operation_get_error (mail_op);
2468 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2469 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2470 modest_platform_run_information_dialog (GTK_WINDOW (win),
2471 dgettext("ke-recv","memr_ib_operation_disabled"),
2477 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2480 TnyFolderStore *current_folder;
2482 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2483 if (current_folder) {
2484 gboolean different = ((TnyFolderStore *) folder != current_folder);
2485 g_object_unref (current_folder);
2491 /* Check if folder is empty and set headers view contents style */
2492 if (tny_folder_get_all_count (folder) == 0)
2493 modest_main_window_set_contents_style (win,
2494 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2499 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2500 TnyFolderStore *folder_store,
2502 ModestMainWindow *main_window)
2505 GtkWidget *header_view;
2507 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2509 header_view = modest_main_window_get_child_widget(main_window,
2510 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2514 conf = modest_runtime_get_conf ();
2516 if (TNY_IS_ACCOUNT (folder_store)) {
2518 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2520 /* Show account details */
2521 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2524 if (TNY_IS_FOLDER (folder_store) && selected) {
2525 TnyAccount *account;
2526 const gchar *account_name = NULL;
2528 /* Update the active account */
2529 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2531 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2533 modest_tny_account_get_parent_modest_account_name_for_server_account (account);
2534 g_object_unref (account);
2538 /* Set the header style by default, it could
2539 be changed later by the refresh callback to
2541 modest_main_window_set_contents_style (main_window,
2542 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2544 /* Set folder on header view. This function
2545 will call tny_folder_refresh_async so we
2546 pass a callback that will be called when
2547 finished. We use that callback to set the
2548 empty view if there are no messages */
2549 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2550 TNY_FOLDER (folder_store),
2552 MODEST_WINDOW (main_window),
2553 folder_refreshed_cb,
2556 /* Restore configuration. We need to do this
2557 *after* the set_folder because the widget
2558 memory asks the header view about its
2560 modest_widget_memory_restore (modest_runtime_get_conf (),
2561 G_OBJECT(header_view),
2562 MODEST_CONF_HEADER_VIEW_KEY);
2564 /* No need to save the header view
2565 configuration for Maemo because it only
2566 saves the sorting stuff and that it's
2567 already being done by the sort
2568 dialog. Remove it when the GNOME version
2569 has the same behaviour */
2570 #ifdef MODEST_TOOLKIT_GTK
2571 if (modest_main_window_get_contents_style (main_window) ==
2572 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2573 modest_widget_memory_save (conf, G_OBJECT (header_view),
2574 MODEST_CONF_HEADER_VIEW_KEY);
2576 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2580 /* Update dimming state */
2581 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2582 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2586 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2593 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2595 online = tny_device_is_online (modest_runtime_get_device());
2598 /* already online -- the item is simply not there... */
2599 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2601 GTK_MESSAGE_WARNING,
2603 _("The %s you selected cannot be found"),
2605 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2606 gtk_dialog_run (GTK_DIALOG(dialog));
2608 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2611 _("mcen_bd_dialog_cancel"),
2612 GTK_RESPONSE_REJECT,
2613 _("mcen_bd_dialog_ok"),
2614 GTK_RESPONSE_ACCEPT,
2616 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2617 "Do you want to get online?"), item);
2618 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2619 gtk_label_new (txt), FALSE, FALSE, 0);
2620 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2623 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2624 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2625 /* TODO: Comment about why is this commented out: */
2626 /* modest_platform_connect_and_wait (); */
2629 gtk_widget_destroy (dialog);
2633 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2636 /* g_message ("%s %s", __FUNCTION__, link); */
2641 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2644 modest_platform_activate_uri (link);
2648 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2651 modest_platform_show_uri_popup (link);
2655 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2658 /* we check for low-mem; in that case, show a warning, and don't allow
2659 * viewing attachments
2661 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2664 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2668 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2669 const gchar *address,
2672 /* g_message ("%s %s", __FUNCTION__, address); */
2676 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2677 TnyMsg *saved_draft,
2680 ModestMsgEditWindow *edit_window;
2682 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2683 #ifndef MODEST_TOOLKIT_HILDON2
2684 ModestMainWindow *win;
2686 /* FIXME. Make the header view sensitive again. This is a
2687 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2689 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2690 modest_runtime_get_window_mgr(), FALSE));
2692 GtkWidget *hdrview = modest_main_window_get_child_widget(
2693 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2694 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2698 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2700 /* Set draft is there was no error */
2701 if (!modest_mail_operation_get_error (mail_op))
2702 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2704 g_object_unref(edit_window);
2708 enough_space_for_message (ModestMsgEditWindow *edit_window,
2711 TnyAccountStore *acc_store;
2712 guint64 available_disk, expected_size;
2717 acc_store = TNY_ACCOUNT_STORE (modest_runtime_get_account_store());
2718 available_disk = modest_utils_get_available_space (NULL);
2719 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2720 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2725 /* Double check: memory full condition or message too big */
2726 if (available_disk < MIN_FREE_SPACE ||
2727 expected_size > available_disk) {
2729 modest_platform_information_banner (NULL, NULL,
2731 "cerm_device_memory_full"));
2736 * djcb: if we're in low-memory state, we only allow for
2737 * saving messages smaller than
2738 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2739 * should still allow for sending anything critical...
2741 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2742 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2746 * djcb: we also make sure that the attachments are smaller than the max size
2747 * this is for the case where we'd try to forward a message with attachments
2748 * bigger than our max allowed size, or sending an message from drafts which
2749 * somehow got past our checks when attaching.
2751 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2752 modest_platform_run_information_dialog (
2753 GTK_WINDOW(edit_window),
2754 dgettext("ke-recv","memr_ib_operation_disabled"),
2763 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2765 TnyTransportAccount *transport_account;
2766 ModestMailOperation *mail_operation;
2768 gchar *account_name, *from;
2769 ModestAccountMgr *account_mgr;
2770 gboolean had_error = FALSE;
2771 ModestMainWindow *win = NULL;
2773 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2775 data = modest_msg_edit_window_get_msg_data (edit_window);
2778 if (!enough_space_for_message (edit_window, data)) {
2779 modest_msg_edit_window_free_msg_data (edit_window, data);
2783 account_name = g_strdup (data->account_name);
2784 account_mgr = modest_runtime_get_account_mgr();
2786 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2788 account_name = modest_account_mgr_get_default_account (account_mgr);
2789 if (!account_name) {
2790 g_printerr ("modest: no account found\n");
2791 modest_msg_edit_window_free_msg_data (edit_window, data);
2795 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2796 account_name = g_strdup (data->account_name);
2800 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2801 (modest_runtime_get_account_store (),
2803 TNY_ACCOUNT_TYPE_TRANSPORT));
2804 if (!transport_account) {
2805 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2806 g_free (account_name);
2807 modest_msg_edit_window_free_msg_data (edit_window, data);
2810 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2812 /* Create the mail operation */
2813 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
2815 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2817 modest_mail_operation_save_to_drafts (mail_operation,
2829 data->priority_flags,
2830 on_save_to_drafts_cb,
2831 g_object_ref(edit_window));
2833 #ifdef MODEST_TOOLKIT_HILDON2
2834 /* In hildon2 we always show the information banner on saving to drafts.
2835 * It will be a system information banner in this case.
2837 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2838 modest_platform_information_banner (NULL, NULL, text);
2841 /* Use the main window as the parent of the banner, if the
2842 main window does not exist it won't be shown, if the parent
2843 window exists then it's properly shown. We don't use the
2844 editor window because it could be closed (save to drafts
2845 could happen after closing the window */
2846 win = (ModestMainWindow *)
2847 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
2849 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2850 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
2854 modest_msg_edit_window_set_modified (edit_window, FALSE);
2858 g_free (account_name);
2859 g_object_unref (G_OBJECT (transport_account));
2860 g_object_unref (G_OBJECT (mail_operation));
2862 modest_msg_edit_window_free_msg_data (edit_window, data);
2865 * If the drafts folder is selected then make the header view
2866 * insensitive while the message is being saved to drafts
2867 * (it'll be sensitive again in on_save_to_drafts_cb()). This
2868 * is not very clean but it avoids letting the drafts folder
2869 * in an inconsistent state: the user could edit the message
2870 * being saved and undesirable things would happen.
2871 * In the average case the user won't notice anything at
2872 * all. In the worst case (the user is editing a really big
2873 * file from Drafts) the header view will be insensitive
2874 * during the saving process (10 or 20 seconds, depending on
2875 * the message). Anyway this is just a quick workaround: once
2876 * we find a better solution it should be removed
2877 * See NB#65125 (commend #18) for details.
2879 if (!had_error && win != NULL) {
2880 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
2881 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
2883 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
2885 if (modest_tny_folder_is_local_folder(folder)) {
2886 TnyFolderType folder_type;
2887 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
2888 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
2889 GtkWidget *hdrview = modest_main_window_get_child_widget(
2890 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2891 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
2895 if (folder != NULL) g_object_unref(folder);
2902 /* For instance, when clicking the Send toolbar button when editing a message: */
2904 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2906 TnyTransportAccount *transport_account = NULL;
2907 gboolean had_error = FALSE;
2909 ModestAccountMgr *account_mgr;
2910 gchar *account_name;
2912 ModestMailOperation *mail_operation;
2914 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
2916 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2919 data = modest_msg_edit_window_get_msg_data (edit_window);
2922 if (!enough_space_for_message (edit_window, data)) {
2923 modest_msg_edit_window_free_msg_data (edit_window, data);
2927 account_mgr = modest_runtime_get_account_mgr();
2928 account_name = g_strdup (data->account_name);
2930 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2933 account_name = modest_account_mgr_get_default_account (account_mgr);
2935 if (!account_name) {
2936 modest_msg_edit_window_free_msg_data (edit_window, data);
2937 /* Run account setup wizard */
2938 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
2943 /* Get the currently-active transport account for this modest account: */
2944 if (strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
2946 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2947 (modest_runtime_get_account_store (),
2948 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
2951 if (!transport_account) {
2952 modest_msg_edit_window_free_msg_data (edit_window, data);
2953 /* Run account setup wizard */
2954 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2959 /* Create the mail operation */
2960 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2961 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
2962 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2964 modest_mail_operation_send_new_mail (mail_operation,
2976 data->priority_flags);
2978 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
2979 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2982 if (modest_mail_operation_get_error (mail_operation) != NULL) {
2983 const GError *error = modest_mail_operation_get_error (mail_operation);
2984 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
2985 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
2986 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
2987 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
2994 g_free (account_name);
2995 g_object_unref (G_OBJECT (transport_account));
2996 g_object_unref (G_OBJECT (mail_operation));
2998 modest_msg_edit_window_free_msg_data (edit_window, data);
3001 modest_msg_edit_window_set_sent (edit_window, TRUE);
3003 /* Save settings and close the window: */
3004 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3011 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3012 ModestMsgEditWindow *window)
3014 ModestMsgEditFormatState *format_state = NULL;
3016 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3017 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3019 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3022 format_state = modest_msg_edit_window_get_format_state (window);
3023 g_return_if_fail (format_state != NULL);
3025 format_state->bold = gtk_toggle_action_get_active (action);
3026 modest_msg_edit_window_set_format_state (window, format_state);
3027 g_free (format_state);
3032 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3033 ModestMsgEditWindow *window)
3035 ModestMsgEditFormatState *format_state = NULL;
3037 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3038 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3040 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3043 format_state = modest_msg_edit_window_get_format_state (window);
3044 g_return_if_fail (format_state != NULL);
3046 format_state->italics = gtk_toggle_action_get_active (action);
3047 modest_msg_edit_window_set_format_state (window, format_state);
3048 g_free (format_state);
3053 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3054 ModestMsgEditWindow *window)
3056 ModestMsgEditFormatState *format_state = NULL;
3058 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3059 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3061 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3064 format_state = modest_msg_edit_window_get_format_state (window);
3065 g_return_if_fail (format_state != NULL);
3067 format_state->bullet = gtk_toggle_action_get_active (action);
3068 modest_msg_edit_window_set_format_state (window, format_state);
3069 g_free (format_state);
3074 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3075 GtkRadioAction *selected,
3076 ModestMsgEditWindow *window)
3078 ModestMsgEditFormatState *format_state = NULL;
3079 GtkJustification value;
3081 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3083 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3086 value = gtk_radio_action_get_current_value (selected);
3088 format_state = modest_msg_edit_window_get_format_state (window);
3089 g_return_if_fail (format_state != NULL);
3091 format_state->justification = value;
3092 modest_msg_edit_window_set_format_state (window, format_state);
3093 g_free (format_state);
3097 modest_ui_actions_on_select_editor_color (GtkAction *action,
3098 ModestMsgEditWindow *window)
3100 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3101 g_return_if_fail (GTK_IS_ACTION (action));
3103 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3106 modest_msg_edit_window_select_color (window);
3110 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3111 ModestMsgEditWindow *window)
3113 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3114 g_return_if_fail (GTK_IS_ACTION (action));
3116 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3119 modest_msg_edit_window_select_background_color (window);
3123 modest_ui_actions_on_insert_image (GtkAction *action,
3124 ModestMsgEditWindow *window)
3126 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3127 g_return_if_fail (GTK_IS_ACTION (action));
3130 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3133 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3136 modest_msg_edit_window_insert_image (window);
3140 modest_ui_actions_on_attach_file (GtkAction *action,
3141 ModestMsgEditWindow *window)
3143 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3144 g_return_if_fail (GTK_IS_ACTION (action));
3146 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3149 modest_msg_edit_window_offer_attach_file (window);
3153 modest_ui_actions_on_remove_attachments (GtkAction *action,
3154 ModestMsgEditWindow *window)
3156 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3157 g_return_if_fail (GTK_IS_ACTION (action));
3159 modest_msg_edit_window_remove_attachments (window, NULL);
3163 #ifndef MODEST_TOOLKIT_GTK
3168 TnyFolderStore *folder;
3169 } CreateFolderHelper;
3172 show_create_folder_in_timeout (gpointer data)
3174 CreateFolderHelper *helper = (CreateFolderHelper *) data;
3176 /* Remove the timeout ASAP, we can not wait until the dialog
3177 is shown because it could take a lot of time and so the
3178 timeout could be called twice or more times */
3179 g_source_remove (helper->handler);
3181 gdk_threads_enter ();
3182 do_create_folder (helper->win, helper->folder, helper->name);
3183 gdk_threads_leave ();
3185 g_object_unref (helper->win);
3186 g_object_unref (helper->folder);
3187 g_free (helper->name);
3188 g_slice_free (CreateFolderHelper, helper);
3195 do_create_folder_cb (ModestMailOperation *mail_op,
3196 TnyFolderStore *parent_folder,
3197 TnyFolder *new_folder,
3200 gchar *suggested_name = (gchar *) user_data;
3201 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3203 if (modest_mail_operation_get_error (mail_op)) {
3205 /* Show an error. If there was some problem writing to
3206 disk, show it, otherwise show the generic folder
3207 create error. We do it here and not in an error
3208 handler because the call to do_create_folder will
3209 stop the main loop in a gtk_dialog_run and then,
3210 the message won't be shown until that dialog is
3212 modest_ui_actions_disk_operations_error_handler (mail_op,
3213 _("mail_in_ui_folder_create_error"));
3215 /* Try again. Do *NOT* show any error because the mail
3216 operations system will do it for us because we
3217 created the mail_op with new_with_error_handler */
3218 #ifndef MODEST_TOOLKIT_GTK
3219 CreateFolderHelper *helper;
3220 helper = g_slice_new0 (CreateFolderHelper);
3221 helper->name = g_strdup (suggested_name);
3222 helper->folder = g_object_ref (parent_folder);
3223 helper->win = g_object_ref (source_win);
3225 /* Ugly but neccesary stuff. The problem is that the
3226 dialog when is shown calls a function that destroys
3227 all the temporary windows, so the banner is
3229 helper->handler = g_timeout_add (2000, show_create_folder_in_timeout, helper);
3231 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3234 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3235 * FIXME: any other? */
3236 GtkWidget *folder_view;
3238 if (MODEST_IS_MAIN_WINDOW(source_win))
3240 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3241 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3243 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3244 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3246 /* Select the newly created folder. It could happen
3247 that the widget is no longer there (i.e. the window
3248 has been destroyed, so we need to check this */
3250 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3252 g_object_unref (new_folder);
3254 /* Free. Note that the first time it'll be NULL so noop */
3255 g_free (suggested_name);
3256 g_object_unref (source_win);
3260 do_create_folder (GtkWindow *parent_window,
3261 TnyFolderStore *parent_folder,
3262 const gchar *suggested_name)
3265 gchar *folder_name = NULL;
3267 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3269 (gchar *) suggested_name,
3272 if (result == GTK_RESPONSE_ACCEPT) {
3273 ModestMailOperation *mail_op;
3275 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3276 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3278 modest_mail_operation_create_folder (mail_op,
3280 (const gchar *) folder_name,
3281 do_create_folder_cb,
3283 g_object_unref (mail_op);
3288 create_folder_performer (gboolean canceled,
3290 GtkWindow *parent_window,
3291 TnyAccount *account,
3294 TnyFolderStore *parent_folder = TNY_FOLDER_STORE (user_data);
3296 if (canceled || err) {
3297 /* In memory full conditions we could get this error here */
3298 check_memory_full_error ((GtkWidget *) parent_window, err);
3302 /* Run the new folder dialog */
3303 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3306 g_object_unref (parent_folder);
3310 modest_ui_actions_create_folder(GtkWidget *parent_window,
3311 GtkWidget *folder_view)
3313 TnyFolderStore *parent_folder;
3315 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3317 if (parent_folder) {
3318 /* The parent folder will be freed in the callback */
3319 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3322 create_folder_performer,
3328 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3331 g_return_if_fail (MODEST_IS_WINDOW(window));
3333 if (MODEST_IS_MAIN_WINDOW (window)) {
3334 GtkWidget *folder_view;
3336 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3337 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3341 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view);
3342 #ifdef MODEST_TOOLKIT_HILDON2
3343 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3344 GtkWidget *folder_view;
3346 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3347 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view);
3350 g_assert_not_reached ();
3355 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3358 const GError *error = NULL;
3359 const gchar *message = NULL;
3361 /* Get error message */
3362 error = modest_mail_operation_get_error (mail_op);
3364 g_return_if_reached ();
3366 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3367 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3368 message = _CS("ckdg_ib_folder_already_exists");
3369 } else if (error->domain == TNY_ERROR_DOMAIN &&
3370 error->code == TNY_SERVICE_ERROR_STATE) {
3371 /* This means that the folder is already in use (a
3372 message is opened for example */
3373 message = _("emev_ni_internal_error");
3375 message = _("emev_ib_ui_imap_unable_to_rename");
3378 /* We don't set a parent for the dialog because the dialog
3379 will be destroyed so the banner won't appear */
3380 modest_platform_information_banner (NULL, NULL, message);
3384 TnyFolderStore *folder;
3389 on_rename_folder_cb (ModestMailOperation *mail_op,
3390 TnyFolder *new_folder,
3393 ModestFolderView *folder_view;
3395 /* If the window was closed when renaming a folder this could
3397 if (!MODEST_IS_FOLDER_VIEW (user_data))
3400 folder_view = MODEST_FOLDER_VIEW (user_data);
3401 /* Note that if the rename fails new_folder will be NULL */
3403 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3405 modest_folder_view_select_first_inbox_or_local (folder_view);
3407 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3411 on_rename_folder_performer (gboolean canceled,
3413 GtkWindow *parent_window,
3414 TnyAccount *account,
3417 ModestMailOperation *mail_op = NULL;
3418 GtkTreeSelection *sel = NULL;
3419 GtkWidget *folder_view = NULL;
3420 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3422 if (canceled || err) {
3423 /* In memory full conditions we could get this error here */
3424 check_memory_full_error ((GtkWidget *) parent_window, err);
3425 } else if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3427 folder_view = modest_main_window_get_child_widget (
3428 MODEST_MAIN_WINDOW (parent_window),
3429 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3432 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3433 modest_ui_actions_rename_folder_error_handler,
3434 parent_window, NULL);
3436 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3439 /* Clear the headers view */
3440 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3441 gtk_tree_selection_unselect_all (sel);
3443 /* Actually rename the folder */
3444 modest_mail_operation_rename_folder (mail_op,
3445 TNY_FOLDER (data->folder),
3446 (const gchar *) (data->new_name),
3447 on_rename_folder_cb,
3449 g_object_unref (data->folder);
3450 g_object_unref (mail_op);
3453 g_free (data->new_name);
3458 modest_ui_actions_on_rename_folder (GtkAction *action,
3459 ModestMainWindow *main_window)
3461 TnyFolderStore *folder;
3462 GtkWidget *folder_view;
3463 GtkWidget *header_view;
3465 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3467 folder_view = modest_main_window_get_child_widget (main_window,
3468 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3472 header_view = modest_main_window_get_child_widget (main_window,
3473 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3478 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3483 if (TNY_IS_FOLDER (folder)) {
3484 gchar *folder_name = NULL;
3486 const gchar *current_name;
3487 TnyFolderStore *parent;
3488 gboolean do_rename = TRUE;
3490 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3491 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3492 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
3493 parent, current_name,
3495 g_object_unref (parent);
3497 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3500 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3501 rename_folder_data->folder = g_object_ref (folder);
3502 rename_folder_data->new_name = folder_name;
3503 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(main_window), TRUE,
3504 folder, on_rename_folder_performer, rename_folder_data);
3507 g_object_unref (folder);
3511 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3514 GObject *win = modest_mail_operation_get_source (mail_op);
3516 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3517 _("mail_in_ui_folder_delete_error"),
3519 g_object_unref (win);
3523 TnyFolderStore *folder;
3524 gboolean move_to_trash;
3528 on_delete_folder_cb (gboolean canceled,
3530 GtkWindow *parent_window,
3531 TnyAccount *account,
3534 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3535 GtkWidget *folder_view;
3536 ModestMailOperation *mail_op;
3537 GtkTreeSelection *sel;
3539 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
3540 g_object_unref (G_OBJECT (info->folder));
3545 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
3546 folder_view = modest_main_window_get_child_widget (
3547 MODEST_MAIN_WINDOW (parent_window),
3548 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3549 #ifdef MODEST_TOOLKIT_HILDON2
3550 } else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3551 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
3555 /* Unselect the folder before deleting it to free the headers */
3556 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3557 gtk_tree_selection_unselect_all (sel);
3559 /* Create the mail operation */
3561 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3562 modest_ui_actions_delete_folder_error_handler,
3565 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3567 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3569 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3571 g_object_unref (G_OBJECT (mail_op));
3572 g_object_unref (G_OBJECT (info->folder));
3577 delete_folder (ModestWindow *window, gboolean move_to_trash)
3579 TnyFolderStore *folder;
3580 GtkWidget *folder_view;
3584 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3586 if (MODEST_IS_MAIN_WINDOW (window)) {
3588 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3589 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3590 #ifdef MODEST_TOOLKIT_HILDON2
3591 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3592 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3598 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3600 /* Show an error if it's an account */
3601 if (!TNY_IS_FOLDER (folder)) {
3602 modest_platform_run_information_dialog (GTK_WINDOW (window),
3603 _("mail_in_ui_folder_delete_error"),
3605 g_object_unref (G_OBJECT (folder));
3610 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3611 tny_folder_get_name (TNY_FOLDER (folder)));
3612 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
3613 (const gchar *) message);
3616 if (response == GTK_RESPONSE_OK) {
3617 DeleteFolderInfo *info;
3618 info = g_new0(DeleteFolderInfo, 1);
3619 info->folder = folder;
3620 info->move_to_trash = move_to_trash;
3621 g_object_ref (G_OBJECT (info->folder));
3622 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder));
3623 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
3625 TNY_FOLDER_STORE (account),
3626 on_delete_folder_cb, info);
3627 g_object_unref (account);
3632 g_object_unref (G_OBJECT (folder));
3636 modest_ui_actions_on_delete_folder (GtkAction *action,
3637 ModestWindow *window)
3639 modest_ui_actions_on_edit_mode_delete_folder (window);
3643 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
3645 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
3647 return delete_folder (window, FALSE);
3651 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3653 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3655 delete_folder (MODEST_WINDOW (main_window), TRUE);
3659 typedef struct _PasswordDialogFields {
3660 GtkWidget *username;
3661 GtkWidget *password;
3663 } PasswordDialogFields;
3666 password_dialog_check_field (GtkEditable *editable,
3667 PasswordDialogFields *fields)
3670 gboolean any_value_empty = FALSE;
3672 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
3673 if ((value == NULL) || value[0] == '\0') {
3674 any_value_empty = TRUE;
3676 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
3677 if ((value == NULL) || value[0] == '\0') {
3678 any_value_empty = TRUE;
3680 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3684 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3685 const gchar* server_account_name,
3690 ModestMainWindow *main_window)
3692 g_return_if_fail(server_account_name);
3693 gboolean completed = FALSE;
3694 PasswordDialogFields *fields = NULL;
3696 /* Initalize output parameters: */
3703 #ifndef MODEST_TOOLKIT_GTK
3704 /* Maemo uses a different (awkward) button order,
3705 * It should probably just use gtk_alternative_dialog_button_order ().
3707 #ifdef MODEST_TOOLKIT_HILDON2
3709 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3712 _HL("wdgt_bd_done"),
3713 GTK_RESPONSE_ACCEPT,
3717 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3720 _("mcen_bd_dialog_ok"),
3721 GTK_RESPONSE_ACCEPT,
3722 _("mcen_bd_dialog_cancel"),
3723 GTK_RESPONSE_REJECT,
3725 #endif /* MODEST_TOOLKIT_HILDON2 */
3728 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3732 GTK_RESPONSE_REJECT,
3734 GTK_RESPONSE_ACCEPT,
3736 #endif /* MODEST_TOOLKIT_GTK */
3738 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3740 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3741 modest_runtime_get_account_mgr(), server_account_name);
3742 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3743 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3746 gtk_widget_destroy (dialog);
3750 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3751 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
3754 g_free (server_name);
3758 gchar *initial_username = modest_account_mgr_get_server_account_username (
3759 modest_runtime_get_account_mgr(), server_account_name);
3761 GtkWidget *entry_username = gtk_entry_new ();
3762 if (initial_username)
3763 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
3764 /* Dim this if a connection has ever succeeded with this username,
3765 * as per the UI spec: */
3766 /* const gboolean username_known = */
3767 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3768 /* modest_runtime_get_account_mgr(), server_account_name); */
3769 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3771 /* We drop the username sensitive code and disallow changing it here
3772 * as tinymail does not support really changing the username in the callback
3774 gtk_widget_set_sensitive (entry_username, FALSE);
3776 #ifndef MODEST_TOOLKIT_GTK
3777 /* Auto-capitalization is the default, so let's turn it off: */
3778 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3780 /* Create a size group to be used by all captions.
3781 * Note that HildonCaption does not create a default size group if we do not specify one.
3782 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3783 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3785 GtkWidget *caption = hildon_caption_new (sizegroup,
3786 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
3787 gtk_widget_show (entry_username);
3788 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3789 FALSE, FALSE, MODEST_MARGIN_HALF);
3790 gtk_widget_show (caption);
3792 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
3794 #endif /* !MODEST_TOOLKIT_GTK */
3797 GtkWidget *entry_password = gtk_entry_new ();
3798 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3799 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3801 #ifndef MODEST_TOOLKIT_GTK
3802 /* Auto-capitalization is the default, so let's turn it off: */
3803 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3804 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3806 caption = hildon_caption_new (sizegroup,
3807 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
3808 gtk_widget_show (entry_password);
3809 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3810 FALSE, FALSE, MODEST_MARGIN_HALF);
3811 gtk_widget_show (caption);
3812 g_object_unref (sizegroup);
3814 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
3816 #endif /* !MODEST_TOOLKIT_GTK */
3818 if (initial_username != NULL)
3819 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3821 /* This is not in the Maemo UI spec:
3822 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3823 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3827 fields = g_slice_new0 (PasswordDialogFields);
3828 fields->username = entry_username;
3829 fields->password = entry_password;
3830 fields->dialog = dialog;
3832 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3833 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3834 password_dialog_check_field (NULL, fields);
3836 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3838 while (!completed) {
3840 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3842 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
3844 /* Note that an empty field becomes the "" string */
3845 if (*username && strlen (*username) > 0) {
3846 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
3847 server_account_name,
3851 const gboolean username_was_changed =
3852 (strcmp (*username, initial_username) != 0);
3853 if (username_was_changed) {
3854 g_warning ("%s: tinymail does not yet support changing the "
3855 "username in the get_password() callback.\n", __FUNCTION__);
3861 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
3862 _("mcen_ib_username_pw_incorrect"));
3868 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
3870 /* We do not save the password in the configuration,
3871 * because this function is only called for passwords that should
3872 * not be remembered:
3873 modest_server_account_set_password (
3874 modest_runtime_get_account_mgr(), server_account_name,
3881 #ifndef MODEST_TOOLKIT_HILDON2
3882 /* Set parent to NULL or the banner will disappear with its parent dialog */
3883 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
3895 /* This is not in the Maemo UI spec:
3896 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3902 g_free (initial_username);
3903 gtk_widget_destroy (dialog);
3904 g_slice_free (PasswordDialogFields, fields);
3906 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3910 modest_ui_actions_on_cut (GtkAction *action,
3911 ModestWindow *window)
3913 GtkWidget *focused_widget;
3914 GtkClipboard *clipboard;
3916 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3917 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3918 if (GTK_IS_EDITABLE (focused_widget)) {
3919 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3920 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3921 gtk_clipboard_store (clipboard);
3922 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3923 GtkTextBuffer *buffer;
3925 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3926 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3927 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3928 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3929 gtk_clipboard_store (clipboard);
3931 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3932 TnyList *header_list = modest_header_view_get_selected_headers (
3933 MODEST_HEADER_VIEW (focused_widget));
3934 gboolean continue_download = FALSE;
3935 gint num_of_unc_msgs;
3937 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3939 if (num_of_unc_msgs) {
3940 TnyAccount *account = get_account_from_header_list (header_list);
3942 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3943 g_object_unref (account);
3947 if (num_of_unc_msgs == 0 || continue_download) {
3948 /* modest_platform_information_banner (
3949 NULL, NULL, _CS("mcen_ib_getting_items"));*/
3950 modest_header_view_cut_selection (
3951 MODEST_HEADER_VIEW (focused_widget));
3954 g_object_unref (header_list);
3955 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3956 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3961 modest_ui_actions_on_copy (GtkAction *action,
3962 ModestWindow *window)
3964 GtkClipboard *clipboard;
3965 GtkWidget *focused_widget;
3966 gboolean copied = TRUE;
3968 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3969 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3971 if (GTK_IS_LABEL (focused_widget)) {
3973 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
3974 gtk_clipboard_set_text (clipboard, selection, -1);
3976 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3977 gtk_clipboard_store (clipboard);
3978 } else if (GTK_IS_EDITABLE (focused_widget)) {
3979 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3980 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3981 gtk_clipboard_store (clipboard);
3982 } else if (GTK_IS_HTML (focused_widget)) {
3985 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
3986 if ((sel == NULL) || (sel[0] == '\0')) {
3989 gtk_html_copy (GTK_HTML (focused_widget));
3990 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3991 gtk_clipboard_store (clipboard);
3993 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3994 GtkTextBuffer *buffer;
3995 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3996 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3997 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3998 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3999 gtk_clipboard_store (clipboard);
4001 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4002 TnyList *header_list = modest_header_view_get_selected_headers (
4003 MODEST_HEADER_VIEW (focused_widget));
4004 gboolean continue_download = FALSE;
4005 gint num_of_unc_msgs;
4007 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4009 if (num_of_unc_msgs) {
4010 TnyAccount *account = get_account_from_header_list (header_list);
4012 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4013 g_object_unref (account);
4017 if (num_of_unc_msgs == 0 || continue_download) {
4018 modest_platform_information_banner (
4019 NULL, NULL, _CS("mcen_ib_getting_items"));
4020 modest_header_view_copy_selection (
4021 MODEST_HEADER_VIEW (focused_widget));
4025 g_object_unref (header_list);
4027 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4028 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4031 /* Show information banner if there was a copy to clipboard */
4033 modest_platform_information_banner (
4034 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4038 modest_ui_actions_on_undo (GtkAction *action,
4039 ModestWindow *window)
4041 ModestEmailClipboard *clipboard = NULL;
4043 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4044 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4045 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4046 /* Clear clipboard source */
4047 clipboard = modest_runtime_get_email_clipboard ();
4048 modest_email_clipboard_clear (clipboard);
4051 g_return_if_reached ();
4056 modest_ui_actions_on_redo (GtkAction *action,
4057 ModestWindow *window)
4059 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4060 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4063 g_return_if_reached ();
4069 destroy_information_note (ModestMailOperation *mail_op,
4072 /* destroy information note */
4073 gtk_widget_destroy (GTK_WIDGET(user_data));
4077 destroy_folder_information_note (ModestMailOperation *mail_op,
4078 TnyFolder *new_folder,
4081 /* destroy information note */
4082 gtk_widget_destroy (GTK_WIDGET(user_data));
4087 paste_as_attachment_free (gpointer data)
4089 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4091 if (helper->banner) {
4092 gtk_widget_destroy (helper->banner);
4093 g_object_unref (helper->banner);
4099 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4104 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4105 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4110 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4115 modest_ui_actions_on_paste (GtkAction *action,
4116 ModestWindow *window)
4118 GtkWidget *focused_widget = NULL;
4119 GtkWidget *inf_note = NULL;
4120 ModestMailOperation *mail_op = NULL;
4122 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4123 if (GTK_IS_EDITABLE (focused_widget)) {
4124 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4125 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4126 ModestEmailClipboard *e_clipboard = NULL;
4127 e_clipboard = modest_runtime_get_email_clipboard ();
4128 if (modest_email_clipboard_cleared (e_clipboard)) {
4129 GtkTextBuffer *buffer;
4130 GtkClipboard *clipboard;
4132 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4133 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4134 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4135 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4136 ModestMailOperation *mail_op;
4137 TnyFolder *src_folder = NULL;
4138 TnyList *data = NULL;
4140 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4141 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4142 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4143 _CS("ckct_nw_pasting"));
4144 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4145 mail_op = modest_mail_operation_new (G_OBJECT (window));
4146 if (helper->banner != NULL) {
4147 g_object_ref (G_OBJECT (helper->banner));
4148 gtk_widget_show (GTK_WIDGET (helper->banner));
4152 modest_mail_operation_get_msgs_full (mail_op,
4154 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4156 paste_as_attachment_free);
4160 g_object_unref (data);
4162 g_object_unref (src_folder);
4165 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4166 ModestEmailClipboard *clipboard = NULL;
4167 TnyFolder *src_folder = NULL;
4168 TnyFolderStore *folder_store = NULL;
4169 TnyList *data = NULL;
4170 gboolean delete = FALSE;
4172 /* Check clipboard source */
4173 clipboard = modest_runtime_get_email_clipboard ();
4174 if (modest_email_clipboard_cleared (clipboard))
4177 /* Get elements to paste */
4178 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4180 /* Create a new mail operation */
4181 mail_op = modest_mail_operation_new (G_OBJECT(window));
4183 /* Get destination folder */
4184 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4186 /* transfer messages */
4190 /* Ask for user confirmation */
4192 modest_ui_actions_msgs_move_to_confirmation (window,
4193 TNY_FOLDER (folder_store),
4197 if (response == GTK_RESPONSE_OK) {
4198 /* Launch notification */
4199 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4200 _CS("ckct_nw_pasting"));
4201 if (inf_note != NULL) {
4202 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4203 gtk_widget_show (GTK_WIDGET(inf_note));
4206 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4207 modest_mail_operation_xfer_msgs (mail_op,
4209 TNY_FOLDER (folder_store),
4211 destroy_information_note,
4214 g_object_unref (mail_op);
4217 } else if (src_folder != NULL) {
4218 /* Launch notification */
4219 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4220 _CS("ckct_nw_pasting"));
4221 if (inf_note != NULL) {
4222 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4223 gtk_widget_show (GTK_WIDGET(inf_note));
4226 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4227 modest_mail_operation_xfer_folder (mail_op,
4231 destroy_folder_information_note,
4237 g_object_unref (data);
4238 if (src_folder != NULL)
4239 g_object_unref (src_folder);
4240 if (folder_store != NULL)
4241 g_object_unref (folder_store);
4247 modest_ui_actions_on_select_all (GtkAction *action,
4248 ModestWindow *window)
4250 GtkWidget *focused_widget;
4252 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4253 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4254 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4255 } else if (GTK_IS_LABEL (focused_widget)) {
4256 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4257 } else if (GTK_IS_EDITABLE (focused_widget)) {
4258 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4259 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4260 GtkTextBuffer *buffer;
4261 GtkTextIter start, end;
4263 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4264 gtk_text_buffer_get_start_iter (buffer, &start);
4265 gtk_text_buffer_get_end_iter (buffer, &end);
4266 gtk_text_buffer_select_range (buffer, &start, &end);
4267 } else if (GTK_IS_HTML (focused_widget)) {
4268 gtk_html_select_all (GTK_HTML (focused_widget));
4269 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4270 GtkWidget *header_view = focused_widget;
4271 GtkTreeSelection *selection = NULL;
4273 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4274 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4275 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4278 /* Disable window dimming management */
4279 modest_window_disable_dimming (MODEST_WINDOW(window));
4281 /* Select all messages */
4282 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4283 gtk_tree_selection_select_all (selection);
4285 /* Set focuse on header view */
4286 gtk_widget_grab_focus (header_view);
4288 /* Enable window dimming management */
4289 modest_window_enable_dimming (MODEST_WINDOW(window));
4290 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4291 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4297 modest_ui_actions_on_mark_as_read (GtkAction *action,
4298 ModestWindow *window)
4300 g_return_if_fail (MODEST_IS_WINDOW(window));
4302 /* Mark each header as read */
4303 do_headers_action (window, headers_action_mark_as_read, NULL);
4307 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4308 ModestWindow *window)
4310 g_return_if_fail (MODEST_IS_WINDOW(window));
4312 /* Mark each header as read */
4313 do_headers_action (window, headers_action_mark_as_unread, NULL);
4317 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4318 GtkRadioAction *selected,
4319 ModestWindow *window)
4323 value = gtk_radio_action_get_current_value (selected);
4324 if (MODEST_IS_WINDOW (window)) {
4325 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4330 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4331 GtkRadioAction *selected,
4332 ModestWindow *window)
4334 TnyHeaderFlags flags;
4335 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4337 flags = gtk_radio_action_get_current_value (selected);
4338 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4342 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4343 GtkRadioAction *selected,
4344 ModestWindow *window)
4348 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4350 file_format = gtk_radio_action_get_current_value (selected);
4351 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4356 modest_ui_actions_on_zoom_plus (GtkAction *action,
4357 ModestWindow *window)
4359 g_return_if_fail (MODEST_IS_WINDOW (window));
4361 modest_window_zoom_plus (MODEST_WINDOW (window));
4365 modest_ui_actions_on_zoom_minus (GtkAction *action,
4366 ModestWindow *window)
4368 g_return_if_fail (MODEST_IS_WINDOW (window));
4370 modest_window_zoom_minus (MODEST_WINDOW (window));
4374 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4375 ModestWindow *window)
4377 ModestWindowMgr *mgr;
4378 gboolean fullscreen, active;
4379 g_return_if_fail (MODEST_IS_WINDOW (window));
4381 mgr = modest_runtime_get_window_mgr ();
4383 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4384 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4386 if (active != fullscreen) {
4387 modest_window_mgr_set_fullscreen_mode (mgr, active);
4388 #ifndef MODEST_TOOLKIT_HILDON2
4389 gtk_window_present (GTK_WINDOW (window));
4395 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4396 ModestWindow *window)
4398 ModestWindowMgr *mgr;
4399 gboolean fullscreen;
4401 g_return_if_fail (MODEST_IS_WINDOW (window));
4403 mgr = modest_runtime_get_window_mgr ();
4404 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4405 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4407 #ifndef MODEST_TOOLKIT_HILDON2
4408 gtk_window_present (GTK_WINDOW (window));
4413 * Used by modest_ui_actions_on_details to call do_headers_action
4416 headers_action_show_details (TnyHeader *header,
4417 ModestWindow *window,
4421 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header);
4425 * Show the header details in a ModestDetailsDialog widget
4428 modest_ui_actions_on_details (GtkAction *action,
4431 TnyList * headers_list;
4435 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4438 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4441 g_object_unref (msg);
4443 headers_list = get_selected_headers (win);
4447 iter = tny_list_create_iterator (headers_list);
4449 header = TNY_HEADER (tny_iterator_get_current (iter));
4451 headers_action_show_details (header, win, NULL);
4452 g_object_unref (header);
4455 g_object_unref (iter);
4456 g_object_unref (headers_list);
4458 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4459 GtkWidget *folder_view, *header_view;
4461 /* Check which widget has the focus */
4462 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4463 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4464 if (gtk_widget_is_focus (folder_view)) {
4465 TnyFolderStore *folder_store
4466 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4467 if (!folder_store) {
4468 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4471 /* Show only when it's a folder */
4472 /* This function should not be called for account items,
4473 * because we dim the menu item for them. */
4474 if (TNY_IS_FOLDER (folder_store)) {
4475 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4476 TNY_FOLDER (folder_store));
4479 g_object_unref (folder_store);
4482 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4483 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4484 /* Show details of each header */
4485 do_headers_action (win, headers_action_show_details, header_view);
4487 #ifdef MODEST_TOOLKIT_HILDON2
4488 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4490 GtkWidget *header_view;
4492 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4493 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4495 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4497 g_object_unref (folder);
4504 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4505 ModestMsgEditWindow *window)
4507 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4509 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4513 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4514 ModestMsgEditWindow *window)
4516 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4518 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4522 modest_ui_actions_toggle_folders_view (GtkAction *action,
4523 ModestMainWindow *main_window)
4525 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4527 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4528 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4530 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4534 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4535 ModestWindow *window)
4537 gboolean active, fullscreen = FALSE;
4538 ModestWindowMgr *mgr;
4540 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4542 /* Check if we want to toggle the toolbar view in fullscreen
4544 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4545 "ViewShowToolbarFullScreen")) {
4549 /* Toggle toolbar */
4550 mgr = modest_runtime_get_window_mgr ();
4551 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4555 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4556 ModestMsgEditWindow *window)
4558 modest_msg_edit_window_select_font (window);
4563 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4564 const gchar *display_name,
4567 /* don't update the display name if it was already set;
4568 * updating the display name apparently is expensive */
4569 const gchar* old_name = gtk_window_get_title (window);
4571 if (display_name == NULL)
4574 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4575 return; /* don't do anything */
4577 /* This is usually used to change the title of the main window, which
4578 * is the one that holds the folder view. Note that this change can
4579 * happen even when the widget doesn't have the focus. */
4580 gtk_window_set_title (window, display_name);
4585 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4587 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4588 modest_msg_edit_window_select_contacts (window);
4592 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4594 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4595 modest_msg_edit_window_check_names (window, FALSE);
4598 #ifndef MODEST_TOOLKIT_HILDON2
4600 * This function is used to track changes in the selection of the
4601 * folder view that is inside the "move to" dialog to enable/disable
4602 * the OK button because we do not want the user to select a disallowed
4603 * destination for a folder.
4604 * The user also not desired to be able to use NEW button on items where
4605 * folder creation is not possibel.
4608 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4609 TnyFolderStore *folder_store,
4613 GtkWidget *dialog = NULL;
4614 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4615 gboolean moving_folder = FALSE;
4616 gboolean is_local_account = TRUE;
4617 GtkWidget *folder_view = NULL;
4618 ModestTnyFolderRules rules;
4620 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
4625 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
4629 /* check if folder_store is an remote account */
4630 if (TNY_IS_ACCOUNT (folder_store)) {
4631 TnyAccount *local_account = NULL;
4632 TnyAccount *mmc_account = NULL;
4633 ModestTnyAccountStore *account_store = NULL;
4635 account_store = modest_runtime_get_account_store ();
4636 local_account = modest_tny_account_store_get_local_folders_account (account_store);
4637 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
4639 if ((gpointer) local_account != (gpointer) folder_store &&
4640 (gpointer) mmc_account != (gpointer) folder_store) {
4641 ModestProtocolType proto;
4642 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
4643 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
4644 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
4646 is_local_account = FALSE;
4647 /* New button should be dimmed on remote
4649 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4651 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
4653 g_object_unref (local_account);
4655 /* It could not exist */
4657 g_object_unref (mmc_account);
4660 /* Check the target folder rules */
4661 if (TNY_IS_FOLDER (folder_store)) {
4662 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
4663 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
4664 ok_sensitive = FALSE;
4665 new_sensitive = FALSE;
4670 /* Check if we're moving a folder */
4671 if (MODEST_IS_MAIN_WINDOW (user_data)) {
4672 /* Get the widgets */
4673 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
4674 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4675 if (gtk_widget_is_focus (folder_view))
4676 moving_folder = TRUE;
4679 if (moving_folder) {
4680 TnyFolderStore *moved_folder = NULL, *parent = NULL;
4682 /* Get the folder to move */
4683 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4685 /* Check that we're not moving to the same folder */
4686 if (TNY_IS_FOLDER (moved_folder)) {
4687 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
4688 if (parent == folder_store)
4689 ok_sensitive = FALSE;
4690 g_object_unref (parent);
4693 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
4694 /* Do not allow to move to an account unless it's the
4695 local folders account */
4696 if (!is_local_account)
4697 ok_sensitive = FALSE;
4700 if (ok_sensitive && (moved_folder == folder_store)) {
4701 /* Do not allow to move to itself */
4702 ok_sensitive = FALSE;
4704 g_object_unref (moved_folder);
4706 TnyFolder *src_folder = NULL;
4708 /* Moving a message */
4709 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
4711 TnyHeader *header = NULL;
4712 header = modest_msg_view_window_get_header
4713 (MODEST_MSG_VIEW_WINDOW (user_data));
4714 if (!TNY_IS_HEADER(header))
4715 g_warning ("%s: could not get source header", __FUNCTION__);
4717 src_folder = tny_header_get_folder (header);
4720 g_object_unref (header);
4723 TNY_FOLDER (modest_folder_view_get_selected
4724 (MODEST_FOLDER_VIEW (folder_view)));
4727 if (TNY_IS_FOLDER(src_folder)) {
4728 /* Do not allow to move the msg to the same folder */
4729 /* Do not allow to move the msg to an account */
4730 if ((gpointer) src_folder == (gpointer) folder_store ||
4731 TNY_IS_ACCOUNT (folder_store))
4732 ok_sensitive = FALSE;
4733 g_object_unref (src_folder);
4735 g_warning ("%s: could not get source folder", __FUNCTION__);
4739 /* Set sensitivity of the OK and NEW button */
4740 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
4741 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
4746 on_move_to_dialog_response (GtkDialog *dialog,
4750 GtkWidget *parent_win, *folder_view;
4751 MoveToInfo *helper = NULL;
4753 helper = (MoveToInfo *) user_data;
4755 parent_win = (GtkWidget *) helper->win;
4756 folder_view = GTK_WIDGET (g_object_get_data (G_OBJECT (dialog),
4757 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4760 TnyFolderStore *dst_folder;
4762 case MODEST_GTK_RESPONSE_NEW_FOLDER:
4763 modest_ui_actions_create_folder (GTK_WIDGET (dialog), folder_view);
4765 case GTK_RESPONSE_NONE:
4766 case GTK_RESPONSE_CANCEL:
4767 case GTK_RESPONSE_DELETE_EVENT:
4769 case GTK_RESPONSE_OK:
4770 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4771 /* Do window specific stuff */
4772 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
4773 modest_ui_actions_on_main_window_move_to (NULL,
4776 MODEST_MAIN_WINDOW (parent_win));
4778 /* Moving from headers window in edit mode */
4779 modest_ui_actions_on_window_move_to (NULL, helper->list,
4781 MODEST_WINDOW (parent_win));
4785 g_object_unref (dst_folder);
4789 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
4792 /* Free the helper and exit */
4793 g_object_unref (helper->list);
4794 g_slice_free (MoveToInfo, helper);
4795 gtk_widget_destroy (GTK_WIDGET (dialog));
4799 create_move_to_dialog (GtkWindow *win,
4800 GtkWidget *folder_view)
4802 GtkWidget *dialog, *tree_view = NULL;
4804 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
4806 #ifndef MODEST_TOOLKIT_HILDON2
4807 /* Track changes in the selection to
4808 * disable the OK button whenever "Move to" is not possible
4809 * disbale NEW button whenever New is not possible */
4810 g_signal_connect (tree_view,
4811 "folder_selection_changed",
4812 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
4816 /* It could happen that we're trying to move a message from a
4817 window (msg window for example) after the main window was
4818 closed, so we can not just get the model of the folder
4820 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4821 const gchar *visible_id = NULL;
4823 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4824 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4825 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4826 MODEST_FOLDER_VIEW(tree_view));
4829 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4831 /* Show the same account than the one that is shown in the main window */
4832 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
4835 const gchar *active_account_name = NULL;
4836 ModestAccountMgr *mgr = NULL;
4837 ModestAccountSettings *settings = NULL;
4838 ModestServerAccountSettings *store_settings = NULL;
4840 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4841 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4842 modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view),
4843 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
4845 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4846 mgr = modest_runtime_get_account_mgr ();
4847 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4850 const gchar *store_account_name;
4851 store_settings = modest_account_settings_get_store_settings (settings);
4852 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4854 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
4855 store_account_name);
4856 g_object_unref (store_settings);
4857 g_object_unref (settings);
4861 /* we keep a pointer to the embedded folder view, so we can
4862 * retrieve it with get_folder_view_from_move_to_dialog (see
4863 * above) later (needed for focus handling)
4865 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
4867 /* Hide special folders */
4868 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
4869 #ifndef MODEST_TOOLKIT_HILDON2
4870 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
4873 gtk_widget_show (GTK_WIDGET (tree_view));
4879 * Shows a confirmation dialog to the user when we're moving messages
4880 * from a remote server to the local storage. Returns the dialog
4881 * response. If it's other kind of movement then it always returns
4884 * This one is used by the next functions:
4885 * modest_ui_actions_on_paste - commented out
4886 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4889 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4890 TnyFolder *dest_folder,
4894 gint response = GTK_RESPONSE_OK;
4895 TnyAccount *account = NULL;
4896 TnyFolder *src_folder = NULL;
4897 TnyIterator *iter = NULL;
4898 TnyHeader *header = NULL;
4900 /* return with OK if the destination is a remote folder */
4901 if (modest_tny_folder_is_remote_folder (dest_folder))
4902 return GTK_RESPONSE_OK;
4904 /* Get source folder */
4905 iter = tny_list_create_iterator (headers);
4906 header = TNY_HEADER (tny_iterator_get_current (iter));
4908 src_folder = tny_header_get_folder (header);
4909 g_object_unref (header);
4911 g_object_unref (iter);
4913 /* if no src_folder, message may be an attahcment */
4914 if (src_folder == NULL)
4915 return GTK_RESPONSE_CANCEL;
4917 /* If the source is a local or MMC folder */
4918 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4919 g_object_unref (src_folder);
4920 return GTK_RESPONSE_OK;
4923 /* Get the account */
4924 account = tny_folder_get_account (src_folder);
4926 /* now if offline we ask the user */
4927 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4928 response = GTK_RESPONSE_OK;
4930 response = GTK_RESPONSE_CANCEL;
4933 g_object_unref (src_folder);
4934 g_object_unref (account);
4940 move_to_helper_destroyer (gpointer user_data)
4942 MoveToHelper *helper = (MoveToHelper *) user_data;
4944 /* Close the "Pasting" information banner */
4945 if (helper->banner) {
4946 gtk_widget_destroy (GTK_WIDGET (helper->banner));
4947 g_object_unref (helper->banner);
4949 if (gtk_tree_row_reference_valid (helper->reference)) {
4950 gtk_tree_row_reference_free (helper->reference);
4951 helper->reference = NULL;
4957 move_to_cb (ModestMailOperation *mail_op,
4960 MoveToHelper *helper = (MoveToHelper *) user_data;
4962 /* Note that the operation could have failed, in that case do
4964 if (modest_mail_operation_get_status (mail_op) ==
4965 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
4967 GObject *object = modest_mail_operation_get_source (mail_op);
4968 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4969 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4971 if (!modest_msg_view_window_select_next_message (self) &&
4972 !modest_msg_view_window_select_previous_message (self)) {
4973 /* No more messages to view, so close this window */
4974 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4976 } else if (MODEST_IS_MAIN_WINDOW (object) &&
4977 gtk_tree_row_reference_valid (helper->reference)) {
4978 GtkWidget *header_view;
4980 GtkTreeSelection *sel;
4982 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4983 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4984 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
4985 path = gtk_tree_row_reference_get_path (helper->reference);
4986 /* We need to unselect the previous one
4987 because we could be copying instead of
4989 gtk_tree_selection_unselect_all (sel);
4990 gtk_tree_selection_select_path (sel, path);
4991 gtk_tree_path_free (path);
4993 g_object_unref (object);
4995 /* Destroy the helper */
4996 move_to_helper_destroyer (helper);
5000 folder_move_to_cb (ModestMailOperation *mail_op,
5001 TnyFolder *new_folder,
5004 GtkWidget *folder_view;
5007 object = modest_mail_operation_get_source (mail_op);
5008 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5009 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5010 g_object_ref (folder_view);
5011 g_object_unref (object);
5012 move_to_cb (mail_op, user_data);
5013 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5014 g_object_unref (folder_view);
5018 msgs_move_to_cb (ModestMailOperation *mail_op,
5021 move_to_cb (mail_op, user_data);
5025 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5028 ModestWindow *main_window = NULL;
5030 /* Disable next automatic folder selection */
5031 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5032 FALSE); /* don't create */
5034 GObject *win = NULL;
5035 GtkWidget *folder_view = NULL;
5037 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5038 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5039 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5041 if (user_data && TNY_IS_FOLDER (user_data)) {
5042 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5043 TNY_FOLDER (user_data), FALSE);
5046 /* Show notification dialog only if the main window exists */
5047 win = modest_mail_operation_get_source (mail_op);
5048 modest_platform_run_information_dialog ((GtkWindow *) win,
5049 _("mail_in_ui_folder_move_target_error"),
5052 g_object_unref (win);
5057 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5066 gint pending_purges = 0;
5067 gboolean some_purged = FALSE;
5068 ModestWindow *win = MODEST_WINDOW (user_data);
5069 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5071 /* If there was any error */
5072 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5073 modest_window_mgr_unregister_header (mgr, header);
5077 /* Once the message has been retrieved for purging, we check if
5078 * it's all ok for purging */
5080 parts = tny_simple_list_new ();
5081 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5082 iter = tny_list_create_iterator (parts);
5084 while (!tny_iterator_is_done (iter)) {
5086 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5087 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5088 if (tny_mime_part_is_purged (part))
5095 g_object_unref (part);
5097 tny_iterator_next (iter);
5099 g_object_unref (iter);
5102 if (pending_purges>0) {
5104 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5106 if (response == GTK_RESPONSE_OK) {
5109 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5110 iter = tny_list_create_iterator (parts);
5111 while (!tny_iterator_is_done (iter)) {
5114 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5115 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5116 tny_mime_part_set_purged (part);
5119 g_object_unref (part);
5121 tny_iterator_next (iter);
5123 g_object_unref (iter);
5125 tny_msg_rewrite_cache (msg);
5127 gtk_widget_destroy (info);
5131 modest_window_mgr_unregister_header (mgr, header);
5133 g_object_unref (parts);
5137 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5138 ModestMainWindow *win)
5140 GtkWidget *header_view;
5141 TnyList *header_list;
5143 TnyHeaderFlags flags;
5144 ModestWindow *msg_view_window = NULL;
5147 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5149 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5150 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5152 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5154 g_warning ("%s: no header selected", __FUNCTION__);
5158 if (tny_list_get_length (header_list) == 1) {
5159 TnyIterator *iter = tny_list_create_iterator (header_list);
5160 header = TNY_HEADER (tny_iterator_get_current (iter));
5161 g_object_unref (iter);
5165 if (!header || !TNY_IS_HEADER(header)) {
5166 g_warning ("%s: header is not valid", __FUNCTION__);
5170 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5171 header, &msg_view_window);
5172 flags = tny_header_get_flags (header);
5173 if (!(flags & TNY_HEADER_FLAG_CACHED))
5176 if (msg_view_window != NULL)
5177 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5179 /* do nothing; uid was registered before, so window is probably on it's way */
5180 g_warning ("debug: header %p has already been registered", header);
5183 ModestMailOperation *mail_op = NULL;
5184 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5185 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5186 modest_ui_actions_disk_operations_error_handler,
5188 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5189 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5191 g_object_unref (mail_op);
5194 g_object_unref (header);
5196 g_object_unref (header_list);
5200 * Checks if we need a connection to do the transfer and if the user
5201 * wants to connect to complete it
5204 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5205 TnyFolderStore *src_folder,
5207 TnyFolder *dst_folder,
5208 gboolean delete_originals,
5209 gboolean *need_connection,
5212 TnyAccount *src_account;
5213 gint uncached_msgs = 0;
5215 uncached_msgs = header_list_count_uncached_msgs (headers);
5217 /* We don't need any further check if
5219 * 1- the source folder is local OR
5220 * 2- the device is already online
5222 if (!modest_tny_folder_store_is_remote (src_folder) ||
5223 tny_device_is_online (modest_runtime_get_device())) {
5224 *need_connection = FALSE;
5229 /* We must ask for a connection when
5231 * - the message(s) is not already cached OR
5232 * - the message(s) is cached but the leave_on_server setting
5233 * is FALSE (because we need to sync the source folder to
5234 * delete the message from the server (for IMAP we could do it
5235 * offline, it'll take place the next time we get a
5238 src_account = get_account_from_folder_store (src_folder);
5239 if (uncached_msgs > 0) {
5243 *need_connection = TRUE;
5244 num_headers = tny_list_get_length (headers);
5245 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5247 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5248 GTK_RESPONSE_CANCEL) {
5254 /* The transfer is possible and the user wants to */
5257 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5258 const gchar *account_name;
5259 gboolean leave_on_server;
5261 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5262 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5265 if (leave_on_server == TRUE) {
5266 *need_connection = FALSE;
5268 *need_connection = TRUE;
5271 *need_connection = FALSE;
5276 g_object_unref (src_account);
5280 xfer_messages_error_handler (ModestMailOperation *mail_op,
5283 ModestWindow *main_window = NULL;
5285 /* Disable next automatic folder selection */
5286 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5287 FALSE); /* don't create */
5289 GObject *win = modest_mail_operation_get_source (mail_op);
5290 modest_platform_run_information_dialog ((GtkWindow *) win,
5291 _("mail_in_ui_folder_move_target_error"),
5294 g_object_unref (win);
5296 move_to_helper_destroyer (user_data);
5300 TnyFolderStore *dst_folder;
5305 * Utility function that transfer messages from both the main window
5306 * and the msg view window when using the "Move to" dialog
5309 xfer_messages_performer (gboolean canceled,
5311 GtkWindow *parent_window,
5312 TnyAccount *account,
5315 ModestWindow *win = MODEST_WINDOW (parent_window);
5316 TnyAccount *dst_account = NULL;
5317 gboolean dst_forbids_message_add = FALSE;
5318 XferMsgsHelper *helper;
5319 MoveToHelper *movehelper;
5320 ModestMailOperation *mail_op;
5322 helper = (XferMsgsHelper *) user_data;
5324 if (canceled || err) {
5325 if (!check_memory_full_error ((GtkWidget *) parent_window, err)) {
5326 /* Show the proper error message */
5327 modest_ui_actions_on_account_connection_error (parent_window, account);
5332 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5334 /* tinymail will return NULL for local folders it seems */
5335 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5336 modest_tny_account_get_protocol_type (dst_account),
5337 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_MESSAGE_ADD);
5338 g_object_unref (dst_account);
5340 if (dst_forbids_message_add) {
5341 modest_platform_information_banner (GTK_WIDGET (win),
5343 ngettext("mail_in_ui_folder_move_target_error",
5344 "mail_in_ui_folder_move_targets_error",
5345 tny_list_get_length (helper->headers)));
5349 movehelper = g_new0 (MoveToHelper, 1);
5350 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5351 _CS("ckct_nw_pasting"));
5352 if (movehelper->banner != NULL) {
5353 g_object_ref (movehelper->banner);
5354 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5357 if (MODEST_IS_MAIN_WINDOW (win)) {
5358 GtkWidget *header_view =
5359 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5360 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5361 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5364 /* Perform the mail operation */
5365 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5366 xfer_messages_error_handler,
5368 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5371 modest_mail_operation_xfer_msgs (mail_op,
5373 TNY_FOLDER (helper->dst_folder),
5378 g_object_unref (G_OBJECT (mail_op));
5380 g_object_unref (helper->dst_folder);
5381 g_object_unref (helper->headers);
5382 g_slice_free (XferMsgsHelper, helper);
5386 TnyFolder *src_folder;
5387 TnyFolderStore *dst_folder;
5388 gboolean delete_original;
5389 GtkWidget *folder_view;
5393 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
5394 TnyAccount *account, gpointer user_data)
5396 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5397 GtkTreeSelection *sel;
5398 ModestMailOperation *mail_op = NULL;
5400 if (canceled || err || !MODEST_IS_MAIN_WINDOW (parent_window)) {
5401 g_object_unref (G_OBJECT (info->src_folder));
5402 g_object_unref (G_OBJECT (info->dst_folder));
5407 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5408 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5409 _CS("ckct_nw_pasting"));
5410 if (helper->banner != NULL) {
5411 g_object_ref (helper->banner);
5412 gtk_widget_show (GTK_WIDGET(helper->banner));
5414 /* Clean folder on header view before moving it */
5415 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5416 gtk_tree_selection_unselect_all (sel);
5418 /* Let gtk events run. We need that the folder
5419 view frees its reference to the source
5420 folder *before* issuing the mail operation
5421 so we need the signal handler of selection
5422 changed to happen before the mail
5424 while (gtk_events_pending ())
5425 gtk_main_iteration (); */
5428 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5429 modest_ui_actions_move_folder_error_handler,
5430 info->src_folder, NULL);
5431 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5434 /* Select *after* the changes */
5435 /* TODO: this function hangs UI after transfer */
5436 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
5437 /* TNY_FOLDER (src_folder), TRUE); */
5439 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5440 TNY_FOLDER (info->dst_folder), TRUE);
5441 modest_mail_operation_xfer_folder (mail_op,
5442 TNY_FOLDER (info->src_folder),
5444 info->delete_original,
5447 g_object_unref (G_OBJECT (info->src_folder));
5449 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5452 /* Unref mail operation */
5453 g_object_unref (G_OBJECT (mail_op));
5454 g_object_unref (G_OBJECT (info->dst_folder));
5459 get_account_from_folder_store (TnyFolderStore *folder_store)
5461 if (TNY_IS_ACCOUNT (folder_store))
5462 return g_object_ref (folder_store);
5464 return tny_folder_get_account (TNY_FOLDER (folder_store));
5468 * UI handler for the "Move to" action when invoked from the
5472 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5473 GtkWidget *folder_view,
5474 TnyFolderStore *dst_folder,
5475 ModestMainWindow *win)
5477 ModestHeaderView *header_view = NULL;
5478 TnyFolderStore *src_folder = NULL;
5480 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5482 /* Get the source folder */
5483 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5485 /* Get header view */
5486 header_view = (ModestHeaderView *)
5487 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5489 /* Get folder or messages to transfer */
5490 if (gtk_widget_is_focus (folder_view)) {
5491 gboolean do_xfer = TRUE;
5493 /* Allow only to transfer folders to the local root folder */
5494 if (TNY_IS_ACCOUNT (dst_folder) &&
5495 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5496 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5498 } else if (!TNY_IS_FOLDER (src_folder)) {
5499 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5504 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5505 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5507 info->src_folder = g_object_ref (src_folder);
5508 info->dst_folder = g_object_ref (dst_folder);
5509 info->delete_original = TRUE;
5510 info->folder_view = folder_view;
5512 connect_info->callback = on_move_folder_cb;
5513 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5514 connect_info->data = info;
5516 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5517 TNY_FOLDER_STORE (src_folder),
5520 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5523 headers = modest_header_view_get_selected_headers(header_view);
5525 /* Transfer the messages */
5526 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
5527 headers, TNY_FOLDER (dst_folder));
5529 g_object_unref (headers);
5533 g_object_unref (src_folder);
5538 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
5539 TnyFolder *src_folder,
5541 TnyFolder *dst_folder)
5543 gboolean need_connection = TRUE;
5544 gboolean do_xfer = TRUE;
5545 XferMsgsHelper *helper;
5547 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5548 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5549 g_return_if_fail (TNY_IS_LIST (headers));
5551 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5552 headers, TNY_FOLDER (dst_folder),
5553 TRUE, &need_connection,
5556 /* If we don't want to transfer just return */
5560 /* Create the helper */
5561 helper = g_slice_new (XferMsgsHelper);
5562 helper->dst_folder = g_object_ref (dst_folder);
5563 helper->headers = g_object_ref (headers);
5565 if (need_connection) {
5566 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5567 connect_info->callback = xfer_messages_performer;
5568 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5569 connect_info->data = helper;
5571 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5572 TNY_FOLDER_STORE (src_folder),
5575 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5576 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
5577 src_account, helper);
5578 g_object_unref (src_account);
5583 * UI handler for the "Move to" action when invoked from the
5584 * ModestMsgViewWindow
5587 modest_ui_actions_on_window_move_to (GtkAction *action,
5589 TnyFolderStore *dst_folder,
5592 TnyFolder *src_folder = NULL;
5594 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5597 TnyHeader *header = NULL;
5600 iter = tny_list_create_iterator (headers);
5601 header = (TnyHeader *) tny_iterator_get_current (iter);
5602 src_folder = tny_header_get_folder (header);
5604 /* Transfer the messages */
5605 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
5607 TNY_FOLDER (dst_folder));
5610 g_object_unref (header);
5611 g_object_unref (iter);
5612 g_object_unref (src_folder);
5617 modest_ui_actions_on_move_to (GtkAction *action,
5620 GtkWidget *dialog = NULL, *folder_view = NULL;
5621 ModestMainWindow *main_window;
5622 MoveToInfo *helper = NULL;
5624 g_return_if_fail (MODEST_IS_WINDOW (win));
5626 /* Get the main window if exists */
5627 if (MODEST_IS_MAIN_WINDOW (win))
5628 main_window = MODEST_MAIN_WINDOW (win);
5631 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5632 FALSE)); /* don't create */
5634 /* Get the folder view widget if exists */
5636 folder_view = modest_main_window_get_child_widget (main_window,
5637 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5641 /* Create and run the dialog */
5642 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view);
5643 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
5644 GTK_WINDOW (dialog),
5648 helper = g_slice_new0 (MoveToInfo);
5649 helper->list = modest_platform_get_list_to_move (MODEST_WINDOW (win));
5652 /* Listen to response signal */
5653 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
5655 /* Show the dialog */
5656 gtk_widget_show (dialog);
5660 * Calls #HeadersFunc for each header already selected in the main
5661 * window or the message currently being shown in the msg view window
5664 do_headers_action (ModestWindow *win,
5668 TnyList *headers_list = NULL;
5669 TnyIterator *iter = NULL;
5670 TnyHeader *header = NULL;
5671 TnyFolder *folder = NULL;
5674 headers_list = get_selected_headers (win);
5678 /* Get the folder */
5679 iter = tny_list_create_iterator (headers_list);
5680 header = TNY_HEADER (tny_iterator_get_current (iter));
5682 folder = tny_header_get_folder (header);
5683 g_object_unref (header);
5686 /* Call the function for each header */
5687 while (!tny_iterator_is_done (iter)) {
5688 header = TNY_HEADER (tny_iterator_get_current (iter));
5689 func (header, win, user_data);
5690 g_object_unref (header);
5691 tny_iterator_next (iter);
5694 /* Trick: do a poke status in order to speed up the signaling
5696 tny_folder_poke_status (folder);
5699 g_object_unref (folder);
5700 g_object_unref (iter);
5701 g_object_unref (headers_list);
5705 modest_ui_actions_view_attachment (GtkAction *action,
5706 ModestWindow *window)
5708 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5709 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5711 /* not supported window for this action */
5712 g_return_if_reached ();
5717 modest_ui_actions_save_attachments (GtkAction *action,
5718 ModestWindow *window)
5720 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5722 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5725 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5727 /* not supported window for this action */
5728 g_return_if_reached ();
5733 modest_ui_actions_remove_attachments (GtkAction *action,
5734 ModestWindow *window)
5736 if (MODEST_IS_MAIN_WINDOW (window)) {
5737 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
5738 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5739 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5741 /* not supported window for this action */
5742 g_return_if_reached ();
5747 modest_ui_actions_on_settings (GtkAction *action,
5752 dialog = modest_platform_get_global_settings_dialog ();
5753 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
5754 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5755 gtk_widget_show_all (dialog);
5757 gtk_dialog_run (GTK_DIALOG (dialog));
5759 gtk_widget_destroy (dialog);
5763 modest_ui_actions_on_help (GtkAction *action,
5766 /* Help app is not available at all in fremantle */
5767 #ifndef MODEST_TOOLKIT_HILDON2
5768 const gchar *help_id;
5770 g_return_if_fail (win && GTK_IS_WINDOW(win));
5772 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5775 modest_platform_show_help (GTK_WINDOW (win), help_id);
5780 modest_ui_actions_on_csm_help (GtkAction *action,
5783 /* Help app is not available at all in fremantle */
5784 #ifndef MODEST_TOOLKIT_HILDON2
5786 const gchar* help_id = NULL;
5787 GtkWidget *folder_view;
5788 TnyFolderStore *folder_store;
5790 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
5792 /* Get selected folder */
5793 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5794 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5795 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5797 /* Switch help_id */
5798 if (folder_store && TNY_IS_FOLDER (folder_store))
5799 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
5802 g_object_unref (folder_store);
5805 modest_platform_show_help (GTK_WINDOW (win), help_id);
5807 modest_ui_actions_on_help (action, win);
5812 retrieve_contents_cb (ModestMailOperation *mail_op,
5819 /* We only need this callback to show an error in case of
5820 memory low condition */
5821 modest_ui_actions_msg_retrieval_check (mail_op, header, msg);
5825 retrieve_msg_contents_performer (gboolean canceled,
5827 GtkWindow *parent_window,
5828 TnyAccount *account,
5831 ModestMailOperation *mail_op;
5832 TnyList *headers = TNY_LIST (user_data);
5834 if (err || canceled) {
5835 check_memory_full_error ((GtkWidget *) parent_window, err);
5839 /* Create mail operation */
5840 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5841 modest_ui_actions_disk_operations_error_handler,
5843 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5844 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
5847 g_object_unref (mail_op);
5849 g_object_unref (headers);
5850 g_object_unref (account);
5854 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5855 ModestWindow *window)
5857 TnyList *headers = NULL;
5858 TnyAccount *account = NULL;
5859 TnyIterator *iter = NULL;
5860 TnyHeader *header = NULL;
5861 TnyFolder *folder = NULL;
5864 headers = get_selected_headers (window);
5868 /* Pick the account */
5869 iter = tny_list_create_iterator (headers);
5870 header = TNY_HEADER (tny_iterator_get_current (iter));
5871 folder = tny_header_get_folder (header);
5872 account = tny_folder_get_account (folder);
5873 g_object_unref (folder);
5874 g_object_unref (header);
5875 g_object_unref (iter);
5877 /* Connect and perform the message retrieval */
5878 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
5879 g_object_ref (account),
5880 retrieve_msg_contents_performer,
5881 g_object_ref (headers));
5884 g_object_unref (account);
5885 g_object_unref (headers);
5889 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
5891 g_return_if_fail (MODEST_IS_WINDOW (window));
5894 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
5898 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
5900 g_return_if_fail (MODEST_IS_WINDOW (window));
5903 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
5907 modest_ui_actions_on_email_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_edit_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_view_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_format_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_tools_menu_activated (GtkAction *action,
5948 ModestWindow *window)
5950 g_return_if_fail (MODEST_IS_WINDOW (window));
5953 modest_ui_actions_check_menu_dimming_rules (window);
5957 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
5958 ModestWindow *window)
5960 g_return_if_fail (MODEST_IS_WINDOW (window));
5963 modest_ui_actions_check_menu_dimming_rules (window);
5967 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
5968 ModestWindow *window)
5970 g_return_if_fail (MODEST_IS_WINDOW (window));
5973 modest_ui_actions_check_menu_dimming_rules (window);
5977 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
5978 ModestWindow *window)
5980 g_return_if_fail (MODEST_IS_WINDOW (window));
5983 modest_ui_actions_check_menu_dimming_rules (window);
5987 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
5988 ModestWindow *window)
5990 g_return_if_fail (MODEST_IS_WINDOW (window));
5993 modest_ui_actions_check_menu_dimming_rules (window);
5997 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
5999 g_return_if_fail (MODEST_IS_WINDOW (window));
6001 /* we check for low-mem; in that case, show a warning, and don't allow
6004 if (modest_platform_check_memory_low (window, TRUE))
6007 modest_platform_show_search_messages (GTK_WINDOW (window));
6011 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6013 g_return_if_fail (MODEST_IS_WINDOW (win));
6016 /* we check for low-mem; in that case, show a warning, and don't allow
6017 * for the addressbook
6019 if (modest_platform_check_memory_low (win, TRUE))
6023 modest_platform_show_addressbook (GTK_WINDOW (win));
6028 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
6029 ModestWindow *window)
6031 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6033 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
6037 on_send_receive_finished (ModestMailOperation *mail_op,
6040 GtkWidget *header_view, *folder_view;
6041 TnyFolderStore *folder_store;
6042 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6044 /* Set send/receive operation finished */
6045 modest_main_window_notify_send_receive_completed (main_win);
6047 /* Don't refresh the current folder if there were any errors */
6048 if (modest_mail_operation_get_status (mail_op) !=
6049 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6052 /* Refresh the current folder if we're viewing a window. We do
6053 this because the user won't be able to see the new mails in
6054 the selected folder after a Send&Receive because it only
6055 performs a poke_status, i.e, only the number of read/unread
6056 messages is updated, but the new headers are not
6058 folder_view = modest_main_window_get_child_widget (main_win,
6059 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6063 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6065 /* Do not need to refresh INBOX again because the
6066 update_account does it always automatically */
6067 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6068 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6069 ModestMailOperation *refresh_op;
6071 header_view = modest_main_window_get_child_widget (main_win,
6072 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6074 /* We do not need to set the contents style
6075 because it hasn't changed. We also do not
6076 need to save the widget status. Just force
6078 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6079 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6080 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6081 folder_refreshed_cb, main_win);
6082 g_object_unref (refresh_op);
6086 g_object_unref (folder_store);
6091 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6097 const gchar* server_name = NULL;
6098 TnyTransportAccount *server_account;
6099 gchar *message = NULL;
6101 /* Don't show anything if the user cancelled something or the
6102 * send receive request is not interactive. Authentication
6103 * errors are managed by the account store so no need to show
6104 * a dialog here again */
6105 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6106 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6107 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6111 /* Get the server name: */
6113 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
6115 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
6117 g_return_if_reached ();
6119 /* Show the appropriate message text for the GError: */
6120 switch (err->code) {
6121 case TNY_SERVICE_ERROR_CONNECT:
6122 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6124 case TNY_SERVICE_ERROR_SEND:
6125 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
6127 case TNY_SERVICE_ERROR_UNAVAILABLE:
6128 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6131 g_warning ("%s: unexpected ERROR %d",
6132 __FUNCTION__, err->code);
6133 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
6137 modest_platform_run_information_dialog (NULL, message, FALSE);
6139 g_object_unref (server_account);
6143 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6148 ModestMainWindow *main_window = NULL;
6149 ModestWindowMgr *mgr = NULL;
6150 GtkWidget *folder_view = NULL, *header_view = NULL;
6151 TnyFolderStore *selected_folder = NULL;
6152 TnyFolderType folder_type;
6154 mgr = modest_runtime_get_window_mgr ();
6155 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr,
6156 FALSE));/* don't create */
6160 /* Check if selected folder is OUTBOX */
6161 folder_view = modest_main_window_get_child_widget (main_window,
6162 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6163 header_view = modest_main_window_get_child_widget (main_window,
6164 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6166 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6167 if (!TNY_IS_FOLDER (selected_folder))
6170 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6171 #if GTK_CHECK_VERSION(2, 8, 0)
6172 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
6173 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6174 GtkTreeViewColumn *tree_column;
6176 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6177 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6179 gtk_tree_view_column_queue_resize (tree_column);
6182 gtk_widget_queue_draw (header_view);
6185 /* Rerun dimming rules, because the message could become deletable for example */
6186 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6187 MODEST_DIMMING_RULES_TOOLBAR);
6188 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6189 MODEST_DIMMING_RULES_MENU);
6193 if (selected_folder != NULL)
6194 g_object_unref (selected_folder);
6198 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6199 TnyAccount *account)
6201 ModestProtocolType protocol_type;
6202 ModestProtocol *protocol;
6203 gchar *error_note = NULL;
6205 protocol_type = modest_tny_account_get_protocol_type (account);
6206 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6209 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6210 if (error_note == NULL) {
6211 g_warning ("%s: This should not be reached", __FUNCTION__);
6213 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6214 g_free (error_note);
6219 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6223 TnyFolderStore *folder = NULL;
6224 TnyAccount *account = NULL;
6225 ModestProtocolType proto;
6226 ModestProtocol *protocol;
6227 TnyHeader *header = NULL;
6229 if (MODEST_IS_MAIN_WINDOW (win)) {
6230 GtkWidget *header_view;
6231 TnyList* headers = NULL;
6233 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6234 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6235 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6236 if (!headers || tny_list_get_length (headers) == 0) {
6238 g_object_unref (headers);
6241 iter = tny_list_create_iterator (headers);
6242 header = TNY_HEADER (tny_iterator_get_current (iter));
6243 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6244 g_object_unref (iter);
6245 g_object_unref (headers);
6246 #ifdef MODEST_TOOLKIT_HILDON2
6247 } else if (MODEST_IS_HEADER_WINDOW (win)) {
6248 GtkWidget *header_view;
6249 TnyList* headers = NULL;
6251 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
6252 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6253 if (!headers || tny_list_get_length (headers) == 0) {
6255 g_object_unref (headers);
6258 iter = tny_list_create_iterator (headers);
6259 header = TNY_HEADER (tny_iterator_get_current (iter));
6260 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6261 g_object_unref (iter);
6262 g_object_unref (headers);
6264 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6265 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6266 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6269 /* Get the account type */
6270 account = tny_folder_get_account (TNY_FOLDER (folder));
6271 proto = modest_tny_account_get_protocol_type (account);
6272 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6275 subject = tny_header_dup_subject (header);
6276 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6280 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6284 g_object_unref (account);
6285 g_object_unref (folder);
6286 g_object_unref (header);
6292 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6293 const gchar *account_name,
6294 const gchar *account_title)
6296 ModestAccountMgr *account_mgr;
6299 ModestProtocol *protocol;
6300 gboolean removed = FALSE;
6302 g_return_val_if_fail (account_name, FALSE);
6303 g_return_val_if_fail (account_title, FALSE);
6305 account_mgr = modest_runtime_get_account_mgr();
6307 /* The warning text depends on the account type: */
6308 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6309 modest_account_mgr_get_store_protocol (account_mgr,
6311 txt = modest_protocol_get_translation (protocol,
6312 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6315 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6317 response = modest_platform_run_confirmation_dialog (parent_window, txt);
6321 if (response == GTK_RESPONSE_OK) {
6322 /* Remove account. If it succeeds then it also removes
6323 the account from the ModestAccountView: */
6324 gboolean is_default = FALSE;
6325 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6326 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6328 g_free (default_account_name);
6330 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6332 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);