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);
180 #ifdef MODEST_TOOLKIT_HILDON2
181 static void modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
182 TnyFolderStore *dst_folder,
187 static void modest_ui_actions_on_window_move_to (GtkAction *action,
188 TnyList *list_to_move,
189 TnyFolderStore *dst_folder,
193 * This function checks whether a TnyFolderStore is a pop account
196 remote_folder_has_leave_on_server (TnyFolderStore *folder)
201 g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
203 account = get_account_from_folder_store (folder);
204 result = (modest_protocol_registry_protocol_type_has_leave_on_server (modest_runtime_get_protocol_registry (),
205 modest_tny_account_get_protocol_type (account)));
206 g_object_unref (account);
211 /* FIXME: this should be merged with the similar code in modest-account-view-window */
212 /* Show the account creation wizard dialog.
213 * returns: TRUE if an account was created. FALSE if the user cancelled.
216 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
218 gboolean result = FALSE;
220 gint dialog_response;
222 /* there is no such wizard yet */
223 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
224 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (wizard), (GtkWindow *) win);
226 /* always present a main window in the background
227 * we do it here, so we cannot end up with two wizards (as this
228 * function might be called in modest_window_mgr_get_main_window as well */
230 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
231 TRUE); /* create if not existent */
233 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
235 /* make sure the mainwindow is visible. We need to present the
236 wizard again to give it the focus back. show_all are needed
237 in order to get the widgets properly drawn (MainWindow main
238 paned won't be in its right position and the dialog will be
240 #ifndef MODEST_TOOLKIT_HILDON2
241 gtk_widget_show_all (GTK_WIDGET (win));
242 gtk_widget_show_all (GTK_WIDGET (wizard));
243 gtk_window_present (GTK_WINDOW (win));
244 gtk_window_present (GTK_WINDOW (wizard));
247 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
248 gtk_widget_destroy (GTK_WIDGET (wizard));
249 if (gtk_events_pending ())
250 gtk_main_iteration ();
252 if (dialog_response == GTK_RESPONSE_CANCEL) {
255 /* Check whether an account was created: */
256 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
263 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
266 const gchar *authors[] = {
267 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
270 about = gtk_about_dialog_new ();
271 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
272 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
273 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
274 _("Copyright (c) 2006, Nokia Corporation\n"
275 "All rights reserved."));
276 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
277 _("a modest e-mail client\n\n"
278 "design and implementation: Dirk-Jan C. Binnema\n"
279 "contributions from the fine people at KC and Ig\n"
280 "uses the tinymail email framework written by Philip van Hoof"));
281 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
282 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
283 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
284 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
286 gtk_dialog_run (GTK_DIALOG (about));
287 gtk_widget_destroy(about);
291 * Gets the list of currently selected messages. If the win is the
292 * main window, then it returns a newly allocated list of the headers
293 * selected in the header view. If win is the msg view window, then
294 * the value returned is a list with just a single header.
296 * The caller of this funcion must free the list.
299 get_selected_headers (ModestWindow *win)
301 if (MODEST_IS_MAIN_WINDOW(win)) {
302 GtkWidget *header_view;
304 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
305 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
306 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
308 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
309 /* for MsgViewWindows, we simply return a list with one element */
311 TnyList *list = NULL;
313 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
314 if (header != NULL) {
315 list = tny_simple_list_new ();
316 tny_list_prepend (list, G_OBJECT(header));
317 g_object_unref (G_OBJECT(header));
322 #ifdef MODEST_TOOLKIT_HILDON2
323 } else if (MODEST_IS_HEADER_WINDOW (win)) {
324 GtkWidget *header_view;
326 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
327 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
333 static GtkTreeRowReference *
334 get_next_after_selected_headers (ModestHeaderView *header_view)
336 GtkTreeSelection *sel;
337 GList *selected_rows, *node;
339 GtkTreeRowReference *result;
342 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
343 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
344 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
346 if (selected_rows == NULL)
349 node = g_list_last (selected_rows);
350 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
351 gtk_tree_path_next (path);
353 result = gtk_tree_row_reference_new (model, path);
355 gtk_tree_path_free (path);
356 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
357 g_list_free (selected_rows);
363 headers_action_mark_as_read (TnyHeader *header,
367 TnyHeaderFlags flags;
369 g_return_if_fail (TNY_IS_HEADER(header));
371 flags = tny_header_get_flags (header);
372 if (flags & TNY_HEADER_FLAG_SEEN) return;
373 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
377 headers_action_mark_as_unread (TnyHeader *header,
381 TnyHeaderFlags flags;
383 g_return_if_fail (TNY_IS_HEADER(header));
385 flags = tny_header_get_flags (header);
386 if (flags & TNY_HEADER_FLAG_SEEN) {
387 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
391 /** After deleing a message that is currently visible in a window,
392 * show the next message from the list, or close the window if there are no more messages.
395 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
397 /* Close msg view window or select next */
398 if (!modest_msg_view_window_select_next_message (win) &&
399 !modest_msg_view_window_select_previous_message (win)) {
401 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
407 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
409 modest_ui_actions_on_edit_mode_delete_message (win);
413 modest_ui_actions_on_edit_mode_delete_message (ModestWindow *win)
415 TnyList *header_list = NULL;
416 TnyIterator *iter = NULL;
417 TnyHeader *header = NULL;
418 gchar *message = NULL;
421 ModestWindowMgr *mgr;
422 GtkWidget *header_view = NULL;
423 gboolean retval = TRUE;
425 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
427 /* Check first if the header view has the focus */
428 if (MODEST_IS_MAIN_WINDOW (win)) {
430 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
431 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
432 if (!gtk_widget_is_focus (header_view))
436 /* Get the headers, either from the header view (if win is the main window),
437 * or from the message view window: */
438 header_list = get_selected_headers (win);
439 if (!header_list) return FALSE;
441 /* Check if any of the headers are already opened, or in the process of being opened */
442 if (MODEST_IS_MAIN_WINDOW (win)) {
443 gint opened_headers = 0;
445 iter = tny_list_create_iterator (header_list);
446 mgr = modest_runtime_get_window_mgr ();
447 while (!tny_iterator_is_done (iter)) {
448 header = TNY_HEADER (tny_iterator_get_current (iter));
450 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
452 g_object_unref (header);
454 tny_iterator_next (iter);
456 g_object_unref (iter);
458 if (opened_headers > 0) {
461 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
464 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg, FALSE);
467 g_object_unref (header_list);
473 if (tny_list_get_length(header_list) == 1) {
474 iter = tny_list_create_iterator (header_list);
475 header = TNY_HEADER (tny_iterator_get_current (iter));
478 subject = tny_header_dup_subject (header);
480 subject = g_strdup (_("mail_va_no_subject"));
481 desc = g_strdup_printf ("%s", subject);
483 g_object_unref (header);
486 g_object_unref (iter);
488 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
489 tny_list_get_length(header_list)), desc);
491 /* Confirmation dialog */
492 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
496 if (response == GTK_RESPONSE_OK) {
497 ModestWindow *main_window = NULL;
498 ModestWindowMgr *mgr = NULL;
499 GtkTreeModel *model = NULL;
500 GtkTreeSelection *sel = NULL;
501 GList *sel_list = NULL, *tmp = NULL;
502 GtkTreeRowReference *next_row_reference = NULL;
503 GtkTreeRowReference *prev_row_reference = NULL;
504 GtkTreePath *next_path = NULL;
505 GtkTreePath *prev_path = NULL;
506 ModestMailOperation *mail_op = NULL;
508 /* Find last selected row */
509 if (MODEST_IS_MAIN_WINDOW (win)) {
510 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
511 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
512 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
513 for (tmp=sel_list; tmp; tmp=tmp->next) {
514 if (tmp->next == NULL) {
515 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
516 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
518 gtk_tree_path_prev (prev_path);
519 gtk_tree_path_next (next_path);
521 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
522 next_row_reference = gtk_tree_row_reference_new (model, next_path);
527 /* Disable window dimming management */
528 modest_window_disable_dimming (MODEST_WINDOW(win));
530 /* Remove each header. If it's a view window header_view == NULL */
531 mail_op = modest_mail_operation_new ((GObject *) win);
532 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
534 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
535 g_object_unref (mail_op);
537 /* Enable window dimming management */
539 gtk_tree_selection_unselect_all (sel);
541 modest_window_enable_dimming (MODEST_WINDOW(win));
543 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
544 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
546 /* Get main window */
547 mgr = modest_runtime_get_window_mgr ();
548 main_window = modest_window_mgr_get_main_window (mgr, FALSE); /* don't create */
549 } else if (MODEST_IS_MAIN_WINDOW (win)) {
550 /* Move cursor to next row */
553 /* Select next or previous row */
554 if (gtk_tree_row_reference_valid (next_row_reference)) {
555 gtk_tree_selection_select_path (sel, next_path);
557 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
558 gtk_tree_selection_select_path (sel, prev_path);
562 if (gtk_tree_row_reference_valid (next_row_reference))
563 gtk_tree_row_reference_free (next_row_reference);
564 if (next_path != NULL)
565 gtk_tree_path_free (next_path);
566 if (gtk_tree_row_reference_valid (prev_row_reference))
567 gtk_tree_row_reference_free (prev_row_reference);
568 if (prev_path != NULL)
569 gtk_tree_path_free (prev_path);
572 /* Update toolbar dimming state */
574 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
575 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
579 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
580 g_list_free (sel_list);
589 g_object_unref (header_list);
597 /* delete either message or folder, based on where we are */
599 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
601 g_return_if_fail (MODEST_IS_WINDOW(win));
603 /* Check first if the header view has the focus */
604 if (MODEST_IS_MAIN_WINDOW (win)) {
606 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
607 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
608 if (gtk_widget_is_focus (w)) {
609 modest_ui_actions_on_delete_folder (action, MODEST_WINDOW(win));
613 modest_ui_actions_on_delete_message (action, win);
617 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
619 ModestWindowMgr *mgr = NULL;
621 #ifdef MODEST_PLATFORM_MAEMO
622 modest_osso_save_state();
623 #endif /* MODEST_PLATFORM_MAEMO */
625 g_debug ("closing down, clearing %d item(s) from operation queue",
626 modest_mail_operation_queue_num_elements
627 (modest_runtime_get_mail_operation_queue()));
629 /* cancel all outstanding operations */
630 modest_mail_operation_queue_cancel_all
631 (modest_runtime_get_mail_operation_queue());
633 g_debug ("queue has been cleared");
636 /* Check if there are opened editing windows */
637 mgr = modest_runtime_get_window_mgr ();
638 modest_window_mgr_close_all_windows (mgr);
640 /* note: when modest-tny-account-store is finalized,
641 it will automatically set all network connections
644 /* gtk_main_quit (); */
648 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
652 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
654 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
655 /* gtk_widget_destroy (GTK_WIDGET (win)); */
656 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
657 /* gboolean ret_value; */
658 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
659 /* } else if (MODEST_IS_WINDOW (win)) { */
660 /* gtk_widget_destroy (GTK_WIDGET (win)); */
662 /* g_return_if_reached (); */
667 modest_ui_actions_add_to_contacts (GtkAction *action, ModestWindow *win)
669 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
671 modest_msg_view_window_add_to_contacts (MODEST_MSG_VIEW_WINDOW (win));
675 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
677 GtkClipboard *clipboard = NULL;
678 gchar *selection = NULL;
680 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
681 selection = gtk_clipboard_wait_for_text (clipboard);
683 /* Question: why is the clipboard being used here?
684 * It doesn't really make a lot of sense. */
688 modest_address_book_add_address (selection);
694 modest_ui_actions_on_new_account (GtkAction *action,
695 ModestWindow *window)
697 modest_ui_actions_run_account_setup_wizard (window);
701 modest_ui_actions_on_accounts (GtkAction *action,
704 /* This is currently only implemented for Maemo */
705 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
706 if (!modest_ui_actions_run_account_setup_wizard (win))
707 g_debug ("%s: wizard was already running", __FUNCTION__);
711 /* Show the list of accounts */
712 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
714 /* The accounts dialog must be modal */
715 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
716 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
721 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
723 /* This is currently only implemented for Maemo,
724 * because it requires an API (libconic) to detect different connection
727 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
729 /* Create the window if necessary: */
730 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
731 modest_connection_specific_smtp_window_fill_with_connections (
732 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
733 modest_runtime_get_account_mgr());
735 /* Show the window: */
736 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
737 GTK_WINDOW (specific_window), (GtkWindow *) win);
738 gtk_widget_show (specific_window);
739 #endif /* !MODEST_TOOLKIT_GTK */
743 modest_ui_actions_compose_msg(ModestWindow *win,
746 const gchar *bcc_str,
747 const gchar *subject_str,
748 const gchar *body_str,
750 gboolean set_as_modified)
752 gchar *account_name = NULL;
754 TnyAccount *account = NULL;
755 TnyFolder *folder = NULL;
756 gchar *from_str = NULL, *signature = NULL, *body = NULL;
757 gboolean use_signature = FALSE;
758 ModestWindow *msg_win = NULL;
759 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
760 ModestTnyAccountStore *store = modest_runtime_get_account_store();
761 GnomeVFSFileSize total_size, allowed_size;
763 /* we check for low-mem */
764 if (modest_platform_check_memory_low (win, TRUE))
767 #ifdef MODEST_TOOLKIT_HILDON2
768 account_name = g_strdup (modest_window_get_active_account(win));
771 account_name = modest_account_mgr_get_default_account(mgr);
774 g_printerr ("modest: no account found\n");
777 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
779 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
782 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
784 g_printerr ("modest: failed to find Drafts folder\n");
787 from_str = modest_account_mgr_get_from_string (mgr, account_name);
789 g_printerr ("modest: failed get from string for '%s'\n", account_name);
793 signature = modest_account_mgr_get_signature (mgr, account_name, &use_signature);
794 if (body_str != NULL) {
795 body = use_signature ? g_strconcat(body_str, "\n--\n", signature, NULL) : g_strdup(body_str);
797 body = use_signature ? g_strconcat("\n--\n", signature, NULL) : g_strdup("");
800 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, body, NULL, NULL, NULL);
802 g_printerr ("modest: failed to create new msg\n");
806 /* Create and register edit window */
807 /* This is destroyed by TODO. */
809 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
810 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
812 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, win)) {
813 gtk_widget_destroy (GTK_WIDGET (msg_win));
816 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
817 gtk_widget_show_all (GTK_WIDGET (msg_win));
819 while (attachments) {
821 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
822 attachments->data, allowed_size);
824 if (total_size > allowed_size) {
825 g_warning ("%s: total size: %u",
826 __FUNCTION__, (unsigned int)total_size);
829 allowed_size -= total_size;
831 attachments = g_slist_next(attachments);
838 g_free (account_name);
840 g_object_unref (G_OBJECT(account));
842 g_object_unref (G_OBJECT(folder));
844 g_object_unref (G_OBJECT(msg));
848 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
850 /* if there are no accounts yet, just show the wizard */
851 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
852 if (!modest_ui_actions_run_account_setup_wizard (win))
855 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
860 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
864 ModestMailOperationStatus status;
866 /* If there is no message or the operation was not successful */
867 status = modest_mail_operation_get_status (mail_op);
868 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
871 /* If it's a memory low issue, then show a banner */
872 error = modest_mail_operation_get_error (mail_op);
873 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
874 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
875 GObject *source = modest_mail_operation_get_source (mail_op);
876 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
877 dgettext("ke-recv","memr_ib_operation_disabled"),
879 g_object_unref (source);
882 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
883 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
884 gchar *subject, *msg;
885 subject = tny_header_dup_subject (header);
887 subject = g_strdup (_("mail_va_no_subject"));;
888 msg = g_strdup_printf (_("emev_ni_ui_imap_message_not_available_in_server"),
890 modest_platform_run_information_dialog (NULL, msg, FALSE);
895 /* Remove the header from the preregistered uids */
896 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
914 OpenMsgBannerInfo *banner_info;
915 GtkTreeRowReference *rowref;
919 open_msg_banner_idle (gpointer userdata)
921 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
923 gdk_threads_enter ();
924 banner_info->idle_handler = 0;
925 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
927 g_object_ref (banner_info->banner);
929 gdk_threads_leave ();
936 get_header_view_from_window (ModestWindow *window)
938 GtkWidget *header_view;
940 if (MODEST_IS_MAIN_WINDOW (window)) {
941 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
942 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
943 #ifdef MODEST_TOOLKIT_HILDON2
944 } else if (MODEST_IS_HEADER_WINDOW (window)){
945 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
955 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
958 gchar *account = NULL;
959 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
964 folder = tny_header_get_folder (header);
965 /* Gets folder type (OUTBOX headers will be opened in edit window */
966 if (modest_tny_folder_is_local_folder (folder)) {
967 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
968 if (folder_type == TNY_FOLDER_TYPE_INVALID)
969 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
972 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
973 TnyTransportAccount *traccount = NULL;
974 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
975 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
977 ModestTnySendQueue *send_queue = NULL;
978 ModestTnySendQueueStatus status;
980 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
981 TNY_ACCOUNT(traccount)));
982 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
983 if (TNY_IS_SEND_QUEUE (send_queue)) {
984 msg_id = modest_tny_send_queue_get_msg_id (header);
985 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
987 /* Only open messages in outbox with the editor if they are in Failed state */
988 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
991 #ifdef MODEST_TOOLKIT_HILDON2
993 /* In Fremantle we can not
994 open any message from
995 outbox which is not in
998 g_object_unref(traccount);
1002 g_object_unref(traccount);
1004 g_warning("Cannot get transport account for message in outbox!!");
1006 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
1007 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
1010 g_object_unref (folder);
1016 open_msg_cb (ModestMailOperation *mail_op,
1023 ModestWindowMgr *mgr = NULL;
1024 ModestWindow *parent_win = NULL;
1025 ModestWindow *win = NULL;
1026 gchar *account = NULL;
1027 gboolean open_in_editor = FALSE;
1029 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1031 /* Do nothing if there was any problem with the mail
1032 operation. The error will be shown by the error_handler of
1033 the mail operation */
1034 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1037 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1039 /* Mark header as read */
1040 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1042 account = get_info_from_header (header, &open_in_editor, &can_open);
1046 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1048 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1050 if (open_in_editor) {
1051 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1052 gchar *from_header = NULL, *acc_name;
1054 from_header = tny_header_dup_from (header);
1056 /* we cannot edit without a valid account... */
1057 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1058 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1059 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1061 g_free (from_header);
1066 acc_name = modest_utils_get_account_name_from_recipient (from_header);
1067 g_free (from_header);
1073 win = modest_msg_edit_window_new (msg, account, TRUE);
1075 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1077 if (helper->rowref && helper->model) {
1078 win = modest_msg_view_window_new_with_header_model (msg, account, (const gchar*) uid,
1079 helper->model, helper->rowref);
1081 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
1086 /* Register and show new window */
1088 mgr = modest_runtime_get_window_mgr ();
1089 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1090 gtk_widget_destroy (GTK_WIDGET (win));
1093 gtk_widget_show_all (GTK_WIDGET(win));
1096 /* Update toolbar dimming state */
1097 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1098 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1104 g_object_unref (parent_win);
1108 is_memory_full_error (GError *error)
1110 gboolean enough_free_space = TRUE;
1111 GnomeVFSURI *cache_dir_uri;
1112 const gchar *cache_dir;
1113 GnomeVFSFileSize free_space;
1115 cache_dir = tny_account_store_get_cache_dir (TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
1116 cache_dir_uri = gnome_vfs_uri_new (cache_dir);
1117 if (gnome_vfs_get_volume_free_space (cache_dir_uri, &free_space) == GNOME_VFS_OK) {
1118 if (free_space < MIN_FREE_SPACE)
1119 enough_free_space = FALSE;
1121 gnome_vfs_uri_unref (cache_dir_uri);
1123 if ((error->code == TNY_SYSTEM_ERROR_MEMORY ||
1124 /* When asking for a mail and no space left on device
1125 tinymail returns this error */
1126 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE ||
1127 /* When the folder summary could not be read or
1129 error->code == TNY_IO_ERROR_WRITE ||
1130 error->code == TNY_IO_ERROR_READ) &&
1131 !enough_free_space) {
1139 check_memory_full_error (GtkWidget *parent_window, GError *err)
1144 if (is_memory_full_error (err))
1145 modest_platform_information_banner (parent_window,
1146 NULL, dgettext("ke-recv",
1147 "cerm_device_memory_full"));
1148 else if (err->code == TNY_SYSTEM_ERROR_MEMORY)
1149 /* If the account was created in memory full
1150 conditions then tinymail won't be able to
1151 connect so it'll return this error code */
1152 modest_platform_information_banner (parent_window,
1153 NULL, _("emev_ui_imap_inbox_select_error"));
1161 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1164 const GError *error;
1165 GObject *win = NULL;
1166 ModestMailOperationStatus status;
1168 win = modest_mail_operation_get_source (mail_op);
1169 error = modest_mail_operation_get_error (mail_op);
1170 status = modest_mail_operation_get_status (mail_op);
1172 /* If the mail op has been cancelled then it's not an error:
1173 don't show any message */
1174 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1175 if (is_memory_full_error ((GError *) error)) {
1176 modest_platform_information_banner ((GtkWidget *) win,
1177 NULL, dgettext("ke-recv",
1178 "cerm_device_memory_full"));
1179 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1180 modest_platform_information_banner ((GtkWidget *) win,
1181 NULL, _("emev_ui_imap_inbox_select_error"));
1182 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1183 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1184 modest_platform_information_banner ((GtkWidget *) win,
1185 NULL, dgettext ("hildon-common-strings", "sfil_ni_unable_to_open_file_not_found"));
1186 } else if (user_data) {
1187 modest_platform_information_banner ((GtkWidget *) win,
1193 g_object_unref (win);
1197 * Returns the account a list of headers belongs to. It returns a
1198 * *new* reference so don't forget to unref it
1201 get_account_from_header_list (TnyList *headers)
1203 TnyAccount *account = NULL;
1205 if (tny_list_get_length (headers) > 0) {
1206 TnyIterator *iter = tny_list_create_iterator (headers);
1207 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1208 TnyFolder *folder = tny_header_get_folder (header);
1211 g_object_unref (header);
1213 while (!tny_iterator_is_done (iter)) {
1214 header = TNY_HEADER (tny_iterator_get_current (iter));
1215 folder = tny_header_get_folder (header);
1218 g_object_unref (header);
1220 tny_iterator_next (iter);
1225 account = tny_folder_get_account (folder);
1226 g_object_unref (folder);
1230 g_object_unref (header);
1232 g_object_unref (iter);
1238 get_account_from_header (TnyHeader *header)
1240 TnyAccount *account = NULL;
1243 folder = tny_header_get_folder (header);
1246 account = tny_folder_get_account (folder);
1247 g_object_unref (folder);
1254 open_msg_helper_destroyer (gpointer user_data)
1256 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1258 if (helper->banner_info) {
1259 g_free (helper->banner_info->message);
1260 if (helper->banner_info->idle_handler > 0) {
1261 g_source_remove (helper->banner_info->idle_handler);
1262 helper->banner_info->idle_handler = 0;
1264 if (helper->banner_info->banner != NULL) {
1265 gtk_widget_destroy (helper->banner_info->banner);
1266 g_object_unref (helper->banner_info->banner);
1267 helper->banner_info->banner = NULL;
1269 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1270 helper->banner_info = NULL;
1272 g_object_unref (helper->model);
1273 g_object_unref (helper->header);
1274 gtk_tree_row_reference_free (helper->rowref);
1275 g_slice_free (OpenMsgHelper, helper);
1279 open_msg_performer(gboolean canceled,
1281 GtkWindow *parent_window,
1282 TnyAccount *account,
1285 ModestMailOperation *mail_op = NULL;
1287 ModestProtocolType proto;
1288 TnyConnectionStatus status;
1289 gboolean show_open_draft = FALSE;
1290 OpenMsgHelper *helper = NULL;
1291 ModestProtocol *protocol;
1292 ModestProtocolRegistry *protocol_registry;
1295 helper = (OpenMsgHelper *) user_data;
1297 status = tny_account_get_connection_status (account);
1298 if (err || canceled) {
1299 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1300 /* Free the helper */
1301 open_msg_helper_destroyer (helper);
1303 /* In memory full conditions we could get this error here */
1304 check_memory_full_error ((GtkWidget *) parent_window, err);
1309 /* Get the error message depending on the protocol */
1310 proto = modest_tny_account_get_protocol_type (account);
1311 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1312 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1315 protocol_registry = modest_runtime_get_protocol_registry ();
1316 subject = tny_header_dup_subject (helper->header);
1318 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1319 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1323 if (error_msg == NULL) {
1324 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1327 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1329 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1331 TnyFolderType folder_type;
1333 folder = tny_header_get_folder (helper->header);
1334 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1335 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1336 g_object_unref (folder);
1339 #ifdef MODEST_TOOLKIT_HILDON2
1342 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1345 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1346 g_free (account_name);
1347 open_msg_helper_destroyer (helper);
1352 ModestWindow *window;
1353 GtkWidget *header_view;
1356 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1357 uid = modest_tny_folder_get_header_unique_id (helper->header);
1359 window = modest_msg_view_window_new_from_header_view
1360 (MODEST_HEADER_VIEW (header_view), account_name, uid, helper->rowref);
1361 if (window != NULL) {
1362 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1364 gtk_widget_destroy (GTK_WIDGET (window));
1366 gtk_widget_show_all (GTK_WIDGET(window));
1370 g_free (account_name);
1372 open_msg_helper_destroyer (helper);
1375 g_free (account_name);
1377 /* Create the mail operation */
1379 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1380 modest_ui_actions_disk_operations_error_handler,
1382 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1385 if (show_open_draft) {
1386 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1387 #ifdef MODEST_TOOLKIT_HILDON2
1388 helper->banner_info->message = g_strdup (_("mail_me_opening"));
1390 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1392 helper->banner_info->banner = NULL;
1393 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1394 helper->banner_info);
1398 headers = TNY_LIST (tny_simple_list_new ());
1399 tny_list_prepend (headers, G_OBJECT (helper->header));
1400 modest_mail_operation_get_msgs_full (mail_op,
1404 open_msg_helper_destroyer);
1405 g_object_unref (headers);
1410 g_object_unref (mail_op);
1411 g_object_unref (account);
1415 * This function is used by both modest_ui_actions_on_open and
1416 * modest_ui_actions_on_header_activated. This way we always do the
1417 * same when trying to open messages.
1420 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1422 ModestWindowMgr *mgr = NULL;
1423 TnyAccount *account;
1424 gboolean cached = FALSE;
1426 GtkWidget *header_view = NULL;
1427 OpenMsgHelper *helper;
1428 ModestWindow *window;
1430 g_return_if_fail (header != NULL && rowref != NULL);
1432 mgr = modest_runtime_get_window_mgr ();
1435 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1436 if (header_view == NULL)
1439 /* Get the account */
1440 account = get_account_from_header (header);
1445 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1447 /* Do not open again the message and present the
1448 window to the user */
1451 #ifndef MODEST_TOOLKIT_HILDON2
1452 gtk_window_present (GTK_WINDOW (window));
1455 /* the header has been registered already, we don't do
1456 * anything but wait for the window to come up*/
1457 g_debug ("header %p already registered, waiting for window", header);
1462 /* Open each message */
1463 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1465 /* Allways download if we are online. */
1466 if (!tny_device_is_online (modest_runtime_get_device ())) {
1469 /* If ask for user permission to download the messages */
1470 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1471 _("mcen_nc_get_msg"));
1473 /* End if the user does not want to continue */
1474 if (response == GTK_RESPONSE_CANCEL) {
1480 /* We register the window for opening */
1481 modest_window_mgr_register_header (mgr, header, NULL);
1483 /* Create the helper. We need to get a reference to the model
1484 here because it could change while the message is readed
1485 (the user could switch between folders) */
1486 helper = g_slice_new (OpenMsgHelper);
1487 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1488 helper->header = g_object_ref (header);
1489 helper->rowref = gtk_tree_row_reference_copy (rowref);
1490 helper->banner_info = NULL;
1492 /* Connect to the account and perform */
1494 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1495 open_msg_performer, helper);
1497 /* Call directly the performer, do not need to connect */
1498 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1499 g_object_ref (account), helper);
1504 g_object_unref (account);
1508 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1515 /* we check for low-mem; in that case, show a warning, and don't allow
1518 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1522 headers = get_selected_headers (win);
1526 headers_count = tny_list_get_length (headers);
1527 if (headers_count != 1) {
1528 if (headers_count > 1) {
1529 /* Don't allow activation if there are more than one message selected */
1530 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1533 g_object_unref (headers);
1537 iter = tny_list_create_iterator (headers);
1538 header = TNY_HEADER (tny_iterator_get_current (iter));
1539 g_object_unref (iter);
1543 open_msg_from_header (header, NULL, win);
1544 g_object_unref (header);
1547 g_object_unref(headers);
1551 rf_helper_window_closed (gpointer data,
1554 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1556 helper->parent_window = NULL;
1559 static ReplyForwardHelper*
1560 create_reply_forward_helper (ReplyForwardAction action,
1562 guint reply_forward_type,
1565 ReplyForwardHelper *rf_helper = NULL;
1566 const gchar *active_acc = modest_window_get_active_account (win);
1568 rf_helper = g_slice_new0 (ReplyForwardHelper);
1569 rf_helper->reply_forward_type = reply_forward_type;
1570 rf_helper->action = action;
1571 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1572 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1573 rf_helper->account_name = (active_acc) ?
1574 g_strdup (active_acc) :
1575 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1577 /* Note that window could be destroyed just AFTER calling
1578 register_window so we must ensure that this pointer does
1579 not hold invalid references */
1580 if (rf_helper->parent_window)
1581 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1582 rf_helper_window_closed, rf_helper);
1588 free_reply_forward_helper (gpointer data)
1590 ReplyForwardHelper *helper;
1592 helper = (ReplyForwardHelper *) data;
1593 g_free (helper->account_name);
1595 g_object_unref (helper->header);
1596 if (helper->parent_window)
1597 g_object_weak_unref (G_OBJECT (helper->parent_window),
1598 rf_helper_window_closed, helper);
1599 g_slice_free (ReplyForwardHelper, helper);
1603 reply_forward_cb (ModestMailOperation *mail_op,
1610 TnyMsg *new_msg = NULL;
1611 ReplyForwardHelper *rf_helper;
1612 ModestWindow *msg_win = NULL;
1613 ModestEditType edit_type;
1615 TnyAccount *account = NULL;
1616 ModestWindowMgr *mgr = NULL;
1617 gchar *signature = NULL;
1618 gboolean use_signature;
1620 /* If there was any error. The mail operation could be NULL,
1621 this means that we already have the message downloaded and
1622 that we didn't do a mail operation to retrieve it */
1623 rf_helper = (ReplyForwardHelper *) user_data;
1624 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1627 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1628 rf_helper->account_name);
1629 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr(),
1630 rf_helper->account_name,
1633 /* Create reply mail */
1634 switch (rf_helper->action) {
1637 modest_tny_msg_create_reply_msg (msg, header, from,
1638 (use_signature) ? signature : NULL,
1639 rf_helper->reply_forward_type,
1640 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1642 case ACTION_REPLY_TO_ALL:
1644 modest_tny_msg_create_reply_msg (msg, header, from,
1645 (use_signature) ? signature : NULL,
1646 rf_helper->reply_forward_type,
1647 MODEST_TNY_MSG_REPLY_MODE_ALL);
1648 edit_type = MODEST_EDIT_TYPE_REPLY;
1650 case ACTION_FORWARD:
1652 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1653 rf_helper->reply_forward_type);
1654 edit_type = MODEST_EDIT_TYPE_FORWARD;
1657 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1659 g_return_if_reached ();
1667 g_warning ("%s: failed to create message\n", __FUNCTION__);
1671 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1672 rf_helper->account_name,
1673 TNY_ACCOUNT_TYPE_STORE);
1675 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1679 /* Create and register the windows */
1680 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1681 mgr = modest_runtime_get_window_mgr ();
1682 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1684 /* Note that register_window could have deleted the account */
1685 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1686 gdouble parent_zoom;
1688 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1689 modest_window_set_zoom (msg_win, parent_zoom);
1692 /* Show edit window */
1693 gtk_widget_show_all (GTK_WIDGET (msg_win));
1696 /* We always unregister the header because the message is
1697 forwarded or replied so the original one is no longer
1699 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1702 g_object_unref (G_OBJECT (new_msg));
1704 g_object_unref (G_OBJECT (account));
1705 free_reply_forward_helper (rf_helper);
1708 /* Checks a list of headers. If any of them are not currently
1709 * downloaded (CACHED) then returns TRUE else returns FALSE.
1712 header_list_count_uncached_msgs (TnyList *header_list)
1715 gint uncached_messages = 0;
1717 iter = tny_list_create_iterator (header_list);
1718 while (!tny_iterator_is_done (iter)) {
1721 header = TNY_HEADER (tny_iterator_get_current (iter));
1723 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1724 uncached_messages ++;
1725 g_object_unref (header);
1728 tny_iterator_next (iter);
1730 g_object_unref (iter);
1732 return uncached_messages;
1735 /* Returns FALSE if the user does not want to download the
1736 * messages. Returns TRUE if the user allowed the download.
1739 connect_to_get_msg (ModestWindow *win,
1740 gint num_of_uncached_msgs,
1741 TnyAccount *account)
1743 GtkResponseType response;
1745 /* Allways download if we are online. */
1746 if (tny_device_is_online (modest_runtime_get_device ()))
1749 /* If offline, then ask for user permission to download the messages */
1750 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1751 ngettext("mcen_nc_get_msg",
1753 num_of_uncached_msgs));
1755 if (response == GTK_RESPONSE_CANCEL)
1758 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1762 reply_forward_performer (gboolean canceled,
1764 GtkWindow *parent_window,
1765 TnyAccount *account,
1768 ReplyForwardHelper *rf_helper = NULL;
1769 ModestMailOperation *mail_op;
1771 rf_helper = (ReplyForwardHelper *) user_data;
1773 if (canceled || err) {
1774 free_reply_forward_helper (rf_helper);
1778 /* Retrieve the message */
1779 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1780 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1781 modest_ui_actions_disk_operations_error_handler,
1783 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1784 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1787 g_object_unref(mail_op);
1791 * Common code for the reply and forward actions
1794 reply_forward (ReplyForwardAction action, ModestWindow *win)
1796 ReplyForwardHelper *rf_helper = NULL;
1797 guint reply_forward_type;
1799 g_return_if_fail (MODEST_IS_WINDOW(win));
1801 /* we check for low-mem; in that case, show a warning, and don't allow
1802 * reply/forward (because it could potentially require a lot of memory */
1803 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1807 /* we need an account when editing */
1808 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1809 if (!modest_ui_actions_run_account_setup_wizard (win))
1813 reply_forward_type =
1814 modest_conf_get_int (modest_runtime_get_conf (),
1815 (action == ACTION_FORWARD) ?
1816 MODEST_CONF_FORWARD_TYPE :
1817 MODEST_CONF_REPLY_TYPE,
1820 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1822 TnyHeader *header = NULL;
1823 /* Get header and message. Do not free them here, the
1824 reply_forward_cb must do it */
1825 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1826 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1828 if (msg && header) {
1830 rf_helper = create_reply_forward_helper (action, win,
1831 reply_forward_type, header);
1832 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1834 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1838 g_object_unref (msg);
1840 g_object_unref (header);
1842 TnyHeader *header = NULL;
1844 gboolean do_retrieve = TRUE;
1845 TnyList *header_list = NULL;
1847 header_list = get_selected_headers (win);
1850 /* Check that only one message is selected for replying */
1851 if (tny_list_get_length (header_list) != 1) {
1852 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1853 NULL, _("mcen_ib_select_one_message"));
1854 g_object_unref (header_list);
1858 /* Only reply/forward to one message */
1859 iter = tny_list_create_iterator (header_list);
1860 header = TNY_HEADER (tny_iterator_get_current (iter));
1861 g_object_unref (iter);
1863 /* Retrieve messages */
1864 do_retrieve = (action == ACTION_FORWARD) ||
1865 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1868 TnyAccount *account = NULL;
1869 TnyFolder *folder = NULL;
1870 gdouble download = TRUE;
1871 guint uncached_msgs = 0;
1873 folder = tny_header_get_folder (header);
1875 goto do_retrieve_frees;
1876 account = tny_folder_get_account (folder);
1878 goto do_retrieve_frees;
1880 uncached_msgs = header_list_count_uncached_msgs (header_list);
1882 if (uncached_msgs > 0) {
1883 /* Allways download if we are online. */
1884 if (!tny_device_is_online (modest_runtime_get_device ())) {
1887 /* If ask for user permission to download the messages */
1888 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1889 ngettext("mcen_nc_get_msg",
1893 /* End if the user does not want to continue */
1894 if (response == GTK_RESPONSE_CANCEL)
1901 rf_helper = create_reply_forward_helper (action, win,
1902 reply_forward_type, header);
1903 if (uncached_msgs > 0) {
1904 modest_platform_connect_and_perform (GTK_WINDOW (win),
1906 reply_forward_performer,
1909 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
1910 account, rf_helper);
1915 g_object_unref (account);
1917 g_object_unref (folder);
1919 reply_forward_cb (NULL, header, FALSE, NULL, NULL, rf_helper);
1922 g_object_unref (header_list);
1923 g_object_unref (header);
1928 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1930 g_return_if_fail (MODEST_IS_WINDOW(win));
1932 reply_forward (ACTION_REPLY, win);
1936 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1938 g_return_if_fail (MODEST_IS_WINDOW(win));
1940 reply_forward (ACTION_FORWARD, win);
1944 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1946 g_return_if_fail (MODEST_IS_WINDOW(win));
1948 reply_forward (ACTION_REPLY_TO_ALL, win);
1952 modest_ui_actions_on_next (GtkAction *action,
1953 ModestWindow *window)
1955 if (MODEST_IS_MAIN_WINDOW (window)) {
1956 GtkWidget *header_view;
1958 header_view = modest_main_window_get_child_widget (
1959 MODEST_MAIN_WINDOW(window),
1960 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1964 modest_header_view_select_next (
1965 MODEST_HEADER_VIEW(header_view));
1966 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1967 modest_msg_view_window_select_next_message (
1968 MODEST_MSG_VIEW_WINDOW (window));
1970 g_return_if_reached ();
1975 modest_ui_actions_on_prev (GtkAction *action,
1976 ModestWindow *window)
1978 g_return_if_fail (MODEST_IS_WINDOW(window));
1980 if (MODEST_IS_MAIN_WINDOW (window)) {
1981 GtkWidget *header_view;
1982 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1983 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1987 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1988 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1989 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1991 g_return_if_reached ();
1996 modest_ui_actions_on_sort (GtkAction *action,
1997 ModestWindow *window)
1999 GtkWidget *header_view = NULL;
2001 g_return_if_fail (MODEST_IS_WINDOW(window));
2003 if (MODEST_IS_MAIN_WINDOW (window)) {
2004 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2005 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2006 #ifdef MODEST_TOOLKIT_HILDON2
2007 } else if (MODEST_IS_HEADER_WINDOW (window)) {
2008 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2013 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
2018 /* Show sorting dialog */
2019 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
2023 new_messages_arrived (ModestMailOperation *self,
2024 TnyList *new_headers,
2028 gboolean show_visual_notifications;
2030 source = modest_mail_operation_get_source (self);
2031 show_visual_notifications = (source) ? FALSE : TRUE;
2033 g_object_unref (source);
2035 /* Notify new messages have been downloaded. If the
2036 send&receive was invoked by the user then do not show any
2037 visual notification, only play a sound and activate the LED
2038 (for the Maemo version) */
2039 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0)
2040 modest_platform_on_new_headers_received (new_headers,
2041 show_visual_notifications);
2046 retrieve_all_messages_cb (GObject *source,
2048 guint retrieve_limit)
2054 window = GTK_WINDOW (source);
2055 msg = g_strdup_printf (_("mail_nc_msg_count_limit_exceeded"),
2056 num_msgs, retrieve_limit);
2058 /* Ask the user if they want to retrieve all the messages */
2060 modest_platform_run_confirmation_dialog_with_buttons (window, msg,
2061 _("mcen_bd_get_all"),
2062 _("mcen_bd_newest_only"));
2063 /* Free and return */
2065 return (response == GTK_RESPONSE_ACCEPT) ? TRUE : FALSE;
2069 TnyAccount *account;
2071 gchar *account_name;
2072 gboolean poke_status;
2073 gboolean interactive;
2074 ModestMailOperation *mail_op;
2078 do_send_receive_performer (gboolean canceled,
2080 GtkWindow *parent_window,
2081 TnyAccount *account,
2084 SendReceiveInfo *info;
2086 info = (SendReceiveInfo *) user_data;
2088 if (err || canceled) {
2089 /* In memory full conditions we could get this error here */
2090 check_memory_full_error ((GtkWidget *) parent_window, err);
2092 if (info->mail_op) {
2093 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2099 /* Set send/receive operation in progress */
2100 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2101 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2104 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2105 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2106 G_CALLBACK (on_send_receive_finished),
2109 /* Send & receive. */
2110 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2111 (info->win) ? retrieve_all_messages_cb : NULL,
2112 new_messages_arrived, info->win);
2117 g_object_unref (G_OBJECT (info->mail_op));
2118 if (info->account_name)
2119 g_free (info->account_name);
2121 g_object_unref (info->win);
2123 g_object_unref (info->account);
2124 g_slice_free (SendReceiveInfo, info);
2128 * This function performs the send & receive required actions. The
2129 * window is used to create the mail operation. Typically it should
2130 * always be the main window, but we pass it as argument in order to
2134 modest_ui_actions_do_send_receive (const gchar *account_name,
2135 gboolean force_connection,
2136 gboolean poke_status,
2137 gboolean interactive,
2140 gchar *acc_name = NULL;
2141 SendReceiveInfo *info;
2142 ModestTnyAccountStore *acc_store;
2144 /* If no account name was provided then get the current account, and if
2145 there is no current account then pick the default one: */
2146 if (!account_name) {
2148 acc_name = g_strdup (modest_window_get_active_account (win));
2150 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2152 g_printerr ("modest: cannot get default account\n");
2156 acc_name = g_strdup (account_name);
2159 acc_store = modest_runtime_get_account_store ();
2161 /* Create the info for the connect and perform */
2162 info = g_slice_new (SendReceiveInfo);
2163 info->account_name = acc_name;
2164 info->win = (win) ? g_object_ref (win) : NULL;
2165 info->poke_status = poke_status;
2166 info->interactive = interactive;
2167 info->account = modest_tny_account_store_get_server_account (acc_store, acc_name,
2168 TNY_ACCOUNT_TYPE_STORE);
2169 /* We need to create the operation here, because otherwise it
2170 could happen that the queue emits the queue-empty signal
2171 while we're trying to connect the account */
2172 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2173 modest_ui_actions_disk_operations_error_handler,
2175 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2177 /* Invoke the connect and perform */
2178 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2179 force_connection, info->account,
2180 do_send_receive_performer, info);
2185 modest_ui_actions_do_cancel_send (const gchar *account_name,
2188 TnyTransportAccount *transport_account;
2189 TnySendQueue *send_queue = NULL;
2190 GError *error = NULL;
2192 /* Get transport account */
2194 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2195 (modest_runtime_get_account_store(),
2197 TNY_ACCOUNT_TYPE_TRANSPORT));
2198 if (!transport_account) {
2199 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2204 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2205 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2206 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2207 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2208 "modest: could not find send queue for account\n");
2210 /* Cancel the current send */
2211 tny_account_cancel (TNY_ACCOUNT (transport_account));
2213 /* Suspend all pending messages */
2214 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2218 if (transport_account != NULL)
2219 g_object_unref (G_OBJECT (transport_account));
2223 modest_ui_actions_cancel_send_all (ModestWindow *win)
2225 GSList *account_names, *iter;
2227 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2230 iter = account_names;
2232 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2233 iter = g_slist_next (iter);
2236 modest_account_mgr_free_account_names (account_names);
2237 account_names = NULL;
2241 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2244 /* Check if accounts exist */
2245 gboolean accounts_exist =
2246 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2248 /* If not, allow the user to create an account before trying to send/receive. */
2249 if (!accounts_exist)
2250 modest_ui_actions_on_accounts (NULL, win);
2252 /* Cancel all sending operaitons */
2253 modest_ui_actions_cancel_send_all (win);
2257 * Refreshes all accounts. This function will be used by automatic
2261 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2262 gboolean force_connection,
2263 gboolean poke_status,
2264 gboolean interactive)
2266 GSList *account_names, *iter;
2268 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2271 iter = account_names;
2273 modest_ui_actions_do_send_receive ((const char*) iter->data,
2275 poke_status, interactive, win);
2276 iter = g_slist_next (iter);
2279 modest_account_mgr_free_account_names (account_names);
2280 account_names = NULL;
2284 * Handler of the click on Send&Receive button in the main toolbar
2287 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2289 /* Check if accounts exist */
2290 gboolean accounts_exist;
2293 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2295 /* If not, allow the user to create an account before trying to send/receive. */
2296 if (!accounts_exist)
2297 modest_ui_actions_on_accounts (NULL, win);
2299 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2300 if (MODEST_IS_MAIN_WINDOW (win)) {
2301 GtkWidget *folder_view;
2302 TnyFolderStore *folder_store;
2305 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2306 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2310 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2313 g_object_unref (folder_store);
2314 /* Refresh the active account. Force the connection if needed
2315 and poke the status of all folders */
2316 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2317 #ifdef MODEST_TOOLKIT_HILDON2
2318 } else if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2319 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2322 const gchar *active_account;
2323 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2325 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2332 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2335 GtkWidget *header_view;
2337 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2339 header_view = modest_main_window_get_child_widget (main_window,
2340 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2344 conf = modest_runtime_get_conf ();
2346 /* what is saved/restored is depending on the style; thus; we save with
2347 * old style, then update the style, and restore for this new style
2349 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2351 if (modest_header_view_get_style
2352 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2353 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2354 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2356 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2357 MODEST_HEADER_VIEW_STYLE_DETAILS);
2359 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2360 MODEST_CONF_HEADER_VIEW_KEY);
2365 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2367 ModestMainWindow *main_window)
2369 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2370 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2372 /* in the case the folder is empty, show the empty folder message and focus
2374 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2375 if (modest_header_view_is_empty (header_view)) {
2376 TnyFolder *folder = modest_header_view_get_folder (header_view);
2377 GtkWidget *folder_view =
2378 modest_main_window_get_child_widget (main_window,
2379 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2380 if (folder != NULL) {
2381 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2382 g_object_unref (folder);
2384 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2388 /* If no header has been selected then exit */
2393 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2394 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2396 /* Update toolbar dimming state */
2397 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2398 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2402 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2405 ModestWindow *window)
2407 GtkWidget *open_widget;
2408 GtkTreeRowReference *rowref;
2410 g_return_if_fail (MODEST_IS_WINDOW(window));
2411 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2412 g_return_if_fail (TNY_IS_HEADER (header));
2414 if (modest_header_view_count_selected_headers (header_view) > 1) {
2415 /* Don't allow activation if there are more than one message selected */
2416 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2420 /* we check for low-mem; in that case, show a warning, and don't allow
2421 * activating headers
2423 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2426 if (MODEST_IS_MAIN_WINDOW (window)) {
2427 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2428 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2429 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2433 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2434 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2435 gtk_tree_row_reference_free (rowref);
2439 set_active_account_from_tny_account (TnyAccount *account,
2440 ModestWindow *window)
2442 const gchar *server_acc_name = tny_account_get_id (account);
2444 /* We need the TnyAccount provided by the
2445 account store because that is the one that
2446 knows the name of the Modest account */
2447 TnyAccount *modest_server_account = modest_server_account =
2448 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2449 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2451 if (!modest_server_account) {
2452 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2456 /* Update active account, but only if it's not a pseudo-account */
2457 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2458 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2459 const gchar *modest_acc_name =
2460 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2461 if (modest_acc_name)
2462 modest_window_set_active_account (window, modest_acc_name);
2465 g_object_unref (modest_server_account);
2470 folder_refreshed_cb (ModestMailOperation *mail_op,
2474 ModestMainWindow *win = NULL;
2475 GtkWidget *folder_view;
2476 const GError *error;
2478 g_return_if_fail (TNY_IS_FOLDER (folder));
2480 win = MODEST_MAIN_WINDOW (user_data);
2482 /* Check if the operation failed due to memory low conditions */
2483 error = modest_mail_operation_get_error (mail_op);
2484 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2485 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2486 modest_platform_run_information_dialog (GTK_WINDOW (win),
2487 dgettext("ke-recv","memr_ib_operation_disabled"),
2493 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2496 TnyFolderStore *current_folder;
2498 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2499 if (current_folder) {
2500 gboolean different = ((TnyFolderStore *) folder != current_folder);
2501 g_object_unref (current_folder);
2507 /* Check if folder is empty and set headers view contents style */
2508 if (tny_folder_get_all_count (folder) == 0)
2509 modest_main_window_set_contents_style (win,
2510 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2515 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2516 TnyFolderStore *folder_store,
2518 ModestMainWindow *main_window)
2521 GtkWidget *header_view;
2523 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2525 header_view = modest_main_window_get_child_widget(main_window,
2526 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2530 conf = modest_runtime_get_conf ();
2532 if (TNY_IS_ACCOUNT (folder_store)) {
2534 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2536 /* Show account details */
2537 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2540 if (TNY_IS_FOLDER (folder_store) && selected) {
2541 TnyAccount *account;
2542 const gchar *account_name = NULL;
2544 /* Update the active account */
2545 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2547 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2549 modest_tny_account_get_parent_modest_account_name_for_server_account (account);
2550 g_object_unref (account);
2554 /* Set the header style by default, it could
2555 be changed later by the refresh callback to
2557 modest_main_window_set_contents_style (main_window,
2558 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2560 /* Set folder on header view. This function
2561 will call tny_folder_refresh_async so we
2562 pass a callback that will be called when
2563 finished. We use that callback to set the
2564 empty view if there are no messages */
2565 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2566 TNY_FOLDER (folder_store),
2568 MODEST_WINDOW (main_window),
2569 folder_refreshed_cb,
2572 /* Restore configuration. We need to do this
2573 *after* the set_folder because the widget
2574 memory asks the header view about its
2576 modest_widget_memory_restore (modest_runtime_get_conf (),
2577 G_OBJECT(header_view),
2578 MODEST_CONF_HEADER_VIEW_KEY);
2580 /* No need to save the header view
2581 configuration for Maemo because it only
2582 saves the sorting stuff and that it's
2583 already being done by the sort
2584 dialog. Remove it when the GNOME version
2585 has the same behaviour */
2586 #ifdef MODEST_TOOLKIT_GTK
2587 if (modest_main_window_get_contents_style (main_window) ==
2588 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2589 modest_widget_memory_save (conf, G_OBJECT (header_view),
2590 MODEST_CONF_HEADER_VIEW_KEY);
2592 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2596 /* Update dimming state */
2597 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2598 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2602 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2609 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2611 online = tny_device_is_online (modest_runtime_get_device());
2614 /* already online -- the item is simply not there... */
2615 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2617 GTK_MESSAGE_WARNING,
2619 _("The %s you selected cannot be found"),
2621 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2622 gtk_dialog_run (GTK_DIALOG(dialog));
2624 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2627 _("mcen_bd_dialog_cancel"),
2628 GTK_RESPONSE_REJECT,
2629 _("mcen_bd_dialog_ok"),
2630 GTK_RESPONSE_ACCEPT,
2632 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2633 "Do you want to get online?"), item);
2634 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2635 gtk_label_new (txt), FALSE, FALSE, 0);
2636 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2639 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2640 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2641 /* TODO: Comment about why is this commented out: */
2642 /* modest_platform_connect_and_wait (); */
2645 gtk_widget_destroy (dialog);
2649 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2652 /* g_message ("%s %s", __FUNCTION__, link); */
2657 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2660 modest_platform_activate_uri (link);
2664 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2667 modest_platform_show_uri_popup (link);
2671 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2674 /* we check for low-mem; in that case, show a warning, and don't allow
2675 * viewing attachments
2677 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2680 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2684 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2685 const gchar *address,
2688 /* g_message ("%s %s", __FUNCTION__, address); */
2692 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2693 TnyMsg *saved_draft,
2696 ModestMsgEditWindow *edit_window;
2698 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2699 #ifndef MODEST_TOOLKIT_HILDON2
2700 ModestMainWindow *win;
2702 /* FIXME. Make the header view sensitive again. This is a
2703 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2705 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2706 modest_runtime_get_window_mgr(), FALSE));
2708 GtkWidget *hdrview = modest_main_window_get_child_widget(
2709 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2710 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2714 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2716 /* Set draft is there was no error */
2717 if (!modest_mail_operation_get_error (mail_op))
2718 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2720 g_object_unref(edit_window);
2724 enough_space_for_message (ModestMsgEditWindow *edit_window,
2727 TnyAccountStore *acc_store;
2728 guint64 available_disk, expected_size;
2733 acc_store = TNY_ACCOUNT_STORE (modest_runtime_get_account_store());
2734 available_disk = modest_utils_get_available_space (NULL);
2735 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2736 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2741 /* Double check: memory full condition or message too big */
2742 if (available_disk < MIN_FREE_SPACE ||
2743 expected_size > available_disk) {
2745 modest_platform_information_banner (NULL, NULL,
2747 "cerm_device_memory_full"));
2752 * djcb: if we're in low-memory state, we only allow for
2753 * saving messages smaller than
2754 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2755 * should still allow for sending anything critical...
2757 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2758 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2762 * djcb: we also make sure that the attachments are smaller than the max size
2763 * this is for the case where we'd try to forward a message with attachments
2764 * bigger than our max allowed size, or sending an message from drafts which
2765 * somehow got past our checks when attaching.
2767 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2768 modest_platform_run_information_dialog (
2769 GTK_WINDOW(edit_window),
2770 dgettext("ke-recv","memr_ib_operation_disabled"),
2779 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2781 TnyTransportAccount *transport_account;
2782 ModestMailOperation *mail_operation;
2784 gchar *account_name, *from;
2785 ModestAccountMgr *account_mgr;
2786 gboolean had_error = FALSE;
2787 ModestMainWindow *win = NULL;
2789 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2791 data = modest_msg_edit_window_get_msg_data (edit_window);
2794 if (!enough_space_for_message (edit_window, data)) {
2795 modest_msg_edit_window_free_msg_data (edit_window, data);
2799 account_name = g_strdup (data->account_name);
2800 account_mgr = modest_runtime_get_account_mgr();
2802 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2804 account_name = modest_account_mgr_get_default_account (account_mgr);
2805 if (!account_name) {
2806 g_printerr ("modest: no account found\n");
2807 modest_msg_edit_window_free_msg_data (edit_window, data);
2811 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2812 account_name = g_strdup (data->account_name);
2816 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2817 (modest_runtime_get_account_store (),
2819 TNY_ACCOUNT_TYPE_TRANSPORT));
2820 if (!transport_account) {
2821 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2822 g_free (account_name);
2823 modest_msg_edit_window_free_msg_data (edit_window, data);
2826 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2828 /* Create the mail operation */
2829 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
2831 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2833 modest_mail_operation_save_to_drafts (mail_operation,
2845 data->priority_flags,
2846 on_save_to_drafts_cb,
2847 g_object_ref(edit_window));
2849 #ifdef MODEST_TOOLKIT_HILDON2
2850 /* In hildon2 we always show the information banner on saving to drafts.
2851 * It will be a system information banner in this case.
2853 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2854 modest_platform_information_banner (NULL, NULL, text);
2857 /* Use the main window as the parent of the banner, if the
2858 main window does not exist it won't be shown, if the parent
2859 window exists then it's properly shown. We don't use the
2860 editor window because it could be closed (save to drafts
2861 could happen after closing the window */
2862 win = (ModestMainWindow *)
2863 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
2865 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2866 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
2870 modest_msg_edit_window_set_modified (edit_window, FALSE);
2874 g_free (account_name);
2875 g_object_unref (G_OBJECT (transport_account));
2876 g_object_unref (G_OBJECT (mail_operation));
2878 modest_msg_edit_window_free_msg_data (edit_window, data);
2881 * If the drafts folder is selected then make the header view
2882 * insensitive while the message is being saved to drafts
2883 * (it'll be sensitive again in on_save_to_drafts_cb()). This
2884 * is not very clean but it avoids letting the drafts folder
2885 * in an inconsistent state: the user could edit the message
2886 * being saved and undesirable things would happen.
2887 * In the average case the user won't notice anything at
2888 * all. In the worst case (the user is editing a really big
2889 * file from Drafts) the header view will be insensitive
2890 * during the saving process (10 or 20 seconds, depending on
2891 * the message). Anyway this is just a quick workaround: once
2892 * we find a better solution it should be removed
2893 * See NB#65125 (commend #18) for details.
2895 if (!had_error && win != NULL) {
2896 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
2897 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
2899 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
2901 if (modest_tny_folder_is_local_folder(folder)) {
2902 TnyFolderType folder_type;
2903 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
2904 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
2905 GtkWidget *hdrview = modest_main_window_get_child_widget(
2906 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2907 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
2911 if (folder != NULL) g_object_unref(folder);
2918 /* For instance, when clicking the Send toolbar button when editing a message: */
2920 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2922 TnyTransportAccount *transport_account = NULL;
2923 gboolean had_error = FALSE;
2925 ModestAccountMgr *account_mgr;
2926 gchar *account_name;
2928 ModestMailOperation *mail_operation;
2930 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
2932 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2935 data = modest_msg_edit_window_get_msg_data (edit_window);
2938 if (!enough_space_for_message (edit_window, data)) {
2939 modest_msg_edit_window_free_msg_data (edit_window, data);
2943 account_mgr = modest_runtime_get_account_mgr();
2944 account_name = g_strdup (data->account_name);
2946 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2949 account_name = modest_account_mgr_get_default_account (account_mgr);
2951 if (!account_name) {
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 /* Get the currently-active transport account for this modest account: */
2960 if (strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
2962 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2963 (modest_runtime_get_account_store (),
2964 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
2967 if (!transport_account) {
2968 modest_msg_edit_window_free_msg_data (edit_window, data);
2969 /* Run account setup wizard */
2970 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2975 /* Create the mail operation */
2976 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2977 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
2978 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2980 modest_mail_operation_send_new_mail (mail_operation,
2992 data->priority_flags);
2994 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
2995 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2998 if (modest_mail_operation_get_error (mail_operation) != NULL) {
2999 const GError *error = modest_mail_operation_get_error (mail_operation);
3000 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3001 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3002 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3003 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3010 g_free (account_name);
3011 g_object_unref (G_OBJECT (transport_account));
3012 g_object_unref (G_OBJECT (mail_operation));
3014 modest_msg_edit_window_free_msg_data (edit_window, data);
3017 modest_msg_edit_window_set_sent (edit_window, TRUE);
3019 /* Save settings and close the window: */
3020 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3027 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3028 ModestMsgEditWindow *window)
3030 ModestMsgEditFormatState *format_state = NULL;
3032 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3033 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3035 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3038 format_state = modest_msg_edit_window_get_format_state (window);
3039 g_return_if_fail (format_state != NULL);
3041 format_state->bold = gtk_toggle_action_get_active (action);
3042 modest_msg_edit_window_set_format_state (window, format_state);
3043 g_free (format_state);
3048 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3049 ModestMsgEditWindow *window)
3051 ModestMsgEditFormatState *format_state = NULL;
3053 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3054 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3056 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3059 format_state = modest_msg_edit_window_get_format_state (window);
3060 g_return_if_fail (format_state != NULL);
3062 format_state->italics = gtk_toggle_action_get_active (action);
3063 modest_msg_edit_window_set_format_state (window, format_state);
3064 g_free (format_state);
3069 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3070 ModestMsgEditWindow *window)
3072 ModestMsgEditFormatState *format_state = NULL;
3074 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3075 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3077 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3080 format_state = modest_msg_edit_window_get_format_state (window);
3081 g_return_if_fail (format_state != NULL);
3083 format_state->bullet = gtk_toggle_action_get_active (action);
3084 modest_msg_edit_window_set_format_state (window, format_state);
3085 g_free (format_state);
3090 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3091 GtkRadioAction *selected,
3092 ModestMsgEditWindow *window)
3094 ModestMsgEditFormatState *format_state = NULL;
3095 GtkJustification value;
3097 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3099 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3102 value = gtk_radio_action_get_current_value (selected);
3104 format_state = modest_msg_edit_window_get_format_state (window);
3105 g_return_if_fail (format_state != NULL);
3107 format_state->justification = value;
3108 modest_msg_edit_window_set_format_state (window, format_state);
3109 g_free (format_state);
3113 modest_ui_actions_on_select_editor_color (GtkAction *action,
3114 ModestMsgEditWindow *window)
3116 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3117 g_return_if_fail (GTK_IS_ACTION (action));
3119 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3122 modest_msg_edit_window_select_color (window);
3126 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3127 ModestMsgEditWindow *window)
3129 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3130 g_return_if_fail (GTK_IS_ACTION (action));
3132 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3135 modest_msg_edit_window_select_background_color (window);
3139 modest_ui_actions_on_insert_image (GObject *object,
3140 ModestMsgEditWindow *window)
3142 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3145 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3148 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3151 modest_msg_edit_window_insert_image (window);
3155 modest_ui_actions_on_attach_file (GtkAction *action,
3156 ModestMsgEditWindow *window)
3158 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3159 g_return_if_fail (GTK_IS_ACTION (action));
3161 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3164 modest_msg_edit_window_offer_attach_file (window);
3168 modest_ui_actions_on_remove_attachments (GtkAction *action,
3169 ModestMsgEditWindow *window)
3171 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3173 modest_msg_edit_window_remove_attachments (window, NULL);
3177 #ifndef MODEST_TOOLKIT_GTK
3182 TnyFolderStore *folder;
3183 } CreateFolderHelper;
3186 show_create_folder_in_timeout (gpointer data)
3188 CreateFolderHelper *helper = (CreateFolderHelper *) data;
3190 /* Remove the timeout ASAP, we can not wait until the dialog
3191 is shown because it could take a lot of time and so the
3192 timeout could be called twice or more times */
3193 g_source_remove (helper->handler);
3195 gdk_threads_enter ();
3196 do_create_folder (helper->win, helper->folder, helper->name);
3197 gdk_threads_leave ();
3199 g_object_unref (helper->win);
3200 g_object_unref (helper->folder);
3201 g_free (helper->name);
3202 g_slice_free (CreateFolderHelper, helper);
3209 do_create_folder_cb (ModestMailOperation *mail_op,
3210 TnyFolderStore *parent_folder,
3211 TnyFolder *new_folder,
3214 gchar *suggested_name = (gchar *) user_data;
3215 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3217 if (modest_mail_operation_get_error (mail_op)) {
3219 /* Show an error. If there was some problem writing to
3220 disk, show it, otherwise show the generic folder
3221 create error. We do it here and not in an error
3222 handler because the call to do_create_folder will
3223 stop the main loop in a gtk_dialog_run and then,
3224 the message won't be shown until that dialog is
3226 modest_ui_actions_disk_operations_error_handler (mail_op,
3227 _("mail_in_ui_folder_create_error"));
3229 /* Try again. Do *NOT* show any error because the mail
3230 operations system will do it for us because we
3231 created the mail_op with new_with_error_handler */
3232 #ifndef MODEST_TOOLKIT_GTK
3233 CreateFolderHelper *helper;
3234 helper = g_slice_new0 (CreateFolderHelper);
3235 helper->name = g_strdup (suggested_name);
3236 helper->folder = g_object_ref (parent_folder);
3237 helper->win = g_object_ref (source_win);
3239 /* Ugly but neccesary stuff. The problem is that the
3240 dialog when is shown calls a function that destroys
3241 all the temporary windows, so the banner is
3243 helper->handler = g_timeout_add (2000, show_create_folder_in_timeout, helper);
3245 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3248 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3249 * FIXME: any other? */
3250 GtkWidget *folder_view;
3252 if (MODEST_IS_MAIN_WINDOW(source_win))
3254 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3255 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3257 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3258 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3260 /* Select the newly created folder. It could happen
3261 that the widget is no longer there (i.e. the window
3262 has been destroyed, so we need to check this */
3264 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3266 g_object_unref (new_folder);
3268 /* Free. Note that the first time it'll be NULL so noop */
3269 g_free (suggested_name);
3270 g_object_unref (source_win);
3274 do_create_folder (GtkWindow *parent_window,
3275 TnyFolderStore *suggested_parent,
3276 const gchar *suggested_name)
3279 gchar *folder_name = NULL;
3280 TnyFolderStore *parent_folder = NULL;
3282 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3284 (gchar *) suggested_name,
3288 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3289 ModestMailOperation *mail_op;
3291 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3292 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3294 modest_mail_operation_create_folder (mail_op,
3296 (const gchar *) folder_name,
3297 do_create_folder_cb,
3299 g_object_unref (mail_op);
3303 g_object_unref (parent_folder);
3307 create_folder_performer (gboolean canceled,
3309 GtkWindow *parent_window,
3310 TnyAccount *account,
3313 TnyFolderStore *parent_folder = TNY_FOLDER_STORE (user_data);
3315 if (canceled || err) {
3316 /* In memory full conditions we could get this error here */
3317 check_memory_full_error ((GtkWidget *) parent_window, err);
3321 /* Run the new folder dialog */
3322 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3325 g_object_unref (parent_folder);
3329 modest_ui_actions_create_folder(GtkWidget *parent_window,
3330 GtkWidget *folder_view)
3332 TnyFolderStore *parent_folder;
3334 #ifdef MODEST_TOOLKIT_HILDON2
3335 const gchar *active_account;
3336 TnyAccount *account;
3337 ModestTnyAccountStore *acc_store;
3339 /* In hildon 2.2 we use the current account as default parent */
3340 acc_store = modest_runtime_get_account_store ();
3341 active_account = modest_window_get_active_account (MODEST_WINDOW (parent_window));
3342 if (active_account) {
3343 account = modest_tny_account_store_get_server_account (acc_store,
3345 TNY_ACCOUNT_TYPE_STORE);
3346 parent_folder = TNY_FOLDER_STORE (account);
3348 parent_folder = (TnyFolderStore *)
3349 modest_tny_account_store_get_local_folders_account (acc_store);
3352 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3355 if (parent_folder) {
3356 /* The parent folder will be freed in the callback */
3357 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3360 create_folder_performer,
3366 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3369 g_return_if_fail (MODEST_IS_WINDOW(window));
3371 if (MODEST_IS_MAIN_WINDOW (window)) {
3372 GtkWidget *folder_view;
3374 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3375 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3379 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view);
3380 #ifdef MODEST_TOOLKIT_HILDON2
3381 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3382 GtkWidget *folder_view;
3384 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3385 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view);
3388 g_assert_not_reached ();
3393 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3396 const GError *error = NULL;
3397 const gchar *message = NULL;
3399 /* Get error message */
3400 error = modest_mail_operation_get_error (mail_op);
3402 g_return_if_reached ();
3404 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3405 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3406 message = _CS("ckdg_ib_folder_already_exists");
3407 } else if (error->domain == TNY_ERROR_DOMAIN &&
3408 error->code == TNY_SERVICE_ERROR_STATE) {
3409 /* This means that the folder is already in use (a
3410 message is opened for example */
3411 message = _("emev_ni_internal_error");
3413 message = _("emev_ib_ui_imap_unable_to_rename");
3416 /* We don't set a parent for the dialog because the dialog
3417 will be destroyed so the banner won't appear */
3418 modest_platform_information_banner (NULL, NULL, message);
3422 TnyFolderStore *folder;
3427 on_rename_folder_cb (ModestMailOperation *mail_op,
3428 TnyFolder *new_folder,
3431 ModestFolderView *folder_view;
3433 /* If the window was closed when renaming a folder, or if
3434 * it's not a main window this will happen */
3435 if (!MODEST_IS_FOLDER_VIEW (user_data))
3438 folder_view = MODEST_FOLDER_VIEW (user_data);
3439 /* Note that if the rename fails new_folder will be NULL */
3441 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3443 modest_folder_view_select_first_inbox_or_local (folder_view);
3445 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3449 on_rename_folder_performer (gboolean canceled,
3451 GtkWindow *parent_window,
3452 TnyAccount *account,
3455 ModestMailOperation *mail_op = NULL;
3456 GtkTreeSelection *sel = NULL;
3457 GtkWidget *folder_view = NULL;
3458 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3460 if (canceled || err) {
3461 /* In memory full conditions we could get this error here */
3462 check_memory_full_error ((GtkWidget *) parent_window, err);
3466 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3467 modest_ui_actions_rename_folder_error_handler,
3468 parent_window, NULL);
3470 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3473 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3475 folder_view = modest_main_window_get_child_widget (
3476 MODEST_MAIN_WINDOW (parent_window),
3477 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3479 /* Clear the headers view */
3480 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3481 gtk_tree_selection_unselect_all (sel);
3486 /* Actually rename the folder */
3487 modest_mail_operation_rename_folder (mail_op,
3488 TNY_FOLDER (data->folder),
3489 (const gchar *) (data->new_name),
3490 on_rename_folder_cb,
3492 g_object_unref (data->folder);
3493 g_object_unref (mail_op);
3496 g_free (data->new_name);
3501 modest_ui_actions_on_rename_folder (GtkAction *action,
3502 ModestWindow *window)
3504 modest_ui_actions_on_edit_mode_rename_folder (window);
3508 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3510 TnyFolderStore *folder;
3511 GtkWidget *folder_view;
3512 gboolean do_rename = TRUE;
3514 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3516 if (MODEST_IS_MAIN_WINDOW (window)) {
3517 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3518 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3522 #ifdef MODEST_TOOLKIT_HILDON2
3523 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3524 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3530 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3535 if (TNY_IS_FOLDER (folder)) {
3536 gchar *folder_name = NULL;
3538 const gchar *current_name;
3539 TnyFolderStore *parent;
3541 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3542 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3543 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
3544 parent, current_name,
3546 g_object_unref (parent);
3548 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3551 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3552 rename_folder_data->folder = g_object_ref (folder);
3553 rename_folder_data->new_name = folder_name;
3554 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
3555 folder, on_rename_folder_performer, rename_folder_data);
3558 g_object_unref (folder);
3563 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3566 GObject *win = modest_mail_operation_get_source (mail_op);
3568 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3569 _("mail_in_ui_folder_delete_error"),
3571 g_object_unref (win);
3575 TnyFolderStore *folder;
3576 gboolean move_to_trash;
3580 on_delete_folder_cb (gboolean canceled,
3582 GtkWindow *parent_window,
3583 TnyAccount *account,
3586 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3587 GtkWidget *folder_view;
3588 ModestMailOperation *mail_op;
3589 GtkTreeSelection *sel;
3591 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
3592 g_object_unref (G_OBJECT (info->folder));
3597 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
3598 folder_view = modest_main_window_get_child_widget (
3599 MODEST_MAIN_WINDOW (parent_window),
3600 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3601 #ifdef MODEST_TOOLKIT_HILDON2
3602 } else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3603 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
3606 g_object_unref (G_OBJECT (info->folder));
3611 /* Unselect the folder before deleting it to free the headers */
3612 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3613 gtk_tree_selection_unselect_all (sel);
3615 /* Create the mail operation */
3617 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3618 modest_ui_actions_delete_folder_error_handler,
3621 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3623 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3625 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3627 g_object_unref (G_OBJECT (mail_op));
3628 g_object_unref (G_OBJECT (info->folder));
3633 delete_folder (ModestWindow *window, gboolean move_to_trash)
3635 TnyFolderStore *folder;
3636 GtkWidget *folder_view;
3640 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3642 if (MODEST_IS_MAIN_WINDOW (window)) {
3644 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3645 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3646 #ifdef MODEST_TOOLKIT_HILDON2
3647 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3648 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3656 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3658 /* Show an error if it's an account */
3659 if (!TNY_IS_FOLDER (folder)) {
3660 modest_platform_run_information_dialog (GTK_WINDOW (window),
3661 _("mail_in_ui_folder_delete_error"),
3663 g_object_unref (G_OBJECT (folder));
3668 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3669 tny_folder_get_name (TNY_FOLDER (folder)));
3670 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
3671 (const gchar *) message);
3674 if (response == GTK_RESPONSE_OK) {
3675 DeleteFolderInfo *info;
3676 info = g_new0(DeleteFolderInfo, 1);
3677 info->folder = folder;
3678 info->move_to_trash = move_to_trash;
3679 g_object_ref (G_OBJECT (info->folder));
3680 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder));
3681 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
3683 TNY_FOLDER_STORE (account),
3684 on_delete_folder_cb, info);
3685 g_object_unref (account);
3690 g_object_unref (G_OBJECT (folder));
3694 modest_ui_actions_on_delete_folder (GtkAction *action,
3695 ModestWindow *window)
3697 modest_ui_actions_on_edit_mode_delete_folder (window);
3701 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
3703 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
3705 return delete_folder (window, FALSE);
3709 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3711 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3713 delete_folder (MODEST_WINDOW (main_window), TRUE);
3717 typedef struct _PasswordDialogFields {
3718 GtkWidget *username;
3719 GtkWidget *password;
3721 } PasswordDialogFields;
3724 password_dialog_check_field (GtkEditable *editable,
3725 PasswordDialogFields *fields)
3728 gboolean any_value_empty = FALSE;
3730 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
3731 if ((value == NULL) || value[0] == '\0') {
3732 any_value_empty = TRUE;
3734 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
3735 if ((value == NULL) || value[0] == '\0') {
3736 any_value_empty = TRUE;
3738 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3742 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3743 const gchar* server_account_name,
3748 ModestMainWindow *main_window)
3750 g_return_if_fail(server_account_name);
3751 gboolean completed = FALSE;
3752 PasswordDialogFields *fields = NULL;
3754 /* Initalize output parameters: */
3761 #ifndef MODEST_TOOLKIT_GTK
3762 /* Maemo uses a different (awkward) button order,
3763 * It should probably just use gtk_alternative_dialog_button_order ().
3765 #ifdef MODEST_TOOLKIT_HILDON2
3767 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3770 _HL("wdgt_bd_done"),
3771 GTK_RESPONSE_ACCEPT,
3775 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3778 _("mcen_bd_dialog_ok"),
3779 GTK_RESPONSE_ACCEPT,
3780 _("mcen_bd_dialog_cancel"),
3781 GTK_RESPONSE_REJECT,
3783 #endif /* MODEST_TOOLKIT_HILDON2 */
3786 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3790 GTK_RESPONSE_REJECT,
3792 GTK_RESPONSE_ACCEPT,
3794 #endif /* MODEST_TOOLKIT_GTK */
3796 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3798 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3799 modest_runtime_get_account_mgr(), server_account_name);
3800 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3801 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3804 gtk_widget_destroy (dialog);
3808 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3809 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
3812 g_free (server_name);
3816 gchar *initial_username = modest_account_mgr_get_server_account_username (
3817 modest_runtime_get_account_mgr(), server_account_name);
3819 GtkWidget *entry_username = gtk_entry_new ();
3820 if (initial_username)
3821 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
3822 /* Dim this if a connection has ever succeeded with this username,
3823 * as per the UI spec: */
3824 /* const gboolean username_known = */
3825 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3826 /* modest_runtime_get_account_mgr(), server_account_name); */
3827 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3829 /* We drop the username sensitive code and disallow changing it here
3830 * as tinymail does not support really changing the username in the callback
3832 gtk_widget_set_sensitive (entry_username, FALSE);
3834 #ifndef MODEST_TOOLKIT_GTK
3835 /* Auto-capitalization is the default, so let's turn it off: */
3836 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3838 /* Create a size group to be used by all captions.
3839 * Note that HildonCaption does not create a default size group if we do not specify one.
3840 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3841 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3843 GtkWidget *caption = hildon_caption_new (sizegroup,
3844 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
3845 gtk_widget_show (entry_username);
3846 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3847 FALSE, FALSE, MODEST_MARGIN_HALF);
3848 gtk_widget_show (caption);
3850 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
3852 #endif /* !MODEST_TOOLKIT_GTK */
3855 GtkWidget *entry_password = gtk_entry_new ();
3856 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3857 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3859 #ifndef MODEST_TOOLKIT_GTK
3860 /* Auto-capitalization is the default, so let's turn it off: */
3861 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3862 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3864 caption = hildon_caption_new (sizegroup,
3865 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
3866 gtk_widget_show (entry_password);
3867 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3868 FALSE, FALSE, MODEST_MARGIN_HALF);
3869 gtk_widget_show (caption);
3870 g_object_unref (sizegroup);
3872 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
3874 #endif /* !MODEST_TOOLKIT_GTK */
3876 if (initial_username != NULL)
3877 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3879 /* This is not in the Maemo UI spec:
3880 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3881 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3885 fields = g_slice_new0 (PasswordDialogFields);
3886 fields->username = entry_username;
3887 fields->password = entry_password;
3888 fields->dialog = dialog;
3890 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3891 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3892 password_dialog_check_field (NULL, fields);
3894 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3896 while (!completed) {
3898 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3900 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
3902 /* Note that an empty field becomes the "" string */
3903 if (*username && strlen (*username) > 0) {
3904 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
3905 server_account_name,
3909 const gboolean username_was_changed =
3910 (strcmp (*username, initial_username) != 0);
3911 if (username_was_changed) {
3912 g_warning ("%s: tinymail does not yet support changing the "
3913 "username in the get_password() callback.\n", __FUNCTION__);
3919 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
3920 _("mcen_ib_username_pw_incorrect"));
3926 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
3928 /* We do not save the password in the configuration,
3929 * because this function is only called for passwords that should
3930 * not be remembered:
3931 modest_server_account_set_password (
3932 modest_runtime_get_account_mgr(), server_account_name,
3939 #ifndef MODEST_TOOLKIT_HILDON2
3940 /* Set parent to NULL or the banner will disappear with its parent dialog */
3941 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
3953 /* This is not in the Maemo UI spec:
3954 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3960 g_free (initial_username);
3961 gtk_widget_destroy (dialog);
3962 g_slice_free (PasswordDialogFields, fields);
3964 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3968 modest_ui_actions_on_cut (GtkAction *action,
3969 ModestWindow *window)
3971 GtkWidget *focused_widget;
3972 GtkClipboard *clipboard;
3974 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3975 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3976 if (GTK_IS_EDITABLE (focused_widget)) {
3977 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3978 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3979 gtk_clipboard_store (clipboard);
3980 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3981 GtkTextBuffer *buffer;
3983 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3984 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3985 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3986 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3987 gtk_clipboard_store (clipboard);
3989 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3990 TnyList *header_list = modest_header_view_get_selected_headers (
3991 MODEST_HEADER_VIEW (focused_widget));
3992 gboolean continue_download = FALSE;
3993 gint num_of_unc_msgs;
3995 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3997 if (num_of_unc_msgs) {
3998 TnyAccount *account = get_account_from_header_list (header_list);
4000 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4001 g_object_unref (account);
4005 if (num_of_unc_msgs == 0 || continue_download) {
4006 /* modest_platform_information_banner (
4007 NULL, NULL, _CS("mcen_ib_getting_items"));*/
4008 modest_header_view_cut_selection (
4009 MODEST_HEADER_VIEW (focused_widget));
4012 g_object_unref (header_list);
4013 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4014 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4019 modest_ui_actions_on_copy (GtkAction *action,
4020 ModestWindow *window)
4022 GtkClipboard *clipboard;
4023 GtkWidget *focused_widget;
4024 gboolean copied = TRUE;
4026 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4027 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4029 if (GTK_IS_LABEL (focused_widget)) {
4031 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4032 gtk_clipboard_set_text (clipboard, selection, -1);
4034 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4035 gtk_clipboard_store (clipboard);
4036 } else if (GTK_IS_EDITABLE (focused_widget)) {
4037 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4038 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4039 gtk_clipboard_store (clipboard);
4040 } else if (GTK_IS_HTML (focused_widget)) {
4043 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4044 if ((sel == NULL) || (sel[0] == '\0')) {
4047 gtk_html_copy (GTK_HTML (focused_widget));
4048 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4049 gtk_clipboard_store (clipboard);
4051 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4052 GtkTextBuffer *buffer;
4053 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4054 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4055 gtk_text_buffer_copy_clipboard (buffer, clipboard);
4056 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4057 gtk_clipboard_store (clipboard);
4059 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4060 TnyList *header_list = modest_header_view_get_selected_headers (
4061 MODEST_HEADER_VIEW (focused_widget));
4062 gboolean continue_download = FALSE;
4063 gint num_of_unc_msgs;
4065 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4067 if (num_of_unc_msgs) {
4068 TnyAccount *account = get_account_from_header_list (header_list);
4070 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4071 g_object_unref (account);
4075 if (num_of_unc_msgs == 0 || continue_download) {
4076 modest_platform_information_banner (
4077 NULL, NULL, _CS("mcen_ib_getting_items"));
4078 modest_header_view_copy_selection (
4079 MODEST_HEADER_VIEW (focused_widget));
4083 g_object_unref (header_list);
4085 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4086 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4089 /* Show information banner if there was a copy to clipboard */
4091 modest_platform_information_banner (
4092 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4096 modest_ui_actions_on_undo (GtkAction *action,
4097 ModestWindow *window)
4099 ModestEmailClipboard *clipboard = NULL;
4101 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4102 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4103 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4104 /* Clear clipboard source */
4105 clipboard = modest_runtime_get_email_clipboard ();
4106 modest_email_clipboard_clear (clipboard);
4109 g_return_if_reached ();
4114 modest_ui_actions_on_redo (GtkAction *action,
4115 ModestWindow *window)
4117 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4118 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4121 g_return_if_reached ();
4127 destroy_information_note (ModestMailOperation *mail_op,
4130 /* destroy information note */
4131 gtk_widget_destroy (GTK_WIDGET(user_data));
4135 destroy_folder_information_note (ModestMailOperation *mail_op,
4136 TnyFolder *new_folder,
4139 /* destroy information note */
4140 gtk_widget_destroy (GTK_WIDGET(user_data));
4145 paste_as_attachment_free (gpointer data)
4147 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4149 if (helper->banner) {
4150 gtk_widget_destroy (helper->banner);
4151 g_object_unref (helper->banner);
4157 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4162 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4163 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4168 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4173 modest_ui_actions_on_paste (GtkAction *action,
4174 ModestWindow *window)
4176 GtkWidget *focused_widget = NULL;
4177 GtkWidget *inf_note = NULL;
4178 ModestMailOperation *mail_op = NULL;
4180 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4181 if (GTK_IS_EDITABLE (focused_widget)) {
4182 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4183 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4184 ModestEmailClipboard *e_clipboard = NULL;
4185 e_clipboard = modest_runtime_get_email_clipboard ();
4186 if (modest_email_clipboard_cleared (e_clipboard)) {
4187 GtkTextBuffer *buffer;
4188 GtkClipboard *clipboard;
4190 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4191 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4192 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4193 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4194 ModestMailOperation *mail_op;
4195 TnyFolder *src_folder = NULL;
4196 TnyList *data = NULL;
4198 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4199 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4200 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4201 _CS("ckct_nw_pasting"));
4202 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4203 mail_op = modest_mail_operation_new (G_OBJECT (window));
4204 if (helper->banner != NULL) {
4205 g_object_ref (G_OBJECT (helper->banner));
4206 gtk_widget_show (GTK_WIDGET (helper->banner));
4210 modest_mail_operation_get_msgs_full (mail_op,
4212 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4214 paste_as_attachment_free);
4218 g_object_unref (data);
4220 g_object_unref (src_folder);
4223 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4224 ModestEmailClipboard *clipboard = NULL;
4225 TnyFolder *src_folder = NULL;
4226 TnyFolderStore *folder_store = NULL;
4227 TnyList *data = NULL;
4228 gboolean delete = FALSE;
4230 /* Check clipboard source */
4231 clipboard = modest_runtime_get_email_clipboard ();
4232 if (modest_email_clipboard_cleared (clipboard))
4235 /* Get elements to paste */
4236 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4238 /* Create a new mail operation */
4239 mail_op = modest_mail_operation_new (G_OBJECT(window));
4241 /* Get destination folder */
4242 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4244 /* transfer messages */
4248 /* Ask for user confirmation */
4250 modest_ui_actions_msgs_move_to_confirmation (window,
4251 TNY_FOLDER (folder_store),
4255 if (response == GTK_RESPONSE_OK) {
4256 /* Launch notification */
4257 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4258 _CS("ckct_nw_pasting"));
4259 if (inf_note != NULL) {
4260 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4261 gtk_widget_show (GTK_WIDGET(inf_note));
4264 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4265 modest_mail_operation_xfer_msgs (mail_op,
4267 TNY_FOLDER (folder_store),
4269 destroy_information_note,
4272 g_object_unref (mail_op);
4275 } else if (src_folder != NULL) {
4276 /* Launch notification */
4277 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4278 _CS("ckct_nw_pasting"));
4279 if (inf_note != NULL) {
4280 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4281 gtk_widget_show (GTK_WIDGET(inf_note));
4284 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4285 modest_mail_operation_xfer_folder (mail_op,
4289 destroy_folder_information_note,
4295 g_object_unref (data);
4296 if (src_folder != NULL)
4297 g_object_unref (src_folder);
4298 if (folder_store != NULL)
4299 g_object_unref (folder_store);
4305 modest_ui_actions_on_select_all (GtkAction *action,
4306 ModestWindow *window)
4308 GtkWidget *focused_widget;
4310 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4311 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4312 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4313 } else if (GTK_IS_LABEL (focused_widget)) {
4314 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4315 } else if (GTK_IS_EDITABLE (focused_widget)) {
4316 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4317 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4318 GtkTextBuffer *buffer;
4319 GtkTextIter start, end;
4321 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4322 gtk_text_buffer_get_start_iter (buffer, &start);
4323 gtk_text_buffer_get_end_iter (buffer, &end);
4324 gtk_text_buffer_select_range (buffer, &start, &end);
4325 } else if (GTK_IS_HTML (focused_widget)) {
4326 gtk_html_select_all (GTK_HTML (focused_widget));
4327 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4328 GtkWidget *header_view = focused_widget;
4329 GtkTreeSelection *selection = NULL;
4331 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4332 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4333 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4336 /* Disable window dimming management */
4337 modest_window_disable_dimming (MODEST_WINDOW(window));
4339 /* Select all messages */
4340 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4341 gtk_tree_selection_select_all (selection);
4343 /* Set focuse on header view */
4344 gtk_widget_grab_focus (header_view);
4346 /* Enable window dimming management */
4347 modest_window_enable_dimming (MODEST_WINDOW(window));
4348 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4349 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4355 modest_ui_actions_on_mark_as_read (GtkAction *action,
4356 ModestWindow *window)
4358 g_return_if_fail (MODEST_IS_WINDOW(window));
4360 /* Mark each header as read */
4361 do_headers_action (window, headers_action_mark_as_read, NULL);
4365 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4366 ModestWindow *window)
4368 g_return_if_fail (MODEST_IS_WINDOW(window));
4370 /* Mark each header as read */
4371 do_headers_action (window, headers_action_mark_as_unread, NULL);
4375 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4376 GtkRadioAction *selected,
4377 ModestWindow *window)
4381 value = gtk_radio_action_get_current_value (selected);
4382 if (MODEST_IS_WINDOW (window)) {
4383 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4388 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4389 GtkRadioAction *selected,
4390 ModestWindow *window)
4392 TnyHeaderFlags flags;
4393 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4395 flags = gtk_radio_action_get_current_value (selected);
4396 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4400 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4401 GtkRadioAction *selected,
4402 ModestWindow *window)
4406 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4408 file_format = gtk_radio_action_get_current_value (selected);
4409 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4414 modest_ui_actions_on_zoom_plus (GtkAction *action,
4415 ModestWindow *window)
4417 g_return_if_fail (MODEST_IS_WINDOW (window));
4419 modest_window_zoom_plus (MODEST_WINDOW (window));
4423 modest_ui_actions_on_zoom_minus (GtkAction *action,
4424 ModestWindow *window)
4426 g_return_if_fail (MODEST_IS_WINDOW (window));
4428 modest_window_zoom_minus (MODEST_WINDOW (window));
4432 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4433 ModestWindow *window)
4435 ModestWindowMgr *mgr;
4436 gboolean fullscreen, active;
4437 g_return_if_fail (MODEST_IS_WINDOW (window));
4439 mgr = modest_runtime_get_window_mgr ();
4441 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4442 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4444 if (active != fullscreen) {
4445 modest_window_mgr_set_fullscreen_mode (mgr, active);
4446 #ifndef MODEST_TOOLKIT_HILDON2
4447 gtk_window_present (GTK_WINDOW (window));
4453 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4454 ModestWindow *window)
4456 ModestWindowMgr *mgr;
4457 gboolean fullscreen;
4459 g_return_if_fail (MODEST_IS_WINDOW (window));
4461 mgr = modest_runtime_get_window_mgr ();
4462 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4463 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4465 #ifndef MODEST_TOOLKIT_HILDON2
4466 gtk_window_present (GTK_WINDOW (window));
4471 * Used by modest_ui_actions_on_details to call do_headers_action
4474 headers_action_show_details (TnyHeader *header,
4475 ModestWindow *window,
4479 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header);
4483 * Show the header details in a ModestDetailsDialog widget
4486 modest_ui_actions_on_details (GtkAction *action,
4489 TnyList * headers_list;
4493 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4496 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4499 g_object_unref (msg);
4501 headers_list = get_selected_headers (win);
4505 iter = tny_list_create_iterator (headers_list);
4507 header = TNY_HEADER (tny_iterator_get_current (iter));
4509 headers_action_show_details (header, win, NULL);
4510 g_object_unref (header);
4513 g_object_unref (iter);
4514 g_object_unref (headers_list);
4516 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4517 GtkWidget *folder_view, *header_view;
4519 /* Check which widget has the focus */
4520 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4521 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4522 if (gtk_widget_is_focus (folder_view)) {
4523 TnyFolderStore *folder_store
4524 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4525 if (!folder_store) {
4526 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4529 /* Show only when it's a folder */
4530 /* This function should not be called for account items,
4531 * because we dim the menu item for them. */
4532 if (TNY_IS_FOLDER (folder_store)) {
4533 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4534 TNY_FOLDER (folder_store));
4537 g_object_unref (folder_store);
4540 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4541 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4542 /* Show details of each header */
4543 do_headers_action (win, headers_action_show_details, header_view);
4545 #ifdef MODEST_TOOLKIT_HILDON2
4546 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4548 GtkWidget *header_view;
4550 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4551 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4553 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4555 g_object_unref (folder);
4562 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4563 ModestMsgEditWindow *window)
4565 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4567 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4571 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4572 ModestMsgEditWindow *window)
4574 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4576 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4580 modest_ui_actions_toggle_folders_view (GtkAction *action,
4581 ModestMainWindow *main_window)
4583 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4585 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4586 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4588 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4592 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4593 ModestWindow *window)
4595 gboolean active, fullscreen = FALSE;
4596 ModestWindowMgr *mgr;
4598 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4600 /* Check if we want to toggle the toolbar view in fullscreen
4602 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4603 "ViewShowToolbarFullScreen")) {
4607 /* Toggle toolbar */
4608 mgr = modest_runtime_get_window_mgr ();
4609 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4613 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4614 ModestMsgEditWindow *window)
4616 modest_msg_edit_window_select_font (window);
4621 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4622 const gchar *display_name,
4625 /* don't update the display name if it was already set;
4626 * updating the display name apparently is expensive */
4627 const gchar* old_name = gtk_window_get_title (window);
4629 if (display_name == NULL)
4632 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4633 return; /* don't do anything */
4635 /* This is usually used to change the title of the main window, which
4636 * is the one that holds the folder view. Note that this change can
4637 * happen even when the widget doesn't have the focus. */
4638 gtk_window_set_title (window, display_name);
4643 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4645 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4646 modest_msg_edit_window_select_contacts (window);
4650 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4652 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4653 modest_msg_edit_window_check_names (window, FALSE);
4656 #ifndef MODEST_TOOLKIT_HILDON2
4658 * This function is used to track changes in the selection of the
4659 * folder view that is inside the "move to" dialog to enable/disable
4660 * the OK button because we do not want the user to select a disallowed
4661 * destination for a folder.
4662 * The user also not desired to be able to use NEW button on items where
4663 * folder creation is not possibel.
4666 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4667 TnyFolderStore *folder_store,
4671 GtkWidget *dialog = NULL;
4672 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4673 gboolean moving_folder = FALSE;
4674 gboolean is_local_account = TRUE;
4675 GtkWidget *folder_view = NULL;
4676 ModestTnyFolderRules rules;
4678 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
4683 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
4687 /* check if folder_store is an remote account */
4688 if (TNY_IS_ACCOUNT (folder_store)) {
4689 TnyAccount *local_account = NULL;
4690 TnyAccount *mmc_account = NULL;
4691 ModestTnyAccountStore *account_store = NULL;
4693 account_store = modest_runtime_get_account_store ();
4694 local_account = modest_tny_account_store_get_local_folders_account (account_store);
4695 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
4697 if ((gpointer) local_account != (gpointer) folder_store &&
4698 (gpointer) mmc_account != (gpointer) folder_store) {
4699 ModestProtocolType proto;
4700 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
4701 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
4702 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
4704 is_local_account = FALSE;
4705 /* New button should be dimmed on remote
4707 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4709 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
4711 g_object_unref (local_account);
4713 /* It could not exist */
4715 g_object_unref (mmc_account);
4718 /* Check the target folder rules */
4719 if (TNY_IS_FOLDER (folder_store)) {
4720 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
4721 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
4722 ok_sensitive = FALSE;
4723 new_sensitive = FALSE;
4728 /* Check if we're moving a folder */
4729 if (MODEST_IS_MAIN_WINDOW (user_data)) {
4730 /* Get the widgets */
4731 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
4732 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4733 if (gtk_widget_is_focus (folder_view))
4734 moving_folder = TRUE;
4737 if (moving_folder) {
4738 TnyFolderStore *moved_folder = NULL, *parent = NULL;
4740 /* Get the folder to move */
4741 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4743 /* Check that we're not moving to the same folder */
4744 if (TNY_IS_FOLDER (moved_folder)) {
4745 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
4746 if (parent == folder_store)
4747 ok_sensitive = FALSE;
4748 g_object_unref (parent);
4751 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
4752 /* Do not allow to move to an account unless it's the
4753 local folders account */
4754 if (!is_local_account)
4755 ok_sensitive = FALSE;
4758 if (ok_sensitive && (moved_folder == folder_store)) {
4759 /* Do not allow to move to itself */
4760 ok_sensitive = FALSE;
4762 g_object_unref (moved_folder);
4764 TnyFolder *src_folder = NULL;
4766 /* Moving a message */
4767 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
4769 TnyHeader *header = NULL;
4770 header = modest_msg_view_window_get_header
4771 (MODEST_MSG_VIEW_WINDOW (user_data));
4772 if (!TNY_IS_HEADER(header))
4773 g_warning ("%s: could not get source header", __FUNCTION__);
4775 src_folder = tny_header_get_folder (header);
4778 g_object_unref (header);
4781 TNY_FOLDER (modest_folder_view_get_selected
4782 (MODEST_FOLDER_VIEW (folder_view)));
4785 if (TNY_IS_FOLDER(src_folder)) {
4786 /* Do not allow to move the msg to the same folder */
4787 /* Do not allow to move the msg to an account */
4788 if ((gpointer) src_folder == (gpointer) folder_store ||
4789 TNY_IS_ACCOUNT (folder_store))
4790 ok_sensitive = FALSE;
4791 g_object_unref (src_folder);
4793 g_warning ("%s: could not get source folder", __FUNCTION__);
4797 /* Set sensitivity of the OK and NEW button */
4798 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
4799 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
4804 on_move_to_dialog_response (GtkDialog *dialog,
4808 GtkWidget *parent_win, *folder_view;
4809 MoveToInfo *helper = NULL;
4811 helper = (MoveToInfo *) user_data;
4813 parent_win = (GtkWidget *) helper->win;
4814 folder_view = GTK_WIDGET (g_object_get_data (G_OBJECT (dialog),
4815 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4818 TnyFolderStore *dst_folder;
4820 case MODEST_GTK_RESPONSE_NEW_FOLDER:
4821 modest_ui_actions_create_folder (GTK_WIDGET (parent_win), folder_view);
4823 case GTK_RESPONSE_NONE:
4824 case GTK_RESPONSE_CANCEL:
4825 case GTK_RESPONSE_DELETE_EVENT:
4827 case GTK_RESPONSE_OK:
4828 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4829 /* Do window specific stuff */
4830 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
4831 modest_ui_actions_on_main_window_move_to (NULL,
4834 MODEST_MAIN_WINDOW (parent_win));
4835 #ifdef MODEST_TOOLKIT_HILDON2
4836 } else if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
4837 modest_ui_actions_on_folder_window_move_to (folder_view,
4840 GTK_WINDOW (parent_win));
4843 /* Moving from headers window in edit mode */
4844 modest_ui_actions_on_window_move_to (NULL, helper->list,
4846 MODEST_WINDOW (parent_win));
4850 g_object_unref (dst_folder);
4854 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
4857 /* Free the helper and exit */
4859 g_object_unref (helper->list);
4860 g_slice_free (MoveToInfo, helper);
4861 gtk_widget_destroy (GTK_WIDGET (dialog));
4865 create_move_to_dialog (GtkWindow *win,
4866 GtkWidget *folder_view)
4868 GtkWidget *dialog, *tree_view = NULL;
4870 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
4872 #ifndef MODEST_TOOLKIT_HILDON2
4873 /* Track changes in the selection to
4874 * disable the OK button whenever "Move to" is not possible
4875 * disbale NEW button whenever New is not possible */
4876 g_signal_connect (tree_view,
4877 "folder_selection_changed",
4878 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
4882 /* It could happen that we're trying to move a message from a
4883 window (msg window for example) after the main window was
4884 closed, so we can not just get the model of the folder
4886 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4887 const gchar *visible_id = NULL;
4889 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4890 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4891 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4892 MODEST_FOLDER_VIEW(tree_view));
4895 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4897 /* Show the same account than the one that is shown in the main window */
4898 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
4901 const gchar *active_account_name = NULL;
4902 ModestAccountMgr *mgr = NULL;
4903 ModestAccountSettings *settings = NULL;
4904 ModestServerAccountSettings *store_settings = NULL;
4906 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4907 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4908 modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view),
4909 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
4911 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4912 mgr = modest_runtime_get_account_mgr ();
4913 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4916 const gchar *store_account_name;
4917 store_settings = modest_account_settings_get_store_settings (settings);
4918 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4920 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
4921 store_account_name);
4922 g_object_unref (store_settings);
4923 g_object_unref (settings);
4927 /* we keep a pointer to the embedded folder view, so we can
4928 * retrieve it with get_folder_view_from_move_to_dialog (see
4929 * above) later (needed for focus handling)
4931 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
4933 /* Hide special folders */
4934 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
4935 #ifndef MODEST_TOOLKIT_HILDON2
4936 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
4939 gtk_widget_show (GTK_WIDGET (tree_view));
4945 * Shows a confirmation dialog to the user when we're moving messages
4946 * from a remote server to the local storage. Returns the dialog
4947 * response. If it's other kind of movement then it always returns
4950 * This one is used by the next functions:
4951 * modest_ui_actions_on_paste - commented out
4952 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4955 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4956 TnyFolder *dest_folder,
4960 gint response = GTK_RESPONSE_OK;
4961 TnyAccount *account = NULL;
4962 TnyFolder *src_folder = NULL;
4963 TnyIterator *iter = NULL;
4964 TnyHeader *header = NULL;
4966 /* return with OK if the destination is a remote folder */
4967 if (modest_tny_folder_is_remote_folder (dest_folder))
4968 return GTK_RESPONSE_OK;
4970 /* Get source folder */
4971 iter = tny_list_create_iterator (headers);
4972 header = TNY_HEADER (tny_iterator_get_current (iter));
4974 src_folder = tny_header_get_folder (header);
4975 g_object_unref (header);
4977 g_object_unref (iter);
4979 /* if no src_folder, message may be an attahcment */
4980 if (src_folder == NULL)
4981 return GTK_RESPONSE_CANCEL;
4983 /* If the source is a local or MMC folder */
4984 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4985 g_object_unref (src_folder);
4986 return GTK_RESPONSE_OK;
4989 /* Get the account */
4990 account = tny_folder_get_account (src_folder);
4992 /* now if offline we ask the user */
4993 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4994 response = GTK_RESPONSE_OK;
4996 response = GTK_RESPONSE_CANCEL;
4999 g_object_unref (src_folder);
5000 g_object_unref (account);
5006 move_to_helper_destroyer (gpointer user_data)
5008 MoveToHelper *helper = (MoveToHelper *) user_data;
5010 /* Close the "Pasting" information banner */
5011 if (helper->banner) {
5012 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5013 g_object_unref (helper->banner);
5015 if (gtk_tree_row_reference_valid (helper->reference)) {
5016 gtk_tree_row_reference_free (helper->reference);
5017 helper->reference = NULL;
5023 move_to_cb (ModestMailOperation *mail_op,
5026 MoveToHelper *helper = (MoveToHelper *) user_data;
5027 GObject *object = modest_mail_operation_get_source (mail_op);
5029 /* Note that the operation could have failed, in that case do
5031 if (modest_mail_operation_get_status (mail_op) !=
5032 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5035 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5036 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5038 if (!modest_msg_view_window_select_next_message (self) &&
5039 !modest_msg_view_window_select_previous_message (self)) {
5040 /* No more messages to view, so close this window */
5041 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5043 } else if (MODEST_IS_MAIN_WINDOW (object) &&
5044 gtk_tree_row_reference_valid (helper->reference)) {
5045 GtkWidget *header_view;
5047 GtkTreeSelection *sel;
5049 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5050 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5051 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5052 path = gtk_tree_row_reference_get_path (helper->reference);
5053 /* We need to unselect the previous one
5054 because we could be copying instead of
5056 gtk_tree_selection_unselect_all (sel);
5057 gtk_tree_selection_select_path (sel, path);
5058 gtk_tree_path_free (path);
5060 g_object_unref (object);
5063 /* Destroy the helper */
5064 move_to_helper_destroyer (helper);
5068 folder_move_to_cb (ModestMailOperation *mail_op,
5069 TnyFolder *new_folder,
5072 GtkWidget *folder_view;
5075 object = modest_mail_operation_get_source (mail_op);
5076 if (MODEST_IS_MAIN_WINDOW (object)) {
5077 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5078 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5079 g_object_ref (folder_view);
5080 g_object_unref (object);
5081 move_to_cb (mail_op, user_data);
5082 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5083 g_object_unref (folder_view);
5085 move_to_cb (mail_op, user_data);
5090 msgs_move_to_cb (ModestMailOperation *mail_op,
5093 move_to_cb (mail_op, user_data);
5097 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5100 ModestWindow *main_window = NULL;
5102 /* Disable next automatic folder selection */
5103 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5104 FALSE); /* don't create */
5106 GObject *win = NULL;
5107 GtkWidget *folder_view = NULL;
5109 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5110 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5111 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5113 if (user_data && TNY_IS_FOLDER (user_data)) {
5114 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5115 TNY_FOLDER (user_data), FALSE);
5118 /* Show notification dialog only if the main window exists */
5119 win = modest_mail_operation_get_source (mail_op);
5120 modest_platform_run_information_dialog ((GtkWindow *) win,
5121 _("mail_in_ui_folder_move_target_error"),
5124 g_object_unref (win);
5129 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5138 gint pending_purges = 0;
5139 gboolean some_purged = FALSE;
5140 ModestWindow *win = MODEST_WINDOW (user_data);
5141 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5143 /* If there was any error */
5144 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5145 modest_window_mgr_unregister_header (mgr, header);
5149 /* Once the message has been retrieved for purging, we check if
5150 * it's all ok for purging */
5152 parts = tny_simple_list_new ();
5153 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5154 iter = tny_list_create_iterator (parts);
5156 while (!tny_iterator_is_done (iter)) {
5158 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5159 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5160 if (tny_mime_part_is_purged (part))
5167 g_object_unref (part);
5169 tny_iterator_next (iter);
5171 g_object_unref (iter);
5174 if (pending_purges>0) {
5176 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5178 if (response == GTK_RESPONSE_OK) {
5181 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5182 iter = tny_list_create_iterator (parts);
5183 while (!tny_iterator_is_done (iter)) {
5186 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5187 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5188 tny_mime_part_set_purged (part);
5191 g_object_unref (part);
5193 tny_iterator_next (iter);
5195 g_object_unref (iter);
5197 tny_msg_rewrite_cache (msg);
5199 gtk_widget_destroy (info);
5203 modest_window_mgr_unregister_header (mgr, header);
5205 g_object_unref (parts);
5209 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5210 ModestMainWindow *win)
5212 GtkWidget *header_view;
5213 TnyList *header_list;
5215 TnyHeaderFlags flags;
5216 ModestWindow *msg_view_window = NULL;
5219 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5221 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5222 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5224 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5226 g_warning ("%s: no header selected", __FUNCTION__);
5230 if (tny_list_get_length (header_list) == 1) {
5231 TnyIterator *iter = tny_list_create_iterator (header_list);
5232 header = TNY_HEADER (tny_iterator_get_current (iter));
5233 g_object_unref (iter);
5237 if (!header || !TNY_IS_HEADER(header)) {
5238 g_warning ("%s: header is not valid", __FUNCTION__);
5242 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5243 header, &msg_view_window);
5244 flags = tny_header_get_flags (header);
5245 if (!(flags & TNY_HEADER_FLAG_CACHED))
5248 if (msg_view_window != NULL)
5249 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5251 /* do nothing; uid was registered before, so window is probably on it's way */
5252 g_warning ("debug: header %p has already been registered", header);
5255 ModestMailOperation *mail_op = NULL;
5256 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5257 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5258 modest_ui_actions_disk_operations_error_handler,
5260 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5261 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5263 g_object_unref (mail_op);
5266 g_object_unref (header);
5268 g_object_unref (header_list);
5272 * Checks if we need a connection to do the transfer and if the user
5273 * wants to connect to complete it
5276 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5277 TnyFolderStore *src_folder,
5279 TnyFolder *dst_folder,
5280 gboolean delete_originals,
5281 gboolean *need_connection,
5284 TnyAccount *src_account;
5285 gint uncached_msgs = 0;
5287 uncached_msgs = header_list_count_uncached_msgs (headers);
5289 /* We don't need any further check if
5291 * 1- the source folder is local OR
5292 * 2- the device is already online
5294 if (!modest_tny_folder_store_is_remote (src_folder) ||
5295 tny_device_is_online (modest_runtime_get_device())) {
5296 *need_connection = FALSE;
5301 /* We must ask for a connection when
5303 * - the message(s) is not already cached OR
5304 * - the message(s) is cached but the leave_on_server setting
5305 * is FALSE (because we need to sync the source folder to
5306 * delete the message from the server (for IMAP we could do it
5307 * offline, it'll take place the next time we get a
5310 src_account = get_account_from_folder_store (src_folder);
5311 if (uncached_msgs > 0) {
5315 *need_connection = TRUE;
5316 num_headers = tny_list_get_length (headers);
5317 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5319 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5320 GTK_RESPONSE_CANCEL) {
5326 /* The transfer is possible and the user wants to */
5329 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5330 const gchar *account_name;
5331 gboolean leave_on_server;
5333 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5334 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5337 if (leave_on_server == TRUE) {
5338 *need_connection = FALSE;
5340 *need_connection = TRUE;
5343 *need_connection = FALSE;
5348 g_object_unref (src_account);
5352 xfer_messages_error_handler (ModestMailOperation *mail_op,
5355 GObject *win = modest_mail_operation_get_source (mail_op);
5356 modest_platform_run_information_dialog ((GtkWindow *) win,
5357 _("mail_in_ui_folder_move_target_error"),
5360 g_object_unref (win);
5364 TnyFolderStore *dst_folder;
5369 * Utility function that transfer messages from both the main window
5370 * and the msg view window when using the "Move to" dialog
5373 xfer_messages_performer (gboolean canceled,
5375 GtkWindow *parent_window,
5376 TnyAccount *account,
5379 ModestWindow *win = MODEST_WINDOW (parent_window);
5380 TnyAccount *dst_account = NULL;
5381 gboolean dst_forbids_message_add = FALSE;
5382 XferMsgsHelper *helper;
5383 MoveToHelper *movehelper;
5384 ModestMailOperation *mail_op;
5386 helper = (XferMsgsHelper *) user_data;
5388 if (canceled || err) {
5389 if (!check_memory_full_error ((GtkWidget *) parent_window, err)) {
5390 /* Show the proper error message */
5391 modest_ui_actions_on_account_connection_error (parent_window, account);
5396 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5398 /* tinymail will return NULL for local folders it seems */
5399 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5400 modest_tny_account_get_protocol_type (dst_account),
5401 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_MESSAGE_ADD);
5402 g_object_unref (dst_account);
5404 if (dst_forbids_message_add) {
5405 modest_platform_information_banner (GTK_WIDGET (win),
5407 ngettext("mail_in_ui_folder_move_target_error",
5408 "mail_in_ui_folder_move_targets_error",
5409 tny_list_get_length (helper->headers)));
5413 movehelper = g_new0 (MoveToHelper, 1);
5415 #ifndef MODEST_TOOLKIT_HILDON2
5416 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5417 _CS("ckct_nw_pasting"));
5418 if (movehelper->banner != NULL) {
5419 g_object_ref (movehelper->banner);
5420 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5424 if (MODEST_IS_MAIN_WINDOW (win)) {
5425 GtkWidget *header_view =
5426 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5427 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5428 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5431 /* Perform the mail operation */
5432 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5433 xfer_messages_error_handler,
5435 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5438 modest_mail_operation_xfer_msgs (mail_op,
5440 TNY_FOLDER (helper->dst_folder),
5445 g_object_unref (G_OBJECT (mail_op));
5447 g_object_unref (helper->dst_folder);
5448 g_object_unref (helper->headers);
5449 g_slice_free (XferMsgsHelper, helper);
5453 TnyFolder *src_folder;
5454 TnyFolderStore *dst_folder;
5455 gboolean delete_original;
5456 GtkWidget *folder_view;
5460 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
5461 TnyAccount *account, gpointer user_data)
5463 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5464 GtkTreeSelection *sel;
5465 ModestMailOperation *mail_op = NULL;
5467 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
5468 g_object_unref (G_OBJECT (info->src_folder));
5469 g_object_unref (G_OBJECT (info->dst_folder));
5474 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5475 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5476 _CS("ckct_nw_pasting"));
5477 if (helper->banner != NULL) {
5478 g_object_ref (helper->banner);
5479 gtk_widget_show (GTK_WIDGET(helper->banner));
5481 /* Clean folder on header view before moving it */
5482 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5483 gtk_tree_selection_unselect_all (sel);
5485 /* Let gtk events run. We need that the folder
5486 view frees its reference to the source
5487 folder *before* issuing the mail operation
5488 so we need the signal handler of selection
5489 changed to happen before the mail
5491 while (gtk_events_pending ())
5492 gtk_main_iteration (); */
5495 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5496 modest_ui_actions_move_folder_error_handler,
5497 info->src_folder, NULL);
5498 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5501 /* Select *after* the changes */
5502 /* TODO: this function hangs UI after transfer */
5503 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
5504 /* TNY_FOLDER (src_folder), TRUE); */
5506 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
5507 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5508 TNY_FOLDER (info->dst_folder), TRUE);
5510 modest_mail_operation_xfer_folder (mail_op,
5511 TNY_FOLDER (info->src_folder),
5513 info->delete_original,
5516 g_object_unref (G_OBJECT (info->src_folder));
5518 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5521 /* Unref mail operation */
5522 g_object_unref (G_OBJECT (mail_op));
5523 g_object_unref (G_OBJECT (info->dst_folder));
5528 get_account_from_folder_store (TnyFolderStore *folder_store)
5530 if (TNY_IS_ACCOUNT (folder_store))
5531 return g_object_ref (folder_store);
5533 return tny_folder_get_account (TNY_FOLDER (folder_store));
5537 * UI handler for the "Move to" action when invoked from the
5541 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5542 GtkWidget *folder_view,
5543 TnyFolderStore *dst_folder,
5544 ModestMainWindow *win)
5546 ModestHeaderView *header_view = NULL;
5547 TnyFolderStore *src_folder = NULL;
5549 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5551 /* Get the source folder */
5552 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5554 /* Get header view */
5555 header_view = (ModestHeaderView *)
5556 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5558 /* Get folder or messages to transfer */
5559 if (gtk_widget_is_focus (folder_view)) {
5560 gboolean do_xfer = TRUE;
5562 /* Allow only to transfer folders to the local root folder */
5563 if (TNY_IS_ACCOUNT (dst_folder) &&
5564 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5565 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5567 } else if (!TNY_IS_FOLDER (src_folder)) {
5568 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5573 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5574 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5576 info->src_folder = g_object_ref (src_folder);
5577 info->dst_folder = g_object_ref (dst_folder);
5578 info->delete_original = TRUE;
5579 info->folder_view = folder_view;
5581 connect_info->callback = on_move_folder_cb;
5582 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5583 connect_info->data = info;
5585 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5586 TNY_FOLDER_STORE (src_folder),
5589 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5592 headers = modest_header_view_get_selected_headers(header_view);
5594 /* Transfer the messages */
5595 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
5596 headers, TNY_FOLDER (dst_folder));
5598 g_object_unref (headers);
5602 g_object_unref (src_folder);
5605 #ifdef MODEST_TOOLKIT_HILDON2
5607 * UI handler for the "Move to" action when invoked from the
5608 * ModestFolderWindow
5611 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
5612 TnyFolderStore *dst_folder,
5616 TnyFolderStore *src_folder = NULL;
5617 TnyIterator *iterator;
5619 if (tny_list_get_length (selection) != 1)
5622 iterator = tny_list_create_iterator (selection);
5623 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
5624 g_object_unref (iterator);
5627 gboolean do_xfer = TRUE;
5629 /* Allow only to transfer folders to the local root folder */
5630 if (TNY_IS_ACCOUNT (dst_folder) &&
5631 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5632 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5634 } else if (!TNY_IS_FOLDER (src_folder)) {
5635 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5640 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5641 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5643 info->src_folder = g_object_ref (src_folder);
5644 info->dst_folder = g_object_ref (dst_folder);
5645 info->delete_original = TRUE;
5646 info->folder_view = folder_view;
5648 connect_info->callback = on_move_folder_cb;
5649 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5650 connect_info->data = info;
5652 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5653 TNY_FOLDER_STORE (src_folder),
5657 g_object_unref (src_folder);
5663 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
5664 TnyFolder *src_folder,
5666 TnyFolder *dst_folder)
5668 gboolean need_connection = TRUE;
5669 gboolean do_xfer = TRUE;
5670 XferMsgsHelper *helper;
5672 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5673 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5674 g_return_if_fail (TNY_IS_LIST (headers));
5676 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5677 headers, TNY_FOLDER (dst_folder),
5678 TRUE, &need_connection,
5681 /* If we don't want to transfer just return */
5685 /* Create the helper */
5686 helper = g_slice_new (XferMsgsHelper);
5687 helper->dst_folder = g_object_ref (dst_folder);
5688 helper->headers = g_object_ref (headers);
5690 if (need_connection) {
5691 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5692 connect_info->callback = xfer_messages_performer;
5693 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5694 connect_info->data = helper;
5696 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5697 TNY_FOLDER_STORE (src_folder),
5700 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5701 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
5702 src_account, helper);
5703 g_object_unref (src_account);
5708 * UI handler for the "Move to" action when invoked from the
5709 * ModestMsgViewWindow
5712 modest_ui_actions_on_window_move_to (GtkAction *action,
5714 TnyFolderStore *dst_folder,
5717 TnyFolder *src_folder = NULL;
5719 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5722 TnyHeader *header = NULL;
5725 iter = tny_list_create_iterator (headers);
5726 header = (TnyHeader *) tny_iterator_get_current (iter);
5727 src_folder = tny_header_get_folder (header);
5729 /* Transfer the messages */
5730 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
5732 TNY_FOLDER (dst_folder));
5735 g_object_unref (header);
5736 g_object_unref (iter);
5737 g_object_unref (src_folder);
5742 modest_ui_actions_on_move_to (GtkAction *action,
5745 modest_ui_actions_on_edit_mode_move_to (win);
5749 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
5751 GtkWidget *dialog = NULL, *folder_view = NULL;
5752 ModestMainWindow *main_window;
5753 MoveToInfo *helper = NULL;
5755 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
5757 /* Get the main window if exists */
5758 if (MODEST_IS_MAIN_WINDOW (win))
5759 main_window = MODEST_MAIN_WINDOW (win);
5762 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5763 FALSE)); /* don't create */
5765 /* Get the folder view widget if exists */
5767 folder_view = modest_main_window_get_child_widget (main_window,
5768 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5772 /* Create and run the dialog */
5773 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view);
5774 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
5775 GTK_WINDOW (dialog),
5779 helper = g_slice_new0 (MoveToInfo);
5780 helper->list = modest_platform_get_list_to_move (MODEST_WINDOW (win));
5783 /* Listen to response signal */
5784 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
5786 /* Show the dialog */
5787 gtk_widget_show (dialog);
5793 * Calls #HeadersFunc for each header already selected in the main
5794 * window or the message currently being shown in the msg view window
5797 do_headers_action (ModestWindow *win,
5801 TnyList *headers_list = NULL;
5802 TnyIterator *iter = NULL;
5803 TnyHeader *header = NULL;
5804 TnyFolder *folder = NULL;
5807 headers_list = get_selected_headers (win);
5811 /* Get the folder */
5812 iter = tny_list_create_iterator (headers_list);
5813 header = TNY_HEADER (tny_iterator_get_current (iter));
5815 folder = tny_header_get_folder (header);
5816 g_object_unref (header);
5819 /* Call the function for each header */
5820 while (!tny_iterator_is_done (iter)) {
5821 header = TNY_HEADER (tny_iterator_get_current (iter));
5822 func (header, win, user_data);
5823 g_object_unref (header);
5824 tny_iterator_next (iter);
5827 /* Trick: do a poke status in order to speed up the signaling
5829 tny_folder_poke_status (folder);
5832 g_object_unref (folder);
5833 g_object_unref (iter);
5834 g_object_unref (headers_list);
5838 modest_ui_actions_view_attachment (GtkAction *action,
5839 ModestWindow *window)
5841 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5842 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5844 /* not supported window for this action */
5845 g_return_if_reached ();
5850 modest_ui_actions_save_attachments (GtkAction *action,
5851 ModestWindow *window)
5853 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5855 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5858 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5860 /* not supported window for this action */
5861 g_return_if_reached ();
5866 modest_ui_actions_remove_attachments (GtkAction *action,
5867 ModestWindow *window)
5869 if (MODEST_IS_MAIN_WINDOW (window)) {
5870 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
5871 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5872 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5874 /* not supported window for this action */
5875 g_return_if_reached ();
5880 modest_ui_actions_on_settings (GtkAction *action,
5885 dialog = modest_platform_get_global_settings_dialog ();
5886 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
5887 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5888 gtk_widget_show_all (dialog);
5890 gtk_dialog_run (GTK_DIALOG (dialog));
5892 gtk_widget_destroy (dialog);
5896 modest_ui_actions_on_help (GtkAction *action,
5899 /* Help app is not available at all in fremantle */
5900 #ifndef MODEST_TOOLKIT_HILDON2
5901 const gchar *help_id;
5903 g_return_if_fail (win && GTK_IS_WINDOW(win));
5905 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5908 modest_platform_show_help (GTK_WINDOW (win), help_id);
5913 modest_ui_actions_on_csm_help (GtkAction *action,
5916 /* Help app is not available at all in fremantle */
5917 #ifndef MODEST_TOOLKIT_HILDON2
5919 const gchar* help_id = NULL;
5920 GtkWidget *folder_view;
5921 TnyFolderStore *folder_store;
5923 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
5925 /* Get selected folder */
5926 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5927 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5928 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5930 /* Switch help_id */
5931 if (folder_store && TNY_IS_FOLDER (folder_store))
5932 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
5935 g_object_unref (folder_store);
5938 modest_platform_show_help (GTK_WINDOW (win), help_id);
5940 modest_ui_actions_on_help (action, win);
5945 retrieve_contents_cb (ModestMailOperation *mail_op,
5952 /* We only need this callback to show an error in case of
5953 memory low condition */
5954 modest_ui_actions_msg_retrieval_check (mail_op, header, msg);
5958 retrieve_msg_contents_performer (gboolean canceled,
5960 GtkWindow *parent_window,
5961 TnyAccount *account,
5964 ModestMailOperation *mail_op;
5965 TnyList *headers = TNY_LIST (user_data);
5967 if (err || canceled) {
5968 check_memory_full_error ((GtkWidget *) parent_window, err);
5972 /* Create mail operation */
5973 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5974 modest_ui_actions_disk_operations_error_handler,
5976 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5977 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
5980 g_object_unref (mail_op);
5982 g_object_unref (headers);
5983 g_object_unref (account);
5987 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5988 ModestWindow *window)
5990 TnyList *headers = NULL;
5991 TnyAccount *account = NULL;
5992 TnyIterator *iter = NULL;
5993 TnyHeader *header = NULL;
5994 TnyFolder *folder = NULL;
5997 headers = get_selected_headers (window);
6001 /* Pick the account */
6002 iter = tny_list_create_iterator (headers);
6003 header = TNY_HEADER (tny_iterator_get_current (iter));
6004 folder = tny_header_get_folder (header);
6005 account = tny_folder_get_account (folder);
6006 g_object_unref (folder);
6007 g_object_unref (header);
6008 g_object_unref (iter);
6010 /* Connect and perform the message retrieval */
6011 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6012 g_object_ref (account),
6013 retrieve_msg_contents_performer,
6014 g_object_ref (headers));
6017 g_object_unref (account);
6018 g_object_unref (headers);
6022 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6024 g_return_if_fail (MODEST_IS_WINDOW (window));
6027 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6031 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6033 g_return_if_fail (MODEST_IS_WINDOW (window));
6036 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6040 modest_ui_actions_on_email_menu_activated (GtkAction *action,
6041 ModestWindow *window)
6043 g_return_if_fail (MODEST_IS_WINDOW (window));
6046 modest_ui_actions_check_menu_dimming_rules (window);
6050 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
6051 ModestWindow *window)
6053 g_return_if_fail (MODEST_IS_WINDOW (window));
6056 modest_ui_actions_check_menu_dimming_rules (window);
6060 modest_ui_actions_on_view_menu_activated (GtkAction *action,
6061 ModestWindow *window)
6063 g_return_if_fail (MODEST_IS_WINDOW (window));
6066 modest_ui_actions_check_menu_dimming_rules (window);
6070 modest_ui_actions_on_format_menu_activated (GtkAction *action,
6071 ModestWindow *window)
6073 g_return_if_fail (MODEST_IS_WINDOW (window));
6076 modest_ui_actions_check_menu_dimming_rules (window);
6080 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
6081 ModestWindow *window)
6083 g_return_if_fail (MODEST_IS_WINDOW (window));
6086 modest_ui_actions_check_menu_dimming_rules (window);
6090 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
6091 ModestWindow *window)
6093 g_return_if_fail (MODEST_IS_WINDOW (window));
6096 modest_ui_actions_check_menu_dimming_rules (window);
6100 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
6101 ModestWindow *window)
6103 g_return_if_fail (MODEST_IS_WINDOW (window));
6106 modest_ui_actions_check_menu_dimming_rules (window);
6110 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
6111 ModestWindow *window)
6113 g_return_if_fail (MODEST_IS_WINDOW (window));
6116 modest_ui_actions_check_menu_dimming_rules (window);
6120 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
6121 ModestWindow *window)
6123 g_return_if_fail (MODEST_IS_WINDOW (window));
6126 modest_ui_actions_check_menu_dimming_rules (window);
6130 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6132 g_return_if_fail (MODEST_IS_WINDOW (window));
6134 /* we check for low-mem; in that case, show a warning, and don't allow
6137 if (modest_platform_check_memory_low (window, TRUE))
6140 modest_platform_show_search_messages (GTK_WINDOW (window));
6144 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6146 g_return_if_fail (MODEST_IS_WINDOW (win));
6149 /* we check for low-mem; in that case, show a warning, and don't allow
6150 * for the addressbook
6152 if (modest_platform_check_memory_low (win, TRUE))
6156 modest_platform_show_addressbook (GTK_WINDOW (win));
6161 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6162 ModestWindow *window)
6165 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6167 if (GTK_IS_TOGGLE_ACTION (action))
6168 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6172 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window),
6177 on_send_receive_finished (ModestMailOperation *mail_op,
6180 GtkWidget *header_view, *folder_view;
6181 TnyFolderStore *folder_store;
6182 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6184 /* Set send/receive operation finished */
6185 modest_main_window_notify_send_receive_completed (main_win);
6187 /* Don't refresh the current folder if there were any errors */
6188 if (modest_mail_operation_get_status (mail_op) !=
6189 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6192 /* Refresh the current folder if we're viewing a window. We do
6193 this because the user won't be able to see the new mails in
6194 the selected folder after a Send&Receive because it only
6195 performs a poke_status, i.e, only the number of read/unread
6196 messages is updated, but the new headers are not
6198 folder_view = modest_main_window_get_child_widget (main_win,
6199 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6203 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6205 /* Do not need to refresh INBOX again because the
6206 update_account does it always automatically */
6207 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6208 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6209 ModestMailOperation *refresh_op;
6211 header_view = modest_main_window_get_child_widget (main_win,
6212 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6214 /* We do not need to set the contents style
6215 because it hasn't changed. We also do not
6216 need to save the widget status. Just force
6218 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6219 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6220 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6221 folder_refreshed_cb, main_win);
6222 g_object_unref (refresh_op);
6226 g_object_unref (folder_store);
6231 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6237 const gchar* server_name = NULL;
6238 TnyTransportAccount *server_account;
6239 gchar *message = NULL;
6241 /* Don't show anything if the user cancelled something or the
6242 * send receive request is not interactive. Authentication
6243 * errors are managed by the account store so no need to show
6244 * a dialog here again */
6245 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6246 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6247 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6251 /* Get the server name: */
6253 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
6255 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
6257 g_return_if_reached ();
6259 /* Show the appropriate message text for the GError: */
6260 switch (err->code) {
6261 case TNY_SERVICE_ERROR_CONNECT:
6262 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6264 case TNY_SERVICE_ERROR_SEND:
6265 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
6267 case TNY_SERVICE_ERROR_UNAVAILABLE:
6268 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6271 g_warning ("%s: unexpected ERROR %d",
6272 __FUNCTION__, err->code);
6273 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
6277 modest_platform_run_information_dialog (NULL, message, FALSE);
6279 g_object_unref (server_account);
6283 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6288 ModestMainWindow *main_window = NULL;
6289 ModestWindowMgr *mgr = NULL;
6290 GtkWidget *folder_view = NULL, *header_view = NULL;
6291 TnyFolderStore *selected_folder = NULL;
6292 TnyFolderType folder_type;
6294 mgr = modest_runtime_get_window_mgr ();
6295 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr,
6296 FALSE));/* don't create */
6300 /* Check if selected folder is OUTBOX */
6301 folder_view = modest_main_window_get_child_widget (main_window,
6302 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6303 header_view = modest_main_window_get_child_widget (main_window,
6304 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6306 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6307 if (!TNY_IS_FOLDER (selected_folder))
6310 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6311 #if GTK_CHECK_VERSION(2, 8, 0)
6312 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
6313 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6314 GtkTreeViewColumn *tree_column;
6316 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6317 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6319 gtk_tree_view_column_queue_resize (tree_column);
6322 gtk_widget_queue_draw (header_view);
6325 /* Rerun dimming rules, because the message could become deletable for example */
6326 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6327 MODEST_DIMMING_RULES_TOOLBAR);
6328 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6329 MODEST_DIMMING_RULES_MENU);
6333 if (selected_folder != NULL)
6334 g_object_unref (selected_folder);
6338 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6339 TnyAccount *account)
6341 ModestProtocolType protocol_type;
6342 ModestProtocol *protocol;
6343 gchar *error_note = NULL;
6345 protocol_type = modest_tny_account_get_protocol_type (account);
6346 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6349 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6350 if (error_note == NULL) {
6351 g_warning ("%s: This should not be reached", __FUNCTION__);
6353 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6354 g_free (error_note);
6359 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6363 TnyFolderStore *folder = NULL;
6364 TnyAccount *account = NULL;
6365 ModestProtocolType proto;
6366 ModestProtocol *protocol;
6367 TnyHeader *header = NULL;
6369 if (MODEST_IS_MAIN_WINDOW (win)) {
6370 GtkWidget *header_view;
6371 TnyList* headers = NULL;
6373 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6374 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6375 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6376 if (!headers || tny_list_get_length (headers) == 0) {
6378 g_object_unref (headers);
6381 iter = tny_list_create_iterator (headers);
6382 header = TNY_HEADER (tny_iterator_get_current (iter));
6383 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6384 g_object_unref (iter);
6385 g_object_unref (headers);
6386 #ifdef MODEST_TOOLKIT_HILDON2
6387 } else if (MODEST_IS_HEADER_WINDOW (win)) {
6388 GtkWidget *header_view;
6389 TnyList* headers = NULL;
6391 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
6392 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6393 if (!headers || tny_list_get_length (headers) == 0) {
6395 g_object_unref (headers);
6398 iter = tny_list_create_iterator (headers);
6399 header = TNY_HEADER (tny_iterator_get_current (iter));
6400 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6401 g_object_unref (iter);
6402 g_object_unref (headers);
6404 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6405 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6406 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6409 /* Get the account type */
6410 account = tny_folder_get_account (TNY_FOLDER (folder));
6411 proto = modest_tny_account_get_protocol_type (account);
6412 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6415 subject = tny_header_dup_subject (header);
6416 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6420 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6424 g_object_unref (account);
6425 g_object_unref (folder);
6426 g_object_unref (header);
6432 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6433 const gchar *account_name,
6434 const gchar *account_title)
6436 ModestAccountMgr *account_mgr;
6439 ModestProtocol *protocol;
6440 gboolean removed = FALSE;
6442 g_return_val_if_fail (account_name, FALSE);
6443 g_return_val_if_fail (account_title, FALSE);
6445 account_mgr = modest_runtime_get_account_mgr();
6447 /* The warning text depends on the account type: */
6448 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6449 modest_account_mgr_get_store_protocol (account_mgr,
6451 txt = modest_protocol_get_translation (protocol,
6452 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6455 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6457 response = modest_platform_run_confirmation_dialog (parent_window, txt);
6461 if (response == GTK_RESPONSE_OK) {
6462 /* Remove account. If it succeeds then it also removes
6463 the account from the ModestAccountView: */
6464 gboolean is_default = FALSE;
6465 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6466 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6468 g_free (default_account_name);
6470 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6472 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);