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 _KR("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, _KR("cerm_device_memory_full"));
1147 else if (err->code == TNY_SYSTEM_ERROR_MEMORY)
1148 /* If the account was created in memory full
1149 conditions then tinymail won't be able to
1150 connect so it'll return this error code */
1151 modest_platform_information_banner (parent_window,
1152 NULL, _("emev_ui_imap_inbox_select_error"));
1160 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1163 const GError *error;
1164 GObject *win = NULL;
1165 ModestMailOperationStatus status;
1167 win = modest_mail_operation_get_source (mail_op);
1168 error = modest_mail_operation_get_error (mail_op);
1169 status = modest_mail_operation_get_status (mail_op);
1171 /* If the mail op has been cancelled then it's not an error:
1172 don't show any message */
1173 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1174 if (is_memory_full_error ((GError *) error)) {
1175 modest_platform_information_banner ((GtkWidget *) win,
1176 NULL, _KR("cerm_device_memory_full"));
1177 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1178 modest_platform_information_banner ((GtkWidget *) win,
1179 NULL, _("emev_ui_imap_inbox_select_error"));
1180 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1181 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1182 modest_platform_information_banner ((GtkWidget *) win,
1183 NULL, _CS ("sfil_ni_unable_to_open_file_not_found"));
1184 } else if (user_data) {
1185 modest_platform_information_banner ((GtkWidget *) win,
1191 g_object_unref (win);
1195 * Returns the account a list of headers belongs to. It returns a
1196 * *new* reference so don't forget to unref it
1199 get_account_from_header_list (TnyList *headers)
1201 TnyAccount *account = NULL;
1203 if (tny_list_get_length (headers) > 0) {
1204 TnyIterator *iter = tny_list_create_iterator (headers);
1205 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1206 TnyFolder *folder = tny_header_get_folder (header);
1209 g_object_unref (header);
1211 while (!tny_iterator_is_done (iter)) {
1212 header = TNY_HEADER (tny_iterator_get_current (iter));
1213 folder = tny_header_get_folder (header);
1216 g_object_unref (header);
1218 tny_iterator_next (iter);
1223 account = tny_folder_get_account (folder);
1224 g_object_unref (folder);
1228 g_object_unref (header);
1230 g_object_unref (iter);
1236 get_account_from_header (TnyHeader *header)
1238 TnyAccount *account = NULL;
1241 folder = tny_header_get_folder (header);
1244 account = tny_folder_get_account (folder);
1245 g_object_unref (folder);
1251 open_msg_helper_destroyer (gpointer user_data)
1253 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1255 if (helper->banner_info) {
1256 g_free (helper->banner_info->message);
1257 if (helper->banner_info->idle_handler > 0) {
1258 g_source_remove (helper->banner_info->idle_handler);
1259 helper->banner_info->idle_handler = 0;
1261 if (helper->banner_info->banner != NULL) {
1262 gtk_widget_destroy (helper->banner_info->banner);
1263 g_object_unref (helper->banner_info->banner);
1264 helper->banner_info->banner = NULL;
1266 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1267 helper->banner_info = NULL;
1269 g_object_unref (helper->model);
1270 g_object_unref (helper->header);
1271 gtk_tree_row_reference_free (helper->rowref);
1272 g_slice_free (OpenMsgHelper, helper);
1276 open_msg_performer(gboolean canceled,
1278 GtkWindow *parent_window,
1279 TnyAccount *account,
1282 ModestMailOperation *mail_op = NULL;
1284 ModestProtocolType proto;
1285 TnyConnectionStatus status;
1286 OpenMsgHelper *helper = NULL;
1287 ModestProtocol *protocol;
1288 ModestProtocolRegistry *protocol_registry;
1291 helper = (OpenMsgHelper *) user_data;
1293 status = tny_account_get_connection_status (account);
1294 if (err || canceled) {
1295 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1296 /* Free the helper */
1297 open_msg_helper_destroyer (helper);
1299 /* In memory full conditions we could get this error here */
1300 check_memory_full_error ((GtkWidget *) parent_window, err);
1305 /* Get the error message depending on the protocol */
1306 proto = modest_tny_account_get_protocol_type (account);
1307 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1308 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1311 protocol_registry = modest_runtime_get_protocol_registry ();
1312 subject = tny_header_dup_subject (helper->header);
1314 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1315 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1319 if (error_msg == NULL) {
1320 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1323 #ifndef MODEST_TOOLKIT_HILDON2
1324 gboolean show_open_draft = FALSE;
1325 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1327 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1329 TnyFolderType folder_type;
1331 folder = tny_header_get_folder (helper->header);
1332 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1333 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1334 g_object_unref (folder);
1338 #ifdef MODEST_TOOLKIT_HILDON2
1341 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1344 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1345 g_free (account_name);
1346 open_msg_helper_destroyer (helper);
1351 ModestWindow *window;
1352 GtkWidget *header_view;
1355 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1356 uid = modest_tny_folder_get_header_unique_id (helper->header);
1358 window = modest_msg_view_window_new_from_header_view
1359 (MODEST_HEADER_VIEW (header_view), account_name, uid, helper->rowref);
1360 if (window != NULL) {
1361 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1363 gtk_widget_destroy (GTK_WIDGET (window));
1365 gtk_widget_show_all (GTK_WIDGET(window));
1369 g_free (account_name);
1371 open_msg_helper_destroyer (helper);
1374 g_free (account_name);
1376 /* Create the mail operation */
1378 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1379 modest_ui_actions_disk_operations_error_handler,
1381 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1385 #ifndef MODEST_TOOLKIT_HILDON2
1386 if (show_open_draft) {
1387 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1388 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1389 helper->banner_info->banner = NULL;
1390 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1391 helper->banner_info);
1397 headers = TNY_LIST (tny_simple_list_new ());
1398 tny_list_prepend (headers, G_OBJECT (helper->header));
1399 modest_mail_operation_get_msgs_full (mail_op,
1403 open_msg_helper_destroyer);
1404 g_object_unref (headers);
1409 g_object_unref (mail_op);
1410 g_object_unref (account);
1414 * This function is used by both modest_ui_actions_on_open and
1415 * modest_ui_actions_on_header_activated. This way we always do the
1416 * same when trying to open messages.
1419 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1421 ModestWindowMgr *mgr = NULL;
1422 TnyAccount *account;
1423 gboolean cached = FALSE;
1425 GtkWidget *header_view = NULL;
1426 OpenMsgHelper *helper;
1427 ModestWindow *window;
1429 g_return_if_fail (header != NULL && rowref != NULL);
1431 mgr = modest_runtime_get_window_mgr ();
1434 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1435 if (header_view == NULL)
1438 /* Get the account */
1439 account = get_account_from_header (header);
1444 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1446 /* Do not open again the message and present the
1447 window to the user */
1450 #ifndef MODEST_TOOLKIT_HILDON2
1451 gtk_window_present (GTK_WINDOW (window));
1454 /* the header has been registered already, we don't do
1455 * anything but wait for the window to come up*/
1456 g_debug ("header %p already registered, waiting for window", header);
1461 /* Open each message */
1462 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1464 /* Allways download if we are online. */
1465 if (!tny_device_is_online (modest_runtime_get_device ())) {
1468 /* If ask for user permission to download the messages */
1469 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1470 _("mcen_nc_get_msg"));
1472 /* End if the user does not want to continue */
1473 if (response == GTK_RESPONSE_CANCEL) {
1479 /* We register the window for opening */
1480 modest_window_mgr_register_header (mgr, header, NULL);
1482 /* Create the helper. We need to get a reference to the model
1483 here because it could change while the message is readed
1484 (the user could switch between folders) */
1485 helper = g_slice_new (OpenMsgHelper);
1486 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1487 helper->header = g_object_ref (header);
1488 helper->rowref = gtk_tree_row_reference_copy (rowref);
1489 helper->banner_info = NULL;
1491 /* Connect to the account and perform */
1493 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1494 open_msg_performer, helper);
1496 /* Call directly the performer, do not need to connect */
1497 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1498 g_object_ref (account), helper);
1503 g_object_unref (account);
1507 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1514 /* we check for low-mem; in that case, show a warning, and don't allow
1517 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1521 headers = get_selected_headers (win);
1525 headers_count = tny_list_get_length (headers);
1526 if (headers_count != 1) {
1527 if (headers_count > 1) {
1528 /* Don't allow activation if there are more than one message selected */
1529 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1532 g_object_unref (headers);
1536 iter = tny_list_create_iterator (headers);
1537 header = TNY_HEADER (tny_iterator_get_current (iter));
1538 g_object_unref (iter);
1542 open_msg_from_header (header, NULL, win);
1543 g_object_unref (header);
1546 g_object_unref(headers);
1550 rf_helper_window_closed (gpointer data,
1553 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1555 helper->parent_window = NULL;
1558 static ReplyForwardHelper*
1559 create_reply_forward_helper (ReplyForwardAction action,
1561 guint reply_forward_type,
1564 ReplyForwardHelper *rf_helper = NULL;
1565 const gchar *active_acc = modest_window_get_active_account (win);
1567 rf_helper = g_slice_new0 (ReplyForwardHelper);
1568 rf_helper->reply_forward_type = reply_forward_type;
1569 rf_helper->action = action;
1570 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1571 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1572 rf_helper->account_name = (active_acc) ?
1573 g_strdup (active_acc) :
1574 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1576 /* Note that window could be destroyed just AFTER calling
1577 register_window so we must ensure that this pointer does
1578 not hold invalid references */
1579 if (rf_helper->parent_window)
1580 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1581 rf_helper_window_closed, rf_helper);
1587 free_reply_forward_helper (gpointer data)
1589 ReplyForwardHelper *helper;
1591 helper = (ReplyForwardHelper *) data;
1592 g_free (helper->account_name);
1594 g_object_unref (helper->header);
1595 if (helper->parent_window)
1596 g_object_weak_unref (G_OBJECT (helper->parent_window),
1597 rf_helper_window_closed, helper);
1598 g_slice_free (ReplyForwardHelper, helper);
1602 reply_forward_cb (ModestMailOperation *mail_op,
1609 TnyMsg *new_msg = NULL;
1610 ReplyForwardHelper *rf_helper;
1611 ModestWindow *msg_win = NULL;
1612 ModestEditType edit_type;
1614 TnyAccount *account = NULL;
1615 ModestWindowMgr *mgr = NULL;
1616 gchar *signature = NULL;
1617 gboolean use_signature;
1619 /* If there was any error. The mail operation could be NULL,
1620 this means that we already have the message downloaded and
1621 that we didn't do a mail operation to retrieve it */
1622 rf_helper = (ReplyForwardHelper *) user_data;
1623 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1626 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1627 rf_helper->account_name);
1628 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr(),
1629 rf_helper->account_name,
1632 /* Create reply mail */
1633 switch (rf_helper->action) {
1636 modest_tny_msg_create_reply_msg (msg, header, from,
1637 (use_signature) ? signature : NULL,
1638 rf_helper->reply_forward_type,
1639 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1641 case ACTION_REPLY_TO_ALL:
1643 modest_tny_msg_create_reply_msg (msg, header, from,
1644 (use_signature) ? signature : NULL,
1645 rf_helper->reply_forward_type,
1646 MODEST_TNY_MSG_REPLY_MODE_ALL);
1647 edit_type = MODEST_EDIT_TYPE_REPLY;
1649 case ACTION_FORWARD:
1651 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1652 rf_helper->reply_forward_type);
1653 edit_type = MODEST_EDIT_TYPE_FORWARD;
1656 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1658 g_return_if_reached ();
1666 g_warning ("%s: failed to create message\n", __FUNCTION__);
1670 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1671 rf_helper->account_name,
1672 TNY_ACCOUNT_TYPE_STORE);
1674 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1678 /* Create and register the windows */
1679 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1680 mgr = modest_runtime_get_window_mgr ();
1681 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1683 /* Note that register_window could have deleted the account */
1684 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1685 gdouble parent_zoom;
1687 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1688 modest_window_set_zoom (msg_win, parent_zoom);
1691 /* Show edit window */
1692 gtk_widget_show_all (GTK_WIDGET (msg_win));
1695 /* We always unregister the header because the message is
1696 forwarded or replied so the original one is no longer
1698 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1701 g_object_unref (G_OBJECT (new_msg));
1703 g_object_unref (G_OBJECT (account));
1704 free_reply_forward_helper (rf_helper);
1707 /* Checks a list of headers. If any of them are not currently
1708 * downloaded (CACHED) then returns TRUE else returns FALSE.
1711 header_list_count_uncached_msgs (TnyList *header_list)
1714 gint uncached_messages = 0;
1716 iter = tny_list_create_iterator (header_list);
1717 while (!tny_iterator_is_done (iter)) {
1720 header = TNY_HEADER (tny_iterator_get_current (iter));
1722 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1723 uncached_messages ++;
1724 g_object_unref (header);
1727 tny_iterator_next (iter);
1729 g_object_unref (iter);
1731 return uncached_messages;
1734 /* Returns FALSE if the user does not want to download the
1735 * messages. Returns TRUE if the user allowed the download.
1738 connect_to_get_msg (ModestWindow *win,
1739 gint num_of_uncached_msgs,
1740 TnyAccount *account)
1742 GtkResponseType response;
1744 /* Allways download if we are online. */
1745 if (tny_device_is_online (modest_runtime_get_device ()))
1748 /* If offline, then ask for user permission to download the messages */
1749 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1750 ngettext("mcen_nc_get_msg",
1752 num_of_uncached_msgs));
1754 if (response == GTK_RESPONSE_CANCEL)
1757 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1761 reply_forward_performer (gboolean canceled,
1763 GtkWindow *parent_window,
1764 TnyAccount *account,
1767 ReplyForwardHelper *rf_helper = NULL;
1768 ModestMailOperation *mail_op;
1770 rf_helper = (ReplyForwardHelper *) user_data;
1772 if (canceled || err) {
1773 free_reply_forward_helper (rf_helper);
1777 /* Retrieve the message */
1778 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1779 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1780 modest_ui_actions_disk_operations_error_handler,
1782 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1783 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1786 g_object_unref(mail_op);
1790 * Common code for the reply and forward actions
1793 reply_forward (ReplyForwardAction action, ModestWindow *win)
1795 ReplyForwardHelper *rf_helper = NULL;
1796 guint reply_forward_type;
1798 g_return_if_fail (MODEST_IS_WINDOW(win));
1800 /* we check for low-mem; in that case, show a warning, and don't allow
1801 * reply/forward (because it could potentially require a lot of memory */
1802 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1806 /* we need an account when editing */
1807 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1808 if (!modest_ui_actions_run_account_setup_wizard (win))
1812 reply_forward_type =
1813 modest_conf_get_int (modest_runtime_get_conf (),
1814 (action == ACTION_FORWARD) ?
1815 MODEST_CONF_FORWARD_TYPE :
1816 MODEST_CONF_REPLY_TYPE,
1819 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1821 TnyHeader *header = NULL;
1822 /* Get header and message. Do not free them here, the
1823 reply_forward_cb must do it */
1824 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1825 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1827 if (msg && header) {
1829 rf_helper = create_reply_forward_helper (action, win,
1830 reply_forward_type, header);
1831 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1833 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1837 g_object_unref (msg);
1839 g_object_unref (header);
1841 TnyHeader *header = NULL;
1843 gboolean do_retrieve = TRUE;
1844 TnyList *header_list = NULL;
1846 header_list = get_selected_headers (win);
1849 /* Check that only one message is selected for replying */
1850 if (tny_list_get_length (header_list) != 1) {
1851 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1852 NULL, _("mcen_ib_select_one_message"));
1853 g_object_unref (header_list);
1857 /* Only reply/forward to one message */
1858 iter = tny_list_create_iterator (header_list);
1859 header = TNY_HEADER (tny_iterator_get_current (iter));
1860 g_object_unref (iter);
1862 /* Retrieve messages */
1863 do_retrieve = (action == ACTION_FORWARD) ||
1864 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1867 TnyAccount *account = NULL;
1868 TnyFolder *folder = NULL;
1869 gdouble download = TRUE;
1870 guint uncached_msgs = 0;
1872 folder = tny_header_get_folder (header);
1874 goto do_retrieve_frees;
1875 account = tny_folder_get_account (folder);
1877 goto do_retrieve_frees;
1879 uncached_msgs = header_list_count_uncached_msgs (header_list);
1881 if (uncached_msgs > 0) {
1882 /* Allways download if we are online. */
1883 if (!tny_device_is_online (modest_runtime_get_device ())) {
1886 /* If ask for user permission to download the messages */
1887 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1888 ngettext("mcen_nc_get_msg",
1892 /* End if the user does not want to continue */
1893 if (response == GTK_RESPONSE_CANCEL)
1900 rf_helper = create_reply_forward_helper (action, win,
1901 reply_forward_type, header);
1902 if (uncached_msgs > 0) {
1903 modest_platform_connect_and_perform (GTK_WINDOW (win),
1905 reply_forward_performer,
1908 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
1909 account, rf_helper);
1914 g_object_unref (account);
1916 g_object_unref (folder);
1918 reply_forward_cb (NULL, header, FALSE, NULL, NULL, rf_helper);
1921 g_object_unref (header_list);
1922 g_object_unref (header);
1927 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1929 g_return_if_fail (MODEST_IS_WINDOW(win));
1931 reply_forward (ACTION_REPLY, win);
1935 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1937 g_return_if_fail (MODEST_IS_WINDOW(win));
1939 reply_forward (ACTION_FORWARD, win);
1943 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1945 g_return_if_fail (MODEST_IS_WINDOW(win));
1947 reply_forward (ACTION_REPLY_TO_ALL, win);
1951 modest_ui_actions_on_next (GtkAction *action,
1952 ModestWindow *window)
1954 if (MODEST_IS_MAIN_WINDOW (window)) {
1955 GtkWidget *header_view;
1957 header_view = modest_main_window_get_child_widget (
1958 MODEST_MAIN_WINDOW(window),
1959 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1963 modest_header_view_select_next (
1964 MODEST_HEADER_VIEW(header_view));
1965 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1966 modest_msg_view_window_select_next_message (
1967 MODEST_MSG_VIEW_WINDOW (window));
1969 g_return_if_reached ();
1974 modest_ui_actions_on_prev (GtkAction *action,
1975 ModestWindow *window)
1977 g_return_if_fail (MODEST_IS_WINDOW(window));
1979 if (MODEST_IS_MAIN_WINDOW (window)) {
1980 GtkWidget *header_view;
1981 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1982 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1986 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1987 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1988 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1990 g_return_if_reached ();
1995 modest_ui_actions_on_sort (GtkAction *action,
1996 ModestWindow *window)
1998 GtkWidget *header_view = NULL;
2000 g_return_if_fail (MODEST_IS_WINDOW(window));
2002 if (MODEST_IS_MAIN_WINDOW (window)) {
2003 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2004 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2005 #ifdef MODEST_TOOLKIT_HILDON2
2006 } else if (MODEST_IS_HEADER_WINDOW (window)) {
2007 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2012 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
2017 /* Show sorting dialog */
2018 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
2022 new_messages_arrived (ModestMailOperation *self,
2023 TnyList *new_headers,
2027 gboolean show_visual_notifications;
2029 source = modest_mail_operation_get_source (self);
2030 show_visual_notifications = (source) ? FALSE : TRUE;
2032 g_object_unref (source);
2034 /* Notify new messages have been downloaded. If the
2035 send&receive was invoked by the user then do not show any
2036 visual notification, only play a sound and activate the LED
2037 (for the Maemo version) */
2038 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0)
2039 modest_platform_on_new_headers_received (new_headers,
2040 show_visual_notifications);
2045 retrieve_all_messages_cb (GObject *source,
2047 guint retrieve_limit)
2053 window = GTK_WINDOW (source);
2054 msg = g_strdup_printf (_("mail_nc_msg_count_limit_exceeded"),
2055 num_msgs, retrieve_limit);
2057 /* Ask the user if they want to retrieve all the messages */
2059 modest_platform_run_confirmation_dialog_with_buttons (window, msg,
2060 _("mcen_bd_get_all"),
2061 _("mcen_bd_newest_only"));
2062 /* Free and return */
2064 return (response == GTK_RESPONSE_ACCEPT) ? TRUE : FALSE;
2068 TnyAccount *account;
2070 gchar *account_name;
2071 gboolean poke_status;
2072 gboolean interactive;
2073 ModestMailOperation *mail_op;
2077 do_send_receive_performer (gboolean canceled,
2079 GtkWindow *parent_window,
2080 TnyAccount *account,
2083 SendReceiveInfo *info;
2085 info = (SendReceiveInfo *) user_data;
2087 if (err || canceled) {
2088 /* In memory full conditions we could get this error here */
2089 check_memory_full_error ((GtkWidget *) parent_window, err);
2091 if (info->mail_op) {
2092 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2098 /* Set send/receive operation in progress */
2099 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2100 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2103 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2104 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2105 G_CALLBACK (on_send_receive_finished),
2108 /* Send & receive. */
2109 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2110 (info->win) ? retrieve_all_messages_cb : NULL,
2111 new_messages_arrived, info->win);
2116 g_object_unref (G_OBJECT (info->mail_op));
2117 if (info->account_name)
2118 g_free (info->account_name);
2120 g_object_unref (info->win);
2122 g_object_unref (info->account);
2123 g_slice_free (SendReceiveInfo, info);
2127 * This function performs the send & receive required actions. The
2128 * window is used to create the mail operation. Typically it should
2129 * always be the main window, but we pass it as argument in order to
2133 modest_ui_actions_do_send_receive (const gchar *account_name,
2134 gboolean force_connection,
2135 gboolean poke_status,
2136 gboolean interactive,
2139 gchar *acc_name = NULL;
2140 SendReceiveInfo *info;
2141 ModestTnyAccountStore *acc_store;
2143 /* If no account name was provided then get the current account, and if
2144 there is no current account then pick the default one: */
2145 if (!account_name) {
2147 acc_name = g_strdup (modest_window_get_active_account (win));
2149 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2151 g_printerr ("modest: cannot get default account\n");
2155 acc_name = g_strdup (account_name);
2158 acc_store = modest_runtime_get_account_store ();
2160 /* Create the info for the connect and perform */
2161 info = g_slice_new (SendReceiveInfo);
2162 info->account_name = acc_name;
2163 info->win = (win) ? g_object_ref (win) : NULL;
2164 info->poke_status = poke_status;
2165 info->interactive = interactive;
2166 info->account = modest_tny_account_store_get_server_account (acc_store, acc_name,
2167 TNY_ACCOUNT_TYPE_STORE);
2168 /* We need to create the operation here, because otherwise it
2169 could happen that the queue emits the queue-empty signal
2170 while we're trying to connect the account */
2171 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2172 modest_ui_actions_disk_operations_error_handler,
2174 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2176 /* Invoke the connect and perform */
2177 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2178 force_connection, info->account,
2179 do_send_receive_performer, info);
2184 modest_ui_actions_do_cancel_send (const gchar *account_name,
2187 TnyTransportAccount *transport_account;
2188 TnySendQueue *send_queue = NULL;
2189 GError *error = NULL;
2191 /* Get transport account */
2193 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2194 (modest_runtime_get_account_store(),
2196 TNY_ACCOUNT_TYPE_TRANSPORT));
2197 if (!transport_account) {
2198 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2203 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2204 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2205 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2206 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2207 "modest: could not find send queue for account\n");
2209 /* Cancel the current send */
2210 tny_account_cancel (TNY_ACCOUNT (transport_account));
2212 /* Suspend all pending messages */
2213 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2217 if (transport_account != NULL)
2218 g_object_unref (G_OBJECT (transport_account));
2222 modest_ui_actions_cancel_send_all (ModestWindow *win)
2224 GSList *account_names, *iter;
2226 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2229 iter = account_names;
2231 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2232 iter = g_slist_next (iter);
2235 modest_account_mgr_free_account_names (account_names);
2236 account_names = NULL;
2240 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2243 /* Check if accounts exist */
2244 gboolean accounts_exist =
2245 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2247 /* If not, allow the user to create an account before trying to send/receive. */
2248 if (!accounts_exist)
2249 modest_ui_actions_on_accounts (NULL, win);
2251 /* Cancel all sending operaitons */
2252 modest_ui_actions_cancel_send_all (win);
2256 * Refreshes all accounts. This function will be used by automatic
2260 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2261 gboolean force_connection,
2262 gboolean poke_status,
2263 gboolean interactive)
2265 GSList *account_names, *iter;
2267 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2270 iter = account_names;
2272 modest_ui_actions_do_send_receive ((const char*) iter->data,
2274 poke_status, interactive, win);
2275 iter = g_slist_next (iter);
2278 modest_account_mgr_free_account_names (account_names);
2279 account_names = NULL;
2283 * Handler of the click on Send&Receive button in the main toolbar
2286 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2288 /* Check if accounts exist */
2289 gboolean accounts_exist;
2292 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2294 /* If not, allow the user to create an account before trying to send/receive. */
2295 if (!accounts_exist)
2296 modest_ui_actions_on_accounts (NULL, win);
2298 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2299 if (MODEST_IS_MAIN_WINDOW (win)) {
2300 GtkWidget *folder_view;
2301 TnyFolderStore *folder_store;
2304 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2305 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2309 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2312 g_object_unref (folder_store);
2313 /* Refresh the active account. Force the connection if needed
2314 and poke the status of all folders */
2315 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2316 #ifdef MODEST_TOOLKIT_HILDON2
2317 } else if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2318 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2321 const gchar *active_account;
2322 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2324 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2331 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2334 GtkWidget *header_view;
2336 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2338 header_view = modest_main_window_get_child_widget (main_window,
2339 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2343 conf = modest_runtime_get_conf ();
2345 /* what is saved/restored is depending on the style; thus; we save with
2346 * old style, then update the style, and restore for this new style
2348 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2350 if (modest_header_view_get_style
2351 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2352 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2353 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2355 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2356 MODEST_HEADER_VIEW_STYLE_DETAILS);
2358 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2359 MODEST_CONF_HEADER_VIEW_KEY);
2364 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2366 ModestMainWindow *main_window)
2368 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2369 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2371 /* in the case the folder is empty, show the empty folder message and focus
2373 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2374 if (modest_header_view_is_empty (header_view)) {
2375 TnyFolder *folder = modest_header_view_get_folder (header_view);
2376 GtkWidget *folder_view =
2377 modest_main_window_get_child_widget (main_window,
2378 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2379 if (folder != NULL) {
2380 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2381 g_object_unref (folder);
2383 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2387 /* If no header has been selected then exit */
2392 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2393 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2395 /* Update toolbar dimming state */
2396 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2397 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2401 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2404 ModestWindow *window)
2406 GtkWidget *open_widget;
2407 GtkTreeRowReference *rowref;
2409 g_return_if_fail (MODEST_IS_WINDOW(window));
2410 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2411 g_return_if_fail (TNY_IS_HEADER (header));
2413 if (modest_header_view_count_selected_headers (header_view) > 1) {
2414 /* Don't allow activation if there are more than one message selected */
2415 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2419 /* we check for low-mem; in that case, show a warning, and don't allow
2420 * activating headers
2422 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2425 if (MODEST_IS_MAIN_WINDOW (window)) {
2426 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2427 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2428 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2432 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2433 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2434 gtk_tree_row_reference_free (rowref);
2438 set_active_account_from_tny_account (TnyAccount *account,
2439 ModestWindow *window)
2441 const gchar *server_acc_name = tny_account_get_id (account);
2443 /* We need the TnyAccount provided by the
2444 account store because that is the one that
2445 knows the name of the Modest account */
2446 TnyAccount *modest_server_account = modest_server_account =
2447 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2448 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2450 if (!modest_server_account) {
2451 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2455 /* Update active account, but only if it's not a pseudo-account */
2456 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2457 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2458 const gchar *modest_acc_name =
2459 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2460 if (modest_acc_name)
2461 modest_window_set_active_account (window, modest_acc_name);
2464 g_object_unref (modest_server_account);
2469 folder_refreshed_cb (ModestMailOperation *mail_op,
2473 ModestMainWindow *win = NULL;
2474 GtkWidget *folder_view;
2475 const GError *error;
2477 g_return_if_fail (TNY_IS_FOLDER (folder));
2479 win = MODEST_MAIN_WINDOW (user_data);
2481 /* Check if the operation failed due to memory low conditions */
2482 error = modest_mail_operation_get_error (mail_op);
2483 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2484 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2485 modest_platform_run_information_dialog (GTK_WINDOW (win),
2486 _KR("memr_ib_operation_disabled"),
2492 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2495 TnyFolderStore *current_folder;
2497 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2498 if (current_folder) {
2499 gboolean different = ((TnyFolderStore *) folder != current_folder);
2500 g_object_unref (current_folder);
2506 /* Check if folder is empty and set headers view contents style */
2507 if (tny_folder_get_all_count (folder) == 0)
2508 modest_main_window_set_contents_style (win,
2509 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2514 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2515 TnyFolderStore *folder_store,
2517 ModestMainWindow *main_window)
2520 GtkWidget *header_view;
2522 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2524 header_view = modest_main_window_get_child_widget(main_window,
2525 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2529 conf = modest_runtime_get_conf ();
2531 if (TNY_IS_ACCOUNT (folder_store)) {
2533 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2535 /* Show account details */
2536 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2539 if (TNY_IS_FOLDER (folder_store) && selected) {
2540 TnyAccount *account;
2541 const gchar *account_name = NULL;
2543 /* Update the active account */
2544 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2546 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2548 modest_tny_account_get_parent_modest_account_name_for_server_account (account);
2549 g_object_unref (account);
2553 /* Set the header style by default, it could
2554 be changed later by the refresh callback to
2556 modest_main_window_set_contents_style (main_window,
2557 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2559 /* Set folder on header view. This function
2560 will call tny_folder_refresh_async so we
2561 pass a callback that will be called when
2562 finished. We use that callback to set the
2563 empty view if there are no messages */
2564 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2565 TNY_FOLDER (folder_store),
2567 MODEST_WINDOW (main_window),
2568 folder_refreshed_cb,
2571 /* Restore configuration. We need to do this
2572 *after* the set_folder because the widget
2573 memory asks the header view about its
2575 modest_widget_memory_restore (modest_runtime_get_conf (),
2576 G_OBJECT(header_view),
2577 MODEST_CONF_HEADER_VIEW_KEY);
2579 /* No need to save the header view
2580 configuration for Maemo because it only
2581 saves the sorting stuff and that it's
2582 already being done by the sort
2583 dialog. Remove it when the GNOME version
2584 has the same behaviour */
2585 #ifdef MODEST_TOOLKIT_GTK
2586 if (modest_main_window_get_contents_style (main_window) ==
2587 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2588 modest_widget_memory_save (conf, G_OBJECT (header_view),
2589 MODEST_CONF_HEADER_VIEW_KEY);
2591 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2595 /* Update dimming state */
2596 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2597 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2601 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2608 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2610 online = tny_device_is_online (modest_runtime_get_device());
2613 /* already online -- the item is simply not there... */
2614 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2616 GTK_MESSAGE_WARNING,
2618 _("The %s you selected cannot be found"),
2620 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2621 gtk_dialog_run (GTK_DIALOG(dialog));
2623 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2626 _("mcen_bd_dialog_cancel"),
2627 GTK_RESPONSE_REJECT,
2628 _("mcen_bd_dialog_ok"),
2629 GTK_RESPONSE_ACCEPT,
2631 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2632 "Do you want to get online?"), item);
2633 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2634 gtk_label_new (txt), FALSE, FALSE, 0);
2635 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2638 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2639 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2640 /* TODO: Comment about why is this commented out: */
2641 /* modest_platform_connect_and_wait (); */
2644 gtk_widget_destroy (dialog);
2648 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2651 /* g_message ("%s %s", __FUNCTION__, link); */
2656 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2659 modest_platform_activate_uri (link);
2663 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2666 modest_platform_show_uri_popup (link);
2670 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2673 /* we check for low-mem; in that case, show a warning, and don't allow
2674 * viewing attachments
2676 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2679 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2683 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2684 const gchar *address,
2687 /* g_message ("%s %s", __FUNCTION__, address); */
2691 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2692 TnyMsg *saved_draft,
2695 ModestMsgEditWindow *edit_window;
2697 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2698 #ifndef MODEST_TOOLKIT_HILDON2
2699 ModestMainWindow *win;
2701 /* FIXME. Make the header view sensitive again. This is a
2702 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2704 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2705 modest_runtime_get_window_mgr(), FALSE));
2707 GtkWidget *hdrview = modest_main_window_get_child_widget(
2708 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2709 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2713 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2715 /* Set draft is there was no error */
2716 if (!modest_mail_operation_get_error (mail_op))
2717 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2719 g_object_unref(edit_window);
2723 enough_space_for_message (ModestMsgEditWindow *edit_window,
2726 TnyAccountStore *acc_store;
2727 guint64 available_disk, expected_size;
2732 acc_store = TNY_ACCOUNT_STORE (modest_runtime_get_account_store());
2733 available_disk = modest_utils_get_available_space (NULL);
2734 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2735 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2740 /* Double check: memory full condition or message too big */
2741 if (available_disk < MIN_FREE_SPACE ||
2742 expected_size > available_disk) {
2744 modest_platform_information_banner (NULL, NULL,
2745 _KR("cerm_device_memory_full"));
2750 * djcb: if we're in low-memory state, we only allow for
2751 * saving messages smaller than
2752 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2753 * should still allow for sending anything critical...
2755 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2756 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2760 * djcb: we also make sure that the attachments are smaller than the max size
2761 * this is for the case where we'd try to forward a message with attachments
2762 * bigger than our max allowed size, or sending an message from drafts which
2763 * somehow got past our checks when attaching.
2765 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2766 modest_platform_run_information_dialog (
2767 GTK_WINDOW(edit_window),
2768 _KR("memr_ib_operation_disabled"),
2777 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2779 TnyTransportAccount *transport_account;
2780 ModestMailOperation *mail_operation;
2782 gchar *account_name, *from;
2783 ModestAccountMgr *account_mgr;
2784 gboolean had_error = FALSE;
2785 ModestMainWindow *win = NULL;
2787 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2789 data = modest_msg_edit_window_get_msg_data (edit_window);
2792 if (!enough_space_for_message (edit_window, data)) {
2793 modest_msg_edit_window_free_msg_data (edit_window, data);
2797 account_name = g_strdup (data->account_name);
2798 account_mgr = modest_runtime_get_account_mgr();
2800 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2802 account_name = modest_account_mgr_get_default_account (account_mgr);
2803 if (!account_name) {
2804 g_printerr ("modest: no account found\n");
2805 modest_msg_edit_window_free_msg_data (edit_window, data);
2809 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2810 account_name = g_strdup (data->account_name);
2814 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2815 (modest_runtime_get_account_store (),
2817 TNY_ACCOUNT_TYPE_TRANSPORT));
2818 if (!transport_account) {
2819 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2820 g_free (account_name);
2821 modest_msg_edit_window_free_msg_data (edit_window, data);
2824 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2826 /* Create the mail operation */
2827 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
2829 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2831 modest_mail_operation_save_to_drafts (mail_operation,
2843 data->priority_flags,
2844 on_save_to_drafts_cb,
2845 g_object_ref(edit_window));
2847 #ifdef MODEST_TOOLKIT_HILDON2
2848 /* In hildon2 we always show the information banner on saving to drafts.
2849 * It will be a system information banner in this case.
2851 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2852 modest_platform_information_banner (NULL, NULL, text);
2855 /* Use the main window as the parent of the banner, if the
2856 main window does not exist it won't be shown, if the parent
2857 window exists then it's properly shown. We don't use the
2858 editor window because it could be closed (save to drafts
2859 could happen after closing the window */
2860 win = (ModestMainWindow *)
2861 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
2863 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2864 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
2868 modest_msg_edit_window_set_modified (edit_window, FALSE);
2872 g_free (account_name);
2873 g_object_unref (G_OBJECT (transport_account));
2874 g_object_unref (G_OBJECT (mail_operation));
2876 modest_msg_edit_window_free_msg_data (edit_window, data);
2879 * If the drafts folder is selected then make the header view
2880 * insensitive while the message is being saved to drafts
2881 * (it'll be sensitive again in on_save_to_drafts_cb()). This
2882 * is not very clean but it avoids letting the drafts folder
2883 * in an inconsistent state: the user could edit the message
2884 * being saved and undesirable things would happen.
2885 * In the average case the user won't notice anything at
2886 * all. In the worst case (the user is editing a really big
2887 * file from Drafts) the header view will be insensitive
2888 * during the saving process (10 or 20 seconds, depending on
2889 * the message). Anyway this is just a quick workaround: once
2890 * we find a better solution it should be removed
2891 * See NB#65125 (commend #18) for details.
2893 if (!had_error && win != NULL) {
2894 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
2895 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
2897 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
2899 if (modest_tny_folder_is_local_folder(folder)) {
2900 TnyFolderType folder_type;
2901 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
2902 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
2903 GtkWidget *hdrview = modest_main_window_get_child_widget(
2904 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2905 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
2909 if (folder != NULL) g_object_unref(folder);
2916 /* For instance, when clicking the Send toolbar button when editing a message: */
2918 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2920 TnyTransportAccount *transport_account = NULL;
2921 gboolean had_error = FALSE;
2923 ModestAccountMgr *account_mgr;
2924 gchar *account_name;
2926 ModestMailOperation *mail_operation;
2928 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
2930 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2933 data = modest_msg_edit_window_get_msg_data (edit_window);
2936 if (!enough_space_for_message (edit_window, data)) {
2937 modest_msg_edit_window_free_msg_data (edit_window, data);
2941 account_mgr = modest_runtime_get_account_mgr();
2942 account_name = g_strdup (data->account_name);
2944 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2947 account_name = modest_account_mgr_get_default_account (account_mgr);
2949 if (!account_name) {
2950 modest_msg_edit_window_free_msg_data (edit_window, data);
2951 /* Run account setup wizard */
2952 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
2957 /* Get the currently-active transport account for this modest account: */
2958 if (strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
2960 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2961 (modest_runtime_get_account_store (),
2962 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
2965 if (!transport_account) {
2966 modest_msg_edit_window_free_msg_data (edit_window, data);
2967 /* Run account setup wizard */
2968 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2973 /* Create the mail operation */
2974 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2975 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
2976 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2978 modest_mail_operation_send_new_mail (mail_operation,
2990 data->priority_flags);
2992 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
2993 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2996 if (modest_mail_operation_get_error (mail_operation) != NULL) {
2997 const GError *error = modest_mail_operation_get_error (mail_operation);
2998 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
2999 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3000 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3001 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3008 g_free (account_name);
3009 g_object_unref (G_OBJECT (transport_account));
3010 g_object_unref (G_OBJECT (mail_operation));
3012 modest_msg_edit_window_free_msg_data (edit_window, data);
3015 modest_msg_edit_window_set_sent (edit_window, TRUE);
3017 /* Save settings and close the window: */
3018 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3025 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3026 ModestMsgEditWindow *window)
3028 ModestMsgEditFormatState *format_state = NULL;
3030 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3031 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3033 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3036 format_state = modest_msg_edit_window_get_format_state (window);
3037 g_return_if_fail (format_state != NULL);
3039 format_state->bold = gtk_toggle_action_get_active (action);
3040 modest_msg_edit_window_set_format_state (window, format_state);
3041 g_free (format_state);
3046 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3047 ModestMsgEditWindow *window)
3049 ModestMsgEditFormatState *format_state = NULL;
3051 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3052 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3054 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3057 format_state = modest_msg_edit_window_get_format_state (window);
3058 g_return_if_fail (format_state != NULL);
3060 format_state->italics = gtk_toggle_action_get_active (action);
3061 modest_msg_edit_window_set_format_state (window, format_state);
3062 g_free (format_state);
3067 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3068 ModestMsgEditWindow *window)
3070 ModestMsgEditFormatState *format_state = NULL;
3072 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3073 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3075 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3078 format_state = modest_msg_edit_window_get_format_state (window);
3079 g_return_if_fail (format_state != NULL);
3081 format_state->bullet = gtk_toggle_action_get_active (action);
3082 modest_msg_edit_window_set_format_state (window, format_state);
3083 g_free (format_state);
3088 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3089 GtkRadioAction *selected,
3090 ModestMsgEditWindow *window)
3092 ModestMsgEditFormatState *format_state = NULL;
3093 GtkJustification value;
3095 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3097 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3100 value = gtk_radio_action_get_current_value (selected);
3102 format_state = modest_msg_edit_window_get_format_state (window);
3103 g_return_if_fail (format_state != NULL);
3105 format_state->justification = value;
3106 modest_msg_edit_window_set_format_state (window, format_state);
3107 g_free (format_state);
3111 modest_ui_actions_on_select_editor_color (GtkAction *action,
3112 ModestMsgEditWindow *window)
3114 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3115 g_return_if_fail (GTK_IS_ACTION (action));
3117 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3120 modest_msg_edit_window_select_color (window);
3124 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3125 ModestMsgEditWindow *window)
3127 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3128 g_return_if_fail (GTK_IS_ACTION (action));
3130 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3133 modest_msg_edit_window_select_background_color (window);
3137 modest_ui_actions_on_insert_image (GObject *object,
3138 ModestMsgEditWindow *window)
3140 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3143 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3146 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3149 modest_msg_edit_window_insert_image (window);
3153 modest_ui_actions_on_attach_file (GtkAction *action,
3154 ModestMsgEditWindow *window)
3156 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3157 g_return_if_fail (GTK_IS_ACTION (action));
3159 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3162 modest_msg_edit_window_offer_attach_file (window);
3166 modest_ui_actions_on_remove_attachments (GtkAction *action,
3167 ModestMsgEditWindow *window)
3169 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3171 modest_msg_edit_window_remove_attachments (window, NULL);
3175 #ifndef MODEST_TOOLKIT_GTK
3180 TnyFolderStore *folder;
3181 } CreateFolderHelper;
3184 show_create_folder_in_timeout (gpointer data)
3186 CreateFolderHelper *helper = (CreateFolderHelper *) data;
3188 /* Remove the timeout ASAP, we can not wait until the dialog
3189 is shown because it could take a lot of time and so the
3190 timeout could be called twice or more times */
3191 g_source_remove (helper->handler);
3193 gdk_threads_enter ();
3194 do_create_folder (helper->win, helper->folder, helper->name);
3195 gdk_threads_leave ();
3197 g_object_unref (helper->win);
3198 g_object_unref (helper->folder);
3199 g_free (helper->name);
3200 g_slice_free (CreateFolderHelper, helper);
3207 do_create_folder_cb (ModestMailOperation *mail_op,
3208 TnyFolderStore *parent_folder,
3209 TnyFolder *new_folder,
3212 gchar *suggested_name = (gchar *) user_data;
3213 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3215 if (modest_mail_operation_get_error (mail_op)) {
3217 /* Show an error. If there was some problem writing to
3218 disk, show it, otherwise show the generic folder
3219 create error. We do it here and not in an error
3220 handler because the call to do_create_folder will
3221 stop the main loop in a gtk_dialog_run and then,
3222 the message won't be shown until that dialog is
3224 modest_ui_actions_disk_operations_error_handler (mail_op,
3225 _("mail_in_ui_folder_create_error"));
3227 /* Try again. Do *NOT* show any error because the mail
3228 operations system will do it for us because we
3229 created the mail_op with new_with_error_handler */
3230 #ifndef MODEST_TOOLKIT_GTK
3231 CreateFolderHelper *helper;
3232 helper = g_slice_new0 (CreateFolderHelper);
3233 helper->name = g_strdup (suggested_name);
3234 helper->folder = g_object_ref (parent_folder);
3235 helper->win = g_object_ref (source_win);
3237 /* Ugly but neccesary stuff. The problem is that the
3238 dialog when is shown calls a function that destroys
3239 all the temporary windows, so the banner is
3241 helper->handler = g_timeout_add (2000, show_create_folder_in_timeout, helper);
3243 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3246 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3247 * FIXME: any other? */
3248 GtkWidget *folder_view;
3250 if (MODEST_IS_MAIN_WINDOW(source_win))
3252 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3253 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3255 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3256 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3258 /* Select the newly created folder. It could happen
3259 that the widget is no longer there (i.e. the window
3260 has been destroyed, so we need to check this */
3262 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3264 g_object_unref (new_folder);
3266 /* Free. Note that the first time it'll be NULL so noop */
3267 g_free (suggested_name);
3268 g_object_unref (source_win);
3272 do_create_folder (GtkWindow *parent_window,
3273 TnyFolderStore *suggested_parent,
3274 const gchar *suggested_name)
3277 gchar *folder_name = NULL;
3278 TnyFolderStore *parent_folder = NULL;
3280 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3282 (gchar *) suggested_name,
3286 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3287 ModestMailOperation *mail_op;
3289 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3290 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3292 modest_mail_operation_create_folder (mail_op,
3294 (const gchar *) folder_name,
3295 do_create_folder_cb,
3297 g_object_unref (mail_op);
3301 g_object_unref (parent_folder);
3305 create_folder_performer (gboolean canceled,
3307 GtkWindow *parent_window,
3308 TnyAccount *account,
3311 TnyFolderStore *parent_folder = TNY_FOLDER_STORE (user_data);
3313 if (canceled || err) {
3314 /* In memory full conditions we could get this error here */
3315 check_memory_full_error ((GtkWidget *) parent_window, err);
3319 /* Run the new folder dialog */
3320 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3323 g_object_unref (parent_folder);
3327 modest_ui_actions_create_folder(GtkWidget *parent_window,
3328 GtkWidget *folder_view)
3330 TnyFolderStore *parent_folder;
3332 #ifdef MODEST_TOOLKIT_HILDON2
3333 const gchar *active_account;
3334 TnyAccount *account;
3335 ModestTnyAccountStore *acc_store;
3337 /* In hildon 2.2 we use the current account as default parent */
3338 acc_store = modest_runtime_get_account_store ();
3339 active_account = modest_window_get_active_account (MODEST_WINDOW (parent_window));
3340 if (active_account) {
3341 account = modest_tny_account_store_get_server_account (acc_store,
3343 TNY_ACCOUNT_TYPE_STORE);
3344 parent_folder = TNY_FOLDER_STORE (account);
3346 parent_folder = (TnyFolderStore *)
3347 modest_tny_account_store_get_local_folders_account (acc_store);
3350 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3353 if (parent_folder) {
3354 /* The parent folder will be freed in the callback */
3355 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3358 create_folder_performer,
3364 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3367 g_return_if_fail (MODEST_IS_WINDOW(window));
3369 if (MODEST_IS_MAIN_WINDOW (window)) {
3370 GtkWidget *folder_view;
3372 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3373 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3377 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view);
3378 #ifdef MODEST_TOOLKIT_HILDON2
3379 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3380 GtkWidget *folder_view;
3382 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3383 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view);
3386 g_assert_not_reached ();
3391 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3394 const GError *error = NULL;
3395 const gchar *message = NULL;
3397 /* Get error message */
3398 error = modest_mail_operation_get_error (mail_op);
3400 g_return_if_reached ();
3402 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3403 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3404 message = _CS("ckdg_ib_folder_already_exists");
3405 } else if (error->domain == TNY_ERROR_DOMAIN &&
3406 error->code == TNY_SERVICE_ERROR_STATE) {
3407 /* This means that the folder is already in use (a
3408 message is opened for example */
3409 message = _("emev_ni_internal_error");
3411 message = _("emev_ib_ui_imap_unable_to_rename");
3414 /* We don't set a parent for the dialog because the dialog
3415 will be destroyed so the banner won't appear */
3416 modest_platform_information_banner (NULL, NULL, message);
3420 TnyFolderStore *folder;
3425 on_rename_folder_cb (ModestMailOperation *mail_op,
3426 TnyFolder *new_folder,
3429 ModestFolderView *folder_view;
3431 /* If the window was closed when renaming a folder, or if
3432 * it's not a main window this will happen */
3433 if (!MODEST_IS_FOLDER_VIEW (user_data))
3436 folder_view = MODEST_FOLDER_VIEW (user_data);
3437 /* Note that if the rename fails new_folder will be NULL */
3439 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3441 modest_folder_view_select_first_inbox_or_local (folder_view);
3443 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3447 on_rename_folder_performer (gboolean canceled,
3449 GtkWindow *parent_window,
3450 TnyAccount *account,
3453 ModestMailOperation *mail_op = NULL;
3454 GtkTreeSelection *sel = NULL;
3455 GtkWidget *folder_view = NULL;
3456 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3458 if (canceled || err) {
3459 /* In memory full conditions we could get this error here */
3460 check_memory_full_error ((GtkWidget *) parent_window, err);
3464 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3465 modest_ui_actions_rename_folder_error_handler,
3466 parent_window, NULL);
3468 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3471 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3473 folder_view = modest_main_window_get_child_widget (
3474 MODEST_MAIN_WINDOW (parent_window),
3475 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3477 /* Clear the headers view */
3478 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3479 gtk_tree_selection_unselect_all (sel);
3484 /* Actually rename the folder */
3485 modest_mail_operation_rename_folder (mail_op,
3486 TNY_FOLDER (data->folder),
3487 (const gchar *) (data->new_name),
3488 on_rename_folder_cb,
3490 g_object_unref (data->folder);
3491 g_object_unref (mail_op);
3494 g_free (data->new_name);
3499 modest_ui_actions_on_rename_folder (GtkAction *action,
3500 ModestWindow *window)
3502 modest_ui_actions_on_edit_mode_rename_folder (window);
3506 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3508 TnyFolderStore *folder;
3509 GtkWidget *folder_view;
3510 gboolean do_rename = TRUE;
3512 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3514 if (MODEST_IS_MAIN_WINDOW (window)) {
3515 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3516 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3520 #ifdef MODEST_TOOLKIT_HILDON2
3521 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3522 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3528 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3533 if (TNY_IS_FOLDER (folder)) {
3534 gchar *folder_name = NULL;
3536 const gchar *current_name;
3537 TnyFolderStore *parent;
3539 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3540 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3541 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
3542 parent, current_name,
3544 g_object_unref (parent);
3546 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3549 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3550 rename_folder_data->folder = g_object_ref (folder);
3551 rename_folder_data->new_name = folder_name;
3552 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
3553 folder, on_rename_folder_performer, rename_folder_data);
3556 g_object_unref (folder);
3561 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3564 GObject *win = modest_mail_operation_get_source (mail_op);
3566 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3567 _("mail_in_ui_folder_delete_error"),
3569 g_object_unref (win);
3573 TnyFolderStore *folder;
3574 gboolean move_to_trash;
3578 on_delete_folder_cb (gboolean canceled,
3580 GtkWindow *parent_window,
3581 TnyAccount *account,
3584 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3585 GtkWidget *folder_view;
3586 ModestMailOperation *mail_op;
3587 GtkTreeSelection *sel;
3589 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
3590 g_object_unref (G_OBJECT (info->folder));
3595 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
3596 folder_view = modest_main_window_get_child_widget (
3597 MODEST_MAIN_WINDOW (parent_window),
3598 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3599 #ifdef MODEST_TOOLKIT_HILDON2
3600 } else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3601 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
3604 g_object_unref (G_OBJECT (info->folder));
3609 /* Unselect the folder before deleting it to free the headers */
3610 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3611 gtk_tree_selection_unselect_all (sel);
3613 /* Create the mail operation */
3615 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3616 modest_ui_actions_delete_folder_error_handler,
3619 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3621 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3623 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3625 g_object_unref (G_OBJECT (mail_op));
3626 g_object_unref (G_OBJECT (info->folder));
3631 delete_folder (ModestWindow *window, gboolean move_to_trash)
3633 TnyFolderStore *folder;
3634 GtkWidget *folder_view;
3638 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3640 if (MODEST_IS_MAIN_WINDOW (window)) {
3642 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3643 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3644 #ifdef MODEST_TOOLKIT_HILDON2
3645 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3646 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3654 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3656 /* Show an error if it's an account */
3657 if (!TNY_IS_FOLDER (folder)) {
3658 modest_platform_run_information_dialog (GTK_WINDOW (window),
3659 _("mail_in_ui_folder_delete_error"),
3661 g_object_unref (G_OBJECT (folder));
3666 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3667 tny_folder_get_name (TNY_FOLDER (folder)));
3668 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
3669 (const gchar *) message);
3672 if (response == GTK_RESPONSE_OK) {
3673 DeleteFolderInfo *info;
3674 info = g_new0(DeleteFolderInfo, 1);
3675 info->folder = folder;
3676 info->move_to_trash = move_to_trash;
3677 g_object_ref (G_OBJECT (info->folder));
3678 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder));
3679 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
3681 TNY_FOLDER_STORE (account),
3682 on_delete_folder_cb, info);
3683 g_object_unref (account);
3688 g_object_unref (G_OBJECT (folder));
3692 modest_ui_actions_on_delete_folder (GtkAction *action,
3693 ModestWindow *window)
3695 modest_ui_actions_on_edit_mode_delete_folder (window);
3699 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
3701 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
3703 return delete_folder (window, FALSE);
3707 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3709 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3711 delete_folder (MODEST_WINDOW (main_window), TRUE);
3715 typedef struct _PasswordDialogFields {
3716 GtkWidget *username;
3717 GtkWidget *password;
3719 } PasswordDialogFields;
3722 password_dialog_check_field (GtkEditable *editable,
3723 PasswordDialogFields *fields)
3726 gboolean any_value_empty = FALSE;
3728 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
3729 if ((value == NULL) || value[0] == '\0') {
3730 any_value_empty = TRUE;
3732 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
3733 if ((value == NULL) || value[0] == '\0') {
3734 any_value_empty = TRUE;
3736 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3740 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3741 const gchar* server_account_name,
3746 ModestMainWindow *main_window)
3748 g_return_if_fail(server_account_name);
3749 gboolean completed = FALSE;
3750 PasswordDialogFields *fields = NULL;
3752 /* Initalize output parameters: */
3759 #ifndef MODEST_TOOLKIT_GTK
3760 /* Maemo uses a different (awkward) button order,
3761 * It should probably just use gtk_alternative_dialog_button_order ().
3763 #ifdef MODEST_TOOLKIT_HILDON2
3765 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3768 _HL("wdgt_bd_done"),
3769 GTK_RESPONSE_ACCEPT,
3773 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3776 _("mcen_bd_dialog_ok"),
3777 GTK_RESPONSE_ACCEPT,
3778 _("mcen_bd_dialog_cancel"),
3779 GTK_RESPONSE_REJECT,
3781 #endif /* MODEST_TOOLKIT_HILDON2 */
3784 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3788 GTK_RESPONSE_REJECT,
3790 GTK_RESPONSE_ACCEPT,
3792 #endif /* MODEST_TOOLKIT_GTK */
3794 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3796 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3797 modest_runtime_get_account_mgr(), server_account_name);
3798 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3799 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3802 gtk_widget_destroy (dialog);
3806 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3807 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
3810 g_free (server_name);
3814 gchar *initial_username = modest_account_mgr_get_server_account_username (
3815 modest_runtime_get_account_mgr(), server_account_name);
3817 GtkWidget *entry_username = gtk_entry_new ();
3818 if (initial_username)
3819 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
3820 /* Dim this if a connection has ever succeeded with this username,
3821 * as per the UI spec: */
3822 /* const gboolean username_known = */
3823 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3824 /* modest_runtime_get_account_mgr(), server_account_name); */
3825 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3827 /* We drop the username sensitive code and disallow changing it here
3828 * as tinymail does not support really changing the username in the callback
3830 gtk_widget_set_sensitive (entry_username, FALSE);
3832 #ifndef MODEST_TOOLKIT_GTK
3833 /* Auto-capitalization is the default, so let's turn it off: */
3834 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3836 /* Create a size group to be used by all captions.
3837 * Note that HildonCaption does not create a default size group if we do not specify one.
3838 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3839 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3841 GtkWidget *caption = hildon_caption_new (sizegroup,
3842 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
3843 gtk_widget_show (entry_username);
3844 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3845 FALSE, FALSE, MODEST_MARGIN_HALF);
3846 gtk_widget_show (caption);
3848 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
3850 #endif /* !MODEST_TOOLKIT_GTK */
3853 GtkWidget *entry_password = gtk_entry_new ();
3854 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3855 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3857 #ifndef MODEST_TOOLKIT_GTK
3858 /* Auto-capitalization is the default, so let's turn it off: */
3859 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3860 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3862 caption = hildon_caption_new (sizegroup,
3863 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
3864 gtk_widget_show (entry_password);
3865 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3866 FALSE, FALSE, MODEST_MARGIN_HALF);
3867 gtk_widget_show (caption);
3868 g_object_unref (sizegroup);
3870 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
3872 #endif /* !MODEST_TOOLKIT_GTK */
3874 if (initial_username != NULL)
3875 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3877 /* This is not in the Maemo UI spec:
3878 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3879 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3883 fields = g_slice_new0 (PasswordDialogFields);
3884 fields->username = entry_username;
3885 fields->password = entry_password;
3886 fields->dialog = dialog;
3888 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3889 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3890 password_dialog_check_field (NULL, fields);
3892 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3894 while (!completed) {
3896 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3898 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
3900 /* Note that an empty field becomes the "" string */
3901 if (*username && strlen (*username) > 0) {
3902 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
3903 server_account_name,
3907 const gboolean username_was_changed =
3908 (strcmp (*username, initial_username) != 0);
3909 if (username_was_changed) {
3910 g_warning ("%s: tinymail does not yet support changing the "
3911 "username in the get_password() callback.\n", __FUNCTION__);
3917 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
3918 _("mcen_ib_username_pw_incorrect"));
3924 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
3926 /* We do not save the password in the configuration,
3927 * because this function is only called for passwords that should
3928 * not be remembered:
3929 modest_server_account_set_password (
3930 modest_runtime_get_account_mgr(), server_account_name,
3937 #ifndef MODEST_TOOLKIT_HILDON2
3938 /* Set parent to NULL or the banner will disappear with its parent dialog */
3939 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
3951 /* This is not in the Maemo UI spec:
3952 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3958 g_free (initial_username);
3959 gtk_widget_destroy (dialog);
3960 g_slice_free (PasswordDialogFields, fields);
3962 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3966 modest_ui_actions_on_cut (GtkAction *action,
3967 ModestWindow *window)
3969 GtkWidget *focused_widget;
3970 GtkClipboard *clipboard;
3972 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3973 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3974 if (GTK_IS_EDITABLE (focused_widget)) {
3975 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3976 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3977 gtk_clipboard_store (clipboard);
3978 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3979 GtkTextBuffer *buffer;
3981 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3982 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3983 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3984 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3985 gtk_clipboard_store (clipboard);
3987 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3988 TnyList *header_list = modest_header_view_get_selected_headers (
3989 MODEST_HEADER_VIEW (focused_widget));
3990 gboolean continue_download = FALSE;
3991 gint num_of_unc_msgs;
3993 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3995 if (num_of_unc_msgs) {
3996 TnyAccount *account = get_account_from_header_list (header_list);
3998 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3999 g_object_unref (account);
4003 if (num_of_unc_msgs == 0 || continue_download) {
4004 /* modest_platform_information_banner (
4005 NULL, NULL, _CS("mcen_ib_getting_items"));*/
4006 modest_header_view_cut_selection (
4007 MODEST_HEADER_VIEW (focused_widget));
4010 g_object_unref (header_list);
4011 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4012 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4017 modest_ui_actions_on_copy (GtkAction *action,
4018 ModestWindow *window)
4020 GtkClipboard *clipboard;
4021 GtkWidget *focused_widget;
4022 gboolean copied = TRUE;
4024 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4025 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4027 if (GTK_IS_LABEL (focused_widget)) {
4029 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4030 gtk_clipboard_set_text (clipboard, selection, -1);
4032 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4033 gtk_clipboard_store (clipboard);
4034 } else if (GTK_IS_EDITABLE (focused_widget)) {
4035 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4036 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4037 gtk_clipboard_store (clipboard);
4038 } else if (GTK_IS_HTML (focused_widget)) {
4041 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4042 if ((sel == NULL) || (sel[0] == '\0')) {
4045 gtk_html_copy (GTK_HTML (focused_widget));
4046 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4047 gtk_clipboard_store (clipboard);
4049 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4050 GtkTextBuffer *buffer;
4051 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4052 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4053 gtk_text_buffer_copy_clipboard (buffer, clipboard);
4054 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4055 gtk_clipboard_store (clipboard);
4057 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4058 TnyList *header_list = modest_header_view_get_selected_headers (
4059 MODEST_HEADER_VIEW (focused_widget));
4060 gboolean continue_download = FALSE;
4061 gint num_of_unc_msgs;
4063 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4065 if (num_of_unc_msgs) {
4066 TnyAccount *account = get_account_from_header_list (header_list);
4068 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4069 g_object_unref (account);
4073 if (num_of_unc_msgs == 0 || continue_download) {
4074 modest_platform_information_banner (
4075 NULL, NULL, _CS("mcen_ib_getting_items"));
4076 modest_header_view_copy_selection (
4077 MODEST_HEADER_VIEW (focused_widget));
4081 g_object_unref (header_list);
4083 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4084 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4087 /* Show information banner if there was a copy to clipboard */
4089 modest_platform_information_banner (
4090 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4094 modest_ui_actions_on_undo (GtkAction *action,
4095 ModestWindow *window)
4097 ModestEmailClipboard *clipboard = NULL;
4099 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4100 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4101 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4102 /* Clear clipboard source */
4103 clipboard = modest_runtime_get_email_clipboard ();
4104 modest_email_clipboard_clear (clipboard);
4107 g_return_if_reached ();
4112 modest_ui_actions_on_redo (GtkAction *action,
4113 ModestWindow *window)
4115 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4116 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4119 g_return_if_reached ();
4125 destroy_information_note (ModestMailOperation *mail_op,
4128 /* destroy information note */
4129 gtk_widget_destroy (GTK_WIDGET(user_data));
4133 destroy_folder_information_note (ModestMailOperation *mail_op,
4134 TnyFolder *new_folder,
4137 /* destroy information note */
4138 gtk_widget_destroy (GTK_WIDGET(user_data));
4143 paste_as_attachment_free (gpointer data)
4145 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4147 if (helper->banner) {
4148 gtk_widget_destroy (helper->banner);
4149 g_object_unref (helper->banner);
4155 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4160 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4161 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4166 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4171 modest_ui_actions_on_paste (GtkAction *action,
4172 ModestWindow *window)
4174 GtkWidget *focused_widget = NULL;
4175 GtkWidget *inf_note = NULL;
4176 ModestMailOperation *mail_op = NULL;
4178 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4179 if (GTK_IS_EDITABLE (focused_widget)) {
4180 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4181 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4182 ModestEmailClipboard *e_clipboard = NULL;
4183 e_clipboard = modest_runtime_get_email_clipboard ();
4184 if (modest_email_clipboard_cleared (e_clipboard)) {
4185 GtkTextBuffer *buffer;
4186 GtkClipboard *clipboard;
4188 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4189 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4190 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4191 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4192 ModestMailOperation *mail_op;
4193 TnyFolder *src_folder = NULL;
4194 TnyList *data = NULL;
4196 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4197 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4198 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4199 _CS("ckct_nw_pasting"));
4200 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4201 mail_op = modest_mail_operation_new (G_OBJECT (window));
4202 if (helper->banner != NULL) {
4203 g_object_ref (G_OBJECT (helper->banner));
4204 gtk_widget_show (GTK_WIDGET (helper->banner));
4208 modest_mail_operation_get_msgs_full (mail_op,
4210 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4212 paste_as_attachment_free);
4216 g_object_unref (data);
4218 g_object_unref (src_folder);
4221 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4222 ModestEmailClipboard *clipboard = NULL;
4223 TnyFolder *src_folder = NULL;
4224 TnyFolderStore *folder_store = NULL;
4225 TnyList *data = NULL;
4226 gboolean delete = FALSE;
4228 /* Check clipboard source */
4229 clipboard = modest_runtime_get_email_clipboard ();
4230 if (modest_email_clipboard_cleared (clipboard))
4233 /* Get elements to paste */
4234 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4236 /* Create a new mail operation */
4237 mail_op = modest_mail_operation_new (G_OBJECT(window));
4239 /* Get destination folder */
4240 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4242 /* transfer messages */
4246 /* Ask for user confirmation */
4248 modest_ui_actions_msgs_move_to_confirmation (window,
4249 TNY_FOLDER (folder_store),
4253 if (response == GTK_RESPONSE_OK) {
4254 /* Launch notification */
4255 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4256 _CS("ckct_nw_pasting"));
4257 if (inf_note != NULL) {
4258 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4259 gtk_widget_show (GTK_WIDGET(inf_note));
4262 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4263 modest_mail_operation_xfer_msgs (mail_op,
4265 TNY_FOLDER (folder_store),
4267 destroy_information_note,
4270 g_object_unref (mail_op);
4273 } else if (src_folder != NULL) {
4274 /* Launch notification */
4275 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4276 _CS("ckct_nw_pasting"));
4277 if (inf_note != NULL) {
4278 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4279 gtk_widget_show (GTK_WIDGET(inf_note));
4282 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4283 modest_mail_operation_xfer_folder (mail_op,
4287 destroy_folder_information_note,
4293 g_object_unref (data);
4294 if (src_folder != NULL)
4295 g_object_unref (src_folder);
4296 if (folder_store != NULL)
4297 g_object_unref (folder_store);
4303 modest_ui_actions_on_select_all (GtkAction *action,
4304 ModestWindow *window)
4306 GtkWidget *focused_widget;
4308 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4309 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4310 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4311 } else if (GTK_IS_LABEL (focused_widget)) {
4312 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4313 } else if (GTK_IS_EDITABLE (focused_widget)) {
4314 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4315 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4316 GtkTextBuffer *buffer;
4317 GtkTextIter start, end;
4319 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4320 gtk_text_buffer_get_start_iter (buffer, &start);
4321 gtk_text_buffer_get_end_iter (buffer, &end);
4322 gtk_text_buffer_select_range (buffer, &start, &end);
4323 } else if (GTK_IS_HTML (focused_widget)) {
4324 gtk_html_select_all (GTK_HTML (focused_widget));
4325 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4326 GtkWidget *header_view = focused_widget;
4327 GtkTreeSelection *selection = NULL;
4329 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4330 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4331 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4334 /* Disable window dimming management */
4335 modest_window_disable_dimming (MODEST_WINDOW(window));
4337 /* Select all messages */
4338 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4339 gtk_tree_selection_select_all (selection);
4341 /* Set focuse on header view */
4342 gtk_widget_grab_focus (header_view);
4344 /* Enable window dimming management */
4345 modest_window_enable_dimming (MODEST_WINDOW(window));
4346 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4347 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4353 modest_ui_actions_on_mark_as_read (GtkAction *action,
4354 ModestWindow *window)
4356 g_return_if_fail (MODEST_IS_WINDOW(window));
4358 /* Mark each header as read */
4359 do_headers_action (window, headers_action_mark_as_read, NULL);
4363 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4364 ModestWindow *window)
4366 g_return_if_fail (MODEST_IS_WINDOW(window));
4368 /* Mark each header as read */
4369 do_headers_action (window, headers_action_mark_as_unread, NULL);
4373 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4374 GtkRadioAction *selected,
4375 ModestWindow *window)
4379 value = gtk_radio_action_get_current_value (selected);
4380 if (MODEST_IS_WINDOW (window)) {
4381 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4386 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4387 GtkRadioAction *selected,
4388 ModestWindow *window)
4390 TnyHeaderFlags flags;
4391 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4393 flags = gtk_radio_action_get_current_value (selected);
4394 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4398 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4399 GtkRadioAction *selected,
4400 ModestWindow *window)
4404 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4406 file_format = gtk_radio_action_get_current_value (selected);
4407 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4412 modest_ui_actions_on_zoom_plus (GtkAction *action,
4413 ModestWindow *window)
4415 g_return_if_fail (MODEST_IS_WINDOW (window));
4417 modest_window_zoom_plus (MODEST_WINDOW (window));
4421 modest_ui_actions_on_zoom_minus (GtkAction *action,
4422 ModestWindow *window)
4424 g_return_if_fail (MODEST_IS_WINDOW (window));
4426 modest_window_zoom_minus (MODEST_WINDOW (window));
4430 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4431 ModestWindow *window)
4433 ModestWindowMgr *mgr;
4434 gboolean fullscreen, active;
4435 g_return_if_fail (MODEST_IS_WINDOW (window));
4437 mgr = modest_runtime_get_window_mgr ();
4439 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4440 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4442 if (active != fullscreen) {
4443 modest_window_mgr_set_fullscreen_mode (mgr, active);
4444 #ifndef MODEST_TOOLKIT_HILDON2
4445 gtk_window_present (GTK_WINDOW (window));
4451 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4452 ModestWindow *window)
4454 ModestWindowMgr *mgr;
4455 gboolean fullscreen;
4457 g_return_if_fail (MODEST_IS_WINDOW (window));
4459 mgr = modest_runtime_get_window_mgr ();
4460 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4461 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4463 #ifndef MODEST_TOOLKIT_HILDON2
4464 gtk_window_present (GTK_WINDOW (window));
4469 * Used by modest_ui_actions_on_details to call do_headers_action
4472 headers_action_show_details (TnyHeader *header,
4473 ModestWindow *window,
4477 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header);
4481 * Show the header details in a ModestDetailsDialog widget
4484 modest_ui_actions_on_details (GtkAction *action,
4487 TnyList * headers_list;
4491 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4494 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4497 g_object_unref (msg);
4499 headers_list = get_selected_headers (win);
4503 iter = tny_list_create_iterator (headers_list);
4505 header = TNY_HEADER (tny_iterator_get_current (iter));
4507 headers_action_show_details (header, win, NULL);
4508 g_object_unref (header);
4511 g_object_unref (iter);
4512 g_object_unref (headers_list);
4514 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4515 GtkWidget *folder_view, *header_view;
4517 /* Check which widget has the focus */
4518 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4519 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4520 if (gtk_widget_is_focus (folder_view)) {
4521 TnyFolderStore *folder_store
4522 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4523 if (!folder_store) {
4524 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4527 /* Show only when it's a folder */
4528 /* This function should not be called for account items,
4529 * because we dim the menu item for them. */
4530 if (TNY_IS_FOLDER (folder_store)) {
4531 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4532 TNY_FOLDER (folder_store));
4535 g_object_unref (folder_store);
4538 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4539 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4540 /* Show details of each header */
4541 do_headers_action (win, headers_action_show_details, header_view);
4543 #ifdef MODEST_TOOLKIT_HILDON2
4544 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4546 GtkWidget *header_view;
4548 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4549 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4551 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4553 g_object_unref (folder);
4560 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4561 ModestMsgEditWindow *window)
4563 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4565 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4569 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4570 ModestMsgEditWindow *window)
4572 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4574 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4578 modest_ui_actions_toggle_folders_view (GtkAction *action,
4579 ModestMainWindow *main_window)
4581 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4583 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4584 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4586 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4590 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4591 ModestWindow *window)
4593 gboolean active, fullscreen = FALSE;
4594 ModestWindowMgr *mgr;
4596 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4598 /* Check if we want to toggle the toolbar view in fullscreen
4600 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4601 "ViewShowToolbarFullScreen")) {
4605 /* Toggle toolbar */
4606 mgr = modest_runtime_get_window_mgr ();
4607 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4611 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4612 ModestMsgEditWindow *window)
4614 modest_msg_edit_window_select_font (window);
4619 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4620 const gchar *display_name,
4623 /* don't update the display name if it was already set;
4624 * updating the display name apparently is expensive */
4625 const gchar* old_name = gtk_window_get_title (window);
4627 if (display_name == NULL)
4630 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4631 return; /* don't do anything */
4633 /* This is usually used to change the title of the main window, which
4634 * is the one that holds the folder view. Note that this change can
4635 * happen even when the widget doesn't have the focus. */
4636 gtk_window_set_title (window, display_name);
4641 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4643 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4644 modest_msg_edit_window_select_contacts (window);
4648 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4650 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4651 modest_msg_edit_window_check_names (window, FALSE);
4654 #ifndef MODEST_TOOLKIT_HILDON2
4656 * This function is used to track changes in the selection of the
4657 * folder view that is inside the "move to" dialog to enable/disable
4658 * the OK button because we do not want the user to select a disallowed
4659 * destination for a folder.
4660 * The user also not desired to be able to use NEW button on items where
4661 * folder creation is not possibel.
4664 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4665 TnyFolderStore *folder_store,
4669 GtkWidget *dialog = NULL;
4670 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4671 gboolean moving_folder = FALSE;
4672 gboolean is_local_account = TRUE;
4673 GtkWidget *folder_view = NULL;
4674 ModestTnyFolderRules rules;
4676 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
4681 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
4685 /* check if folder_store is an remote account */
4686 if (TNY_IS_ACCOUNT (folder_store)) {
4687 TnyAccount *local_account = NULL;
4688 TnyAccount *mmc_account = NULL;
4689 ModestTnyAccountStore *account_store = NULL;
4691 account_store = modest_runtime_get_account_store ();
4692 local_account = modest_tny_account_store_get_local_folders_account (account_store);
4693 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
4695 if ((gpointer) local_account != (gpointer) folder_store &&
4696 (gpointer) mmc_account != (gpointer) folder_store) {
4697 ModestProtocolType proto;
4698 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
4699 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
4700 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
4702 is_local_account = FALSE;
4703 /* New button should be dimmed on remote
4705 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4707 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
4709 g_object_unref (local_account);
4711 /* It could not exist */
4713 g_object_unref (mmc_account);
4716 /* Check the target folder rules */
4717 if (TNY_IS_FOLDER (folder_store)) {
4718 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
4719 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
4720 ok_sensitive = FALSE;
4721 new_sensitive = FALSE;
4726 /* Check if we're moving a folder */
4727 if (MODEST_IS_MAIN_WINDOW (user_data)) {
4728 /* Get the widgets */
4729 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
4730 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4731 if (gtk_widget_is_focus (folder_view))
4732 moving_folder = TRUE;
4735 if (moving_folder) {
4736 TnyFolderStore *moved_folder = NULL, *parent = NULL;
4738 /* Get the folder to move */
4739 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4741 /* Check that we're not moving to the same folder */
4742 if (TNY_IS_FOLDER (moved_folder)) {
4743 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
4744 if (parent == folder_store)
4745 ok_sensitive = FALSE;
4746 g_object_unref (parent);
4749 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
4750 /* Do not allow to move to an account unless it's the
4751 local folders account */
4752 if (!is_local_account)
4753 ok_sensitive = FALSE;
4756 if (ok_sensitive && (moved_folder == folder_store)) {
4757 /* Do not allow to move to itself */
4758 ok_sensitive = FALSE;
4760 g_object_unref (moved_folder);
4762 TnyFolder *src_folder = NULL;
4764 /* Moving a message */
4765 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
4767 TnyHeader *header = NULL;
4768 header = modest_msg_view_window_get_header
4769 (MODEST_MSG_VIEW_WINDOW (user_data));
4770 if (!TNY_IS_HEADER(header))
4771 g_warning ("%s: could not get source header", __FUNCTION__);
4773 src_folder = tny_header_get_folder (header);
4776 g_object_unref (header);
4779 TNY_FOLDER (modest_folder_view_get_selected
4780 (MODEST_FOLDER_VIEW (folder_view)));
4783 if (TNY_IS_FOLDER(src_folder)) {
4784 /* Do not allow to move the msg to the same folder */
4785 /* Do not allow to move the msg to an account */
4786 if ((gpointer) src_folder == (gpointer) folder_store ||
4787 TNY_IS_ACCOUNT (folder_store))
4788 ok_sensitive = FALSE;
4789 g_object_unref (src_folder);
4791 g_warning ("%s: could not get source folder", __FUNCTION__);
4795 /* Set sensitivity of the OK and NEW button */
4796 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
4797 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
4802 on_move_to_dialog_response (GtkDialog *dialog,
4806 GtkWidget *parent_win, *folder_view;
4807 MoveToInfo *helper = NULL;
4809 helper = (MoveToInfo *) user_data;
4811 parent_win = (GtkWidget *) helper->win;
4812 folder_view = GTK_WIDGET (g_object_get_data (G_OBJECT (dialog),
4813 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4816 TnyFolderStore *dst_folder;
4818 case MODEST_GTK_RESPONSE_NEW_FOLDER:
4819 modest_ui_actions_create_folder (GTK_WIDGET (parent_win), folder_view);
4821 case GTK_RESPONSE_NONE:
4822 case GTK_RESPONSE_CANCEL:
4823 case GTK_RESPONSE_DELETE_EVENT:
4825 case GTK_RESPONSE_OK:
4826 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4827 /* Do window specific stuff */
4828 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
4829 modest_ui_actions_on_main_window_move_to (NULL,
4832 MODEST_MAIN_WINDOW (parent_win));
4833 #ifdef MODEST_TOOLKIT_HILDON2
4834 } else if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
4835 modest_ui_actions_on_folder_window_move_to (folder_view,
4838 GTK_WINDOW (parent_win));
4841 /* Moving from headers window in edit mode */
4842 modest_ui_actions_on_window_move_to (NULL, helper->list,
4844 MODEST_WINDOW (parent_win));
4848 g_object_unref (dst_folder);
4852 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
4855 /* Free the helper and exit */
4857 g_object_unref (helper->list);
4858 g_slice_free (MoveToInfo, helper);
4859 gtk_widget_destroy (GTK_WIDGET (dialog));
4863 create_move_to_dialog (GtkWindow *win,
4864 GtkWidget *folder_view)
4866 GtkWidget *dialog, *tree_view = NULL;
4868 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
4870 #ifndef MODEST_TOOLKIT_HILDON2
4871 /* Track changes in the selection to
4872 * disable the OK button whenever "Move to" is not possible
4873 * disbale NEW button whenever New is not possible */
4874 g_signal_connect (tree_view,
4875 "folder_selection_changed",
4876 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
4880 /* It could happen that we're trying to move a message from a
4881 window (msg window for example) after the main window was
4882 closed, so we can not just get the model of the folder
4884 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4885 const gchar *visible_id = NULL;
4887 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4888 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4889 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4890 MODEST_FOLDER_VIEW(tree_view));
4893 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4895 /* Show the same account than the one that is shown in the main window */
4896 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
4899 const gchar *active_account_name = NULL;
4900 ModestAccountMgr *mgr = NULL;
4901 ModestAccountSettings *settings = NULL;
4902 ModestServerAccountSettings *store_settings = NULL;
4904 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4905 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4906 modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view),
4907 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
4909 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4910 mgr = modest_runtime_get_account_mgr ();
4911 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4914 const gchar *store_account_name;
4915 store_settings = modest_account_settings_get_store_settings (settings);
4916 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4918 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
4919 store_account_name);
4920 g_object_unref (store_settings);
4921 g_object_unref (settings);
4925 /* we keep a pointer to the embedded folder view, so we can
4926 * retrieve it with get_folder_view_from_move_to_dialog (see
4927 * above) later (needed for focus handling)
4929 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
4931 /* Hide special folders */
4932 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
4933 #ifndef MODEST_TOOLKIT_HILDON2
4934 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
4937 gtk_widget_show (GTK_WIDGET (tree_view));
4943 * Shows a confirmation dialog to the user when we're moving messages
4944 * from a remote server to the local storage. Returns the dialog
4945 * response. If it's other kind of movement then it always returns
4948 * This one is used by the next functions:
4949 * modest_ui_actions_on_paste - commented out
4950 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4953 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4954 TnyFolder *dest_folder,
4958 gint response = GTK_RESPONSE_OK;
4959 TnyAccount *account = NULL;
4960 TnyFolder *src_folder = NULL;
4961 TnyIterator *iter = NULL;
4962 TnyHeader *header = NULL;
4964 /* return with OK if the destination is a remote folder */
4965 if (modest_tny_folder_is_remote_folder (dest_folder))
4966 return GTK_RESPONSE_OK;
4968 /* Get source folder */
4969 iter = tny_list_create_iterator (headers);
4970 header = TNY_HEADER (tny_iterator_get_current (iter));
4972 src_folder = tny_header_get_folder (header);
4973 g_object_unref (header);
4975 g_object_unref (iter);
4977 /* if no src_folder, message may be an attahcment */
4978 if (src_folder == NULL)
4979 return GTK_RESPONSE_CANCEL;
4981 /* If the source is a local or MMC folder */
4982 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4983 g_object_unref (src_folder);
4984 return GTK_RESPONSE_OK;
4987 /* Get the account */
4988 account = tny_folder_get_account (src_folder);
4990 /* now if offline we ask the user */
4991 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4992 response = GTK_RESPONSE_OK;
4994 response = GTK_RESPONSE_CANCEL;
4997 g_object_unref (src_folder);
4998 g_object_unref (account);
5004 move_to_helper_destroyer (gpointer user_data)
5006 MoveToHelper *helper = (MoveToHelper *) user_data;
5008 /* Close the "Pasting" information banner */
5009 if (helper->banner) {
5010 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5011 g_object_unref (helper->banner);
5013 if (gtk_tree_row_reference_valid (helper->reference)) {
5014 gtk_tree_row_reference_free (helper->reference);
5015 helper->reference = NULL;
5021 move_to_cb (ModestMailOperation *mail_op,
5024 MoveToHelper *helper = (MoveToHelper *) user_data;
5025 GObject *object = modest_mail_operation_get_source (mail_op);
5027 /* Note that the operation could have failed, in that case do
5029 if (modest_mail_operation_get_status (mail_op) !=
5030 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5033 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5034 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5036 if (!modest_msg_view_window_select_next_message (self) &&
5037 !modest_msg_view_window_select_previous_message (self)) {
5038 /* No more messages to view, so close this window */
5039 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5041 } else if (MODEST_IS_MAIN_WINDOW (object) &&
5042 gtk_tree_row_reference_valid (helper->reference)) {
5043 GtkWidget *header_view;
5045 GtkTreeSelection *sel;
5047 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5048 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5049 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5050 path = gtk_tree_row_reference_get_path (helper->reference);
5051 /* We need to unselect the previous one
5052 because we could be copying instead of
5054 gtk_tree_selection_unselect_all (sel);
5055 gtk_tree_selection_select_path (sel, path);
5056 gtk_tree_path_free (path);
5058 g_object_unref (object);
5061 /* Destroy the helper */
5062 move_to_helper_destroyer (helper);
5066 folder_move_to_cb (ModestMailOperation *mail_op,
5067 TnyFolder *new_folder,
5070 GtkWidget *folder_view;
5073 object = modest_mail_operation_get_source (mail_op);
5074 if (MODEST_IS_MAIN_WINDOW (object)) {
5075 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5076 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5077 g_object_ref (folder_view);
5078 g_object_unref (object);
5079 move_to_cb (mail_op, user_data);
5080 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5081 g_object_unref (folder_view);
5083 move_to_cb (mail_op, user_data);
5088 msgs_move_to_cb (ModestMailOperation *mail_op,
5091 move_to_cb (mail_op, user_data);
5095 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5098 ModestWindow *main_window = NULL;
5100 /* Disable next automatic folder selection */
5101 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5102 FALSE); /* don't create */
5104 GObject *win = NULL;
5105 GtkWidget *folder_view = NULL;
5107 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5108 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5109 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5111 if (user_data && TNY_IS_FOLDER (user_data)) {
5112 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5113 TNY_FOLDER (user_data), FALSE);
5116 /* Show notification dialog only if the main window exists */
5117 win = modest_mail_operation_get_source (mail_op);
5118 modest_platform_run_information_dialog ((GtkWindow *) win,
5119 _("mail_in_ui_folder_move_target_error"),
5122 g_object_unref (win);
5127 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5136 gint pending_purges = 0;
5137 gboolean some_purged = FALSE;
5138 ModestWindow *win = MODEST_WINDOW (user_data);
5139 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5141 /* If there was any error */
5142 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5143 modest_window_mgr_unregister_header (mgr, header);
5147 /* Once the message has been retrieved for purging, we check if
5148 * it's all ok for purging */
5150 parts = tny_simple_list_new ();
5151 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5152 iter = tny_list_create_iterator (parts);
5154 while (!tny_iterator_is_done (iter)) {
5156 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5157 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5158 if (tny_mime_part_is_purged (part))
5165 g_object_unref (part);
5167 tny_iterator_next (iter);
5169 g_object_unref (iter);
5172 if (pending_purges>0) {
5174 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5176 if (response == GTK_RESPONSE_OK) {
5179 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5180 iter = tny_list_create_iterator (parts);
5181 while (!tny_iterator_is_done (iter)) {
5184 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5185 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5186 tny_mime_part_set_purged (part);
5189 g_object_unref (part);
5191 tny_iterator_next (iter);
5193 g_object_unref (iter);
5195 tny_msg_rewrite_cache (msg);
5197 gtk_widget_destroy (info);
5201 modest_window_mgr_unregister_header (mgr, header);
5203 g_object_unref (parts);
5207 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5208 ModestMainWindow *win)
5210 GtkWidget *header_view;
5211 TnyList *header_list;
5213 TnyHeaderFlags flags;
5214 ModestWindow *msg_view_window = NULL;
5217 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5219 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5220 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5222 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5224 g_warning ("%s: no header selected", __FUNCTION__);
5228 if (tny_list_get_length (header_list) == 1) {
5229 TnyIterator *iter = tny_list_create_iterator (header_list);
5230 header = TNY_HEADER (tny_iterator_get_current (iter));
5231 g_object_unref (iter);
5235 if (!header || !TNY_IS_HEADER(header)) {
5236 g_warning ("%s: header is not valid", __FUNCTION__);
5240 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5241 header, &msg_view_window);
5242 flags = tny_header_get_flags (header);
5243 if (!(flags & TNY_HEADER_FLAG_CACHED))
5246 if (msg_view_window != NULL)
5247 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5249 /* do nothing; uid was registered before, so window is probably on it's way */
5250 g_warning ("debug: header %p has already been registered", header);
5253 ModestMailOperation *mail_op = NULL;
5254 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5255 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5256 modest_ui_actions_disk_operations_error_handler,
5258 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5259 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5261 g_object_unref (mail_op);
5264 g_object_unref (header);
5266 g_object_unref (header_list);
5270 * Checks if we need a connection to do the transfer and if the user
5271 * wants to connect to complete it
5274 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5275 TnyFolderStore *src_folder,
5277 TnyFolder *dst_folder,
5278 gboolean delete_originals,
5279 gboolean *need_connection,
5282 TnyAccount *src_account;
5283 gint uncached_msgs = 0;
5285 uncached_msgs = header_list_count_uncached_msgs (headers);
5287 /* We don't need any further check if
5289 * 1- the source folder is local OR
5290 * 2- the device is already online
5292 if (!modest_tny_folder_store_is_remote (src_folder) ||
5293 tny_device_is_online (modest_runtime_get_device())) {
5294 *need_connection = FALSE;
5299 /* We must ask for a connection when
5301 * - the message(s) is not already cached OR
5302 * - the message(s) is cached but the leave_on_server setting
5303 * is FALSE (because we need to sync the source folder to
5304 * delete the message from the server (for IMAP we could do it
5305 * offline, it'll take place the next time we get a
5308 src_account = get_account_from_folder_store (src_folder);
5309 if (uncached_msgs > 0) {
5313 *need_connection = TRUE;
5314 num_headers = tny_list_get_length (headers);
5315 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5317 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5318 GTK_RESPONSE_CANCEL) {
5324 /* The transfer is possible and the user wants to */
5327 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5328 const gchar *account_name;
5329 gboolean leave_on_server;
5331 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5332 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5335 if (leave_on_server == TRUE) {
5336 *need_connection = FALSE;
5338 *need_connection = TRUE;
5341 *need_connection = FALSE;
5346 g_object_unref (src_account);
5350 xfer_messages_error_handler (ModestMailOperation *mail_op,
5353 GObject *win = modest_mail_operation_get_source (mail_op);
5354 modest_platform_run_information_dialog ((GtkWindow *) win,
5355 _("mail_in_ui_folder_move_target_error"),
5358 g_object_unref (win);
5362 TnyFolderStore *dst_folder;
5367 * Utility function that transfer messages from both the main window
5368 * and the msg view window when using the "Move to" dialog
5371 xfer_messages_performer (gboolean canceled,
5373 GtkWindow *parent_window,
5374 TnyAccount *account,
5377 ModestWindow *win = MODEST_WINDOW (parent_window);
5378 TnyAccount *dst_account = NULL;
5379 gboolean dst_forbids_message_add = FALSE;
5380 XferMsgsHelper *helper;
5381 MoveToHelper *movehelper;
5382 ModestMailOperation *mail_op;
5384 helper = (XferMsgsHelper *) user_data;
5386 if (canceled || err) {
5387 if (!check_memory_full_error ((GtkWidget *) parent_window, err)) {
5388 /* Show the proper error message */
5389 modest_ui_actions_on_account_connection_error (parent_window, account);
5394 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5396 /* tinymail will return NULL for local folders it seems */
5397 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5398 modest_tny_account_get_protocol_type (dst_account),
5399 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_MESSAGE_ADD);
5400 g_object_unref (dst_account);
5402 if (dst_forbids_message_add) {
5403 modest_platform_information_banner (GTK_WIDGET (win),
5405 ngettext("mail_in_ui_folder_move_target_error",
5406 "mail_in_ui_folder_move_targets_error",
5407 tny_list_get_length (helper->headers)));
5411 movehelper = g_new0 (MoveToHelper, 1);
5413 #ifndef MODEST_TOOLKIT_HILDON2
5414 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5415 _CS("ckct_nw_pasting"));
5416 if (movehelper->banner != NULL) {
5417 g_object_ref (movehelper->banner);
5418 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5422 if (MODEST_IS_MAIN_WINDOW (win)) {
5423 GtkWidget *header_view =
5424 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5425 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5426 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5429 /* Perform the mail operation */
5430 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5431 xfer_messages_error_handler,
5433 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5436 modest_mail_operation_xfer_msgs (mail_op,
5438 TNY_FOLDER (helper->dst_folder),
5443 g_object_unref (G_OBJECT (mail_op));
5445 g_object_unref (helper->dst_folder);
5446 g_object_unref (helper->headers);
5447 g_slice_free (XferMsgsHelper, helper);
5451 TnyFolder *src_folder;
5452 TnyFolderStore *dst_folder;
5453 gboolean delete_original;
5454 GtkWidget *folder_view;
5458 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
5459 TnyAccount *account, gpointer user_data)
5461 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5462 GtkTreeSelection *sel;
5463 ModestMailOperation *mail_op = NULL;
5465 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
5466 g_object_unref (G_OBJECT (info->src_folder));
5467 g_object_unref (G_OBJECT (info->dst_folder));
5472 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5473 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5474 _CS("ckct_nw_pasting"));
5475 if (helper->banner != NULL) {
5476 g_object_ref (helper->banner);
5477 gtk_widget_show (GTK_WIDGET(helper->banner));
5479 /* Clean folder on header view before moving it */
5480 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5481 gtk_tree_selection_unselect_all (sel);
5483 /* Let gtk events run. We need that the folder
5484 view frees its reference to the source
5485 folder *before* issuing the mail operation
5486 so we need the signal handler of selection
5487 changed to happen before the mail
5489 while (gtk_events_pending ())
5490 gtk_main_iteration (); */
5493 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5494 modest_ui_actions_move_folder_error_handler,
5495 info->src_folder, NULL);
5496 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5499 /* Select *after* the changes */
5500 /* TODO: this function hangs UI after transfer */
5501 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
5502 /* TNY_FOLDER (src_folder), TRUE); */
5504 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
5505 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5506 TNY_FOLDER (info->dst_folder), TRUE);
5508 modest_mail_operation_xfer_folder (mail_op,
5509 TNY_FOLDER (info->src_folder),
5511 info->delete_original,
5514 g_object_unref (G_OBJECT (info->src_folder));
5516 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5519 /* Unref mail operation */
5520 g_object_unref (G_OBJECT (mail_op));
5521 g_object_unref (G_OBJECT (info->dst_folder));
5526 get_account_from_folder_store (TnyFolderStore *folder_store)
5528 if (TNY_IS_ACCOUNT (folder_store))
5529 return g_object_ref (folder_store);
5531 return tny_folder_get_account (TNY_FOLDER (folder_store));
5535 * UI handler for the "Move to" action when invoked from the
5539 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5540 GtkWidget *folder_view,
5541 TnyFolderStore *dst_folder,
5542 ModestMainWindow *win)
5544 ModestHeaderView *header_view = NULL;
5545 TnyFolderStore *src_folder = NULL;
5547 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5549 /* Get the source folder */
5550 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5552 /* Get header view */
5553 header_view = (ModestHeaderView *)
5554 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5556 /* Get folder or messages to transfer */
5557 if (gtk_widget_is_focus (folder_view)) {
5558 gboolean do_xfer = TRUE;
5560 /* Allow only to transfer folders to the local root folder */
5561 if (TNY_IS_ACCOUNT (dst_folder) &&
5562 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5563 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5565 } else if (!TNY_IS_FOLDER (src_folder)) {
5566 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5571 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5572 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5574 info->src_folder = g_object_ref (src_folder);
5575 info->dst_folder = g_object_ref (dst_folder);
5576 info->delete_original = TRUE;
5577 info->folder_view = folder_view;
5579 connect_info->callback = on_move_folder_cb;
5580 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5581 connect_info->data = info;
5583 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5584 TNY_FOLDER_STORE (src_folder),
5587 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5590 headers = modest_header_view_get_selected_headers(header_view);
5592 /* Transfer the messages */
5593 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
5594 headers, TNY_FOLDER (dst_folder));
5596 g_object_unref (headers);
5600 g_object_unref (src_folder);
5603 #ifdef MODEST_TOOLKIT_HILDON2
5605 * UI handler for the "Move to" action when invoked from the
5606 * ModestFolderWindow
5609 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
5610 TnyFolderStore *dst_folder,
5614 TnyFolderStore *src_folder = NULL;
5615 TnyIterator *iterator;
5617 if (tny_list_get_length (selection) != 1)
5620 iterator = tny_list_create_iterator (selection);
5621 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
5622 g_object_unref (iterator);
5625 gboolean do_xfer = TRUE;
5627 /* Allow only to transfer folders to the local root folder */
5628 if (TNY_IS_ACCOUNT (dst_folder) &&
5629 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5630 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5632 } else if (!TNY_IS_FOLDER (src_folder)) {
5633 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5638 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5639 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5641 info->src_folder = g_object_ref (src_folder);
5642 info->dst_folder = g_object_ref (dst_folder);
5643 info->delete_original = TRUE;
5644 info->folder_view = folder_view;
5646 connect_info->callback = on_move_folder_cb;
5647 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5648 connect_info->data = info;
5650 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5651 TNY_FOLDER_STORE (src_folder),
5655 g_object_unref (src_folder);
5661 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
5662 TnyFolder *src_folder,
5664 TnyFolder *dst_folder)
5666 gboolean need_connection = TRUE;
5667 gboolean do_xfer = TRUE;
5668 XferMsgsHelper *helper;
5670 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5671 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5672 g_return_if_fail (TNY_IS_LIST (headers));
5674 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5675 headers, TNY_FOLDER (dst_folder),
5676 TRUE, &need_connection,
5679 /* If we don't want to transfer just return */
5683 /* Create the helper */
5684 helper = g_slice_new (XferMsgsHelper);
5685 helper->dst_folder = g_object_ref (dst_folder);
5686 helper->headers = g_object_ref (headers);
5688 if (need_connection) {
5689 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5690 connect_info->callback = xfer_messages_performer;
5691 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5692 connect_info->data = helper;
5694 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5695 TNY_FOLDER_STORE (src_folder),
5698 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5699 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
5700 src_account, helper);
5701 g_object_unref (src_account);
5706 * UI handler for the "Move to" action when invoked from the
5707 * ModestMsgViewWindow
5710 modest_ui_actions_on_window_move_to (GtkAction *action,
5712 TnyFolderStore *dst_folder,
5715 TnyFolder *src_folder = NULL;
5717 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5720 TnyHeader *header = NULL;
5723 iter = tny_list_create_iterator (headers);
5724 header = (TnyHeader *) tny_iterator_get_current (iter);
5725 src_folder = tny_header_get_folder (header);
5727 /* Transfer the messages */
5728 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
5730 TNY_FOLDER (dst_folder));
5733 g_object_unref (header);
5734 g_object_unref (iter);
5735 g_object_unref (src_folder);
5740 modest_ui_actions_on_move_to (GtkAction *action,
5743 modest_ui_actions_on_edit_mode_move_to (win);
5747 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
5749 GtkWidget *dialog = NULL, *folder_view = NULL;
5750 ModestMainWindow *main_window;
5751 MoveToInfo *helper = NULL;
5752 TnyList *list_to_move;
5754 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
5756 /* Get the main window if exists */
5757 if (MODEST_IS_MAIN_WINDOW (win))
5758 main_window = MODEST_MAIN_WINDOW (win);
5761 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5762 FALSE)); /* don't create */
5764 /* Get the folder view widget if exists */
5766 folder_view = modest_main_window_get_child_widget (main_window,
5767 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5771 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
5772 if (tny_list_get_length (list_to_move) < 1) {
5773 g_object_unref (list_to_move);
5777 /* Create and run the dialog */
5778 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view);
5779 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
5780 GTK_WINDOW (dialog),
5784 helper = g_slice_new0 (MoveToInfo);
5785 helper->list = modest_platform_get_list_to_move (MODEST_WINDOW (win));
5788 /* Listen to response signal */
5789 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
5791 /* Show the dialog */
5792 gtk_widget_show (dialog);
5798 * Calls #HeadersFunc for each header already selected in the main
5799 * window or the message currently being shown in the msg view window
5802 do_headers_action (ModestWindow *win,
5806 TnyList *headers_list = NULL;
5807 TnyIterator *iter = NULL;
5808 TnyHeader *header = NULL;
5809 TnyFolder *folder = NULL;
5812 headers_list = get_selected_headers (win);
5816 /* Get the folder */
5817 iter = tny_list_create_iterator (headers_list);
5818 header = TNY_HEADER (tny_iterator_get_current (iter));
5820 folder = tny_header_get_folder (header);
5821 g_object_unref (header);
5824 /* Call the function for each header */
5825 while (!tny_iterator_is_done (iter)) {
5826 header = TNY_HEADER (tny_iterator_get_current (iter));
5827 func (header, win, user_data);
5828 g_object_unref (header);
5829 tny_iterator_next (iter);
5832 /* Trick: do a poke status in order to speed up the signaling
5834 tny_folder_poke_status (folder);
5837 g_object_unref (folder);
5838 g_object_unref (iter);
5839 g_object_unref (headers_list);
5843 modest_ui_actions_view_attachment (GtkAction *action,
5844 ModestWindow *window)
5846 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5847 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5849 /* not supported window for this action */
5850 g_return_if_reached ();
5855 modest_ui_actions_save_attachments (GtkAction *action,
5856 ModestWindow *window)
5858 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5860 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5863 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5865 /* not supported window for this action */
5866 g_return_if_reached ();
5871 modest_ui_actions_remove_attachments (GtkAction *action,
5872 ModestWindow *window)
5874 if (MODEST_IS_MAIN_WINDOW (window)) {
5875 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
5876 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5877 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5879 /* not supported window for this action */
5880 g_return_if_reached ();
5885 modest_ui_actions_on_settings (GtkAction *action,
5890 dialog = modest_platform_get_global_settings_dialog ();
5891 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
5892 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5893 gtk_widget_show_all (dialog);
5895 gtk_dialog_run (GTK_DIALOG (dialog));
5897 gtk_widget_destroy (dialog);
5901 modest_ui_actions_on_help (GtkAction *action,
5904 /* Help app is not available at all in fremantle */
5905 #ifndef MODEST_TOOLKIT_HILDON2
5906 const gchar *help_id;
5908 g_return_if_fail (win && GTK_IS_WINDOW(win));
5910 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5913 modest_platform_show_help (GTK_WINDOW (win), help_id);
5918 modest_ui_actions_on_csm_help (GtkAction *action,
5921 /* Help app is not available at all in fremantle */
5922 #ifndef MODEST_TOOLKIT_HILDON2
5924 const gchar* help_id = NULL;
5925 GtkWidget *folder_view;
5926 TnyFolderStore *folder_store;
5928 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
5930 /* Get selected folder */
5931 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5932 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5933 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5935 /* Switch help_id */
5936 if (folder_store && TNY_IS_FOLDER (folder_store))
5937 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
5940 g_object_unref (folder_store);
5943 modest_platform_show_help (GTK_WINDOW (win), help_id);
5945 modest_ui_actions_on_help (action, win);
5950 retrieve_contents_cb (ModestMailOperation *mail_op,
5957 /* We only need this callback to show an error in case of
5958 memory low condition */
5959 modest_ui_actions_msg_retrieval_check (mail_op, header, msg);
5963 retrieve_msg_contents_performer (gboolean canceled,
5965 GtkWindow *parent_window,
5966 TnyAccount *account,
5969 ModestMailOperation *mail_op;
5970 TnyList *headers = TNY_LIST (user_data);
5972 if (err || canceled) {
5973 check_memory_full_error ((GtkWidget *) parent_window, err);
5977 /* Create mail operation */
5978 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5979 modest_ui_actions_disk_operations_error_handler,
5981 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5982 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
5985 g_object_unref (mail_op);
5987 g_object_unref (headers);
5988 g_object_unref (account);
5992 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5993 ModestWindow *window)
5995 TnyList *headers = NULL;
5996 TnyAccount *account = NULL;
5997 TnyIterator *iter = NULL;
5998 TnyHeader *header = NULL;
5999 TnyFolder *folder = NULL;
6002 headers = get_selected_headers (window);
6006 /* Pick the account */
6007 iter = tny_list_create_iterator (headers);
6008 header = TNY_HEADER (tny_iterator_get_current (iter));
6009 folder = tny_header_get_folder (header);
6010 account = tny_folder_get_account (folder);
6011 g_object_unref (folder);
6012 g_object_unref (header);
6013 g_object_unref (iter);
6015 /* Connect and perform the message retrieval */
6016 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6017 g_object_ref (account),
6018 retrieve_msg_contents_performer,
6019 g_object_ref (headers));
6022 g_object_unref (account);
6023 g_object_unref (headers);
6027 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6029 g_return_if_fail (MODEST_IS_WINDOW (window));
6032 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6036 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6038 g_return_if_fail (MODEST_IS_WINDOW (window));
6041 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6045 modest_ui_actions_on_email_menu_activated (GtkAction *action,
6046 ModestWindow *window)
6048 g_return_if_fail (MODEST_IS_WINDOW (window));
6051 modest_ui_actions_check_menu_dimming_rules (window);
6055 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
6056 ModestWindow *window)
6058 g_return_if_fail (MODEST_IS_WINDOW (window));
6061 modest_ui_actions_check_menu_dimming_rules (window);
6065 modest_ui_actions_on_view_menu_activated (GtkAction *action,
6066 ModestWindow *window)
6068 g_return_if_fail (MODEST_IS_WINDOW (window));
6071 modest_ui_actions_check_menu_dimming_rules (window);
6075 modest_ui_actions_on_format_menu_activated (GtkAction *action,
6076 ModestWindow *window)
6078 g_return_if_fail (MODEST_IS_WINDOW (window));
6081 modest_ui_actions_check_menu_dimming_rules (window);
6085 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
6086 ModestWindow *window)
6088 g_return_if_fail (MODEST_IS_WINDOW (window));
6091 modest_ui_actions_check_menu_dimming_rules (window);
6095 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
6096 ModestWindow *window)
6098 g_return_if_fail (MODEST_IS_WINDOW (window));
6101 modest_ui_actions_check_menu_dimming_rules (window);
6105 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
6106 ModestWindow *window)
6108 g_return_if_fail (MODEST_IS_WINDOW (window));
6111 modest_ui_actions_check_menu_dimming_rules (window);
6115 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
6116 ModestWindow *window)
6118 g_return_if_fail (MODEST_IS_WINDOW (window));
6121 modest_ui_actions_check_menu_dimming_rules (window);
6125 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
6126 ModestWindow *window)
6128 g_return_if_fail (MODEST_IS_WINDOW (window));
6131 modest_ui_actions_check_menu_dimming_rules (window);
6135 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6137 g_return_if_fail (MODEST_IS_WINDOW (window));
6139 /* we check for low-mem; in that case, show a warning, and don't allow
6142 if (modest_platform_check_memory_low (window, TRUE))
6145 modest_platform_show_search_messages (GTK_WINDOW (window));
6149 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6151 g_return_if_fail (MODEST_IS_WINDOW (win));
6154 /* we check for low-mem; in that case, show a warning, and don't allow
6155 * for the addressbook
6157 if (modest_platform_check_memory_low (win, TRUE))
6161 modest_platform_show_addressbook (GTK_WINDOW (win));
6166 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6167 ModestWindow *window)
6170 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6172 if (GTK_IS_TOGGLE_ACTION (action))
6173 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6177 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window),
6182 on_send_receive_finished (ModestMailOperation *mail_op,
6185 GtkWidget *header_view, *folder_view;
6186 TnyFolderStore *folder_store;
6187 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6189 /* Set send/receive operation finished */
6190 modest_main_window_notify_send_receive_completed (main_win);
6192 /* Don't refresh the current folder if there were any errors */
6193 if (modest_mail_operation_get_status (mail_op) !=
6194 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6197 /* Refresh the current folder if we're viewing a window. We do
6198 this because the user won't be able to see the new mails in
6199 the selected folder after a Send&Receive because it only
6200 performs a poke_status, i.e, only the number of read/unread
6201 messages is updated, but the new headers are not
6203 folder_view = modest_main_window_get_child_widget (main_win,
6204 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6208 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6210 /* Do not need to refresh INBOX again because the
6211 update_account does it always automatically */
6212 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6213 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6214 ModestMailOperation *refresh_op;
6216 header_view = modest_main_window_get_child_widget (main_win,
6217 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6219 /* We do not need to set the contents style
6220 because it hasn't changed. We also do not
6221 need to save the widget status. Just force
6223 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6224 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6225 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6226 folder_refreshed_cb, main_win);
6227 g_object_unref (refresh_op);
6231 g_object_unref (folder_store);
6236 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6242 const gchar* server_name = NULL;
6243 TnyTransportAccount *server_account;
6244 gchar *message = NULL;
6246 /* Don't show anything if the user cancelled something or the
6247 * send receive request is not interactive. Authentication
6248 * errors are managed by the account store so no need to show
6249 * a dialog here again */
6250 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6251 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6252 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6256 /* Get the server name: */
6258 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
6260 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
6262 g_return_if_reached ();
6264 /* Show the appropriate message text for the GError: */
6265 switch (err->code) {
6266 case TNY_SERVICE_ERROR_CONNECT:
6267 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6269 case TNY_SERVICE_ERROR_SEND:
6270 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6272 case TNY_SERVICE_ERROR_UNAVAILABLE:
6273 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6276 g_warning ("%s: unexpected ERROR %d",
6277 __FUNCTION__, err->code);
6278 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6282 modest_platform_run_information_dialog (NULL, message, FALSE);
6284 g_object_unref (server_account);
6288 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6293 ModestMainWindow *main_window = NULL;
6294 ModestWindowMgr *mgr = NULL;
6295 GtkWidget *folder_view = NULL, *header_view = NULL;
6296 TnyFolderStore *selected_folder = NULL;
6297 TnyFolderType folder_type;
6299 mgr = modest_runtime_get_window_mgr ();
6300 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr,
6301 FALSE));/* don't create */
6305 /* Check if selected folder is OUTBOX */
6306 folder_view = modest_main_window_get_child_widget (main_window,
6307 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6308 header_view = modest_main_window_get_child_widget (main_window,
6309 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6311 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6312 if (!TNY_IS_FOLDER (selected_folder))
6315 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6316 #if GTK_CHECK_VERSION(2, 8, 0)
6317 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
6318 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6319 GtkTreeViewColumn *tree_column;
6321 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6322 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6324 gtk_tree_view_column_queue_resize (tree_column);
6327 gtk_widget_queue_draw (header_view);
6330 /* Rerun dimming rules, because the message could become deletable for example */
6331 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6332 MODEST_DIMMING_RULES_TOOLBAR);
6333 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6334 MODEST_DIMMING_RULES_MENU);
6338 if (selected_folder != NULL)
6339 g_object_unref (selected_folder);
6343 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6344 TnyAccount *account)
6346 ModestProtocolType protocol_type;
6347 ModestProtocol *protocol;
6348 gchar *error_note = NULL;
6350 protocol_type = modest_tny_account_get_protocol_type (account);
6351 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6354 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6355 if (error_note == NULL) {
6356 g_warning ("%s: This should not be reached", __FUNCTION__);
6358 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6359 g_free (error_note);
6364 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6368 TnyFolderStore *folder = NULL;
6369 TnyAccount *account = NULL;
6370 ModestProtocolType proto;
6371 ModestProtocol *protocol;
6372 TnyHeader *header = NULL;
6374 if (MODEST_IS_MAIN_WINDOW (win)) {
6375 GtkWidget *header_view;
6376 TnyList* headers = NULL;
6378 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6379 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6380 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6381 if (!headers || tny_list_get_length (headers) == 0) {
6383 g_object_unref (headers);
6386 iter = tny_list_create_iterator (headers);
6387 header = TNY_HEADER (tny_iterator_get_current (iter));
6388 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6389 g_object_unref (iter);
6390 g_object_unref (headers);
6391 #ifdef MODEST_TOOLKIT_HILDON2
6392 } else if (MODEST_IS_HEADER_WINDOW (win)) {
6393 GtkWidget *header_view;
6394 TnyList* headers = NULL;
6396 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
6397 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6398 if (!headers || tny_list_get_length (headers) == 0) {
6400 g_object_unref (headers);
6403 iter = tny_list_create_iterator (headers);
6404 header = TNY_HEADER (tny_iterator_get_current (iter));
6405 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6406 g_object_unref (iter);
6407 g_object_unref (headers);
6409 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6410 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6411 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6414 /* Get the account type */
6415 account = tny_folder_get_account (TNY_FOLDER (folder));
6416 proto = modest_tny_account_get_protocol_type (account);
6417 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6420 subject = tny_header_dup_subject (header);
6421 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6425 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6429 g_object_unref (account);
6430 g_object_unref (folder);
6431 g_object_unref (header);
6437 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6438 const gchar *account_name,
6439 const gchar *account_title)
6441 ModestAccountMgr *account_mgr;
6444 ModestProtocol *protocol;
6445 gboolean removed = FALSE;
6447 g_return_val_if_fail (account_name, FALSE);
6448 g_return_val_if_fail (account_title, FALSE);
6450 account_mgr = modest_runtime_get_account_mgr();
6452 /* The warning text depends on the account type: */
6453 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6454 modest_account_mgr_get_store_protocol (account_mgr,
6456 txt = modest_protocol_get_translation (protocol,
6457 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6460 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6462 response = modest_platform_run_confirmation_dialog (parent_window, txt);
6466 if (response == GTK_RESPONSE_OK) {
6467 /* Remove account. If it succeeds then it also removes
6468 the account from the ModestAccountView: */
6469 gboolean is_default = FALSE;
6470 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6471 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6473 g_free (default_account_name);
6475 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6477 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);