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);
1252 open_msg_helper_destroyer (gpointer user_data)
1254 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1256 if (helper->banner_info) {
1257 g_free (helper->banner_info->message);
1258 if (helper->banner_info->idle_handler > 0) {
1259 g_source_remove (helper->banner_info->idle_handler);
1260 helper->banner_info->idle_handler = 0;
1262 if (helper->banner_info->banner != NULL) {
1263 gtk_widget_destroy (helper->banner_info->banner);
1264 g_object_unref (helper->banner_info->banner);
1265 helper->banner_info->banner = NULL;
1267 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1268 helper->banner_info = NULL;
1270 g_object_unref (helper->model);
1271 g_object_unref (helper->header);
1272 gtk_tree_row_reference_free (helper->rowref);
1273 g_slice_free (OpenMsgHelper, helper);
1277 open_msg_performer(gboolean canceled,
1279 GtkWindow *parent_window,
1280 TnyAccount *account,
1283 ModestMailOperation *mail_op = NULL;
1285 ModestProtocolType proto;
1286 TnyConnectionStatus status;
1287 gboolean show_open_draft = FALSE;
1288 OpenMsgHelper *helper = NULL;
1289 ModestProtocol *protocol;
1290 ModestProtocolRegistry *protocol_registry;
1293 helper = (OpenMsgHelper *) user_data;
1295 status = tny_account_get_connection_status (account);
1296 if (err || canceled) {
1297 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1298 /* Free the helper */
1299 open_msg_helper_destroyer (helper);
1301 /* In memory full conditions we could get this error here */
1302 check_memory_full_error ((GtkWidget *) parent_window, err);
1307 /* Get the error message depending on the protocol */
1308 proto = modest_tny_account_get_protocol_type (account);
1309 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1310 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1313 protocol_registry = modest_runtime_get_protocol_registry ();
1314 subject = tny_header_dup_subject (helper->header);
1316 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1317 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1321 if (error_msg == NULL) {
1322 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
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);
1337 #ifdef MODEST_TOOLKIT_HILDON2
1340 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1343 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1344 g_free (account_name);
1345 open_msg_helper_destroyer (helper);
1350 ModestWindow *window;
1351 GtkWidget *header_view;
1354 header_view = get_header_view_from_window (MODEST_WINDOW (parent_window));
1355 uid = modest_tny_folder_get_header_unique_id (helper->header);
1357 window = modest_msg_view_window_new_from_header_view
1358 (MODEST_HEADER_VIEW (header_view), account_name, uid, helper->rowref);
1359 if (window != NULL) {
1360 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1362 gtk_widget_destroy (GTK_WIDGET (window));
1364 gtk_widget_show_all (GTK_WIDGET(window));
1368 g_free (account_name);
1370 open_msg_helper_destroyer (helper);
1373 g_free (account_name);
1375 /* Create the mail operation */
1377 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1378 modest_ui_actions_disk_operations_error_handler,
1380 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1383 if (show_open_draft) {
1384 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1385 #ifdef MODEST_TOOLKIT_HILDON2
1386 helper->banner_info->message = g_strdup (_("mail_me_opening"));
1388 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1390 helper->banner_info->banner = NULL;
1391 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1392 helper->banner_info);
1396 headers = TNY_LIST (tny_simple_list_new ());
1397 tny_list_prepend (headers, G_OBJECT (helper->header));
1398 modest_mail_operation_get_msgs_full (mail_op,
1402 open_msg_helper_destroyer);
1403 g_object_unref (headers);
1408 g_object_unref (mail_op);
1409 g_object_unref (account);
1413 * This function is used by both modest_ui_actions_on_open and
1414 * modest_ui_actions_on_header_activated. This way we always do the
1415 * same when trying to open messages.
1418 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1420 ModestWindowMgr *mgr = NULL;
1421 TnyAccount *account;
1422 gboolean cached = FALSE;
1424 GtkWidget *header_view = NULL;
1425 OpenMsgHelper *helper;
1426 ModestWindow *window;
1428 g_return_if_fail (header != NULL && rowref != NULL);
1430 mgr = modest_runtime_get_window_mgr ();
1433 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1434 if (header_view == NULL)
1437 /* Get the account */
1438 account = get_account_from_header (header);
1443 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1445 /* Do not open again the message and present the
1446 window to the user */
1449 #ifndef MODEST_TOOLKIT_HILDON2
1450 gtk_window_present (GTK_WINDOW (window));
1453 /* the header has been registered already, we don't do
1454 * anything but wait for the window to come up*/
1455 g_debug ("header %p already registered, waiting for window", header);
1460 /* Open each message */
1461 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1463 /* Allways download if we are online. */
1464 if (!tny_device_is_online (modest_runtime_get_device ())) {
1467 /* If ask for user permission to download the messages */
1468 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1469 _("mcen_nc_get_msg"));
1471 /* End if the user does not want to continue */
1472 if (response == GTK_RESPONSE_CANCEL) {
1478 /* We register the window for opening */
1479 modest_window_mgr_register_header (mgr, header, NULL);
1481 /* Create the helper. We need to get a reference to the model
1482 here because it could change while the message is readed
1483 (the user could switch between folders) */
1484 helper = g_slice_new (OpenMsgHelper);
1485 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1486 helper->header = g_object_ref (header);
1487 helper->rowref = gtk_tree_row_reference_copy (rowref);
1488 helper->banner_info = NULL;
1490 /* Connect to the account and perform */
1492 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1493 open_msg_performer, helper);
1495 /* Call directly the performer, do not need to connect */
1496 open_msg_performer (FALSE, NULL, (GtkWindow *) win,
1497 g_object_ref (account), helper);
1502 g_object_unref (account);
1506 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1513 /* we check for low-mem; in that case, show a warning, and don't allow
1516 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1520 headers = get_selected_headers (win);
1524 headers_count = tny_list_get_length (headers);
1525 if (headers_count != 1) {
1526 if (headers_count > 1) {
1527 /* Don't allow activation if there are more than one message selected */
1528 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1531 g_object_unref (headers);
1535 iter = tny_list_create_iterator (headers);
1536 header = TNY_HEADER (tny_iterator_get_current (iter));
1537 g_object_unref (iter);
1541 open_msg_from_header (header, NULL, win);
1542 g_object_unref (header);
1545 g_object_unref(headers);
1549 rf_helper_window_closed (gpointer data,
1552 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1554 helper->parent_window = NULL;
1557 static ReplyForwardHelper*
1558 create_reply_forward_helper (ReplyForwardAction action,
1560 guint reply_forward_type,
1563 ReplyForwardHelper *rf_helper = NULL;
1564 const gchar *active_acc = modest_window_get_active_account (win);
1566 rf_helper = g_slice_new0 (ReplyForwardHelper);
1567 rf_helper->reply_forward_type = reply_forward_type;
1568 rf_helper->action = action;
1569 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1570 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1571 rf_helper->account_name = (active_acc) ?
1572 g_strdup (active_acc) :
1573 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1575 /* Note that window could be destroyed just AFTER calling
1576 register_window so we must ensure that this pointer does
1577 not hold invalid references */
1578 if (rf_helper->parent_window)
1579 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1580 rf_helper_window_closed, rf_helper);
1586 free_reply_forward_helper (gpointer data)
1588 ReplyForwardHelper *helper;
1590 helper = (ReplyForwardHelper *) data;
1591 g_free (helper->account_name);
1593 g_object_unref (helper->header);
1594 if (helper->parent_window)
1595 g_object_weak_unref (G_OBJECT (helper->parent_window),
1596 rf_helper_window_closed, helper);
1597 g_slice_free (ReplyForwardHelper, helper);
1601 reply_forward_cb (ModestMailOperation *mail_op,
1608 TnyMsg *new_msg = NULL;
1609 ReplyForwardHelper *rf_helper;
1610 ModestWindow *msg_win = NULL;
1611 ModestEditType edit_type;
1613 TnyAccount *account = NULL;
1614 ModestWindowMgr *mgr = NULL;
1615 gchar *signature = NULL;
1616 gboolean use_signature;
1618 /* If there was any error. The mail operation could be NULL,
1619 this means that we already have the message downloaded and
1620 that we didn't do a mail operation to retrieve it */
1621 rf_helper = (ReplyForwardHelper *) user_data;
1622 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1625 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1626 rf_helper->account_name);
1627 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr(),
1628 rf_helper->account_name,
1631 /* Create reply mail */
1632 switch (rf_helper->action) {
1635 modest_tny_msg_create_reply_msg (msg, header, from,
1636 (use_signature) ? signature : NULL,
1637 rf_helper->reply_forward_type,
1638 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1640 case ACTION_REPLY_TO_ALL:
1642 modest_tny_msg_create_reply_msg (msg, header, from,
1643 (use_signature) ? signature : NULL,
1644 rf_helper->reply_forward_type,
1645 MODEST_TNY_MSG_REPLY_MODE_ALL);
1646 edit_type = MODEST_EDIT_TYPE_REPLY;
1648 case ACTION_FORWARD:
1650 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1651 rf_helper->reply_forward_type);
1652 edit_type = MODEST_EDIT_TYPE_FORWARD;
1655 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1657 g_return_if_reached ();
1665 g_warning ("%s: failed to create message\n", __FUNCTION__);
1669 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1670 rf_helper->account_name,
1671 TNY_ACCOUNT_TYPE_STORE);
1673 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1677 /* Create and register the windows */
1678 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1679 mgr = modest_runtime_get_window_mgr ();
1680 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1682 /* Note that register_window could have deleted the account */
1683 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1684 gdouble parent_zoom;
1686 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1687 modest_window_set_zoom (msg_win, parent_zoom);
1690 /* Show edit window */
1691 gtk_widget_show_all (GTK_WIDGET (msg_win));
1694 /* We always unregister the header because the message is
1695 forwarded or replied so the original one is no longer
1697 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1700 g_object_unref (G_OBJECT (new_msg));
1702 g_object_unref (G_OBJECT (account));
1703 free_reply_forward_helper (rf_helper);
1706 /* Checks a list of headers. If any of them are not currently
1707 * downloaded (CACHED) then returns TRUE else returns FALSE.
1710 header_list_count_uncached_msgs (TnyList *header_list)
1713 gint uncached_messages = 0;
1715 iter = tny_list_create_iterator (header_list);
1716 while (!tny_iterator_is_done (iter)) {
1719 header = TNY_HEADER (tny_iterator_get_current (iter));
1721 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1722 uncached_messages ++;
1723 g_object_unref (header);
1726 tny_iterator_next (iter);
1728 g_object_unref (iter);
1730 return uncached_messages;
1733 /* Returns FALSE if the user does not want to download the
1734 * messages. Returns TRUE if the user allowed the download.
1737 connect_to_get_msg (ModestWindow *win,
1738 gint num_of_uncached_msgs,
1739 TnyAccount *account)
1741 GtkResponseType response;
1743 /* Allways download if we are online. */
1744 if (tny_device_is_online (modest_runtime_get_device ()))
1747 /* If offline, then ask for user permission to download the messages */
1748 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1749 ngettext("mcen_nc_get_msg",
1751 num_of_uncached_msgs));
1753 if (response == GTK_RESPONSE_CANCEL)
1756 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1760 reply_forward_performer (gboolean canceled,
1762 GtkWindow *parent_window,
1763 TnyAccount *account,
1766 ReplyForwardHelper *rf_helper = NULL;
1767 ModestMailOperation *mail_op;
1769 rf_helper = (ReplyForwardHelper *) user_data;
1771 if (canceled || err) {
1772 free_reply_forward_helper (rf_helper);
1776 /* Retrieve the message */
1777 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1778 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1779 modest_ui_actions_disk_operations_error_handler,
1781 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1782 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1785 g_object_unref(mail_op);
1789 * Common code for the reply and forward actions
1792 reply_forward (ReplyForwardAction action, ModestWindow *win)
1794 ReplyForwardHelper *rf_helper = NULL;
1795 guint reply_forward_type;
1797 g_return_if_fail (MODEST_IS_WINDOW(win));
1799 /* we check for low-mem; in that case, show a warning, and don't allow
1800 * reply/forward (because it could potentially require a lot of memory */
1801 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1805 /* we need an account when editing */
1806 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1807 if (!modest_ui_actions_run_account_setup_wizard (win))
1811 reply_forward_type =
1812 modest_conf_get_int (modest_runtime_get_conf (),
1813 (action == ACTION_FORWARD) ?
1814 MODEST_CONF_FORWARD_TYPE :
1815 MODEST_CONF_REPLY_TYPE,
1818 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1820 TnyHeader *header = NULL;
1821 /* Get header and message. Do not free them here, the
1822 reply_forward_cb must do it */
1823 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1824 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1826 if (msg && header) {
1828 rf_helper = create_reply_forward_helper (action, win,
1829 reply_forward_type, header);
1830 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1832 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1836 g_object_unref (msg);
1838 g_object_unref (header);
1840 TnyHeader *header = NULL;
1842 gboolean do_retrieve = TRUE;
1843 TnyList *header_list = NULL;
1845 header_list = get_selected_headers (win);
1848 /* Check that only one message is selected for replying */
1849 if (tny_list_get_length (header_list) != 1) {
1850 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1851 NULL, _("mcen_ib_select_one_message"));
1852 g_object_unref (header_list);
1856 /* Only reply/forward to one message */
1857 iter = tny_list_create_iterator (header_list);
1858 header = TNY_HEADER (tny_iterator_get_current (iter));
1859 g_object_unref (iter);
1861 /* Retrieve messages */
1862 do_retrieve = (action == ACTION_FORWARD) ||
1863 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1866 TnyAccount *account = NULL;
1867 TnyFolder *folder = NULL;
1868 gdouble download = TRUE;
1869 guint uncached_msgs = 0;
1871 folder = tny_header_get_folder (header);
1873 goto do_retrieve_frees;
1874 account = tny_folder_get_account (folder);
1876 goto do_retrieve_frees;
1878 uncached_msgs = header_list_count_uncached_msgs (header_list);
1880 if (uncached_msgs > 0) {
1881 /* Allways download if we are online. */
1882 if (!tny_device_is_online (modest_runtime_get_device ())) {
1885 /* If ask for user permission to download the messages */
1886 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1887 ngettext("mcen_nc_get_msg",
1891 /* End if the user does not want to continue */
1892 if (response == GTK_RESPONSE_CANCEL)
1899 rf_helper = create_reply_forward_helper (action, win,
1900 reply_forward_type, header);
1901 if (uncached_msgs > 0) {
1902 modest_platform_connect_and_perform (GTK_WINDOW (win),
1904 reply_forward_performer,
1907 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
1908 account, rf_helper);
1913 g_object_unref (account);
1915 g_object_unref (folder);
1917 reply_forward_cb (NULL, header, FALSE, NULL, NULL, rf_helper);
1920 g_object_unref (header_list);
1921 g_object_unref (header);
1926 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1928 g_return_if_fail (MODEST_IS_WINDOW(win));
1930 reply_forward (ACTION_REPLY, win);
1934 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1936 g_return_if_fail (MODEST_IS_WINDOW(win));
1938 reply_forward (ACTION_FORWARD, win);
1942 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1944 g_return_if_fail (MODEST_IS_WINDOW(win));
1946 reply_forward (ACTION_REPLY_TO_ALL, win);
1950 modest_ui_actions_on_next (GtkAction *action,
1951 ModestWindow *window)
1953 if (MODEST_IS_MAIN_WINDOW (window)) {
1954 GtkWidget *header_view;
1956 header_view = modest_main_window_get_child_widget (
1957 MODEST_MAIN_WINDOW(window),
1958 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1962 modest_header_view_select_next (
1963 MODEST_HEADER_VIEW(header_view));
1964 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1965 modest_msg_view_window_select_next_message (
1966 MODEST_MSG_VIEW_WINDOW (window));
1968 g_return_if_reached ();
1973 modest_ui_actions_on_prev (GtkAction *action,
1974 ModestWindow *window)
1976 g_return_if_fail (MODEST_IS_WINDOW(window));
1978 if (MODEST_IS_MAIN_WINDOW (window)) {
1979 GtkWidget *header_view;
1980 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1981 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1985 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1986 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1987 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1989 g_return_if_reached ();
1994 modest_ui_actions_on_sort (GtkAction *action,
1995 ModestWindow *window)
1997 GtkWidget *header_view = NULL;
1999 g_return_if_fail (MODEST_IS_WINDOW(window));
2001 if (MODEST_IS_MAIN_WINDOW (window)) {
2002 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
2003 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2004 #ifdef MODEST_TOOLKIT_HILDON2
2005 } else if (MODEST_IS_HEADER_WINDOW (window)) {
2006 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2011 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
2016 /* Show sorting dialog */
2017 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
2021 new_messages_arrived (ModestMailOperation *self,
2022 TnyList *new_headers,
2026 gboolean show_visual_notifications;
2028 source = modest_mail_operation_get_source (self);
2029 show_visual_notifications = (source) ? FALSE : TRUE;
2031 g_object_unref (source);
2033 /* Notify new messages have been downloaded. If the
2034 send&receive was invoked by the user then do not show any
2035 visual notification, only play a sound and activate the LED
2036 (for the Maemo version) */
2037 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0)
2038 modest_platform_on_new_headers_received (new_headers,
2039 show_visual_notifications);
2044 retrieve_all_messages_cb (GObject *source,
2046 guint retrieve_limit)
2052 window = GTK_WINDOW (source);
2053 msg = g_strdup_printf (_("mail_nc_msg_count_limit_exceeded"),
2054 num_msgs, retrieve_limit);
2056 /* Ask the user if they want to retrieve all the messages */
2058 modest_platform_run_confirmation_dialog_with_buttons (window, msg,
2059 _("mcen_bd_get_all"),
2060 _("mcen_bd_newest_only"));
2061 /* Free and return */
2063 return (response == GTK_RESPONSE_ACCEPT) ? TRUE : FALSE;
2067 TnyAccount *account;
2069 gchar *account_name;
2070 gboolean poke_status;
2071 gboolean interactive;
2072 ModestMailOperation *mail_op;
2076 do_send_receive_performer (gboolean canceled,
2078 GtkWindow *parent_window,
2079 TnyAccount *account,
2082 SendReceiveInfo *info;
2084 info = (SendReceiveInfo *) user_data;
2086 if (err || canceled) {
2087 /* In memory full conditions we could get this error here */
2088 check_memory_full_error ((GtkWidget *) parent_window, err);
2090 if (info->mail_op) {
2091 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2097 /* Set send/receive operation in progress */
2098 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2099 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2102 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2103 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2104 G_CALLBACK (on_send_receive_finished),
2107 /* Send & receive. */
2108 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2109 (info->win) ? retrieve_all_messages_cb : NULL,
2110 new_messages_arrived, info->win);
2115 g_object_unref (G_OBJECT (info->mail_op));
2116 if (info->account_name)
2117 g_free (info->account_name);
2119 g_object_unref (info->win);
2121 g_object_unref (info->account);
2122 g_slice_free (SendReceiveInfo, info);
2126 * This function performs the send & receive required actions. The
2127 * window is used to create the mail operation. Typically it should
2128 * always be the main window, but we pass it as argument in order to
2132 modest_ui_actions_do_send_receive (const gchar *account_name,
2133 gboolean force_connection,
2134 gboolean poke_status,
2135 gboolean interactive,
2138 gchar *acc_name = NULL;
2139 SendReceiveInfo *info;
2140 ModestTnyAccountStore *acc_store;
2142 /* If no account name was provided then get the current account, and if
2143 there is no current account then pick the default one: */
2144 if (!account_name) {
2146 acc_name = g_strdup (modest_window_get_active_account (win));
2148 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2150 g_printerr ("modest: cannot get default account\n");
2154 acc_name = g_strdup (account_name);
2157 acc_store = modest_runtime_get_account_store ();
2159 /* Create the info for the connect and perform */
2160 info = g_slice_new (SendReceiveInfo);
2161 info->account_name = acc_name;
2162 info->win = (win) ? g_object_ref (win) : NULL;
2163 info->poke_status = poke_status;
2164 info->interactive = interactive;
2165 info->account = modest_tny_account_store_get_server_account (acc_store, acc_name,
2166 TNY_ACCOUNT_TYPE_STORE);
2167 /* We need to create the operation here, because otherwise it
2168 could happen that the queue emits the queue-empty signal
2169 while we're trying to connect the account */
2170 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2171 modest_ui_actions_disk_operations_error_handler,
2173 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2175 /* Invoke the connect and perform */
2176 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2177 force_connection, info->account,
2178 do_send_receive_performer, info);
2183 modest_ui_actions_do_cancel_send (const gchar *account_name,
2186 TnyTransportAccount *transport_account;
2187 TnySendQueue *send_queue = NULL;
2188 GError *error = NULL;
2190 /* Get transport account */
2192 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2193 (modest_runtime_get_account_store(),
2195 TNY_ACCOUNT_TYPE_TRANSPORT));
2196 if (!transport_account) {
2197 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2202 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2203 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2204 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2205 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2206 "modest: could not find send queue for account\n");
2208 /* Cancel the current send */
2209 tny_account_cancel (TNY_ACCOUNT (transport_account));
2211 /* Suspend all pending messages */
2212 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2216 if (transport_account != NULL)
2217 g_object_unref (G_OBJECT (transport_account));
2221 modest_ui_actions_cancel_send_all (ModestWindow *win)
2223 GSList *account_names, *iter;
2225 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2228 iter = account_names;
2230 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2231 iter = g_slist_next (iter);
2234 modest_account_mgr_free_account_names (account_names);
2235 account_names = NULL;
2239 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2242 /* Check if accounts exist */
2243 gboolean accounts_exist =
2244 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2246 /* If not, allow the user to create an account before trying to send/receive. */
2247 if (!accounts_exist)
2248 modest_ui_actions_on_accounts (NULL, win);
2250 /* Cancel all sending operaitons */
2251 modest_ui_actions_cancel_send_all (win);
2255 * Refreshes all accounts. This function will be used by automatic
2259 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2260 gboolean force_connection,
2261 gboolean poke_status,
2262 gboolean interactive)
2264 GSList *account_names, *iter;
2266 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2269 iter = account_names;
2271 modest_ui_actions_do_send_receive ((const char*) iter->data,
2273 poke_status, interactive, win);
2274 iter = g_slist_next (iter);
2277 modest_account_mgr_free_account_names (account_names);
2278 account_names = NULL;
2282 * Handler of the click on Send&Receive button in the main toolbar
2285 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2287 /* Check if accounts exist */
2288 gboolean accounts_exist;
2291 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2293 /* If not, allow the user to create an account before trying to send/receive. */
2294 if (!accounts_exist)
2295 modest_ui_actions_on_accounts (NULL, win);
2297 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2298 if (MODEST_IS_MAIN_WINDOW (win)) {
2299 GtkWidget *folder_view;
2300 TnyFolderStore *folder_store;
2303 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2304 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2308 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2311 g_object_unref (folder_store);
2312 /* Refresh the active account. Force the connection if needed
2313 and poke the status of all folders */
2314 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2315 #ifdef MODEST_TOOLKIT_HILDON2
2316 } else if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2317 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2320 const gchar *active_account;
2321 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2323 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2330 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2333 GtkWidget *header_view;
2335 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2337 header_view = modest_main_window_get_child_widget (main_window,
2338 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2342 conf = modest_runtime_get_conf ();
2344 /* what is saved/restored is depending on the style; thus; we save with
2345 * old style, then update the style, and restore for this new style
2347 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2349 if (modest_header_view_get_style
2350 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2351 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2352 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2354 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2355 MODEST_HEADER_VIEW_STYLE_DETAILS);
2357 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2358 MODEST_CONF_HEADER_VIEW_KEY);
2363 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2365 ModestMainWindow *main_window)
2367 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2368 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2370 /* in the case the folder is empty, show the empty folder message and focus
2372 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2373 if (modest_header_view_is_empty (header_view)) {
2374 TnyFolder *folder = modest_header_view_get_folder (header_view);
2375 GtkWidget *folder_view =
2376 modest_main_window_get_child_widget (main_window,
2377 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2378 if (folder != NULL) {
2379 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2380 g_object_unref (folder);
2382 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2386 /* If no header has been selected then exit */
2391 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2392 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2394 /* Update toolbar dimming state */
2395 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2396 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2400 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2403 ModestWindow *window)
2405 GtkWidget *open_widget;
2406 GtkTreeRowReference *rowref;
2408 g_return_if_fail (MODEST_IS_WINDOW(window));
2409 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2410 g_return_if_fail (TNY_IS_HEADER (header));
2412 if (modest_header_view_count_selected_headers (header_view) > 1) {
2413 /* Don't allow activation if there are more than one message selected */
2414 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2418 /* we check for low-mem; in that case, show a warning, and don't allow
2419 * activating headers
2421 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2424 if (MODEST_IS_MAIN_WINDOW (window)) {
2425 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
2426 open_widget = modest_window_get_action_widget (MODEST_WINDOW (window), "/MenuBar/EmailMenu/EmailOpenMenu");
2427 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2431 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2432 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2433 gtk_tree_row_reference_free (rowref);
2437 set_active_account_from_tny_account (TnyAccount *account,
2438 ModestWindow *window)
2440 const gchar *server_acc_name = tny_account_get_id (account);
2442 /* We need the TnyAccount provided by the
2443 account store because that is the one that
2444 knows the name of the Modest account */
2445 TnyAccount *modest_server_account = modest_server_account =
2446 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2447 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2449 if (!modest_server_account) {
2450 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2454 /* Update active account, but only if it's not a pseudo-account */
2455 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2456 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2457 const gchar *modest_acc_name =
2458 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2459 if (modest_acc_name)
2460 modest_window_set_active_account (window, modest_acc_name);
2463 g_object_unref (modest_server_account);
2468 folder_refreshed_cb (ModestMailOperation *mail_op,
2472 ModestMainWindow *win = NULL;
2473 GtkWidget *folder_view;
2474 const GError *error;
2476 g_return_if_fail (TNY_IS_FOLDER (folder));
2478 win = MODEST_MAIN_WINDOW (user_data);
2480 /* Check if the operation failed due to memory low conditions */
2481 error = modest_mail_operation_get_error (mail_op);
2482 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2483 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2484 modest_platform_run_information_dialog (GTK_WINDOW (win),
2485 _KR("memr_ib_operation_disabled"),
2491 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2494 TnyFolderStore *current_folder;
2496 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2497 if (current_folder) {
2498 gboolean different = ((TnyFolderStore *) folder != current_folder);
2499 g_object_unref (current_folder);
2505 /* Check if folder is empty and set headers view contents style */
2506 if (tny_folder_get_all_count (folder) == 0)
2507 modest_main_window_set_contents_style (win,
2508 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2513 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2514 TnyFolderStore *folder_store,
2516 ModestMainWindow *main_window)
2519 GtkWidget *header_view;
2521 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2523 header_view = modest_main_window_get_child_widget(main_window,
2524 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2528 conf = modest_runtime_get_conf ();
2530 if (TNY_IS_ACCOUNT (folder_store)) {
2532 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2534 /* Show account details */
2535 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2538 if (TNY_IS_FOLDER (folder_store) && selected) {
2539 TnyAccount *account;
2540 const gchar *account_name = NULL;
2542 /* Update the active account */
2543 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2545 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2547 modest_tny_account_get_parent_modest_account_name_for_server_account (account);
2548 g_object_unref (account);
2552 /* Set the header style by default, it could
2553 be changed later by the refresh callback to
2555 modest_main_window_set_contents_style (main_window,
2556 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2558 /* Set folder on header view. This function
2559 will call tny_folder_refresh_async so we
2560 pass a callback that will be called when
2561 finished. We use that callback to set the
2562 empty view if there are no messages */
2563 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2564 TNY_FOLDER (folder_store),
2566 MODEST_WINDOW (main_window),
2567 folder_refreshed_cb,
2570 /* Restore configuration. We need to do this
2571 *after* the set_folder because the widget
2572 memory asks the header view about its
2574 modest_widget_memory_restore (modest_runtime_get_conf (),
2575 G_OBJECT(header_view),
2576 MODEST_CONF_HEADER_VIEW_KEY);
2578 /* No need to save the header view
2579 configuration for Maemo because it only
2580 saves the sorting stuff and that it's
2581 already being done by the sort
2582 dialog. Remove it when the GNOME version
2583 has the same behaviour */
2584 #ifdef MODEST_TOOLKIT_GTK
2585 if (modest_main_window_get_contents_style (main_window) ==
2586 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2587 modest_widget_memory_save (conf, G_OBJECT (header_view),
2588 MODEST_CONF_HEADER_VIEW_KEY);
2590 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2594 /* Update dimming state */
2595 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2596 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2600 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2607 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2609 online = tny_device_is_online (modest_runtime_get_device());
2612 /* already online -- the item is simply not there... */
2613 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2615 GTK_MESSAGE_WARNING,
2617 _("The %s you selected cannot be found"),
2619 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2620 gtk_dialog_run (GTK_DIALOG(dialog));
2622 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2625 _("mcen_bd_dialog_cancel"),
2626 GTK_RESPONSE_REJECT,
2627 _("mcen_bd_dialog_ok"),
2628 GTK_RESPONSE_ACCEPT,
2630 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2631 "Do you want to get online?"), item);
2632 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2633 gtk_label_new (txt), FALSE, FALSE, 0);
2634 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2637 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2638 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2639 /* TODO: Comment about why is this commented out: */
2640 /* modest_platform_connect_and_wait (); */
2643 gtk_widget_destroy (dialog);
2647 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2650 /* g_message ("%s %s", __FUNCTION__, link); */
2655 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2658 modest_platform_activate_uri (link);
2662 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2665 modest_platform_show_uri_popup (link);
2669 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2672 /* we check for low-mem; in that case, show a warning, and don't allow
2673 * viewing attachments
2675 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2678 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2682 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2683 const gchar *address,
2686 /* g_message ("%s %s", __FUNCTION__, address); */
2690 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2691 TnyMsg *saved_draft,
2694 ModestMsgEditWindow *edit_window;
2696 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2697 #ifndef MODEST_TOOLKIT_HILDON2
2698 ModestMainWindow *win;
2700 /* FIXME. Make the header view sensitive again. This is a
2701 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2703 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2704 modest_runtime_get_window_mgr(), FALSE));
2706 GtkWidget *hdrview = modest_main_window_get_child_widget(
2707 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2708 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2712 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2714 /* Set draft is there was no error */
2715 if (!modest_mail_operation_get_error (mail_op))
2716 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2718 g_object_unref(edit_window);
2722 enough_space_for_message (ModestMsgEditWindow *edit_window,
2725 TnyAccountStore *acc_store;
2726 guint64 available_disk, expected_size;
2731 acc_store = TNY_ACCOUNT_STORE (modest_runtime_get_account_store());
2732 available_disk = modest_utils_get_available_space (NULL);
2733 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2734 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2739 /* Double check: memory full condition or message too big */
2740 if (available_disk < MIN_FREE_SPACE ||
2741 expected_size > available_disk) {
2743 modest_platform_information_banner (NULL, NULL,
2744 _KR("cerm_device_memory_full"));
2749 * djcb: if we're in low-memory state, we only allow for
2750 * saving messages smaller than
2751 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2752 * should still allow for sending anything critical...
2754 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2755 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2759 * djcb: we also make sure that the attachments are smaller than the max size
2760 * this is for the case where we'd try to forward a message with attachments
2761 * bigger than our max allowed size, or sending an message from drafts which
2762 * somehow got past our checks when attaching.
2764 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2765 modest_platform_run_information_dialog (
2766 GTK_WINDOW(edit_window),
2767 _KR("memr_ib_operation_disabled"),
2776 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2778 TnyTransportAccount *transport_account;
2779 ModestMailOperation *mail_operation;
2781 gchar *account_name, *from;
2782 ModestAccountMgr *account_mgr;
2783 gboolean had_error = FALSE;
2784 ModestMainWindow *win = NULL;
2786 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2788 data = modest_msg_edit_window_get_msg_data (edit_window);
2791 if (!enough_space_for_message (edit_window, data)) {
2792 modest_msg_edit_window_free_msg_data (edit_window, data);
2796 account_name = g_strdup (data->account_name);
2797 account_mgr = modest_runtime_get_account_mgr();
2799 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2801 account_name = modest_account_mgr_get_default_account (account_mgr);
2802 if (!account_name) {
2803 g_printerr ("modest: no account found\n");
2804 modest_msg_edit_window_free_msg_data (edit_window, data);
2808 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2809 account_name = g_strdup (data->account_name);
2813 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2814 (modest_runtime_get_account_store (),
2816 TNY_ACCOUNT_TYPE_TRANSPORT));
2817 if (!transport_account) {
2818 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2819 g_free (account_name);
2820 modest_msg_edit_window_free_msg_data (edit_window, data);
2823 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2825 /* Create the mail operation */
2826 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
2828 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2830 modest_mail_operation_save_to_drafts (mail_operation,
2842 data->priority_flags,
2843 on_save_to_drafts_cb,
2844 g_object_ref(edit_window));
2846 #ifdef MODEST_TOOLKIT_HILDON2
2847 /* In hildon2 we always show the information banner on saving to drafts.
2848 * It will be a system information banner in this case.
2850 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2851 modest_platform_information_banner (NULL, NULL, text);
2854 /* Use the main window as the parent of the banner, if the
2855 main window does not exist it won't be shown, if the parent
2856 window exists then it's properly shown. We don't use the
2857 editor window because it could be closed (save to drafts
2858 could happen after closing the window */
2859 win = (ModestMainWindow *)
2860 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
2862 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2863 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
2867 modest_msg_edit_window_set_modified (edit_window, FALSE);
2871 g_free (account_name);
2872 g_object_unref (G_OBJECT (transport_account));
2873 g_object_unref (G_OBJECT (mail_operation));
2875 modest_msg_edit_window_free_msg_data (edit_window, data);
2878 * If the drafts folder is selected then make the header view
2879 * insensitive while the message is being saved to drafts
2880 * (it'll be sensitive again in on_save_to_drafts_cb()). This
2881 * is not very clean but it avoids letting the drafts folder
2882 * in an inconsistent state: the user could edit the message
2883 * being saved and undesirable things would happen.
2884 * In the average case the user won't notice anything at
2885 * all. In the worst case (the user is editing a really big
2886 * file from Drafts) the header view will be insensitive
2887 * during the saving process (10 or 20 seconds, depending on
2888 * the message). Anyway this is just a quick workaround: once
2889 * we find a better solution it should be removed
2890 * See NB#65125 (commend #18) for details.
2892 if (!had_error && win != NULL) {
2893 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
2894 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
2896 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
2898 if (modest_tny_folder_is_local_folder(folder)) {
2899 TnyFolderType folder_type;
2900 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
2901 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
2902 GtkWidget *hdrview = modest_main_window_get_child_widget(
2903 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2904 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
2908 if (folder != NULL) g_object_unref(folder);
2915 /* For instance, when clicking the Send toolbar button when editing a message: */
2917 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2919 TnyTransportAccount *transport_account = NULL;
2920 gboolean had_error = FALSE;
2922 ModestAccountMgr *account_mgr;
2923 gchar *account_name;
2925 ModestMailOperation *mail_operation;
2927 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
2929 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2932 data = modest_msg_edit_window_get_msg_data (edit_window);
2935 if (!enough_space_for_message (edit_window, data)) {
2936 modest_msg_edit_window_free_msg_data (edit_window, data);
2940 account_mgr = modest_runtime_get_account_mgr();
2941 account_name = g_strdup (data->account_name);
2943 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2946 account_name = modest_account_mgr_get_default_account (account_mgr);
2948 if (!account_name) {
2949 modest_msg_edit_window_free_msg_data (edit_window, data);
2950 /* Run account setup wizard */
2951 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
2956 /* Get the currently-active transport account for this modest account: */
2957 if (strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
2959 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2960 (modest_runtime_get_account_store (),
2961 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
2964 if (!transport_account) {
2965 modest_msg_edit_window_free_msg_data (edit_window, data);
2966 /* Run account setup wizard */
2967 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2972 /* Create the mail operation */
2973 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2974 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
2975 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2977 modest_mail_operation_send_new_mail (mail_operation,
2989 data->priority_flags);
2991 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
2992 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2995 if (modest_mail_operation_get_error (mail_operation) != NULL) {
2996 const GError *error = modest_mail_operation_get_error (mail_operation);
2997 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
2998 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
2999 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3000 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3007 g_free (account_name);
3008 g_object_unref (G_OBJECT (transport_account));
3009 g_object_unref (G_OBJECT (mail_operation));
3011 modest_msg_edit_window_free_msg_data (edit_window, data);
3014 modest_msg_edit_window_set_sent (edit_window, TRUE);
3016 /* Save settings and close the window: */
3017 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
3024 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3025 ModestMsgEditWindow *window)
3027 ModestMsgEditFormatState *format_state = NULL;
3029 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3030 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3032 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3035 format_state = modest_msg_edit_window_get_format_state (window);
3036 g_return_if_fail (format_state != NULL);
3038 format_state->bold = gtk_toggle_action_get_active (action);
3039 modest_msg_edit_window_set_format_state (window, format_state);
3040 g_free (format_state);
3045 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3046 ModestMsgEditWindow *window)
3048 ModestMsgEditFormatState *format_state = NULL;
3050 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3051 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3053 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3056 format_state = modest_msg_edit_window_get_format_state (window);
3057 g_return_if_fail (format_state != NULL);
3059 format_state->italics = gtk_toggle_action_get_active (action);
3060 modest_msg_edit_window_set_format_state (window, format_state);
3061 g_free (format_state);
3066 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3067 ModestMsgEditWindow *window)
3069 ModestMsgEditFormatState *format_state = NULL;
3071 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3072 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3074 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3077 format_state = modest_msg_edit_window_get_format_state (window);
3078 g_return_if_fail (format_state != NULL);
3080 format_state->bullet = gtk_toggle_action_get_active (action);
3081 modest_msg_edit_window_set_format_state (window, format_state);
3082 g_free (format_state);
3087 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3088 GtkRadioAction *selected,
3089 ModestMsgEditWindow *window)
3091 ModestMsgEditFormatState *format_state = NULL;
3092 GtkJustification value;
3094 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3096 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3099 value = gtk_radio_action_get_current_value (selected);
3101 format_state = modest_msg_edit_window_get_format_state (window);
3102 g_return_if_fail (format_state != NULL);
3104 format_state->justification = value;
3105 modest_msg_edit_window_set_format_state (window, format_state);
3106 g_free (format_state);
3110 modest_ui_actions_on_select_editor_color (GtkAction *action,
3111 ModestMsgEditWindow *window)
3113 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3114 g_return_if_fail (GTK_IS_ACTION (action));
3116 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3119 modest_msg_edit_window_select_color (window);
3123 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3124 ModestMsgEditWindow *window)
3126 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3127 g_return_if_fail (GTK_IS_ACTION (action));
3129 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3132 modest_msg_edit_window_select_background_color (window);
3136 modest_ui_actions_on_insert_image (GObject *object,
3137 ModestMsgEditWindow *window)
3139 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3142 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3145 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3148 modest_msg_edit_window_insert_image (window);
3152 modest_ui_actions_on_attach_file (GtkAction *action,
3153 ModestMsgEditWindow *window)
3155 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3156 g_return_if_fail (GTK_IS_ACTION (action));
3158 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3161 modest_msg_edit_window_offer_attach_file (window);
3165 modest_ui_actions_on_remove_attachments (GtkAction *action,
3166 ModestMsgEditWindow *window)
3168 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3170 modest_msg_edit_window_remove_attachments (window, NULL);
3174 #ifndef MODEST_TOOLKIT_GTK
3179 TnyFolderStore *folder;
3180 } CreateFolderHelper;
3183 show_create_folder_in_timeout (gpointer data)
3185 CreateFolderHelper *helper = (CreateFolderHelper *) data;
3187 /* Remove the timeout ASAP, we can not wait until the dialog
3188 is shown because it could take a lot of time and so the
3189 timeout could be called twice or more times */
3190 g_source_remove (helper->handler);
3192 gdk_threads_enter ();
3193 do_create_folder (helper->win, helper->folder, helper->name);
3194 gdk_threads_leave ();
3196 g_object_unref (helper->win);
3197 g_object_unref (helper->folder);
3198 g_free (helper->name);
3199 g_slice_free (CreateFolderHelper, helper);
3206 do_create_folder_cb (ModestMailOperation *mail_op,
3207 TnyFolderStore *parent_folder,
3208 TnyFolder *new_folder,
3211 gchar *suggested_name = (gchar *) user_data;
3212 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3214 if (modest_mail_operation_get_error (mail_op)) {
3216 /* Show an error. If there was some problem writing to
3217 disk, show it, otherwise show the generic folder
3218 create error. We do it here and not in an error
3219 handler because the call to do_create_folder will
3220 stop the main loop in a gtk_dialog_run and then,
3221 the message won't be shown until that dialog is
3223 modest_ui_actions_disk_operations_error_handler (mail_op,
3224 _("mail_in_ui_folder_create_error"));
3226 /* Try again. Do *NOT* show any error because the mail
3227 operations system will do it for us because we
3228 created the mail_op with new_with_error_handler */
3229 #ifndef MODEST_TOOLKIT_GTK
3230 CreateFolderHelper *helper;
3231 helper = g_slice_new0 (CreateFolderHelper);
3232 helper->name = g_strdup (suggested_name);
3233 helper->folder = g_object_ref (parent_folder);
3234 helper->win = g_object_ref (source_win);
3236 /* Ugly but neccesary stuff. The problem is that the
3237 dialog when is shown calls a function that destroys
3238 all the temporary windows, so the banner is
3240 helper->handler = g_timeout_add (2000, show_create_folder_in_timeout, helper);
3242 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3245 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3246 * FIXME: any other? */
3247 GtkWidget *folder_view;
3249 if (MODEST_IS_MAIN_WINDOW(source_win))
3251 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3252 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3254 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3255 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3257 /* Select the newly created folder. It could happen
3258 that the widget is no longer there (i.e. the window
3259 has been destroyed, so we need to check this */
3261 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3263 g_object_unref (new_folder);
3265 /* Free. Note that the first time it'll be NULL so noop */
3266 g_free (suggested_name);
3267 g_object_unref (source_win);
3271 do_create_folder (GtkWindow *parent_window,
3272 TnyFolderStore *suggested_parent,
3273 const gchar *suggested_name)
3276 gchar *folder_name = NULL;
3277 TnyFolderStore *parent_folder = NULL;
3279 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3281 (gchar *) suggested_name,
3285 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3286 ModestMailOperation *mail_op;
3288 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3289 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3291 modest_mail_operation_create_folder (mail_op,
3293 (const gchar *) folder_name,
3294 do_create_folder_cb,
3296 g_object_unref (mail_op);
3300 g_object_unref (parent_folder);
3304 create_folder_performer (gboolean canceled,
3306 GtkWindow *parent_window,
3307 TnyAccount *account,
3310 TnyFolderStore *parent_folder = TNY_FOLDER_STORE (user_data);
3312 if (canceled || err) {
3313 /* In memory full conditions we could get this error here */
3314 check_memory_full_error ((GtkWidget *) parent_window, err);
3318 /* Run the new folder dialog */
3319 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3322 g_object_unref (parent_folder);
3326 modest_ui_actions_create_folder(GtkWidget *parent_window,
3327 GtkWidget *folder_view)
3329 TnyFolderStore *parent_folder;
3331 #ifdef MODEST_TOOLKIT_HILDON2
3332 const gchar *active_account;
3333 TnyAccount *account;
3334 ModestTnyAccountStore *acc_store;
3336 /* In hildon 2.2 we use the current account as default parent */
3337 acc_store = modest_runtime_get_account_store ();
3338 active_account = modest_window_get_active_account (MODEST_WINDOW (parent_window));
3339 if (active_account) {
3340 account = modest_tny_account_store_get_server_account (acc_store,
3342 TNY_ACCOUNT_TYPE_STORE);
3343 parent_folder = TNY_FOLDER_STORE (account);
3345 parent_folder = (TnyFolderStore *)
3346 modest_tny_account_store_get_local_folders_account (acc_store);
3349 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3352 if (parent_folder) {
3353 /* The parent folder will be freed in the callback */
3354 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3357 create_folder_performer,
3363 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3366 g_return_if_fail (MODEST_IS_WINDOW(window));
3368 if (MODEST_IS_MAIN_WINDOW (window)) {
3369 GtkWidget *folder_view;
3371 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3372 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3376 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view);
3377 #ifdef MODEST_TOOLKIT_HILDON2
3378 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3379 GtkWidget *folder_view;
3381 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3382 modest_ui_actions_create_folder (GTK_WIDGET (window), folder_view);
3385 g_assert_not_reached ();
3390 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3393 const GError *error = NULL;
3394 const gchar *message = NULL;
3396 /* Get error message */
3397 error = modest_mail_operation_get_error (mail_op);
3399 g_return_if_reached ();
3401 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3402 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3403 message = _CS("ckdg_ib_folder_already_exists");
3404 } else if (error->domain == TNY_ERROR_DOMAIN &&
3405 error->code == TNY_SERVICE_ERROR_STATE) {
3406 /* This means that the folder is already in use (a
3407 message is opened for example */
3408 message = _("emev_ni_internal_error");
3410 message = _("emev_ib_ui_imap_unable_to_rename");
3413 /* We don't set a parent for the dialog because the dialog
3414 will be destroyed so the banner won't appear */
3415 modest_platform_information_banner (NULL, NULL, message);
3419 TnyFolderStore *folder;
3424 on_rename_folder_cb (ModestMailOperation *mail_op,
3425 TnyFolder *new_folder,
3428 ModestFolderView *folder_view;
3430 /* If the window was closed when renaming a folder, or if
3431 * it's not a main window this will happen */
3432 if (!MODEST_IS_FOLDER_VIEW (user_data))
3435 folder_view = MODEST_FOLDER_VIEW (user_data);
3436 /* Note that if the rename fails new_folder will be NULL */
3438 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3440 modest_folder_view_select_first_inbox_or_local (folder_view);
3442 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3446 on_rename_folder_performer (gboolean canceled,
3448 GtkWindow *parent_window,
3449 TnyAccount *account,
3452 ModestMailOperation *mail_op = NULL;
3453 GtkTreeSelection *sel = NULL;
3454 GtkWidget *folder_view = NULL;
3455 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3457 if (canceled || err) {
3458 /* In memory full conditions we could get this error here */
3459 check_memory_full_error ((GtkWidget *) parent_window, err);
3463 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3464 modest_ui_actions_rename_folder_error_handler,
3465 parent_window, NULL);
3467 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3470 if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3472 folder_view = modest_main_window_get_child_widget (
3473 MODEST_MAIN_WINDOW (parent_window),
3474 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3476 /* Clear the headers view */
3477 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3478 gtk_tree_selection_unselect_all (sel);
3483 /* Actually rename the folder */
3484 modest_mail_operation_rename_folder (mail_op,
3485 TNY_FOLDER (data->folder),
3486 (const gchar *) (data->new_name),
3487 on_rename_folder_cb,
3489 g_object_unref (data->folder);
3490 g_object_unref (mail_op);
3493 g_free (data->new_name);
3498 modest_ui_actions_on_rename_folder (GtkAction *action,
3499 ModestWindow *window)
3501 modest_ui_actions_on_edit_mode_rename_folder (window);
3505 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3507 TnyFolderStore *folder;
3508 GtkWidget *folder_view;
3509 gboolean do_rename = TRUE;
3511 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3513 if (MODEST_IS_MAIN_WINDOW (window)) {
3514 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3515 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3519 #ifdef MODEST_TOOLKIT_HILDON2
3520 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3521 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3527 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3532 if (TNY_IS_FOLDER (folder)) {
3533 gchar *folder_name = NULL;
3535 const gchar *current_name;
3536 TnyFolderStore *parent;
3538 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3539 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3540 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (window),
3541 parent, current_name,
3543 g_object_unref (parent);
3545 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3548 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3549 rename_folder_data->folder = g_object_ref (folder);
3550 rename_folder_data->new_name = folder_name;
3551 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(window), TRUE,
3552 folder, on_rename_folder_performer, rename_folder_data);
3555 g_object_unref (folder);
3560 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3563 GObject *win = modest_mail_operation_get_source (mail_op);
3565 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3566 _("mail_in_ui_folder_delete_error"),
3568 g_object_unref (win);
3572 TnyFolderStore *folder;
3573 gboolean move_to_trash;
3577 on_delete_folder_cb (gboolean canceled,
3579 GtkWindow *parent_window,
3580 TnyAccount *account,
3583 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3584 GtkWidget *folder_view;
3585 ModestMailOperation *mail_op;
3586 GtkTreeSelection *sel;
3588 if (!MODEST_IS_WINDOW(parent_window) || canceled || (err!=NULL)) {
3589 g_object_unref (G_OBJECT (info->folder));
3594 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
3595 folder_view = modest_main_window_get_child_widget (
3596 MODEST_MAIN_WINDOW (parent_window),
3597 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3598 #ifdef MODEST_TOOLKIT_HILDON2
3599 } else if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3600 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (parent_window)));
3603 g_object_unref (G_OBJECT (info->folder));
3608 /* Unselect the folder before deleting it to free the headers */
3609 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3610 gtk_tree_selection_unselect_all (sel);
3612 /* Create the mail operation */
3614 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3615 modest_ui_actions_delete_folder_error_handler,
3618 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3620 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3622 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3624 g_object_unref (G_OBJECT (mail_op));
3625 g_object_unref (G_OBJECT (info->folder));
3630 delete_folder (ModestWindow *window, gboolean move_to_trash)
3632 TnyFolderStore *folder;
3633 GtkWidget *folder_view;
3637 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3639 if (MODEST_IS_MAIN_WINDOW (window)) {
3641 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3642 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3643 #ifdef MODEST_TOOLKIT_HILDON2
3644 } else if (MODEST_IS_FOLDER_WINDOW (window)) {
3645 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3653 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3655 /* Show an error if it's an account */
3656 if (!TNY_IS_FOLDER (folder)) {
3657 modest_platform_run_information_dialog (GTK_WINDOW (window),
3658 _("mail_in_ui_folder_delete_error"),
3660 g_object_unref (G_OBJECT (folder));
3665 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3666 tny_folder_get_name (TNY_FOLDER (folder)));
3667 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (window),
3668 (const gchar *) message);
3671 if (response == GTK_RESPONSE_OK) {
3672 DeleteFolderInfo *info;
3673 info = g_new0(DeleteFolderInfo, 1);
3674 info->folder = folder;
3675 info->move_to_trash = move_to_trash;
3676 g_object_ref (G_OBJECT (info->folder));
3677 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder));
3678 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (window),
3680 TNY_FOLDER_STORE (account),
3681 on_delete_folder_cb, info);
3682 g_object_unref (account);
3687 g_object_unref (G_OBJECT (folder));
3691 modest_ui_actions_on_delete_folder (GtkAction *action,
3692 ModestWindow *window)
3694 modest_ui_actions_on_edit_mode_delete_folder (window);
3698 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
3700 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
3702 return delete_folder (window, FALSE);
3706 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3708 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3710 delete_folder (MODEST_WINDOW (main_window), TRUE);
3714 typedef struct _PasswordDialogFields {
3715 GtkWidget *username;
3716 GtkWidget *password;
3718 } PasswordDialogFields;
3721 password_dialog_check_field (GtkEditable *editable,
3722 PasswordDialogFields *fields)
3725 gboolean any_value_empty = FALSE;
3727 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
3728 if ((value == NULL) || value[0] == '\0') {
3729 any_value_empty = TRUE;
3731 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
3732 if ((value == NULL) || value[0] == '\0') {
3733 any_value_empty = TRUE;
3735 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3739 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3740 const gchar* server_account_name,
3745 ModestMainWindow *main_window)
3747 g_return_if_fail(server_account_name);
3748 gboolean completed = FALSE;
3749 PasswordDialogFields *fields = NULL;
3751 /* Initalize output parameters: */
3758 #ifndef MODEST_TOOLKIT_GTK
3759 /* Maemo uses a different (awkward) button order,
3760 * It should probably just use gtk_alternative_dialog_button_order ().
3762 #ifdef MODEST_TOOLKIT_HILDON2
3764 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3767 _HL("wdgt_bd_done"),
3768 GTK_RESPONSE_ACCEPT,
3772 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3775 _("mcen_bd_dialog_ok"),
3776 GTK_RESPONSE_ACCEPT,
3777 _("mcen_bd_dialog_cancel"),
3778 GTK_RESPONSE_REJECT,
3780 #endif /* MODEST_TOOLKIT_HILDON2 */
3783 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3787 GTK_RESPONSE_REJECT,
3789 GTK_RESPONSE_ACCEPT,
3791 #endif /* MODEST_TOOLKIT_GTK */
3793 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3795 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3796 modest_runtime_get_account_mgr(), server_account_name);
3797 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3798 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3801 gtk_widget_destroy (dialog);
3805 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3806 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
3809 g_free (server_name);
3813 gchar *initial_username = modest_account_mgr_get_server_account_username (
3814 modest_runtime_get_account_mgr(), server_account_name);
3816 GtkWidget *entry_username = gtk_entry_new ();
3817 if (initial_username)
3818 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
3819 /* Dim this if a connection has ever succeeded with this username,
3820 * as per the UI spec: */
3821 /* const gboolean username_known = */
3822 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3823 /* modest_runtime_get_account_mgr(), server_account_name); */
3824 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3826 /* We drop the username sensitive code and disallow changing it here
3827 * as tinymail does not support really changing the username in the callback
3829 gtk_widget_set_sensitive (entry_username, FALSE);
3831 #ifndef MODEST_TOOLKIT_GTK
3832 /* Auto-capitalization is the default, so let's turn it off: */
3833 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3835 /* Create a size group to be used by all captions.
3836 * Note that HildonCaption does not create a default size group if we do not specify one.
3837 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3838 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3840 GtkWidget *caption = hildon_caption_new (sizegroup,
3841 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
3842 gtk_widget_show (entry_username);
3843 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3844 FALSE, FALSE, MODEST_MARGIN_HALF);
3845 gtk_widget_show (caption);
3847 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
3849 #endif /* !MODEST_TOOLKIT_GTK */
3852 GtkWidget *entry_password = gtk_entry_new ();
3853 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3854 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3856 #ifndef MODEST_TOOLKIT_GTK
3857 /* Auto-capitalization is the default, so let's turn it off: */
3858 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3859 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3861 caption = hildon_caption_new (sizegroup,
3862 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
3863 gtk_widget_show (entry_password);
3864 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3865 FALSE, FALSE, MODEST_MARGIN_HALF);
3866 gtk_widget_show (caption);
3867 g_object_unref (sizegroup);
3869 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
3871 #endif /* !MODEST_TOOLKIT_GTK */
3873 if (initial_username != NULL)
3874 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3876 /* This is not in the Maemo UI spec:
3877 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3878 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3882 fields = g_slice_new0 (PasswordDialogFields);
3883 fields->username = entry_username;
3884 fields->password = entry_password;
3885 fields->dialog = dialog;
3887 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3888 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3889 password_dialog_check_field (NULL, fields);
3891 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3893 while (!completed) {
3895 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3897 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
3899 /* Note that an empty field becomes the "" string */
3900 if (*username && strlen (*username) > 0) {
3901 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
3902 server_account_name,
3906 const gboolean username_was_changed =
3907 (strcmp (*username, initial_username) != 0);
3908 if (username_was_changed) {
3909 g_warning ("%s: tinymail does not yet support changing the "
3910 "username in the get_password() callback.\n", __FUNCTION__);
3916 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
3917 _("mcen_ib_username_pw_incorrect"));
3923 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
3925 /* We do not save the password in the configuration,
3926 * because this function is only called for passwords that should
3927 * not be remembered:
3928 modest_server_account_set_password (
3929 modest_runtime_get_account_mgr(), server_account_name,
3936 #ifndef MODEST_TOOLKIT_HILDON2
3937 /* Set parent to NULL or the banner will disappear with its parent dialog */
3938 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
3950 /* This is not in the Maemo UI spec:
3951 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3957 g_free (initial_username);
3958 gtk_widget_destroy (dialog);
3959 g_slice_free (PasswordDialogFields, fields);
3961 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3965 modest_ui_actions_on_cut (GtkAction *action,
3966 ModestWindow *window)
3968 GtkWidget *focused_widget;
3969 GtkClipboard *clipboard;
3971 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3972 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3973 if (GTK_IS_EDITABLE (focused_widget)) {
3974 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3975 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3976 gtk_clipboard_store (clipboard);
3977 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3978 GtkTextBuffer *buffer;
3980 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3981 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3982 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3983 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3984 gtk_clipboard_store (clipboard);
3986 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3987 TnyList *header_list = modest_header_view_get_selected_headers (
3988 MODEST_HEADER_VIEW (focused_widget));
3989 gboolean continue_download = FALSE;
3990 gint num_of_unc_msgs;
3992 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3994 if (num_of_unc_msgs) {
3995 TnyAccount *account = get_account_from_header_list (header_list);
3997 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3998 g_object_unref (account);
4002 if (num_of_unc_msgs == 0 || continue_download) {
4003 /* modest_platform_information_banner (
4004 NULL, NULL, _CS("mcen_ib_getting_items"));*/
4005 modest_header_view_cut_selection (
4006 MODEST_HEADER_VIEW (focused_widget));
4009 g_object_unref (header_list);
4010 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4011 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4016 modest_ui_actions_on_copy (GtkAction *action,
4017 ModestWindow *window)
4019 GtkClipboard *clipboard;
4020 GtkWidget *focused_widget;
4021 gboolean copied = TRUE;
4023 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4024 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4026 if (GTK_IS_LABEL (focused_widget)) {
4028 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4029 gtk_clipboard_set_text (clipboard, selection, -1);
4031 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4032 gtk_clipboard_store (clipboard);
4033 } else if (GTK_IS_EDITABLE (focused_widget)) {
4034 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4035 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4036 gtk_clipboard_store (clipboard);
4037 } else if (GTK_IS_HTML (focused_widget)) {
4040 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4041 if ((sel == NULL) || (sel[0] == '\0')) {
4044 gtk_html_copy (GTK_HTML (focused_widget));
4045 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4046 gtk_clipboard_store (clipboard);
4048 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4049 GtkTextBuffer *buffer;
4050 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4051 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4052 gtk_text_buffer_copy_clipboard (buffer, clipboard);
4053 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4054 gtk_clipboard_store (clipboard);
4056 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4057 TnyList *header_list = modest_header_view_get_selected_headers (
4058 MODEST_HEADER_VIEW (focused_widget));
4059 gboolean continue_download = FALSE;
4060 gint num_of_unc_msgs;
4062 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4064 if (num_of_unc_msgs) {
4065 TnyAccount *account = get_account_from_header_list (header_list);
4067 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4068 g_object_unref (account);
4072 if (num_of_unc_msgs == 0 || continue_download) {
4073 modest_platform_information_banner (
4074 NULL, NULL, _CS("mcen_ib_getting_items"));
4075 modest_header_view_copy_selection (
4076 MODEST_HEADER_VIEW (focused_widget));
4080 g_object_unref (header_list);
4082 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4083 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4086 /* Show information banner if there was a copy to clipboard */
4088 modest_platform_information_banner (
4089 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
4093 modest_ui_actions_on_undo (GtkAction *action,
4094 ModestWindow *window)
4096 ModestEmailClipboard *clipboard = NULL;
4098 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4099 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4100 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4101 /* Clear clipboard source */
4102 clipboard = modest_runtime_get_email_clipboard ();
4103 modest_email_clipboard_clear (clipboard);
4106 g_return_if_reached ();
4111 modest_ui_actions_on_redo (GtkAction *action,
4112 ModestWindow *window)
4114 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4115 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4118 g_return_if_reached ();
4124 destroy_information_note (ModestMailOperation *mail_op,
4127 /* destroy information note */
4128 gtk_widget_destroy (GTK_WIDGET(user_data));
4132 destroy_folder_information_note (ModestMailOperation *mail_op,
4133 TnyFolder *new_folder,
4136 /* destroy information note */
4137 gtk_widget_destroy (GTK_WIDGET(user_data));
4142 paste_as_attachment_free (gpointer data)
4144 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4146 if (helper->banner) {
4147 gtk_widget_destroy (helper->banner);
4148 g_object_unref (helper->banner);
4154 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4159 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4160 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4165 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4170 modest_ui_actions_on_paste (GtkAction *action,
4171 ModestWindow *window)
4173 GtkWidget *focused_widget = NULL;
4174 GtkWidget *inf_note = NULL;
4175 ModestMailOperation *mail_op = NULL;
4177 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4178 if (GTK_IS_EDITABLE (focused_widget)) {
4179 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4180 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4181 ModestEmailClipboard *e_clipboard = NULL;
4182 e_clipboard = modest_runtime_get_email_clipboard ();
4183 if (modest_email_clipboard_cleared (e_clipboard)) {
4184 GtkTextBuffer *buffer;
4185 GtkClipboard *clipboard;
4187 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4188 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4189 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4190 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4191 ModestMailOperation *mail_op;
4192 TnyFolder *src_folder = NULL;
4193 TnyList *data = NULL;
4195 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4196 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4197 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4198 _CS("ckct_nw_pasting"));
4199 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4200 mail_op = modest_mail_operation_new (G_OBJECT (window));
4201 if (helper->banner != NULL) {
4202 g_object_ref (G_OBJECT (helper->banner));
4203 gtk_widget_show (GTK_WIDGET (helper->banner));
4207 modest_mail_operation_get_msgs_full (mail_op,
4209 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4211 paste_as_attachment_free);
4215 g_object_unref (data);
4217 g_object_unref (src_folder);
4220 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4221 ModestEmailClipboard *clipboard = NULL;
4222 TnyFolder *src_folder = NULL;
4223 TnyFolderStore *folder_store = NULL;
4224 TnyList *data = NULL;
4225 gboolean delete = FALSE;
4227 /* Check clipboard source */
4228 clipboard = modest_runtime_get_email_clipboard ();
4229 if (modest_email_clipboard_cleared (clipboard))
4232 /* Get elements to paste */
4233 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4235 /* Create a new mail operation */
4236 mail_op = modest_mail_operation_new (G_OBJECT(window));
4238 /* Get destination folder */
4239 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4241 /* transfer messages */
4245 /* Ask for user confirmation */
4247 modest_ui_actions_msgs_move_to_confirmation (window,
4248 TNY_FOLDER (folder_store),
4252 if (response == GTK_RESPONSE_OK) {
4253 /* Launch notification */
4254 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4255 _CS("ckct_nw_pasting"));
4256 if (inf_note != NULL) {
4257 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4258 gtk_widget_show (GTK_WIDGET(inf_note));
4261 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4262 modest_mail_operation_xfer_msgs (mail_op,
4264 TNY_FOLDER (folder_store),
4266 destroy_information_note,
4269 g_object_unref (mail_op);
4272 } else if (src_folder != NULL) {
4273 /* Launch notification */
4274 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4275 _CS("ckct_nw_pasting"));
4276 if (inf_note != NULL) {
4277 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4278 gtk_widget_show (GTK_WIDGET(inf_note));
4281 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4282 modest_mail_operation_xfer_folder (mail_op,
4286 destroy_folder_information_note,
4292 g_object_unref (data);
4293 if (src_folder != NULL)
4294 g_object_unref (src_folder);
4295 if (folder_store != NULL)
4296 g_object_unref (folder_store);
4302 modest_ui_actions_on_select_all (GtkAction *action,
4303 ModestWindow *window)
4305 GtkWidget *focused_widget;
4307 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4308 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4309 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4310 } else if (GTK_IS_LABEL (focused_widget)) {
4311 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4312 } else if (GTK_IS_EDITABLE (focused_widget)) {
4313 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4314 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4315 GtkTextBuffer *buffer;
4316 GtkTextIter start, end;
4318 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4319 gtk_text_buffer_get_start_iter (buffer, &start);
4320 gtk_text_buffer_get_end_iter (buffer, &end);
4321 gtk_text_buffer_select_range (buffer, &start, &end);
4322 } else if (GTK_IS_HTML (focused_widget)) {
4323 gtk_html_select_all (GTK_HTML (focused_widget));
4324 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4325 GtkWidget *header_view = focused_widget;
4326 GtkTreeSelection *selection = NULL;
4328 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4329 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4330 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4333 /* Disable window dimming management */
4334 modest_window_disable_dimming (MODEST_WINDOW(window));
4336 /* Select all messages */
4337 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4338 gtk_tree_selection_select_all (selection);
4340 /* Set focuse on header view */
4341 gtk_widget_grab_focus (header_view);
4343 /* Enable window dimming management */
4344 modest_window_enable_dimming (MODEST_WINDOW(window));
4345 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4346 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4352 modest_ui_actions_on_mark_as_read (GtkAction *action,
4353 ModestWindow *window)
4355 g_return_if_fail (MODEST_IS_WINDOW(window));
4357 /* Mark each header as read */
4358 do_headers_action (window, headers_action_mark_as_read, NULL);
4362 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4363 ModestWindow *window)
4365 g_return_if_fail (MODEST_IS_WINDOW(window));
4367 /* Mark each header as read */
4368 do_headers_action (window, headers_action_mark_as_unread, NULL);
4372 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4373 GtkRadioAction *selected,
4374 ModestWindow *window)
4378 value = gtk_radio_action_get_current_value (selected);
4379 if (MODEST_IS_WINDOW (window)) {
4380 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4385 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4386 GtkRadioAction *selected,
4387 ModestWindow *window)
4389 TnyHeaderFlags flags;
4390 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4392 flags = gtk_radio_action_get_current_value (selected);
4393 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4397 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4398 GtkRadioAction *selected,
4399 ModestWindow *window)
4403 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4405 file_format = gtk_radio_action_get_current_value (selected);
4406 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4411 modest_ui_actions_on_zoom_plus (GtkAction *action,
4412 ModestWindow *window)
4414 g_return_if_fail (MODEST_IS_WINDOW (window));
4416 modest_window_zoom_plus (MODEST_WINDOW (window));
4420 modest_ui_actions_on_zoom_minus (GtkAction *action,
4421 ModestWindow *window)
4423 g_return_if_fail (MODEST_IS_WINDOW (window));
4425 modest_window_zoom_minus (MODEST_WINDOW (window));
4429 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4430 ModestWindow *window)
4432 ModestWindowMgr *mgr;
4433 gboolean fullscreen, active;
4434 g_return_if_fail (MODEST_IS_WINDOW (window));
4436 mgr = modest_runtime_get_window_mgr ();
4438 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4439 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4441 if (active != fullscreen) {
4442 modest_window_mgr_set_fullscreen_mode (mgr, active);
4443 #ifndef MODEST_TOOLKIT_HILDON2
4444 gtk_window_present (GTK_WINDOW (window));
4450 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4451 ModestWindow *window)
4453 ModestWindowMgr *mgr;
4454 gboolean fullscreen;
4456 g_return_if_fail (MODEST_IS_WINDOW (window));
4458 mgr = modest_runtime_get_window_mgr ();
4459 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4460 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4462 #ifndef MODEST_TOOLKIT_HILDON2
4463 gtk_window_present (GTK_WINDOW (window));
4468 * Used by modest_ui_actions_on_details to call do_headers_action
4471 headers_action_show_details (TnyHeader *header,
4472 ModestWindow *window,
4476 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header);
4480 * Show the header details in a ModestDetailsDialog widget
4483 modest_ui_actions_on_details (GtkAction *action,
4486 TnyList * headers_list;
4490 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4493 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4496 g_object_unref (msg);
4498 headers_list = get_selected_headers (win);
4502 iter = tny_list_create_iterator (headers_list);
4504 header = TNY_HEADER (tny_iterator_get_current (iter));
4506 headers_action_show_details (header, win, NULL);
4507 g_object_unref (header);
4510 g_object_unref (iter);
4511 g_object_unref (headers_list);
4513 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4514 GtkWidget *folder_view, *header_view;
4516 /* Check which widget has the focus */
4517 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4518 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4519 if (gtk_widget_is_focus (folder_view)) {
4520 TnyFolderStore *folder_store
4521 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4522 if (!folder_store) {
4523 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4526 /* Show only when it's a folder */
4527 /* This function should not be called for account items,
4528 * because we dim the menu item for them. */
4529 if (TNY_IS_FOLDER (folder_store)) {
4530 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4531 TNY_FOLDER (folder_store));
4534 g_object_unref (folder_store);
4537 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4538 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4539 /* Show details of each header */
4540 do_headers_action (win, headers_action_show_details, header_view);
4542 #ifdef MODEST_TOOLKIT_HILDON2
4543 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4545 GtkWidget *header_view;
4547 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4548 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4550 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4552 g_object_unref (folder);
4559 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4560 ModestMsgEditWindow *window)
4562 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4564 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4568 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4569 ModestMsgEditWindow *window)
4571 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4573 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4577 modest_ui_actions_toggle_folders_view (GtkAction *action,
4578 ModestMainWindow *main_window)
4580 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4582 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4583 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4585 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4589 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4590 ModestWindow *window)
4592 gboolean active, fullscreen = FALSE;
4593 ModestWindowMgr *mgr;
4595 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4597 /* Check if we want to toggle the toolbar view in fullscreen
4599 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4600 "ViewShowToolbarFullScreen")) {
4604 /* Toggle toolbar */
4605 mgr = modest_runtime_get_window_mgr ();
4606 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4610 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4611 ModestMsgEditWindow *window)
4613 modest_msg_edit_window_select_font (window);
4618 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4619 const gchar *display_name,
4622 /* don't update the display name if it was already set;
4623 * updating the display name apparently is expensive */
4624 const gchar* old_name = gtk_window_get_title (window);
4626 if (display_name == NULL)
4629 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4630 return; /* don't do anything */
4632 /* This is usually used to change the title of the main window, which
4633 * is the one that holds the folder view. Note that this change can
4634 * happen even when the widget doesn't have the focus. */
4635 gtk_window_set_title (window, display_name);
4640 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4642 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4643 modest_msg_edit_window_select_contacts (window);
4647 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4649 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4650 modest_msg_edit_window_check_names (window, FALSE);
4653 #ifndef MODEST_TOOLKIT_HILDON2
4655 * This function is used to track changes in the selection of the
4656 * folder view that is inside the "move to" dialog to enable/disable
4657 * the OK button because we do not want the user to select a disallowed
4658 * destination for a folder.
4659 * The user also not desired to be able to use NEW button on items where
4660 * folder creation is not possibel.
4663 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4664 TnyFolderStore *folder_store,
4668 GtkWidget *dialog = NULL;
4669 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4670 gboolean moving_folder = FALSE;
4671 gboolean is_local_account = TRUE;
4672 GtkWidget *folder_view = NULL;
4673 ModestTnyFolderRules rules;
4675 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
4680 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
4684 /* check if folder_store is an remote account */
4685 if (TNY_IS_ACCOUNT (folder_store)) {
4686 TnyAccount *local_account = NULL;
4687 TnyAccount *mmc_account = NULL;
4688 ModestTnyAccountStore *account_store = NULL;
4690 account_store = modest_runtime_get_account_store ();
4691 local_account = modest_tny_account_store_get_local_folders_account (account_store);
4692 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
4694 if ((gpointer) local_account != (gpointer) folder_store &&
4695 (gpointer) mmc_account != (gpointer) folder_store) {
4696 ModestProtocolType proto;
4697 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
4698 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
4699 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
4701 is_local_account = FALSE;
4702 /* New button should be dimmed on remote
4704 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4706 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
4708 g_object_unref (local_account);
4710 /* It could not exist */
4712 g_object_unref (mmc_account);
4715 /* Check the target folder rules */
4716 if (TNY_IS_FOLDER (folder_store)) {
4717 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
4718 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
4719 ok_sensitive = FALSE;
4720 new_sensitive = FALSE;
4725 /* Check if we're moving a folder */
4726 if (MODEST_IS_MAIN_WINDOW (user_data)) {
4727 /* Get the widgets */
4728 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
4729 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4730 if (gtk_widget_is_focus (folder_view))
4731 moving_folder = TRUE;
4734 if (moving_folder) {
4735 TnyFolderStore *moved_folder = NULL, *parent = NULL;
4737 /* Get the folder to move */
4738 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4740 /* Check that we're not moving to the same folder */
4741 if (TNY_IS_FOLDER (moved_folder)) {
4742 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
4743 if (parent == folder_store)
4744 ok_sensitive = FALSE;
4745 g_object_unref (parent);
4748 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
4749 /* Do not allow to move to an account unless it's the
4750 local folders account */
4751 if (!is_local_account)
4752 ok_sensitive = FALSE;
4755 if (ok_sensitive && (moved_folder == folder_store)) {
4756 /* Do not allow to move to itself */
4757 ok_sensitive = FALSE;
4759 g_object_unref (moved_folder);
4761 TnyFolder *src_folder = NULL;
4763 /* Moving a message */
4764 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
4766 TnyHeader *header = NULL;
4767 header = modest_msg_view_window_get_header
4768 (MODEST_MSG_VIEW_WINDOW (user_data));
4769 if (!TNY_IS_HEADER(header))
4770 g_warning ("%s: could not get source header", __FUNCTION__);
4772 src_folder = tny_header_get_folder (header);
4775 g_object_unref (header);
4778 TNY_FOLDER (modest_folder_view_get_selected
4779 (MODEST_FOLDER_VIEW (folder_view)));
4782 if (TNY_IS_FOLDER(src_folder)) {
4783 /* Do not allow to move the msg to the same folder */
4784 /* Do not allow to move the msg to an account */
4785 if ((gpointer) src_folder == (gpointer) folder_store ||
4786 TNY_IS_ACCOUNT (folder_store))
4787 ok_sensitive = FALSE;
4788 g_object_unref (src_folder);
4790 g_warning ("%s: could not get source folder", __FUNCTION__);
4794 /* Set sensitivity of the OK and NEW button */
4795 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, ok_sensitive);
4796 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), MODEST_GTK_RESPONSE_NEW_FOLDER, new_sensitive);
4801 on_move_to_dialog_response (GtkDialog *dialog,
4805 GtkWidget *parent_win, *folder_view;
4806 MoveToInfo *helper = NULL;
4808 helper = (MoveToInfo *) user_data;
4810 parent_win = (GtkWidget *) helper->win;
4811 folder_view = GTK_WIDGET (g_object_get_data (G_OBJECT (dialog),
4812 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4815 TnyFolderStore *dst_folder;
4817 case MODEST_GTK_RESPONSE_NEW_FOLDER:
4818 modest_ui_actions_create_folder (GTK_WIDGET (parent_win), folder_view);
4820 case GTK_RESPONSE_NONE:
4821 case GTK_RESPONSE_CANCEL:
4822 case GTK_RESPONSE_DELETE_EVENT:
4824 case GTK_RESPONSE_OK:
4825 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4826 /* Do window specific stuff */
4827 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
4828 modest_ui_actions_on_main_window_move_to (NULL,
4831 MODEST_MAIN_WINDOW (parent_win));
4832 #ifdef MODEST_TOOLKIT_HILDON2
4833 } else if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
4834 modest_ui_actions_on_folder_window_move_to (folder_view,
4837 GTK_WINDOW (parent_win));
4840 /* Moving from headers window in edit mode */
4841 modest_ui_actions_on_window_move_to (NULL, helper->list,
4843 MODEST_WINDOW (parent_win));
4847 g_object_unref (dst_folder);
4851 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
4854 /* Free the helper and exit */
4856 g_object_unref (helper->list);
4857 g_slice_free (MoveToInfo, helper);
4858 gtk_widget_destroy (GTK_WIDGET (dialog));
4862 create_move_to_dialog (GtkWindow *win,
4863 GtkWidget *folder_view)
4865 GtkWidget *dialog, *tree_view = NULL;
4867 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
4869 #ifndef MODEST_TOOLKIT_HILDON2
4870 /* Track changes in the selection to
4871 * disable the OK button whenever "Move to" is not possible
4872 * disbale NEW button whenever New is not possible */
4873 g_signal_connect (tree_view,
4874 "folder_selection_changed",
4875 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
4879 /* It could happen that we're trying to move a message from a
4880 window (msg window for example) after the main window was
4881 closed, so we can not just get the model of the folder
4883 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4884 const gchar *visible_id = NULL;
4886 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4887 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4888 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4889 MODEST_FOLDER_VIEW(tree_view));
4892 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4894 /* Show the same account than the one that is shown in the main window */
4895 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
4898 const gchar *active_account_name = NULL;
4899 ModestAccountMgr *mgr = NULL;
4900 ModestAccountSettings *settings = NULL;
4901 ModestServerAccountSettings *store_settings = NULL;
4903 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4904 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4905 modest_folder_view_update_model (MODEST_FOLDER_VIEW (tree_view),
4906 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
4908 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4909 mgr = modest_runtime_get_account_mgr ();
4910 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4913 const gchar *store_account_name;
4914 store_settings = modest_account_settings_get_store_settings (settings);
4915 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4917 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
4918 store_account_name);
4919 g_object_unref (store_settings);
4920 g_object_unref (settings);
4924 /* we keep a pointer to the embedded folder view, so we can
4925 * retrieve it with get_folder_view_from_move_to_dialog (see
4926 * above) later (needed for focus handling)
4928 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
4930 /* Hide special folders */
4931 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (tree_view), FALSE);
4932 #ifndef MODEST_TOOLKIT_HILDON2
4933 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
4936 gtk_widget_show (GTK_WIDGET (tree_view));
4942 * Shows a confirmation dialog to the user when we're moving messages
4943 * from a remote server to the local storage. Returns the dialog
4944 * response. If it's other kind of movement then it always returns
4947 * This one is used by the next functions:
4948 * modest_ui_actions_on_paste - commented out
4949 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4952 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4953 TnyFolder *dest_folder,
4957 gint response = GTK_RESPONSE_OK;
4958 TnyAccount *account = NULL;
4959 TnyFolder *src_folder = NULL;
4960 TnyIterator *iter = NULL;
4961 TnyHeader *header = NULL;
4963 /* return with OK if the destination is a remote folder */
4964 if (modest_tny_folder_is_remote_folder (dest_folder))
4965 return GTK_RESPONSE_OK;
4967 /* Get source folder */
4968 iter = tny_list_create_iterator (headers);
4969 header = TNY_HEADER (tny_iterator_get_current (iter));
4971 src_folder = tny_header_get_folder (header);
4972 g_object_unref (header);
4974 g_object_unref (iter);
4976 /* if no src_folder, message may be an attahcment */
4977 if (src_folder == NULL)
4978 return GTK_RESPONSE_CANCEL;
4980 /* If the source is a local or MMC folder */
4981 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4982 g_object_unref (src_folder);
4983 return GTK_RESPONSE_OK;
4986 /* Get the account */
4987 account = tny_folder_get_account (src_folder);
4989 /* now if offline we ask the user */
4990 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4991 response = GTK_RESPONSE_OK;
4993 response = GTK_RESPONSE_CANCEL;
4996 g_object_unref (src_folder);
4997 g_object_unref (account);
5003 move_to_helper_destroyer (gpointer user_data)
5005 MoveToHelper *helper = (MoveToHelper *) user_data;
5007 /* Close the "Pasting" information banner */
5008 if (helper->banner) {
5009 gtk_widget_destroy (GTK_WIDGET (helper->banner));
5010 g_object_unref (helper->banner);
5012 if (gtk_tree_row_reference_valid (helper->reference)) {
5013 gtk_tree_row_reference_free (helper->reference);
5014 helper->reference = NULL;
5020 move_to_cb (ModestMailOperation *mail_op,
5023 MoveToHelper *helper = (MoveToHelper *) user_data;
5024 GObject *object = modest_mail_operation_get_source (mail_op);
5026 /* Note that the operation could have failed, in that case do
5028 if (modest_mail_operation_get_status (mail_op) !=
5029 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5032 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
5033 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
5035 if (!modest_msg_view_window_select_next_message (self) &&
5036 !modest_msg_view_window_select_previous_message (self)) {
5037 /* No more messages to view, so close this window */
5038 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
5040 } else if (MODEST_IS_MAIN_WINDOW (object) &&
5041 gtk_tree_row_reference_valid (helper->reference)) {
5042 GtkWidget *header_view;
5044 GtkTreeSelection *sel;
5046 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5047 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5048 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
5049 path = gtk_tree_row_reference_get_path (helper->reference);
5050 /* We need to unselect the previous one
5051 because we could be copying instead of
5053 gtk_tree_selection_unselect_all (sel);
5054 gtk_tree_selection_select_path (sel, path);
5055 gtk_tree_path_free (path);
5057 g_object_unref (object);
5060 /* Destroy the helper */
5061 move_to_helper_destroyer (helper);
5065 folder_move_to_cb (ModestMailOperation *mail_op,
5066 TnyFolder *new_folder,
5069 GtkWidget *folder_view;
5072 object = modest_mail_operation_get_source (mail_op);
5073 if (MODEST_IS_MAIN_WINDOW (object)) {
5074 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
5075 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5076 g_object_ref (folder_view);
5077 g_object_unref (object);
5078 move_to_cb (mail_op, user_data);
5079 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
5080 g_object_unref (folder_view);
5082 move_to_cb (mail_op, user_data);
5087 msgs_move_to_cb (ModestMailOperation *mail_op,
5090 move_to_cb (mail_op, user_data);
5094 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
5097 ModestWindow *main_window = NULL;
5099 /* Disable next automatic folder selection */
5100 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5101 FALSE); /* don't create */
5103 GObject *win = NULL;
5104 GtkWidget *folder_view = NULL;
5106 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
5107 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5108 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
5110 if (user_data && TNY_IS_FOLDER (user_data)) {
5111 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
5112 TNY_FOLDER (user_data), FALSE);
5115 /* Show notification dialog only if the main window exists */
5116 win = modest_mail_operation_get_source (mail_op);
5117 modest_platform_run_information_dialog ((GtkWindow *) win,
5118 _("mail_in_ui_folder_move_target_error"),
5121 g_object_unref (win);
5126 open_msg_for_purge_cb (ModestMailOperation *mail_op,
5135 gint pending_purges = 0;
5136 gboolean some_purged = FALSE;
5137 ModestWindow *win = MODEST_WINDOW (user_data);
5138 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
5140 /* If there was any error */
5141 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5142 modest_window_mgr_unregister_header (mgr, header);
5146 /* Once the message has been retrieved for purging, we check if
5147 * it's all ok for purging */
5149 parts = tny_simple_list_new ();
5150 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
5151 iter = tny_list_create_iterator (parts);
5153 while (!tny_iterator_is_done (iter)) {
5155 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5156 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
5157 if (tny_mime_part_is_purged (part))
5164 g_object_unref (part);
5166 tny_iterator_next (iter);
5168 g_object_unref (iter);
5171 if (pending_purges>0) {
5173 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
5175 if (response == GTK_RESPONSE_OK) {
5178 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_me_inbox_remove_attachments"));
5179 iter = tny_list_create_iterator (parts);
5180 while (!tny_iterator_is_done (iter)) {
5183 part = TNY_MIME_PART (tny_iterator_get_current (iter));
5184 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
5185 tny_mime_part_set_purged (part);
5188 g_object_unref (part);
5190 tny_iterator_next (iter);
5192 g_object_unref (iter);
5194 tny_msg_rewrite_cache (msg);
5196 gtk_widget_destroy (info);
5200 modest_window_mgr_unregister_header (mgr, header);
5202 g_object_unref (parts);
5206 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5207 ModestMainWindow *win)
5209 GtkWidget *header_view;
5210 TnyList *header_list;
5212 TnyHeaderFlags flags;
5213 ModestWindow *msg_view_window = NULL;
5216 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5218 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5219 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5221 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5223 g_warning ("%s: no header selected", __FUNCTION__);
5227 if (tny_list_get_length (header_list) == 1) {
5228 TnyIterator *iter = tny_list_create_iterator (header_list);
5229 header = TNY_HEADER (tny_iterator_get_current (iter));
5230 g_object_unref (iter);
5234 if (!header || !TNY_IS_HEADER(header)) {
5235 g_warning ("%s: header is not valid", __FUNCTION__);
5239 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5240 header, &msg_view_window);
5241 flags = tny_header_get_flags (header);
5242 if (!(flags & TNY_HEADER_FLAG_CACHED))
5245 if (msg_view_window != NULL)
5246 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5248 /* do nothing; uid was registered before, so window is probably on it's way */
5249 g_warning ("debug: header %p has already been registered", header);
5252 ModestMailOperation *mail_op = NULL;
5253 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5254 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5255 modest_ui_actions_disk_operations_error_handler,
5257 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5258 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5260 g_object_unref (mail_op);
5263 g_object_unref (header);
5265 g_object_unref (header_list);
5269 * Checks if we need a connection to do the transfer and if the user
5270 * wants to connect to complete it
5273 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5274 TnyFolderStore *src_folder,
5276 TnyFolder *dst_folder,
5277 gboolean delete_originals,
5278 gboolean *need_connection,
5281 TnyAccount *src_account;
5282 gint uncached_msgs = 0;
5284 uncached_msgs = header_list_count_uncached_msgs (headers);
5286 /* We don't need any further check if
5288 * 1- the source folder is local OR
5289 * 2- the device is already online
5291 if (!modest_tny_folder_store_is_remote (src_folder) ||
5292 tny_device_is_online (modest_runtime_get_device())) {
5293 *need_connection = FALSE;
5298 /* We must ask for a connection when
5300 * - the message(s) is not already cached OR
5301 * - the message(s) is cached but the leave_on_server setting
5302 * is FALSE (because we need to sync the source folder to
5303 * delete the message from the server (for IMAP we could do it
5304 * offline, it'll take place the next time we get a
5307 src_account = get_account_from_folder_store (src_folder);
5308 if (uncached_msgs > 0) {
5312 *need_connection = TRUE;
5313 num_headers = tny_list_get_length (headers);
5314 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5316 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5317 GTK_RESPONSE_CANCEL) {
5323 /* The transfer is possible and the user wants to */
5326 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5327 const gchar *account_name;
5328 gboolean leave_on_server;
5330 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5331 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5334 if (leave_on_server == TRUE) {
5335 *need_connection = FALSE;
5337 *need_connection = TRUE;
5340 *need_connection = FALSE;
5345 g_object_unref (src_account);
5349 xfer_messages_error_handler (ModestMailOperation *mail_op,
5352 GObject *win = modest_mail_operation_get_source (mail_op);
5353 modest_platform_run_information_dialog ((GtkWindow *) win,
5354 _("mail_in_ui_folder_move_target_error"),
5357 g_object_unref (win);
5361 TnyFolderStore *dst_folder;
5366 * Utility function that transfer messages from both the main window
5367 * and the msg view window when using the "Move to" dialog
5370 xfer_messages_performer (gboolean canceled,
5372 GtkWindow *parent_window,
5373 TnyAccount *account,
5376 ModestWindow *win = MODEST_WINDOW (parent_window);
5377 TnyAccount *dst_account = NULL;
5378 gboolean dst_forbids_message_add = FALSE;
5379 XferMsgsHelper *helper;
5380 MoveToHelper *movehelper;
5381 ModestMailOperation *mail_op;
5383 helper = (XferMsgsHelper *) user_data;
5385 if (canceled || err) {
5386 if (!check_memory_full_error ((GtkWidget *) parent_window, err)) {
5387 /* Show the proper error message */
5388 modest_ui_actions_on_account_connection_error (parent_window, account);
5393 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5395 /* tinymail will return NULL for local folders it seems */
5396 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5397 modest_tny_account_get_protocol_type (dst_account),
5398 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_MESSAGE_ADD);
5399 g_object_unref (dst_account);
5401 if (dst_forbids_message_add) {
5402 modest_platform_information_banner (GTK_WIDGET (win),
5404 ngettext("mail_in_ui_folder_move_target_error",
5405 "mail_in_ui_folder_move_targets_error",
5406 tny_list_get_length (helper->headers)));
5410 movehelper = g_new0 (MoveToHelper, 1);
5412 #ifndef MODEST_TOOLKIT_HILDON2
5413 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5414 _CS("ckct_nw_pasting"));
5415 if (movehelper->banner != NULL) {
5416 g_object_ref (movehelper->banner);
5417 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5421 if (MODEST_IS_MAIN_WINDOW (win)) {
5422 GtkWidget *header_view =
5423 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5424 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5425 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5428 /* Perform the mail operation */
5429 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5430 xfer_messages_error_handler,
5432 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5435 modest_mail_operation_xfer_msgs (mail_op,
5437 TNY_FOLDER (helper->dst_folder),
5442 g_object_unref (G_OBJECT (mail_op));
5444 g_object_unref (helper->dst_folder);
5445 g_object_unref (helper->headers);
5446 g_slice_free (XferMsgsHelper, helper);
5450 TnyFolder *src_folder;
5451 TnyFolderStore *dst_folder;
5452 gboolean delete_original;
5453 GtkWidget *folder_view;
5457 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
5458 TnyAccount *account, gpointer user_data)
5460 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5461 GtkTreeSelection *sel;
5462 ModestMailOperation *mail_op = NULL;
5464 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
5465 g_object_unref (G_OBJECT (info->src_folder));
5466 g_object_unref (G_OBJECT (info->dst_folder));
5471 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5472 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5473 _CS("ckct_nw_pasting"));
5474 if (helper->banner != NULL) {
5475 g_object_ref (helper->banner);
5476 gtk_widget_show (GTK_WIDGET(helper->banner));
5478 /* Clean folder on header view before moving it */
5479 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5480 gtk_tree_selection_unselect_all (sel);
5482 /* Let gtk events run. We need that the folder
5483 view frees its reference to the source
5484 folder *before* issuing the mail operation
5485 so we need the signal handler of selection
5486 changed to happen before the mail
5488 while (gtk_events_pending ())
5489 gtk_main_iteration (); */
5492 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5493 modest_ui_actions_move_folder_error_handler,
5494 info->src_folder, NULL);
5495 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5498 /* Select *after* the changes */
5499 /* TODO: this function hangs UI after transfer */
5500 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
5501 /* TNY_FOLDER (src_folder), TRUE); */
5503 if (MODEST_IS_MAIN_WINDOW (parent_window)) {
5504 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5505 TNY_FOLDER (info->dst_folder), TRUE);
5507 modest_mail_operation_xfer_folder (mail_op,
5508 TNY_FOLDER (info->src_folder),
5510 info->delete_original,
5513 g_object_unref (G_OBJECT (info->src_folder));
5515 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5518 /* Unref mail operation */
5519 g_object_unref (G_OBJECT (mail_op));
5520 g_object_unref (G_OBJECT (info->dst_folder));
5525 get_account_from_folder_store (TnyFolderStore *folder_store)
5527 if (TNY_IS_ACCOUNT (folder_store))
5528 return g_object_ref (folder_store);
5530 return tny_folder_get_account (TNY_FOLDER (folder_store));
5534 * UI handler for the "Move to" action when invoked from the
5538 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5539 GtkWidget *folder_view,
5540 TnyFolderStore *dst_folder,
5541 ModestMainWindow *win)
5543 ModestHeaderView *header_view = NULL;
5544 TnyFolderStore *src_folder = NULL;
5546 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5548 /* Get the source folder */
5549 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5551 /* Get header view */
5552 header_view = (ModestHeaderView *)
5553 modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5555 /* Get folder or messages to transfer */
5556 if (gtk_widget_is_focus (folder_view)) {
5557 gboolean do_xfer = TRUE;
5559 /* Allow only to transfer folders to the local root folder */
5560 if (TNY_IS_ACCOUNT (dst_folder) &&
5561 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5562 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5564 } else if (!TNY_IS_FOLDER (src_folder)) {
5565 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5570 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5571 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5573 info->src_folder = g_object_ref (src_folder);
5574 info->dst_folder = g_object_ref (dst_folder);
5575 info->delete_original = TRUE;
5576 info->folder_view = folder_view;
5578 connect_info->callback = on_move_folder_cb;
5579 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5580 connect_info->data = info;
5582 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5583 TNY_FOLDER_STORE (src_folder),
5586 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5589 headers = modest_header_view_get_selected_headers(header_view);
5591 /* Transfer the messages */
5592 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
5593 headers, TNY_FOLDER (dst_folder));
5595 g_object_unref (headers);
5599 g_object_unref (src_folder);
5602 #ifdef MODEST_TOOLKIT_HILDON2
5604 * UI handler for the "Move to" action when invoked from the
5605 * ModestFolderWindow
5608 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
5609 TnyFolderStore *dst_folder,
5613 TnyFolderStore *src_folder = NULL;
5614 TnyIterator *iterator;
5616 if (tny_list_get_length (selection) != 1)
5619 iterator = tny_list_create_iterator (selection);
5620 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
5621 g_object_unref (iterator);
5624 gboolean do_xfer = TRUE;
5626 /* Allow only to transfer folders to the local root folder */
5627 if (TNY_IS_ACCOUNT (dst_folder) &&
5628 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5629 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5631 } else if (!TNY_IS_FOLDER (src_folder)) {
5632 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5637 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5638 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5640 info->src_folder = g_object_ref (src_folder);
5641 info->dst_folder = g_object_ref (dst_folder);
5642 info->delete_original = TRUE;
5643 info->folder_view = folder_view;
5645 connect_info->callback = on_move_folder_cb;
5646 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5647 connect_info->data = info;
5649 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5650 TNY_FOLDER_STORE (src_folder),
5654 g_object_unref (src_folder);
5660 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
5661 TnyFolder *src_folder,
5663 TnyFolder *dst_folder)
5665 gboolean need_connection = TRUE;
5666 gboolean do_xfer = TRUE;
5667 XferMsgsHelper *helper;
5669 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5670 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5671 g_return_if_fail (TNY_IS_LIST (headers));
5673 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5674 headers, TNY_FOLDER (dst_folder),
5675 TRUE, &need_connection,
5678 /* If we don't want to transfer just return */
5682 /* Create the helper */
5683 helper = g_slice_new (XferMsgsHelper);
5684 helper->dst_folder = g_object_ref (dst_folder);
5685 helper->headers = g_object_ref (headers);
5687 if (need_connection) {
5688 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5689 connect_info->callback = xfer_messages_performer;
5690 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5691 connect_info->data = helper;
5693 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5694 TNY_FOLDER_STORE (src_folder),
5697 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5698 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
5699 src_account, helper);
5700 g_object_unref (src_account);
5705 * UI handler for the "Move to" action when invoked from the
5706 * ModestMsgViewWindow
5709 modest_ui_actions_on_window_move_to (GtkAction *action,
5711 TnyFolderStore *dst_folder,
5714 TnyFolder *src_folder = NULL;
5716 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5719 TnyHeader *header = NULL;
5722 iter = tny_list_create_iterator (headers);
5723 header = (TnyHeader *) tny_iterator_get_current (iter);
5724 src_folder = tny_header_get_folder (header);
5726 /* Transfer the messages */
5727 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder,
5729 TNY_FOLDER (dst_folder));
5732 g_object_unref (header);
5733 g_object_unref (iter);
5734 g_object_unref (src_folder);
5739 modest_ui_actions_on_move_to (GtkAction *action,
5742 modest_ui_actions_on_edit_mode_move_to (win);
5746 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
5748 GtkWidget *dialog = NULL, *folder_view = NULL;
5749 ModestMainWindow *main_window;
5750 MoveToInfo *helper = NULL;
5751 TnyList *list_to_move;
5753 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
5755 /* Get the main window if exists */
5756 if (MODEST_IS_MAIN_WINDOW (win))
5757 main_window = MODEST_MAIN_WINDOW (win);
5760 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5761 FALSE)); /* don't create */
5763 /* Get the folder view widget if exists */
5765 folder_view = modest_main_window_get_child_widget (main_window,
5766 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5770 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
5771 if (tny_list_get_length (list_to_move) < 1) {
5772 g_object_unref (list_to_move);
5776 /* Create and run the dialog */
5777 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view);
5778 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
5779 GTK_WINDOW (dialog),
5783 helper = g_slice_new0 (MoveToInfo);
5784 helper->list = modest_platform_get_list_to_move (MODEST_WINDOW (win));
5787 /* Listen to response signal */
5788 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
5790 /* Show the dialog */
5791 gtk_widget_show (dialog);
5797 * Calls #HeadersFunc for each header already selected in the main
5798 * window or the message currently being shown in the msg view window
5801 do_headers_action (ModestWindow *win,
5805 TnyList *headers_list = NULL;
5806 TnyIterator *iter = NULL;
5807 TnyHeader *header = NULL;
5808 TnyFolder *folder = NULL;
5811 headers_list = get_selected_headers (win);
5815 /* Get the folder */
5816 iter = tny_list_create_iterator (headers_list);
5817 header = TNY_HEADER (tny_iterator_get_current (iter));
5819 folder = tny_header_get_folder (header);
5820 g_object_unref (header);
5823 /* Call the function for each header */
5824 while (!tny_iterator_is_done (iter)) {
5825 header = TNY_HEADER (tny_iterator_get_current (iter));
5826 func (header, win, user_data);
5827 g_object_unref (header);
5828 tny_iterator_next (iter);
5831 /* Trick: do a poke status in order to speed up the signaling
5833 tny_folder_poke_status (folder);
5836 g_object_unref (folder);
5837 g_object_unref (iter);
5838 g_object_unref (headers_list);
5842 modest_ui_actions_view_attachment (GtkAction *action,
5843 ModestWindow *window)
5845 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5846 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5848 /* not supported window for this action */
5849 g_return_if_reached ();
5854 modest_ui_actions_save_attachments (GtkAction *action,
5855 ModestWindow *window)
5857 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5859 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5862 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5864 /* not supported window for this action */
5865 g_return_if_reached ();
5870 modest_ui_actions_remove_attachments (GtkAction *action,
5871 ModestWindow *window)
5873 if (MODEST_IS_MAIN_WINDOW (window)) {
5874 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
5875 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5876 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5878 /* not supported window for this action */
5879 g_return_if_reached ();
5884 modest_ui_actions_on_settings (GtkAction *action,
5889 dialog = modest_platform_get_global_settings_dialog ();
5890 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
5891 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5892 gtk_widget_show_all (dialog);
5894 gtk_dialog_run (GTK_DIALOG (dialog));
5896 gtk_widget_destroy (dialog);
5900 modest_ui_actions_on_help (GtkAction *action,
5903 /* Help app is not available at all in fremantle */
5904 #ifndef MODEST_TOOLKIT_HILDON2
5905 const gchar *help_id;
5907 g_return_if_fail (win && GTK_IS_WINDOW(win));
5909 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5912 modest_platform_show_help (GTK_WINDOW (win), help_id);
5917 modest_ui_actions_on_csm_help (GtkAction *action,
5920 /* Help app is not available at all in fremantle */
5921 #ifndef MODEST_TOOLKIT_HILDON2
5923 const gchar* help_id = NULL;
5924 GtkWidget *folder_view;
5925 TnyFolderStore *folder_store;
5927 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
5929 /* Get selected folder */
5930 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5931 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5932 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5934 /* Switch help_id */
5935 if (folder_store && TNY_IS_FOLDER (folder_store))
5936 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
5939 g_object_unref (folder_store);
5942 modest_platform_show_help (GTK_WINDOW (win), help_id);
5944 modest_ui_actions_on_help (action, win);
5949 retrieve_contents_cb (ModestMailOperation *mail_op,
5956 /* We only need this callback to show an error in case of
5957 memory low condition */
5958 modest_ui_actions_msg_retrieval_check (mail_op, header, msg);
5962 retrieve_msg_contents_performer (gboolean canceled,
5964 GtkWindow *parent_window,
5965 TnyAccount *account,
5968 ModestMailOperation *mail_op;
5969 TnyList *headers = TNY_LIST (user_data);
5971 if (err || canceled) {
5972 check_memory_full_error ((GtkWidget *) parent_window, err);
5976 /* Create mail operation */
5977 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5978 modest_ui_actions_disk_operations_error_handler,
5980 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5981 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
5984 g_object_unref (mail_op);
5986 g_object_unref (headers);
5987 g_object_unref (account);
5991 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5992 ModestWindow *window)
5994 TnyList *headers = NULL;
5995 TnyAccount *account = NULL;
5996 TnyIterator *iter = NULL;
5997 TnyHeader *header = NULL;
5998 TnyFolder *folder = NULL;
6001 headers = get_selected_headers (window);
6005 /* Pick the account */
6006 iter = tny_list_create_iterator (headers);
6007 header = TNY_HEADER (tny_iterator_get_current (iter));
6008 folder = tny_header_get_folder (header);
6009 account = tny_folder_get_account (folder);
6010 g_object_unref (folder);
6011 g_object_unref (header);
6012 g_object_unref (iter);
6014 /* Connect and perform the message retrieval */
6015 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
6016 g_object_ref (account),
6017 retrieve_msg_contents_performer,
6018 g_object_ref (headers));
6021 g_object_unref (account);
6022 g_object_unref (headers);
6026 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
6028 g_return_if_fail (MODEST_IS_WINDOW (window));
6031 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
6035 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
6037 g_return_if_fail (MODEST_IS_WINDOW (window));
6040 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
6044 modest_ui_actions_on_email_menu_activated (GtkAction *action,
6045 ModestWindow *window)
6047 g_return_if_fail (MODEST_IS_WINDOW (window));
6050 modest_ui_actions_check_menu_dimming_rules (window);
6054 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
6055 ModestWindow *window)
6057 g_return_if_fail (MODEST_IS_WINDOW (window));
6060 modest_ui_actions_check_menu_dimming_rules (window);
6064 modest_ui_actions_on_view_menu_activated (GtkAction *action,
6065 ModestWindow *window)
6067 g_return_if_fail (MODEST_IS_WINDOW (window));
6070 modest_ui_actions_check_menu_dimming_rules (window);
6074 modest_ui_actions_on_format_menu_activated (GtkAction *action,
6075 ModestWindow *window)
6077 g_return_if_fail (MODEST_IS_WINDOW (window));
6080 modest_ui_actions_check_menu_dimming_rules (window);
6084 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
6085 ModestWindow *window)
6087 g_return_if_fail (MODEST_IS_WINDOW (window));
6090 modest_ui_actions_check_menu_dimming_rules (window);
6094 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
6095 ModestWindow *window)
6097 g_return_if_fail (MODEST_IS_WINDOW (window));
6100 modest_ui_actions_check_menu_dimming_rules (window);
6104 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
6105 ModestWindow *window)
6107 g_return_if_fail (MODEST_IS_WINDOW (window));
6110 modest_ui_actions_check_menu_dimming_rules (window);
6114 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
6115 ModestWindow *window)
6117 g_return_if_fail (MODEST_IS_WINDOW (window));
6120 modest_ui_actions_check_menu_dimming_rules (window);
6124 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
6125 ModestWindow *window)
6127 g_return_if_fail (MODEST_IS_WINDOW (window));
6130 modest_ui_actions_check_menu_dimming_rules (window);
6134 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
6136 g_return_if_fail (MODEST_IS_WINDOW (window));
6138 /* we check for low-mem; in that case, show a warning, and don't allow
6141 if (modest_platform_check_memory_low (window, TRUE))
6144 modest_platform_show_search_messages (GTK_WINDOW (window));
6148 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
6150 g_return_if_fail (MODEST_IS_WINDOW (win));
6153 /* we check for low-mem; in that case, show a warning, and don't allow
6154 * for the addressbook
6156 if (modest_platform_check_memory_low (win, TRUE))
6160 modest_platform_show_addressbook (GTK_WINDOW (win));
6165 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
6166 ModestWindow *window)
6169 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
6171 if (GTK_IS_TOGGLE_ACTION (action))
6172 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
6176 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window),
6181 on_send_receive_finished (ModestMailOperation *mail_op,
6184 GtkWidget *header_view, *folder_view;
6185 TnyFolderStore *folder_store;
6186 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
6188 /* Set send/receive operation finished */
6189 modest_main_window_notify_send_receive_completed (main_win);
6191 /* Don't refresh the current folder if there were any errors */
6192 if (modest_mail_operation_get_status (mail_op) !=
6193 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
6196 /* Refresh the current folder if we're viewing a window. We do
6197 this because the user won't be able to see the new mails in
6198 the selected folder after a Send&Receive because it only
6199 performs a poke_status, i.e, only the number of read/unread
6200 messages is updated, but the new headers are not
6202 folder_view = modest_main_window_get_child_widget (main_win,
6203 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6207 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6209 /* Do not need to refresh INBOX again because the
6210 update_account does it always automatically */
6211 if (folder_store && TNY_IS_FOLDER (folder_store) &&
6212 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
6213 ModestMailOperation *refresh_op;
6215 header_view = modest_main_window_get_child_widget (main_win,
6216 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6218 /* We do not need to set the contents style
6219 because it hasn't changed. We also do not
6220 need to save the widget status. Just force
6222 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
6223 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
6224 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
6225 folder_refreshed_cb, main_win);
6226 g_object_unref (refresh_op);
6230 g_object_unref (folder_store);
6235 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
6241 const gchar* server_name = NULL;
6242 TnyTransportAccount *server_account;
6243 gchar *message = NULL;
6245 /* Don't show anything if the user cancelled something or the
6246 * send receive request is not interactive. Authentication
6247 * errors are managed by the account store so no need to show
6248 * a dialog here again */
6249 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
6250 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
6251 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
6255 /* Get the server name: */
6257 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
6259 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
6261 g_return_if_reached ();
6263 /* Show the appropriate message text for the GError: */
6264 switch (err->code) {
6265 case TNY_SERVICE_ERROR_CONNECT:
6266 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6268 case TNY_SERVICE_ERROR_SEND:
6269 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6271 case TNY_SERVICE_ERROR_UNAVAILABLE:
6272 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6275 g_warning ("%s: unexpected ERROR %d",
6276 __FUNCTION__, err->code);
6277 message = g_strdup (_CS("sfil_ib_unable_to_send"));
6281 modest_platform_run_information_dialog (NULL, message, FALSE);
6283 g_object_unref (server_account);
6287 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6292 ModestMainWindow *main_window = NULL;
6293 ModestWindowMgr *mgr = NULL;
6294 GtkWidget *folder_view = NULL, *header_view = NULL;
6295 TnyFolderStore *selected_folder = NULL;
6296 TnyFolderType folder_type;
6298 mgr = modest_runtime_get_window_mgr ();
6299 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr,
6300 FALSE));/* don't create */
6304 /* Check if selected folder is OUTBOX */
6305 folder_view = modest_main_window_get_child_widget (main_window,
6306 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6307 header_view = modest_main_window_get_child_widget (main_window,
6308 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6310 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6311 if (!TNY_IS_FOLDER (selected_folder))
6314 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6315 #if GTK_CHECK_VERSION(2, 8, 0)
6316 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
6317 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6318 GtkTreeViewColumn *tree_column;
6320 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6321 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6323 gtk_tree_view_column_queue_resize (tree_column);
6326 gtk_widget_queue_draw (header_view);
6329 /* Rerun dimming rules, because the message could become deletable for example */
6330 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6331 MODEST_DIMMING_RULES_TOOLBAR);
6332 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6333 MODEST_DIMMING_RULES_MENU);
6337 if (selected_folder != NULL)
6338 g_object_unref (selected_folder);
6342 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6343 TnyAccount *account)
6345 ModestProtocolType protocol_type;
6346 ModestProtocol *protocol;
6347 gchar *error_note = NULL;
6349 protocol_type = modest_tny_account_get_protocol_type (account);
6350 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6353 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6354 if (error_note == NULL) {
6355 g_warning ("%s: This should not be reached", __FUNCTION__);
6357 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6358 g_free (error_note);
6363 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6367 TnyFolderStore *folder = NULL;
6368 TnyAccount *account = NULL;
6369 ModestProtocolType proto;
6370 ModestProtocol *protocol;
6371 TnyHeader *header = NULL;
6373 if (MODEST_IS_MAIN_WINDOW (win)) {
6374 GtkWidget *header_view;
6375 TnyList* headers = NULL;
6377 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6378 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6379 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6380 if (!headers || tny_list_get_length (headers) == 0) {
6382 g_object_unref (headers);
6385 iter = tny_list_create_iterator (headers);
6386 header = TNY_HEADER (tny_iterator_get_current (iter));
6387 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6388 g_object_unref (iter);
6389 g_object_unref (headers);
6390 #ifdef MODEST_TOOLKIT_HILDON2
6391 } else if (MODEST_IS_HEADER_WINDOW (win)) {
6392 GtkWidget *header_view;
6393 TnyList* headers = NULL;
6395 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
6396 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6397 if (!headers || tny_list_get_length (headers) == 0) {
6399 g_object_unref (headers);
6402 iter = tny_list_create_iterator (headers);
6403 header = TNY_HEADER (tny_iterator_get_current (iter));
6404 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6405 g_object_unref (iter);
6406 g_object_unref (headers);
6408 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6409 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6410 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6413 /* Get the account type */
6414 account = tny_folder_get_account (TNY_FOLDER (folder));
6415 proto = modest_tny_account_get_protocol_type (account);
6416 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6419 subject = tny_header_dup_subject (header);
6420 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6424 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6428 g_object_unref (account);
6429 g_object_unref (folder);
6430 g_object_unref (header);
6436 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
6437 const gchar *account_name,
6438 const gchar *account_title)
6440 ModestAccountMgr *account_mgr;
6443 ModestProtocol *protocol;
6444 gboolean removed = FALSE;
6446 g_return_val_if_fail (account_name, FALSE);
6447 g_return_val_if_fail (account_title, FALSE);
6449 account_mgr = modest_runtime_get_account_mgr();
6451 /* The warning text depends on the account type: */
6452 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6453 modest_account_mgr_get_store_protocol (account_mgr,
6455 txt = modest_protocol_get_translation (protocol,
6456 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6459 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6461 response = modest_platform_run_confirmation_dialog (parent_window, txt);
6465 if (response == GTK_RESPONSE_OK) {
6466 /* Remove account. If it succeeds then it also removes
6467 the account from the ModestAccountView: */
6468 gboolean is_default = FALSE;
6469 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6470 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6472 g_free (default_account_name);
6474 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6476 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);