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"
45 #include "modest-tny-platform-factory.h"
46 #include "modest-platform.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>
52 #ifdef MODEST_PLATFORM_MAEMO
53 #include "maemo/modest-osso-state-saving.h"
54 #include "maemo/modest-maemo-utils.h"
55 #include "maemo/modest-hildon-includes.h"
56 #endif /* MODEST_PLATFORM_MAEMO */
58 #include "widgets/modest-ui-constants.h"
59 #include <widgets/modest-main-window.h>
60 #include <widgets/modest-msg-view-window.h>
61 #include <widgets/modest-account-view-window.h>
62 #include <widgets/modest-details-dialog.h>
63 #include <widgets/modest-attachments-view.h>
64 #include "widgets/modest-folder-view.h"
65 #include "widgets/modest-global-settings-dialog.h"
66 #include "modest-connection-specific-smtp-window.h"
67 #include "modest-account-mgr-helpers.h"
68 #include "modest-mail-operation.h"
69 #include "modest-text-utils.h"
71 #ifdef MODEST_HAVE_EASYSETUP
72 #include "easysetup/modest-easysetup-wizard.h"
73 #endif /* MODEST_HAVE_EASYSETUP */
75 #include <modest-widget-memory.h>
76 #include <tny-error.h>
77 #include <tny-simple-list.h>
78 #include <tny-msg-view.h>
79 #include <tny-device.h>
80 #include <tny-merge-folder.h>
82 #include <gtkhtml/gtkhtml.h>
84 typedef struct _GetMsgAsyncHelper {
86 ModestMailOperation *mail_op;
93 typedef enum _ReplyForwardAction {
99 typedef struct _ReplyForwardHelper {
100 guint reply_forward_type;
101 ReplyForwardAction action;
103 GtkWidget *parent_window;
104 } ReplyForwardHelper;
106 typedef struct _MoveToHelper {
107 GtkTreeRowReference *reference;
111 typedef struct _PasteAsAttachmentHelper {
112 ModestMsgEditWindow *window;
114 } PasteAsAttachmentHelper;
118 * The do_headers_action uses this kind of functions to perform some
119 * action to each member of a list of headers
121 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
123 static void do_headers_action (ModestWindow *win,
127 static void open_msg_cb (ModestMailOperation *mail_op,
132 static void reply_forward_cb (ModestMailOperation *mail_op,
137 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
139 static void folder_refreshed_cb (ModestMailOperation *mail_op,
143 static void on_send_receive_finished (ModestMailOperation *mail_op,
146 static gint header_list_count_uncached_msgs (TnyList *header_list);
147 static gboolean connect_to_get_msg (
149 gint num_of_uncached_msgs);
151 static gboolean remote_folder_is_pop (const TnyFolderStore *folder);
153 static gboolean msgs_already_deleted_from_server ( TnyList *headers,
154 const TnyFolderStore *src_folder);
158 * This function checks whether a TnyFolderStore is a pop account
161 remote_folder_is_pop (const TnyFolderStore *folder)
163 const gchar *proto = NULL;
164 TnyAccount *account = NULL;
166 g_return_val_if_fail (TNY_IS_FOLDER_STORE(folder), FALSE);
168 if (TNY_IS_ACCOUNT (folder)) {
169 account = TNY_ACCOUNT(folder);
170 g_object_ref(account);
171 } else if (TNY_IS_FOLDER (folder)) {
172 account = tny_folder_get_account(TNY_FOLDER(folder));
175 proto = tny_account_get_proto(account);
176 g_object_unref (account);
179 (modest_protocol_info_get_transport_store_protocol (proto) == MODEST_PROTOCOL_STORE_POP);
183 * This functions checks whether if a list of messages are already
184 * deleted from the server: that is, if the server is a POP account
185 * and all messages are already cached.
188 msgs_already_deleted_from_server (TnyList *headers, const TnyFolderStore *src_folder)
190 g_return_val_if_fail (TNY_IS_FOLDER_STORE(src_folder), FALSE);
191 g_return_val_if_fail (TNY_IS_LIST(headers), FALSE);
193 gboolean src_is_pop = remote_folder_is_pop (src_folder);
194 gint uncached_msgs = header_list_count_uncached_msgs (headers);
196 return (src_is_pop && !uncached_msgs);
200 /* FIXME: this should be merged with the similar code in modest-account-view-window */
201 /* Show the account creation wizard dialog.
202 * returns: TRUE if an account was created. FALSE if the user cancelled.
205 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
207 gboolean result = FALSE;
208 GtkWindow *dialog, *wizard;
209 gint dialog_response;
211 /* Show the easy-setup wizard: */
212 dialog = modest_window_mgr_get_modal (modest_runtime_get_window_mgr());
213 if (dialog && MODEST_IS_EASYSETUP_WIZARD_DIALOG(dialog)) {
214 /* old wizard is active already;
216 gtk_window_present (GTK_WINDOW(dialog));
221 /* there is no such wizard yet */
222 wizard = GTK_WINDOW (modest_easysetup_wizard_dialog_new ());
223 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), wizard);
225 /* always present a main window in the background
226 * we do it here, so we cannot end up with to wizards (as this
227 * function might be called in modest_window_mgr_get_main_window as well */
229 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr());
231 /* make sure the mainwindow is visible */
232 gtk_widget_show_all (GTK_WIDGET(win));
233 gtk_window_present (GTK_WINDOW(win));
235 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
236 gtk_widget_destroy (GTK_WIDGET (wizard));
237 if (gtk_events_pending ())
238 gtk_main_iteration ();
240 if (dialog_response == GTK_RESPONSE_CANCEL) {
243 /* Check whether an account was created: */
244 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
252 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
255 const gchar *authors[] = {
256 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
259 about = gtk_about_dialog_new ();
260 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
261 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
262 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
263 _("Copyright (c) 2006, Nokia Corporation\n"
264 "All rights reserved."));
265 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
266 _("a modest e-mail client\n\n"
267 "design and implementation: Dirk-Jan C. Binnema\n"
268 "contributions from the fine people at KC and Ig\n"
269 "uses the tinymail email framework written by Philip van Hoof"));
270 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
271 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
272 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
273 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
275 gtk_dialog_run (GTK_DIALOG (about));
276 gtk_widget_destroy(about);
280 * Gets the list of currently selected messages. If the win is the
281 * main window, then it returns a newly allocated list of the headers
282 * selected in the header view. If win is the msg view window, then
283 * the value returned is a list with just a single header.
285 * The caller of this funcion must free the list.
288 get_selected_headers (ModestWindow *win)
290 if (MODEST_IS_MAIN_WINDOW(win)) {
291 GtkWidget *header_view;
293 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
294 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
295 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
297 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
298 /* for MsgViewWindows, we simply return a list with one element */
300 TnyList *list = NULL;
302 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
303 if (header != NULL) {
304 list = tny_simple_list_new ();
305 tny_list_prepend (list, G_OBJECT(header));
306 g_object_unref (G_OBJECT(header));
315 static GtkTreeRowReference *
316 get_next_after_selected_headers (ModestHeaderView *header_view)
318 GtkTreeSelection *sel;
319 GList *selected_rows, *node;
321 GtkTreeRowReference *result;
324 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
325 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
326 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
328 if (selected_rows == NULL)
331 node = g_list_last (selected_rows);
332 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
333 gtk_tree_path_next (path);
335 result = gtk_tree_row_reference_new (model, path);
337 gtk_tree_path_free (path);
338 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
339 g_list_free (selected_rows);
345 headers_action_mark_as_read (TnyHeader *header,
349 TnyHeaderFlags flags;
351 g_return_if_fail (TNY_IS_HEADER(header));
353 flags = tny_header_get_flags (header);
354 if (flags & TNY_HEADER_FLAG_SEEN) return;
355 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
359 headers_action_mark_as_unread (TnyHeader *header,
363 TnyHeaderFlags flags;
365 g_return_if_fail (TNY_IS_HEADER(header));
367 flags = tny_header_get_flags (header);
368 if (flags & TNY_HEADER_FLAG_SEEN) {
369 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
373 /** A convenience method, because deleting a message is
374 * otherwise complicated, and it's best to change it in one place
377 void modest_do_message_delete (TnyHeader *header, ModestWindow *win)
379 ModestMailOperation *mail_op = NULL;
380 mail_op = modest_mail_operation_new (win ? G_OBJECT(win) : NULL);
381 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
384 /* Always delete. TODO: Move to trash still not supported */
385 modest_mail_operation_remove_msg (mail_op, header, FALSE);
386 g_object_unref (G_OBJECT (mail_op));
389 /** A convenience method, because deleting a message is
390 * otherwise complicated, and it's best to change it in one place
393 void modest_do_messages_delete (TnyList *headers, ModestWindow *win)
395 ModestMailOperation *mail_op = NULL;
396 mail_op = modest_mail_operation_new (win ? G_OBJECT(win) : NULL);
397 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
400 /* Always delete. TODO: Move to trash still not supported */
401 modest_mail_operation_remove_msgs (mail_op, headers, FALSE);
402 g_object_unref (G_OBJECT (mail_op));
405 /** After deleing a message that is currently visible in a window,
406 * show the next message from the list, or close the window if there are no more messages.
409 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
411 /* Close msg view window or select next */
412 if (modest_msg_view_window_last_message_selected (win) &&
413 modest_msg_view_window_first_message_selected (win)) {
414 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
415 } else if (!modest_msg_view_window_select_next_message (win)) {
417 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
422 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
424 TnyList *header_list = NULL;
425 TnyIterator *iter = NULL;
426 TnyHeader *header = NULL;
427 gchar *message = NULL;
430 ModestWindowMgr *mgr;
431 GtkWidget *header_view = NULL;
433 g_return_if_fail (MODEST_IS_WINDOW(win));
435 /* Check first if the header view has the focus */
436 if (MODEST_IS_MAIN_WINDOW (win)) {
438 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
439 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
440 if (!gtk_widget_is_focus (header_view))
444 /* Get the headers, either from the header view (if win is the main window),
445 * or from the message view window: */
446 header_list = get_selected_headers (win);
447 if (!header_list) return;
449 /* Check if any of the headers are already opened, or in the process of being opened */
450 if (MODEST_IS_MAIN_WINDOW (win)) {
451 gint opened_headers = 0;
453 iter = tny_list_create_iterator (header_list);
454 mgr = modest_runtime_get_window_mgr ();
455 while (!tny_iterator_is_done (iter)) {
456 header = TNY_HEADER (tny_iterator_get_current (iter));
458 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
460 g_object_unref (header);
462 tny_iterator_next (iter);
464 g_object_unref (iter);
466 if (opened_headers > 0) {
469 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
472 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
475 g_object_unref (header_list);
481 if (tny_list_get_length(header_list) == 1) {
482 iter = tny_list_create_iterator (header_list);
483 header = TNY_HEADER (tny_iterator_get_current (iter));
485 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
486 g_object_unref (header);
489 g_object_unref (iter);
491 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
492 tny_list_get_length(header_list)), desc);
494 /* Confirmation dialog */
495 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
499 if (response == GTK_RESPONSE_OK) {
500 ModestWindow *main_window = NULL;
501 ModestWindowMgr *mgr = NULL;
502 GtkTreeModel *model = NULL;
503 GtkTreeSelection *sel = NULL;
504 GList *sel_list = NULL, *tmp = NULL;
505 GtkTreeRowReference *next_row_reference = NULL;
506 GtkTreeRowReference *prev_row_reference = NULL;
507 GtkTreePath *next_path = NULL;
508 GtkTreePath *prev_path = NULL;
511 /* Find last selected row */
512 if (MODEST_IS_MAIN_WINDOW (win)) {
513 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
514 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
515 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
516 for (tmp=sel_list; tmp; tmp=tmp->next) {
517 if (tmp->next == NULL) {
518 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
519 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
521 gtk_tree_path_prev (prev_path);
522 gtk_tree_path_next (next_path);
524 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
525 next_row_reference = gtk_tree_row_reference_new (model, next_path);
530 /* Disable window dimming management */
531 modest_window_disable_dimming (MODEST_WINDOW(win));
533 /* Remove each header. If it's a view window header_view == NULL */
534 modest_do_messages_delete (header_list, win);
536 /* Enable window dimming management */
538 gtk_tree_selection_unselect_all (sel);
540 modest_window_enable_dimming (MODEST_WINDOW(win));
542 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
543 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
545 /* Get main window */
546 mgr = modest_runtime_get_window_mgr ();
547 main_window = modest_window_mgr_get_main_window (mgr);
550 /* Move cursor to next row */
553 /* Select next or previous row */
554 if (gtk_tree_row_reference_valid (next_row_reference)) {
555 /* next_path = gtk_tree_row_reference_get_path (row_reference); */
556 gtk_tree_selection_select_path (sel, next_path);
558 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
559 gtk_tree_selection_select_path (sel, prev_path);
563 if (next_row_reference != NULL)
564 gtk_tree_row_reference_free (next_row_reference);
565 if (next_path != NULL)
566 gtk_tree_path_free (next_path);
567 if (prev_row_reference != NULL)
568 gtk_tree_row_reference_free (prev_row_reference);
569 if (prev_path != NULL)
570 gtk_tree_path_free (prev_path);
574 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, err->code, err->message);
578 /* Update toolbar dimming state */
579 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
582 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
583 g_list_free (sel_list);
589 g_object_unref (header_list);
595 /* delete either message or folder, based on where we are */
597 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
599 g_return_if_fail (MODEST_IS_WINDOW(win));
601 /* Check first if the header view has the focus */
602 if (MODEST_IS_MAIN_WINDOW (win)) {
604 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
605 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
606 if (gtk_widget_is_focus (w)) {
607 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
611 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_on_add_to_contacts (GtkAction *action, ModestWindow *win)
669 GtkClipboard *clipboard = NULL;
670 gchar *selection = NULL;
672 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
673 selection = gtk_clipboard_wait_for_text (clipboard);
675 /* Question: why is the clipboard being used here?
676 * It doesn't really make a lot of sense. */
680 modest_address_book_add_address (selection);
686 modest_ui_actions_on_accounts (GtkAction *action,
689 /* This is currently only implemented for Maemo */
690 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
691 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
692 modest_ui_actions_run_account_setup_wizard (win);
695 /* Show the list of accounts */
696 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
697 gtk_window_set_transient_for (account_win, GTK_WINDOW (win));
699 /* The accounts dialog must be modal */
700 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), account_win);
701 modest_maemo_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
704 GtkWidget *dialog, *label;
706 /* Create the widgets */
708 dialog = gtk_dialog_new_with_buttons ("Message",
710 GTK_DIALOG_DESTROY_WITH_PARENT,
714 label = gtk_label_new ("Hello World!");
716 /* Ensure that the dialog box is destroyed when the user responds. */
718 g_signal_connect_swapped (dialog, "response",
719 G_CALLBACK (gtk_widget_destroy),
722 /* Add the label, and show everything we've added to the dialog. */
724 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
726 gtk_widget_show_all (dialog);
727 #endif /* MODEST_PLATFORM_MAEMO */
731 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
733 /* Save any changes. */
734 modest_connection_specific_smtp_window_save_server_accounts (
735 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window));
736 gtk_widget_destroy (GTK_WIDGET (window));
742 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
744 /* This is currently only implemented for Maemo,
745 * because it requires an API (libconic) to detect different connection
748 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
750 /* Create the window if necessary: */
751 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
752 modest_connection_specific_smtp_window_fill_with_connections (
753 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
754 modest_runtime_get_account_mgr());
756 /* Show the window: */
757 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
758 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
759 gtk_widget_show (specific_window);
761 /* Save changes when the window is hidden: */
762 g_signal_connect (specific_window, "hide",
763 G_CALLBACK (on_smtp_servers_window_hide), win);
764 #endif /* MODEST_PLATFORM_MAEMO */
768 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
770 ModestWindow *msg_win = NULL;
772 TnyFolder *folder = NULL;
773 gchar *account_name = NULL;
774 gchar *from_str = NULL;
775 /* GError *err = NULL; */
776 TnyAccount *account = NULL;
777 ModestWindowMgr *mgr;
778 gchar *signature = NULL, *blank_and_signature = NULL;
780 /* if there are no accounts yet, just show the wizard */
781 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
782 if (!modest_ui_actions_run_account_setup_wizard (win))
786 account_name = g_strdup (modest_window_get_active_account (win));
788 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
790 g_printerr ("modest: no account found\n");
794 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
796 TNY_ACCOUNT_TYPE_STORE);
798 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
802 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
804 g_printerr ("modest: failed get from string for '%s'\n", account_name);
808 gboolean use_signature = FALSE;
809 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr (), account_name, &use_signature);
812 blank_and_signature = g_strconcat ("\n", signature, NULL);
814 blank_and_signature = g_strdup ("");
819 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
821 g_printerr ("modest: failed to create new msg\n");
825 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
827 g_printerr ("modest: failed to find Drafts folder\n");
832 /* Create and register edit window */
833 /* This is destroyed by TODO. */
834 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
835 mgr = modest_runtime_get_window_mgr ();
836 modest_window_mgr_register_window (mgr, msg_win);
839 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
841 gtk_widget_show_all (GTK_WIDGET (msg_win));
844 g_free (account_name);
846 g_free (blank_and_signature);
848 g_object_unref (msg_win);
850 g_object_unref (G_OBJECT(account));
852 g_object_unref (G_OBJECT(msg));
854 g_object_unref (G_OBJECT(folder));
858 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
862 ModestMailOperationStatus status;
864 /* If there is no message or the operation was not successful */
865 status = modest_mail_operation_get_status (mail_op);
866 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
868 /* Remove the header from the preregistered uids */
869 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
879 open_msg_cb (ModestMailOperation *mail_op, TnyHeader *header, TnyMsg *msg, gpointer user_data)
881 ModestWindowMgr *mgr = NULL;
882 ModestWindow *parent_win = NULL;
883 ModestWindow *win = NULL;
884 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
885 gchar *account = NULL;
888 /* Do nothing if there was any problem with the mail
889 operation. The error will be shown by the error_handler of
890 the mail operation */
891 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
894 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
895 folder = tny_header_get_folder (header);
897 /* Mark header as read */
898 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
901 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
903 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
905 /* Gets folder type (OUTBOX headers will be opened in edit window */
906 if (modest_tny_folder_is_local_folder (folder))
907 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
909 /* If the header is in the drafts folder then open the editor,
910 else the message view window */
911 if ((folder_type == TNY_FOLDER_TYPE_DRAFTS) ||
912 (folder_type == TNY_FOLDER_TYPE_OUTBOX)) {
913 /* we cannot edit without a valid account... */
914 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
915 if (!modest_ui_actions_run_account_setup_wizard(parent_win))
918 win = modest_msg_edit_window_new (msg, account, TRUE);
922 modest_platform_information_banner (NULL, NULL, _("mail_ib_opening_draft_message"));
925 gchar *uid = modest_tny_folder_get_header_unique_id (header);
927 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
928 GtkWidget *header_view;
929 GtkTreeSelection *sel;
930 GList *sel_list = NULL;
933 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
934 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
936 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
937 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
939 if (sel_list != NULL) {
940 GtkTreeRowReference *row_reference;
942 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
943 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
944 g_list_free (sel_list);
946 win = modest_msg_view_window_new_with_header_model (
947 msg, account, (const gchar*) uid,
948 model, row_reference);
949 gtk_tree_row_reference_free (row_reference);
951 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
954 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
959 /* Register and show new window */
961 mgr = modest_runtime_get_window_mgr ();
962 modest_window_mgr_register_window (mgr, win);
963 g_object_unref (win);
964 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
965 gtk_widget_show_all (GTK_WIDGET(win));
968 /* Update toolbar dimming state */
969 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
970 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
976 g_object_unref (parent_win);
977 g_object_unref (folder);
981 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
985 GObject *win = modest_mail_operation_get_source (mail_op);
987 error = modest_mail_operation_get_error (mail_op);
988 /* printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, error->code, error->message); */
990 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
992 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
995 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
996 _("mail_ni_ui_folder_get_msg_folder_error"));
1000 g_object_unref (win);
1004 * This function is used by both modest_ui_actions_on_open and
1005 * modest_ui_actions_on_header_activated. This way we always do the
1006 * same when trying to open messages.
1009 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
1011 ModestWindowMgr *mgr = NULL;
1012 TnyIterator *iter = NULL;
1013 ModestMailOperation *mail_op = NULL;
1014 TnyList *not_opened_headers = NULL;
1015 TnyHeaderFlags flags = 0;
1017 g_return_if_fail (headers != NULL);
1019 /* Check that only one message is selected for opening */
1020 if (tny_list_get_length (headers) != 1) {
1021 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1022 _("mcen_ib_select_one_message"));
1027 /* Look if we already have a message view for each header. If
1028 true, then remove the header from the list of headers to
1030 mgr = modest_runtime_get_window_mgr ();
1031 iter = tny_list_create_iterator (headers);
1032 not_opened_headers = tny_simple_list_new ();
1034 while (!tny_iterator_is_done (iter)) {
1036 ModestWindow *window = NULL;
1037 TnyHeader *header = NULL;
1038 gboolean found = FALSE;
1040 header = TNY_HEADER (tny_iterator_get_current (iter));
1042 flags = tny_header_get_flags (header);
1045 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1047 /* Do not open again the message and present the
1048 window to the user */
1051 gtk_window_present (GTK_WINDOW (window));
1053 /* the header has been registered already, we don't do
1054 * anything but wait for the window to come up*/
1055 g_debug ("header %p already registered, waiting for window", header);
1057 tny_list_append (not_opened_headers, G_OBJECT (header));
1061 g_object_unref (header);
1063 tny_iterator_next (iter);
1065 g_object_unref (iter);
1068 /* If some messages would have to be downloaded, ask the user to
1069 * make a connection. It's generally easier to do this here (in the mainloop)
1070 * than later in a thread:
1072 if (tny_list_get_length (not_opened_headers) > 0) {
1074 gboolean found = FALSE;
1076 iter = tny_list_create_iterator (not_opened_headers);
1077 while (!tny_iterator_is_done (iter) && !found) {
1078 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1079 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1082 tny_iterator_next (iter);
1084 g_object_unref (header);
1086 g_object_unref (iter);
1088 if (found && !modest_platform_connect_and_wait (GTK_WINDOW (win), NULL)) {
1089 g_object_unref (not_opened_headers);
1094 /* Register the headers before actually creating the windows: */
1095 TnyIterator *iter_not_opened = tny_list_create_iterator (not_opened_headers);
1096 while (!tny_iterator_is_done (iter_not_opened)) {
1097 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1099 modest_window_mgr_register_header (mgr, header);
1100 g_object_unref (header);
1103 tny_iterator_next (iter_not_opened);
1105 g_object_unref (iter_not_opened);
1106 iter_not_opened = NULL;
1108 /* Open each message */
1109 if (tny_list_get_length (not_opened_headers) > 0) {
1110 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
1111 modest_ui_actions_get_msgs_full_error_handler,
1113 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1114 if (tny_list_get_length (not_opened_headers) > 1) {
1115 modest_mail_operation_get_msgs_full (mail_op,
1121 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1122 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1123 modest_mail_operation_get_msg (mail_op, header, open_msg_cb, NULL);
1124 g_object_unref (header);
1125 g_object_unref (iter);
1127 g_object_unref (mail_op);
1131 if (not_opened_headers != NULL)
1132 g_object_unref (not_opened_headers);
1136 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1141 headers = get_selected_headers (win);
1146 _modest_ui_actions_open (headers, win);
1148 g_object_unref(headers);
1153 free_reply_forward_helper (gpointer data)
1155 ReplyForwardHelper *helper;
1157 helper = (ReplyForwardHelper *) data;
1158 g_free (helper->account_name);
1159 g_slice_free (ReplyForwardHelper, helper);
1163 reply_forward_cb (ModestMailOperation *mail_op, TnyHeader *header, TnyMsg *msg,
1167 ReplyForwardHelper *rf_helper;
1168 ModestWindow *msg_win = NULL;
1169 ModestEditType edit_type;
1171 TnyAccount *account = NULL;
1172 ModestWindowMgr *mgr = NULL;
1173 gchar *signature = NULL;
1174 gboolean use_signature;
1176 /* If there was any error. The mail operation could be NULL,
1177 this means that we already have the message downloaded and
1178 that we didn't do a mail operation to retrieve it */
1179 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1182 g_return_if_fail (user_data != NULL);
1183 rf_helper = (ReplyForwardHelper *) user_data;
1185 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1186 rf_helper->account_name);
1187 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr(),
1188 rf_helper->account_name,
1191 /* Create reply mail */
1192 switch (rf_helper->action) {
1195 modest_tny_msg_create_reply_msg (msg, header, from, signature,
1196 rf_helper->reply_forward_type,
1197 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1199 case ACTION_REPLY_TO_ALL:
1201 modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1202 MODEST_TNY_MSG_REPLY_MODE_ALL);
1203 edit_type = MODEST_EDIT_TYPE_REPLY;
1205 case ACTION_FORWARD:
1207 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1208 edit_type = MODEST_EDIT_TYPE_FORWARD;
1211 g_return_if_reached ();
1218 g_printerr ("modest: failed to create message\n");
1222 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1223 rf_helper->account_name,
1224 TNY_ACCOUNT_TYPE_STORE);
1226 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1230 /* Create and register the windows */
1231 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1232 mgr = modest_runtime_get_window_mgr ();
1233 modest_window_mgr_register_window (mgr, msg_win);
1235 if (rf_helper->parent_window != NULL) {
1236 gdouble parent_zoom;
1238 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1239 modest_window_set_zoom (msg_win, parent_zoom);
1242 /* Show edit window */
1243 gtk_widget_show_all (GTK_WIDGET (msg_win));
1247 g_object_unref (msg_win);
1249 g_object_unref (G_OBJECT (new_msg));
1251 g_object_unref (G_OBJECT (account));
1252 /* g_object_unref (msg); */
1253 free_reply_forward_helper (rf_helper);
1256 /* Checks a list of headers. If any of them are not currently
1257 * downloaded (CACHED) then returns TRUE else returns FALSE.
1260 header_list_count_uncached_msgs (TnyList *header_list)
1263 gint uncached_messages = 0;
1265 iter = tny_list_create_iterator (header_list);
1266 while (!tny_iterator_is_done (iter)) {
1269 header = TNY_HEADER (tny_iterator_get_current (iter));
1271 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1272 uncached_messages ++;
1273 g_object_unref (header);
1276 tny_iterator_next (iter);
1278 g_object_unref (iter);
1280 return uncached_messages;
1283 /* Returns FALSE if the user does not want to download the
1284 * messages. Returns TRUE if the user allowed the download.
1287 connect_to_get_msg (GtkWindow *win,
1288 gint num_of_uncached_msgs)
1290 /* Allways download if we are online. */
1291 if (tny_device_is_online (modest_runtime_get_device ()))
1294 /* If offline, then ask for user permission to download the messages */
1295 GtkResponseType response;
1296 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1297 ngettext("mcen_nc_get_msg",
1299 num_of_uncached_msgs));
1300 if (response == GTK_RESPONSE_CANCEL)
1303 return modest_platform_connect_and_wait(win, NULL);
1307 * Common code for the reply and forward actions
1310 reply_forward (ReplyForwardAction action, ModestWindow *win)
1312 ModestMailOperation *mail_op = NULL;
1313 TnyList *header_list = NULL;
1314 ReplyForwardHelper *rf_helper = NULL;
1315 guint reply_forward_type;
1316 gboolean continue_download = TRUE;
1317 gboolean do_retrieve = TRUE;
1319 g_return_if_fail (MODEST_IS_WINDOW(win));
1321 /* we need an account when editing */
1322 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1323 if (!modest_ui_actions_run_account_setup_wizard (win))
1327 header_list = get_selected_headers (win);
1331 reply_forward_type =
1332 modest_conf_get_int (modest_runtime_get_conf (),
1333 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1336 /* check if we need to download msg before asking about it */
1337 do_retrieve = (action == ACTION_FORWARD) ||
1338 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1341 gint num_of_unc_msgs;
1342 /* check that the messages have been previously downloaded */
1343 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
1344 /* If there are any uncached message ask the user
1345 * whether he/she wants to download them. */
1346 if (num_of_unc_msgs)
1347 continue_download = connect_to_get_msg (
1352 if (!continue_download) {
1353 g_object_unref (header_list);
1357 /* We assume that we can only select messages of the
1358 same folder and that we reply all of them from the
1359 same account. In fact the interface currently only
1360 allows single selection */
1363 rf_helper = g_slice_new0 (ReplyForwardHelper);
1364 rf_helper->reply_forward_type = reply_forward_type;
1365 rf_helper->action = action;
1366 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1368 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1369 rf_helper->parent_window = GTK_WIDGET (win);
1370 if (!rf_helper->account_name)
1371 rf_helper->account_name =
1372 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1374 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1377 /* Get header and message. Do not free them here, the
1378 reply_forward_cb must do it */
1379 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1380 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1381 if (!msg || !header) {
1383 g_object_unref (msg);
1384 g_printerr ("modest: no message found\n");
1387 reply_forward_cb (NULL, header, msg, rf_helper);
1390 g_object_unref (header);
1395 /* Only reply/forward to one message */
1396 iter = tny_list_create_iterator (header_list);
1397 header = TNY_HEADER (tny_iterator_get_current (iter));
1398 g_object_unref (iter);
1401 /* Retrieve messages */
1403 mail_op = modest_mail_operation_new_with_error_handling (
1405 modest_ui_actions_get_msgs_full_error_handler,
1407 modest_mail_operation_queue_add (
1408 modest_runtime_get_mail_operation_queue (), mail_op);
1410 modest_mail_operation_get_msg (mail_op,
1415 g_object_unref(mail_op);
1417 /* we put a ref here to prevent double unref as the reply
1418 * forward callback unrefs the header at its end */
1419 reply_forward_cb (NULL, header, NULL, rf_helper);
1423 g_object_unref (header);
1429 g_object_unref (header_list);
1433 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1435 g_return_if_fail (MODEST_IS_WINDOW(win));
1437 reply_forward (ACTION_REPLY, win);
1441 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1443 g_return_if_fail (MODEST_IS_WINDOW(win));
1445 reply_forward (ACTION_FORWARD, win);
1449 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1451 g_return_if_fail (MODEST_IS_WINDOW(win));
1453 reply_forward (ACTION_REPLY_TO_ALL, win);
1457 modest_ui_actions_on_next (GtkAction *action,
1458 ModestWindow *window)
1460 if (MODEST_IS_MAIN_WINDOW (window)) {
1461 GtkWidget *header_view;
1463 header_view = modest_main_window_get_child_widget (
1464 MODEST_MAIN_WINDOW(window),
1465 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1469 modest_header_view_select_next (
1470 MODEST_HEADER_VIEW(header_view));
1471 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1472 modest_msg_view_window_select_next_message (
1473 MODEST_MSG_VIEW_WINDOW (window));
1475 g_return_if_reached ();
1480 modest_ui_actions_on_prev (GtkAction *action,
1481 ModestWindow *window)
1483 g_return_if_fail (MODEST_IS_WINDOW(window));
1485 if (MODEST_IS_MAIN_WINDOW (window)) {
1486 GtkWidget *header_view;
1487 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1488 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1492 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1493 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1494 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1496 g_return_if_reached ();
1501 modest_ui_actions_on_sort (GtkAction *action,
1502 ModestWindow *window)
1504 g_return_if_fail (MODEST_IS_WINDOW(window));
1506 if (MODEST_IS_MAIN_WINDOW (window)) {
1507 GtkWidget *header_view;
1508 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1509 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1511 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1516 /* Show sorting dialog */
1517 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1522 new_messages_arrived (ModestMailOperation *self,
1523 TnyList *new_headers,
1526 ModestMainWindow *win = NULL;
1527 GtkWidget *folder_view = NULL;
1528 TnyFolderStore *folder = NULL;
1529 gboolean folder_empty = FALSE;
1531 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
1532 win = MODEST_MAIN_WINDOW (user_data);
1534 /* Don't do anything if there are not new headers, this could
1535 happen if there was any problem with the mail operation */
1539 /* Set contents style of headers view */
1540 if (modest_main_window_get_contents_style (win) == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1541 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1542 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1543 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1546 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1549 modest_main_window_set_contents_style (win,
1550 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1553 /* Notify new messages have been downloaded */
1554 if ((new_headers != NULL) && (tny_list_get_length (new_headers) > 0)) {
1555 TnyIterator *iter = tny_list_create_iterator (new_headers);
1557 TnyHeader *header = NULL;
1559 header = TNY_HEADER (tny_iterator_get_current (iter));
1560 modest_platform_on_new_header_received (header);
1561 g_object_unref (header);
1563 tny_iterator_next (iter);
1564 } while (!tny_iterator_is_done (iter));
1565 g_object_unref (iter);
1570 * This function performs the send & receive required actions. The
1571 * window is used to create the mail operation. Typically it should
1572 * always be the main window, but we pass it as argument in order to
1576 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1578 gchar *acc_name = NULL;
1579 ModestMailOperation *mail_op;
1580 TnyAccount *store_account = NULL;
1582 /* If no account name was provided then get the current account, and if
1583 there is no current account then pick the default one: */
1584 if (!account_name) {
1585 acc_name = g_strdup (modest_window_get_active_account(win));
1587 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1589 g_printerr ("modest: cannot get default account\n");
1593 acc_name = g_strdup (account_name);
1597 /* Ensure that we have a connection available */
1599 modest_tny_account_store_get_server_account (modest_runtime_get_account_store (),
1601 TNY_ACCOUNT_TYPE_STORE);
1602 if (!modest_platform_connect_and_wait (NULL, TNY_ACCOUNT (store_account))) {
1603 g_object_unref (store_account);
1606 g_object_unref (store_account);
1608 /* Set send/receive operation in progress */
1609 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1611 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
1612 modest_ui_actions_send_receive_error_handler,
1615 g_signal_connect (G_OBJECT(mail_op), "operation-finished",
1616 G_CALLBACK (on_send_receive_finished),
1619 /* Send & receive. */
1620 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1621 /* Receive and then send. The operation is tagged initially as
1622 a receive operation because the account update performs a
1623 receive and then a send. The operation changes its type
1624 internally, so the progress objects will receive the proper
1625 progress information */
1626 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1627 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, win);
1628 g_object_unref (G_OBJECT (mail_op));
1636 modest_ui_actions_do_cancel_send (const gchar *account_name,
1639 TnyTransportAccount *transport_account;
1640 TnySendQueue *send_queue = NULL;
1641 GError *error = NULL;
1643 /* Get transport account */
1645 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1646 (modest_runtime_get_account_store(),
1648 TNY_ACCOUNT_TYPE_TRANSPORT));
1649 if (!transport_account) {
1650 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1655 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1656 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1657 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1658 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1659 "modest: could not find send queue for account\n");
1661 /* Keeep messages in outbox folder */
1662 tny_send_queue_cancel (send_queue, FALSE, &error);
1666 if (transport_account != NULL)
1667 g_object_unref (G_OBJECT (transport_account));
1671 modest_ui_actions_cancel_send_all (ModestWindow *win)
1673 GSList *account_names, *iter;
1675 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1678 iter = account_names;
1680 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1681 iter = g_slist_next (iter);
1684 modest_account_mgr_free_account_names (account_names);
1685 account_names = NULL;
1689 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1692 /* Check if accounts exist */
1693 gboolean accounts_exist =
1694 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1696 /* If not, allow the user to create an account before trying to send/receive. */
1697 if (!accounts_exist)
1698 modest_ui_actions_on_accounts (NULL, win);
1700 /* Cancel all sending operaitons */
1701 modest_ui_actions_cancel_send_all (win);
1705 * Refreshes all accounts. This function will be used by automatic
1709 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1711 GSList *account_names, *iter;
1713 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1716 iter = account_names;
1718 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1719 iter = g_slist_next (iter);
1722 modest_account_mgr_free_account_names (account_names);
1723 account_names = NULL;
1727 modest_do_refresh_current_folder(ModestWindow *win)
1729 /* Refresh currently selected folder. Note that if we only
1730 want to retreive the headers, then the refresh only will
1731 invoke a poke_status over all folders, i.e., only the
1732 total/unread count will be updated */
1733 if (MODEST_IS_MAIN_WINDOW (win)) {
1734 GtkWidget *header_view, *folder_view;
1735 TnyFolderStore *folder_store;
1737 /* Get folder and header view */
1739 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1740 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1744 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1746 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1748 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1749 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1751 /* We do not need to set the contents style
1752 because it hasn't changed. We also do not
1753 need to save the widget status. Just force
1755 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1756 TNY_FOLDER (folder_store),
1757 folder_refreshed_cb,
1758 MODEST_MAIN_WINDOW (win));
1762 g_object_unref (folder_store);
1768 * Handler of the click on Send&Receive button in the main toolbar
1771 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1773 /* Check if accounts exist */
1774 gboolean accounts_exist =
1775 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1777 /* If not, allow the user to create an account before trying to send/receive. */
1778 if (!accounts_exist)
1779 modest_ui_actions_on_accounts (NULL, win);
1781 modest_do_refresh_current_folder (win);
1783 /* Refresh the active account */
1784 modest_ui_actions_do_send_receive (NULL, win);
1789 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1792 GtkWidget *header_view;
1794 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1796 header_view = modest_main_window_get_child_widget (main_window,
1797 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1801 conf = modest_runtime_get_conf ();
1803 /* what is saved/restored is depending on the style; thus; we save with
1804 * old style, then update the style, and restore for this new style
1806 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1808 if (modest_header_view_get_style
1809 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1810 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1811 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1813 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1814 MODEST_HEADER_VIEW_STYLE_DETAILS);
1816 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1817 MODEST_CONF_HEADER_VIEW_KEY);
1822 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1824 ModestMainWindow *main_window)
1826 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1827 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1829 /* in the case the folder is empty, show the empty folder message and focus
1831 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1832 if (modest_header_view_is_empty (header_view)) {
1833 TnyFolder *folder = modest_header_view_get_folder (header_view);
1834 GtkWidget *folder_view =
1835 modest_main_window_get_child_widget (main_window,
1836 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1838 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1839 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1843 /* If no header has been selected then exit */
1848 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1849 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1851 /* Update toolbar dimming state */
1852 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1856 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1858 ModestMainWindow *main_window)
1862 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1867 if (modest_header_view_count_selected_headers (header_view) > 1) {
1868 hildon_banner_show_information (NULL, NULL, _("mcen_ib_select_one_message"));
1873 /* headers = tny_simple_list_new (); */
1874 /* tny_list_prepend (headers, G_OBJECT (header)); */
1875 headers = modest_header_view_get_selected_headers (header_view);
1877 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1879 g_object_unref (headers);
1883 set_active_account_from_tny_account (TnyAccount *account,
1884 ModestWindow *window)
1886 const gchar *server_acc_name = tny_account_get_id (account);
1888 /* We need the TnyAccount provided by the
1889 account store because that is the one that
1890 knows the name of the Modest account */
1891 TnyAccount *modest_server_account = modest_server_account =
1892 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1893 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1895 if (!modest_server_account) {
1896 g_warning ("%s: could not get tny account\n", __FUNCTION__);
1900 /* Update active account, but only if it's not a pseudo-account */
1901 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
1902 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
1903 const gchar *modest_acc_name =
1904 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1905 if (modest_acc_name)
1906 modest_window_set_active_account (window, modest_acc_name);
1909 g_object_unref (modest_server_account);
1914 folder_refreshed_cb (ModestMailOperation *mail_op,
1918 ModestMainWindow *win = NULL;
1919 GtkWidget *header_view;
1920 gboolean folder_empty = FALSE;
1921 gboolean all_marked_as_deleted = FALSE;
1923 g_return_if_fail (TNY_IS_FOLDER (folder));
1925 win = MODEST_MAIN_WINDOW (user_data);
1927 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1930 TnyFolder *current_folder;
1932 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1933 if (current_folder != NULL && folder != current_folder) {
1934 g_object_unref (current_folder);
1937 g_object_unref (current_folder);
1940 /* Check if folder is empty and set headers view contents style */
1941 folder_empty = (tny_folder_get_all_count (folder) == 0);
1942 all_marked_as_deleted = modest_header_view_is_empty (MODEST_HEADER_VIEW(header_view));
1943 if (folder_empty || all_marked_as_deleted)
1944 modest_main_window_set_contents_style (win,
1945 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1949 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1950 TnyFolderStore *folder_store,
1952 ModestMainWindow *main_window)
1955 GtkWidget *header_view;
1957 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1959 header_view = modest_main_window_get_child_widget(main_window,
1960 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1964 conf = modest_runtime_get_conf ();
1966 if (TNY_IS_ACCOUNT (folder_store)) {
1968 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1970 /* Show account details */
1971 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1974 if (TNY_IS_FOLDER (folder_store) && selected) {
1976 /* Update the active account */
1977 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1979 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1980 g_object_unref (account);
1984 /* Set the header style by default, it could
1985 be changed later by the refresh callback to
1987 modest_main_window_set_contents_style (main_window,
1988 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1990 /* Set folder on header view. This function
1991 will call tny_folder_refresh_async so we
1992 pass a callback that will be called when
1993 finished. We use that callback to set the
1994 empty view if there are no messages */
1995 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1996 TNY_FOLDER (folder_store),
1997 folder_refreshed_cb,
2000 /* Restore configuration. We need to do this
2001 *after* the set_folder because the widget
2002 memory asks the header view about its
2004 modest_widget_memory_restore (modest_runtime_get_conf (),
2005 G_OBJECT(header_view),
2006 MODEST_CONF_HEADER_VIEW_KEY);
2008 /* Update the active account */
2009 //modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
2010 /* Save only if we're seeing headers */
2011 if (modest_main_window_get_contents_style (main_window) ==
2012 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2013 modest_widget_memory_save (conf, G_OBJECT (header_view),
2014 MODEST_CONF_HEADER_VIEW_KEY);
2015 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2019 /* Update toolbar dimming state */
2020 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2024 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2031 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2033 online = tny_device_is_online (modest_runtime_get_device());
2036 /* already online -- the item is simply not there... */
2037 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2039 GTK_MESSAGE_WARNING,
2041 _("The %s you selected cannot be found"),
2043 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2044 gtk_dialog_run (GTK_DIALOG(dialog));
2046 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2049 _("mcen_bd_dialog_cancel"),
2050 GTK_RESPONSE_REJECT,
2051 _("mcen_bd_dialog_ok"),
2052 GTK_RESPONSE_ACCEPT,
2054 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2055 "Do you want to get online?"), item);
2056 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2057 gtk_label_new (txt), FALSE, FALSE, 0);
2058 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2061 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2062 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2063 /* TODO: Comment about why is this commented out: */
2064 /* modest_platform_connect_and_wait (); */
2067 gtk_widget_destroy (dialog);
2071 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2074 /* g_message ("%s %s", __FUNCTION__, link); */
2079 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2082 modest_platform_activate_uri (link);
2086 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2089 modest_platform_show_uri_popup (link);
2093 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2096 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2100 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2101 const gchar *address,
2104 /* g_message ("%s %s", __FUNCTION__, address); */
2108 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2109 TnyMsg *saved_draft,
2112 ModestMsgEditWindow *edit_window;
2114 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2116 /* If there was any error do nothing */
2117 if (modest_mail_operation_get_error (mail_op) != NULL)
2120 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2124 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2126 TnyTransportAccount *transport_account;
2127 ModestMailOperation *mail_operation;
2129 gchar *account_name, *from;
2130 ModestAccountMgr *account_mgr;
2131 gchar *info_text = NULL;
2133 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2135 data = modest_msg_edit_window_get_msg_data (edit_window);
2137 account_mgr = modest_runtime_get_account_mgr();
2138 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2140 account_name = modest_account_mgr_get_default_account (account_mgr);
2141 if (!account_name) {
2142 g_printerr ("modest: no account found\n");
2143 modest_msg_edit_window_free_msg_data (edit_window, data);
2147 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2148 account_name = g_strdup (data->account_name);
2152 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2153 (modest_runtime_get_account_store(),
2155 TNY_ACCOUNT_TYPE_TRANSPORT));
2156 if (!transport_account) {
2157 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2158 g_free (account_name);
2159 modest_msg_edit_window_free_msg_data (edit_window, data);
2162 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2164 /* Create the mail operation */
2165 mail_operation = modest_mail_operation_new (G_OBJECT(edit_window));
2166 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2168 modest_mail_operation_save_to_drafts (mail_operation,
2180 data->priority_flags,
2181 on_save_to_drafts_cb,
2185 g_free (account_name);
2186 g_object_unref (G_OBJECT (transport_account));
2187 g_object_unref (G_OBJECT (mail_operation));
2189 modest_msg_edit_window_free_msg_data (edit_window, data);
2191 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2192 modest_platform_information_banner (NULL, NULL, info_text);
2193 modest_msg_edit_window_reset_modified (edit_window);
2197 /* For instance, when clicking the Send toolbar button when editing a message: */
2199 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2201 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2203 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2206 /* FIXME: Code added just for testing. The final version will
2207 use the send queue provided by tinymail and some
2209 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2210 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2212 account_name = modest_account_mgr_get_default_account (account_mgr);
2214 if (!account_name) {
2215 /* Run account setup wizard */
2216 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window)))
2220 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2222 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2223 account_name = g_strdup (data->account_name);
2226 /* Get the currently-active transport account for this modest account: */
2227 TnyTransportAccount *transport_account =
2228 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2229 (modest_runtime_get_account_store(),
2231 if (!transport_account) {
2232 /* Run account setup wizard */
2233 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2237 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2239 /* Create the mail operation */
2240 ModestMailOperation *mail_operation = modest_mail_operation_new (G_OBJECT(edit_window));
2241 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2243 modest_mail_operation_send_new_mail (mail_operation,
2255 data->priority_flags);
2259 g_free (account_name);
2260 g_object_unref (G_OBJECT (transport_account));
2261 g_object_unref (G_OBJECT (mail_operation));
2263 modest_msg_edit_window_free_msg_data (edit_window, data);
2264 modest_msg_edit_window_set_sent (edit_window, TRUE);
2266 /* Save settings and close the window: */
2267 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2271 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2272 ModestMsgEditWindow *window)
2274 ModestMsgEditFormatState *format_state = NULL;
2276 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2277 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2279 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2282 format_state = modest_msg_edit_window_get_format_state (window);
2283 g_return_if_fail (format_state != NULL);
2285 format_state->bold = gtk_toggle_action_get_active (action);
2286 modest_msg_edit_window_set_format_state (window, format_state);
2287 g_free (format_state);
2292 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2293 ModestMsgEditWindow *window)
2295 ModestMsgEditFormatState *format_state = NULL;
2297 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2298 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2300 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2303 format_state = modest_msg_edit_window_get_format_state (window);
2304 g_return_if_fail (format_state != NULL);
2306 format_state->italics = gtk_toggle_action_get_active (action);
2307 modest_msg_edit_window_set_format_state (window, format_state);
2308 g_free (format_state);
2313 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2314 ModestMsgEditWindow *window)
2316 ModestMsgEditFormatState *format_state = NULL;
2318 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2319 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2321 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2324 format_state = modest_msg_edit_window_get_format_state (window);
2325 g_return_if_fail (format_state != NULL);
2327 format_state->bullet = gtk_toggle_action_get_active (action);
2328 modest_msg_edit_window_set_format_state (window, format_state);
2329 g_free (format_state);
2334 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2335 GtkRadioAction *selected,
2336 ModestMsgEditWindow *window)
2338 ModestMsgEditFormatState *format_state = NULL;
2339 GtkJustification value;
2341 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2343 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2346 value = gtk_radio_action_get_current_value (selected);
2348 format_state = modest_msg_edit_window_get_format_state (window);
2349 g_return_if_fail (format_state != NULL);
2351 format_state->justification = value;
2352 modest_msg_edit_window_set_format_state (window, format_state);
2353 g_free (format_state);
2357 modest_ui_actions_on_select_editor_color (GtkAction *action,
2358 ModestMsgEditWindow *window)
2360 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2361 g_return_if_fail (GTK_IS_ACTION (action));
2363 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2366 modest_msg_edit_window_select_color (window);
2370 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2371 ModestMsgEditWindow *window)
2373 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2374 g_return_if_fail (GTK_IS_ACTION (action));
2376 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2379 modest_msg_edit_window_select_background_color (window);
2383 modest_ui_actions_on_insert_image (GtkAction *action,
2384 ModestMsgEditWindow *window)
2386 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2387 g_return_if_fail (GTK_IS_ACTION (action));
2389 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2392 modest_msg_edit_window_insert_image (window);
2396 modest_ui_actions_on_attach_file (GtkAction *action,
2397 ModestMsgEditWindow *window)
2399 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2400 g_return_if_fail (GTK_IS_ACTION (action));
2402 modest_msg_edit_window_offer_attach_file (window);
2406 modest_ui_actions_on_remove_attachments (GtkAction *action,
2407 ModestMsgEditWindow *window)
2409 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2410 g_return_if_fail (GTK_IS_ACTION (action));
2412 modest_msg_edit_window_remove_attachments (window, NULL);
2416 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2419 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2420 const GError *error = modest_mail_operation_get_error (mail_op);
2423 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2424 _("mail_in_ui_folder_create_error"));
2429 modest_ui_actions_create_folder(GtkWidget *parent_window,
2430 GtkWidget *folder_view)
2432 TnyFolderStore *parent_folder;
2434 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2436 if (parent_folder) {
2437 gboolean finished = FALSE;
2439 gchar *folder_name = NULL, *suggested_name = NULL;
2440 const gchar *proto_str = NULL;
2441 TnyAccount *account;
2443 if (TNY_IS_ACCOUNT (parent_folder))
2444 account = g_object_ref (parent_folder);
2446 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2447 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2449 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2450 MODEST_PROTOCOL_STORE_POP) {
2452 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2454 g_object_unref (account);
2456 /* Run the new folder dialog */
2458 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2463 g_free (suggested_name);
2464 suggested_name = NULL;
2466 if (result == GTK_RESPONSE_REJECT) {
2469 ModestMailOperation *mail_op;
2470 TnyFolder *new_folder = NULL;
2472 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
2473 modest_ui_actions_new_folder_error_handler,
2476 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2478 new_folder = modest_mail_operation_create_folder (mail_op,
2480 (const gchar *) folder_name);
2482 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2485 g_object_unref (new_folder);
2488 g_object_unref (mail_op);
2491 suggested_name = folder_name;
2495 g_object_unref (parent_folder);
2500 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2502 GtkWidget *folder_view;
2504 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2506 folder_view = modest_main_window_get_child_widget (main_window,
2507 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2511 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2515 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2518 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2519 const GError *error = NULL;
2520 const gchar *message = NULL;
2522 /* Get error message */
2523 error = modest_mail_operation_get_error (mail_op);
2525 g_return_if_reached ();
2527 switch (error->code) {
2528 case MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS:
2529 message = _CS("ckdg_ib_folder_already_exists");
2532 g_return_if_reached ();
2535 modest_platform_information_banner (GTK_WIDGET (window), NULL, message);
2539 modest_ui_actions_on_rename_folder (GtkAction *action,
2540 ModestMainWindow *main_window)
2542 TnyFolderStore *folder;
2543 GtkWidget *folder_view;
2544 GtkWidget *header_view;
2546 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2548 folder_view = modest_main_window_get_child_widget (main_window,
2549 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2553 header_view = modest_main_window_get_child_widget (main_window,
2554 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2559 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2564 if (TNY_IS_FOLDER (folder)) {
2567 const gchar *current_name;
2568 TnyFolderStore *parent;
2569 gboolean do_rename = TRUE;
2571 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2572 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
2573 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
2574 parent, current_name,
2576 g_object_unref (parent);
2578 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
2580 } else if (modest_platform_is_network_folderstore(folder) &&
2581 !tny_device_is_online (modest_runtime_get_device())) {
2582 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2583 do_rename = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2584 g_object_unref(account);
2588 ModestMailOperation *mail_op;
2589 GtkTreeSelection *sel = NULL;
2592 modest_mail_operation_new_with_error_handling (G_OBJECT(main_window),
2593 modest_ui_actions_rename_folder_error_handler,
2596 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2599 /* Clear the headers view */
2600 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2601 gtk_tree_selection_unselect_all (sel);
2603 /* Select *after* the changes */
2604 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2605 TNY_FOLDER(folder), TRUE);
2607 /* Actually rename the folder */
2608 modest_mail_operation_rename_folder (mail_op,
2609 TNY_FOLDER (folder),
2610 (const gchar *) folder_name);
2612 g_object_unref (mail_op);
2613 g_free (folder_name);
2616 g_object_unref (folder);
2620 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2623 GObject *win = modest_mail_operation_get_source (mail_op);
2625 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2626 _("mail_in_ui_folder_delete_error"));
2627 g_object_unref (win);
2631 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2633 TnyFolderStore *folder;
2634 GtkWidget *folder_view;
2637 gboolean do_delete = TRUE;
2639 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (main_window), FALSE);
2641 folder_view = modest_main_window_get_child_widget (main_window,
2642 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2646 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2648 /* Show an error if it's an account */
2649 if (!TNY_IS_FOLDER (folder)) {
2650 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2651 _("mail_in_ui_folder_delete_error"));
2652 g_object_unref (G_OBJECT (folder));
2657 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2658 tny_folder_get_name (TNY_FOLDER (folder)));
2659 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2660 (const gchar *) message);
2663 if (response != GTK_RESPONSE_OK) {
2665 } else if (modest_platform_is_network_folderstore(folder) &&
2666 !tny_device_is_online (modest_runtime_get_device())) {
2667 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2668 do_delete = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2669 g_object_unref(account);
2673 ModestMailOperation *mail_op;
2674 GtkTreeSelection *sel;
2676 /* Unselect the folder before deleting it to free the headers */
2677 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2678 gtk_tree_selection_unselect_all (sel);
2680 /* Create the mail operation */
2682 modest_mail_operation_new_with_error_handling (G_OBJECT(main_window),
2683 modest_ui_actions_delete_folder_error_handler,
2686 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2688 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2689 g_object_unref (G_OBJECT (mail_op));
2692 g_object_unref (G_OBJECT (folder));
2698 modest_ui_actions_on_delete_folder (GtkAction *action,
2699 ModestMainWindow *main_window)
2701 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2703 if (delete_folder (main_window, FALSE)) {
2704 GtkWidget *folder_view;
2706 folder_view = modest_main_window_get_child_widget (main_window,
2707 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2708 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2713 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2715 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2717 delete_folder (main_window, TRUE);
2722 show_error (GtkWidget *parent_widget, const gchar* text)
2724 hildon_banner_show_information(parent_widget, NULL, text);
2727 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2729 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2736 gtk_dialog_run (dialog);
2737 gtk_widget_destroy (GTK_WIDGET (dialog));
2742 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2743 const gchar* server_account_name,
2748 ModestMainWindow *main_window)
2750 g_return_if_fail(server_account_name);
2751 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2753 /* Initalize output parameters: */
2760 #ifdef MODEST_PLATFORM_MAEMO
2761 /* Maemo uses a different (awkward) button order,
2762 * It should probably just use gtk_alternative_dialog_button_order ().
2764 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2767 _("mcen_bd_dialog_ok"),
2768 GTK_RESPONSE_ACCEPT,
2769 _("mcen_bd_dialog_cancel"),
2770 GTK_RESPONSE_REJECT,
2773 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2777 GTK_RESPONSE_REJECT,
2779 GTK_RESPONSE_ACCEPT,
2781 #endif /* MODEST_PLATFORM_MAEMO */
2783 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2785 gchar *server_name = modest_account_mgr_get_server_account_hostname (
2786 modest_runtime_get_account_mgr(), server_account_name);
2787 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2788 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2793 /* This causes a warning because the logical ID has no %s in it,
2794 * though the translation does, but there is not much we can do about that: */
2795 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2796 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2799 g_free (server_name);
2803 gchar *initial_username = modest_account_mgr_get_server_account_username (
2804 modest_runtime_get_account_mgr(), server_account_name);
2806 GtkWidget *entry_username = gtk_entry_new ();
2807 if (initial_username)
2808 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2809 /* Dim this if a connection has ever succeeded with this username,
2810 * as per the UI spec: */
2811 const gboolean username_known =
2812 modest_account_mgr_get_server_account_username_has_succeeded(
2813 modest_runtime_get_account_mgr(), server_account_name);
2814 gtk_widget_set_sensitive (entry_username, !username_known);
2816 #ifdef MODEST_PLATFORM_MAEMO
2817 /* Auto-capitalization is the default, so let's turn it off: */
2818 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2820 /* Create a size group to be used by all captions.
2821 * Note that HildonCaption does not create a default size group if we do not specify one.
2822 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2823 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2825 GtkWidget *caption = hildon_caption_new (sizegroup,
2826 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2827 gtk_widget_show (entry_username);
2828 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2829 FALSE, FALSE, MODEST_MARGIN_HALF);
2830 gtk_widget_show (caption);
2832 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2834 #endif /* MODEST_PLATFORM_MAEMO */
2837 GtkWidget *entry_password = gtk_entry_new ();
2838 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2839 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2841 #ifdef MODEST_PLATFORM_MAEMO
2842 /* Auto-capitalization is the default, so let's turn it off: */
2843 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2844 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2846 caption = hildon_caption_new (sizegroup,
2847 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2848 gtk_widget_show (entry_password);
2849 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2850 FALSE, FALSE, MODEST_MARGIN_HALF);
2851 gtk_widget_show (caption);
2852 g_object_unref (sizegroup);
2854 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2856 #endif /* MODEST_PLATFORM_MAEMO */
2858 if (initial_username != NULL)
2859 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
2861 /* This is not in the Maemo UI spec:
2862 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2863 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2867 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2869 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2871 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2873 modest_account_mgr_set_server_account_username (
2874 modest_runtime_get_account_mgr(), server_account_name,
2877 const gboolean username_was_changed =
2878 (strcmp (*username, initial_username) != 0);
2879 if (username_was_changed) {
2880 g_warning ("%s: tinymail does not yet support changing the "
2881 "username in the get_password() callback.\n", __FUNCTION__);
2886 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2888 /* We do not save the password in the configuration,
2889 * because this function is only called for passwords that should
2890 * not be remembered:
2891 modest_server_account_set_password (
2892 modest_runtime_get_account_mgr(), server_account_name,
2901 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2913 /* This is not in the Maemo UI spec:
2914 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2920 gtk_widget_destroy (dialog);
2922 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2926 modest_ui_actions_on_cut (GtkAction *action,
2927 ModestWindow *window)
2929 GtkWidget *focused_widget;
2930 GtkClipboard *clipboard;
2932 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2933 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2934 if (GTK_IS_EDITABLE (focused_widget)) {
2935 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2936 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2937 gtk_clipboard_store (clipboard);
2938 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2939 GtkTextBuffer *buffer;
2941 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2942 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2943 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2944 gtk_clipboard_store (clipboard);
2945 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2946 TnyList *header_list = modest_header_view_get_selected_headers (
2947 MODEST_HEADER_VIEW (focused_widget));
2948 gboolean continue_download = FALSE;
2949 gint num_of_unc_msgs;
2951 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
2953 if (num_of_unc_msgs)
2954 continue_download = connect_to_get_msg(
2955 GTK_WINDOW (window),
2958 if (num_of_unc_msgs == 0 || continue_download) {
2959 /* modest_platform_information_banner (
2960 NULL, NULL, _CS("mcen_ib_getting_items"));*/
2961 modest_header_view_cut_selection (
2962 MODEST_HEADER_VIEW (focused_widget));
2965 g_object_unref (header_list);
2966 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2967 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2972 modest_ui_actions_on_copy (GtkAction *action,
2973 ModestWindow *window)
2975 GtkClipboard *clipboard;
2976 GtkWidget *focused_widget;
2977 gboolean copied = TRUE;
2979 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2980 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2982 if (GTK_IS_LABEL (focused_widget)) {
2983 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2984 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2985 gtk_clipboard_store (clipboard);
2986 } else if (GTK_IS_EDITABLE (focused_widget)) {
2987 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2988 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2989 gtk_clipboard_store (clipboard);
2990 } else if (GTK_IS_HTML (focused_widget)) {
2991 gtk_html_copy (GTK_HTML (focused_widget));
2992 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2993 gtk_clipboard_store (clipboard);
2994 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2995 GtkTextBuffer *buffer;
2996 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2997 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2998 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2999 gtk_clipboard_store (clipboard);
3000 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3001 TnyList *header_list = modest_header_view_get_selected_headers (
3002 MODEST_HEADER_VIEW (focused_widget));
3003 gboolean continue_download = FALSE;
3004 gint num_of_unc_msgs;
3006 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3008 if (num_of_unc_msgs)
3009 continue_download = connect_to_get_msg(
3010 GTK_WINDOW (window),
3013 if (num_of_unc_msgs == 0 || continue_download) {
3014 modest_platform_information_banner (
3015 NULL, NULL, _CS("mcen_ib_getting_items"));
3016 modest_header_view_copy_selection (
3017 MODEST_HEADER_VIEW (focused_widget));
3021 g_object_unref (header_list);
3023 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3024 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3027 /* Show information banner if there was a copy to clipboard */
3029 modest_platform_information_banner (
3030 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3034 modest_ui_actions_on_undo (GtkAction *action,
3035 ModestWindow *window)
3037 ModestEmailClipboard *clipboard = NULL;
3039 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3040 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3041 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3042 /* Clear clipboard source */
3043 clipboard = modest_runtime_get_email_clipboard ();
3044 modest_email_clipboard_clear (clipboard);
3047 g_return_if_reached ();
3052 modest_ui_actions_on_redo (GtkAction *action,
3053 ModestWindow *window)
3055 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3056 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3059 g_return_if_reached ();
3065 destroy_information_note (ModestMailOperation *mail_op, gpointer user_data)
3067 /* destroy information note */
3068 gtk_widget_destroy (GTK_WIDGET(user_data));
3073 paste_as_attachment_free (gpointer data)
3075 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3077 gtk_widget_destroy (helper->banner);
3078 g_object_unref (helper->banner);
3083 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3088 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3089 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3094 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3099 modest_ui_actions_on_paste (GtkAction *action,
3100 ModestWindow *window)
3102 GtkWidget *focused_widget = NULL;
3103 GtkWidget *inf_note = NULL;
3104 ModestMailOperation *mail_op = NULL;
3106 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3107 if (GTK_IS_EDITABLE (focused_widget)) {
3108 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3109 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3110 ModestEmailClipboard *e_clipboard = NULL;
3111 e_clipboard = modest_runtime_get_email_clipboard ();
3112 if (modest_email_clipboard_cleared (e_clipboard)) {
3113 GtkTextBuffer *buffer;
3114 GtkClipboard *clipboard;
3116 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3117 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3118 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3119 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3120 ModestMailOperation *mail_op;
3121 TnyFolder *src_folder;
3124 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3125 helper->window = MODEST_MSG_EDIT_WINDOW (window);
3126 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3127 _CS("ckct_nw_pasting"));
3128 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
3129 mail_op = modest_mail_operation_new (G_OBJECT (window));
3130 if (helper->banner != NULL) {
3131 g_object_ref (G_OBJECT (helper->banner));
3132 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
3133 gtk_widget_show (GTK_WIDGET (helper->banner));
3137 modest_mail_operation_get_msgs_full (mail_op,
3139 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
3141 paste_as_attachment_free);
3144 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3145 ModestEmailClipboard *clipboard = NULL;
3146 TnyFolder *src_folder = NULL;
3147 TnyFolderStore *folder_store = NULL;
3148 TnyList *data = NULL;
3149 gboolean delete = FALSE;
3151 /* Check clipboard source */
3152 clipboard = modest_runtime_get_email_clipboard ();
3153 if (modest_email_clipboard_cleared (clipboard))
3156 /* Get elements to paste */
3157 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
3159 /* Create a new mail operation */
3160 mail_op = modest_mail_operation_new (G_OBJECT(window));
3162 /* Get destination folder */
3163 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
3165 /* transfer messages */
3169 /* Ask for user confirmation */
3171 modest_ui_actions_msgs_move_to_confirmation (GTK_WINDOW (window),
3172 TNY_FOLDER (folder_store),
3176 if (response == GTK_RESPONSE_OK) {
3177 /* Launch notification */
3178 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3179 _CS("ckct_nw_pasting"));
3180 if (inf_note != NULL) {
3181 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3182 gtk_widget_show (GTK_WIDGET(inf_note));
3185 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3186 modest_mail_operation_xfer_msgs (mail_op,
3188 TNY_FOLDER (folder_store),
3190 destroy_information_note,
3193 g_object_unref (mail_op);
3196 } else if (src_folder != NULL) {
3197 /* Launch notification */
3198 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3199 _CS("ckct_nw_pasting"));
3200 if (inf_note != NULL) {
3201 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3202 gtk_widget_show (GTK_WIDGET(inf_note));
3205 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3206 modest_mail_operation_xfer_folder (mail_op,
3210 destroy_information_note,
3216 g_object_unref (data);
3217 if (src_folder != NULL)
3218 g_object_unref (src_folder);
3219 if (folder_store != NULL)
3220 g_object_unref (folder_store);
3226 modest_ui_actions_on_select_all (GtkAction *action,
3227 ModestWindow *window)
3229 GtkWidget *focused_widget;
3231 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3232 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3233 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3234 } else if (GTK_IS_LABEL (focused_widget)) {
3235 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3236 } else if (GTK_IS_EDITABLE (focused_widget)) {
3237 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3238 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3239 GtkTextBuffer *buffer;
3240 GtkTextIter start, end;
3242 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3243 gtk_text_buffer_get_start_iter (buffer, &start);
3244 gtk_text_buffer_get_end_iter (buffer, &end);
3245 gtk_text_buffer_select_range (buffer, &start, &end);
3246 } else if (GTK_IS_HTML (focused_widget)) {
3247 gtk_html_select_all (GTK_HTML (focused_widget));
3248 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3249 GtkWidget *header_view = focused_widget;
3250 GtkTreeSelection *selection = NULL;
3252 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
3253 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3254 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3257 /* Disable window dimming management */
3258 modest_window_disable_dimming (MODEST_WINDOW(window));
3260 /* Select all messages */
3261 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3262 gtk_tree_selection_select_all (selection);
3264 /* Set focuse on header view */
3265 gtk_widget_grab_focus (header_view);
3268 /* Enable window dimming management */
3269 modest_window_enable_dimming (MODEST_WINDOW(window));
3270 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3276 modest_ui_actions_on_mark_as_read (GtkAction *action,
3277 ModestWindow *window)
3279 g_return_if_fail (MODEST_IS_WINDOW(window));
3281 /* Mark each header as read */
3282 do_headers_action (window, headers_action_mark_as_read, NULL);
3286 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3287 ModestWindow *window)
3289 g_return_if_fail (MODEST_IS_WINDOW(window));
3291 /* Mark each header as read */
3292 do_headers_action (window, headers_action_mark_as_unread, NULL);
3296 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3297 GtkRadioAction *selected,
3298 ModestWindow *window)
3302 value = gtk_radio_action_get_current_value (selected);
3303 if (MODEST_IS_WINDOW (window)) {
3304 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3309 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3310 GtkRadioAction *selected,
3311 ModestWindow *window)
3313 TnyHeaderFlags flags;
3314 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3316 flags = gtk_radio_action_get_current_value (selected);
3317 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3321 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3322 GtkRadioAction *selected,
3323 ModestWindow *window)
3327 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3329 file_format = gtk_radio_action_get_current_value (selected);
3330 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3335 modest_ui_actions_on_zoom_plus (GtkAction *action,
3336 ModestWindow *window)
3338 g_return_if_fail (MODEST_IS_WINDOW (window));
3340 modest_window_zoom_plus (MODEST_WINDOW (window));
3344 modest_ui_actions_on_zoom_minus (GtkAction *action,
3345 ModestWindow *window)
3347 g_return_if_fail (MODEST_IS_WINDOW (window));
3349 modest_window_zoom_minus (MODEST_WINDOW (window));
3353 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3354 ModestWindow *window)
3356 ModestWindowMgr *mgr;
3357 gboolean fullscreen, active;
3358 g_return_if_fail (MODEST_IS_WINDOW (window));
3360 mgr = modest_runtime_get_window_mgr ();
3362 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3363 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3365 if (active != fullscreen) {
3366 modest_window_mgr_set_fullscreen_mode (mgr, active);
3367 gtk_window_present (GTK_WINDOW (window));
3372 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3373 ModestWindow *window)
3375 ModestWindowMgr *mgr;
3376 gboolean fullscreen;
3378 g_return_if_fail (MODEST_IS_WINDOW (window));
3380 mgr = modest_runtime_get_window_mgr ();
3381 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3382 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3384 gtk_window_present (GTK_WINDOW (window));
3388 * Used by modest_ui_actions_on_details to call do_headers_action
3391 headers_action_show_details (TnyHeader *header,
3392 ModestWindow *window,
3399 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3402 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3403 gtk_widget_show_all (dialog);
3404 gtk_dialog_run (GTK_DIALOG (dialog));
3406 gtk_widget_destroy (dialog);
3410 * Show the folder details in a ModestDetailsDialog widget
3413 show_folder_details (TnyFolder *folder,
3419 dialog = modest_details_dialog_new_with_folder (window, folder);
3422 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3423 gtk_widget_show_all (dialog);
3424 gtk_dialog_run (GTK_DIALOG (dialog));
3426 gtk_widget_destroy (dialog);
3430 * Show the header details in a ModestDetailsDialog widget
3433 modest_ui_actions_on_details (GtkAction *action,
3436 TnyList * headers_list;
3440 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3443 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3446 g_object_unref (msg);
3448 headers_list = get_selected_headers (win);
3452 iter = tny_list_create_iterator (headers_list);
3454 header = TNY_HEADER (tny_iterator_get_current (iter));
3456 headers_action_show_details (header, win, NULL);
3457 g_object_unref (header);
3460 g_object_unref (iter);
3461 g_object_unref (headers_list);
3463 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3464 GtkWidget *folder_view, *header_view;
3466 /* Check which widget has the focus */
3467 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3468 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3469 if (gtk_widget_is_focus (folder_view)) {
3470 TnyFolderStore *folder_store
3471 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3472 if (!folder_store) {
3473 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3476 /* Show only when it's a folder */
3477 /* This function should not be called for account items,
3478 * because we dim the menu item for them. */
3479 if (TNY_IS_FOLDER (folder_store)) {
3480 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3483 g_object_unref (folder_store);
3486 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3487 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3488 /* Show details of each header */
3489 do_headers_action (win, headers_action_show_details, header_view);
3495 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3496 ModestMsgEditWindow *window)
3498 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3500 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3504 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3505 ModestMsgEditWindow *window)
3507 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3509 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3513 modest_ui_actions_toggle_folders_view (GtkAction *action,
3514 ModestMainWindow *main_window)
3516 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3518 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3519 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3521 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3525 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3526 ModestWindow *window)
3528 gboolean active, fullscreen = FALSE;
3529 ModestWindowMgr *mgr;
3531 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3533 /* Check if we want to toggle the toolbar vuew in fullscreen
3535 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3536 "ViewShowToolbarFullScreen")) {
3540 /* Toggle toolbar */
3541 mgr = modest_runtime_get_window_mgr ();
3542 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
3546 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3547 ModestMsgEditWindow *window)
3549 modest_msg_edit_window_select_font (window);
3553 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3554 const gchar *display_name,
3557 /* Do not change the application name if the widget has not
3558 the focus. This callback could be called even if the folder
3559 view has not the focus, because the handled signal could be
3560 emitted when the folder view is redrawn */
3561 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3563 gtk_window_set_title (window, display_name);
3565 gtk_window_set_title (window, " ");
3570 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3572 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3573 modest_msg_edit_window_select_contacts (window);
3577 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3579 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3580 modest_msg_edit_window_check_names (window, FALSE);
3584 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3586 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3587 GTK_WIDGET (user_data));
3591 * This function is used to track changes in the selection of the
3592 * folder view that is inside the "move to" dialog to enable/disable
3593 * the OK button because we do not want the user to select a disallowed
3594 * destination for a folder.
3595 * The user also not desired to be able to use NEW button on items where
3596 * folder creation is not possibel.
3599 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
3600 TnyFolderStore *folder_store,
3604 GtkWidget *dialog = NULL;
3605 GtkWidget *ok_button = NULL, *new_button = NULL;
3606 GList *children = NULL;
3607 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
3608 gboolean moving_folder = FALSE;
3609 gboolean is_local_account = TRUE;
3610 GtkWidget *folder_view = NULL;
3611 ModestTnyFolderRules rules;
3616 /* Get the OK button */
3617 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
3621 children = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
3622 ok_button = GTK_WIDGET (children->next->next->data);
3623 new_button = GTK_WIDGET (children->next->data);
3624 g_list_free (children);
3626 /* check if folder_store is an remote account */
3627 if (TNY_IS_ACCOUNT (folder_store)) {
3628 TnyAccount *local_account = NULL;
3629 ModestTnyAccountStore *account_store = NULL;
3631 account_store = modest_runtime_get_account_store ();
3632 local_account = modest_tny_account_store_get_local_folders_account (account_store);
3634 if ((gpointer) local_account != (gpointer) folder_store) {
3635 is_local_account = FALSE;
3636 /* New button should be dimmed on remote
3638 new_sensitive = FALSE;
3640 g_object_unref (local_account);
3643 /* Check the target folder rules */
3644 if (TNY_IS_FOLDER (folder_store)) {
3645 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
3646 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
3647 ok_sensitive = FALSE;
3648 new_sensitive = FALSE;
3653 /* Check if we're moving a folder */
3654 if (MODEST_IS_MAIN_WINDOW (user_data)) {
3655 /* Get the widgets */
3656 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
3657 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3658 if (gtk_widget_is_focus (folder_view))
3659 moving_folder = TRUE;
3662 if (moving_folder) {
3663 TnyFolderStore *moved_folder = NULL, *parent = NULL;
3665 /* Get the folder to move */
3666 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3668 /* Check that we're not moving to the same folder */
3669 if (TNY_IS_FOLDER (moved_folder)) {
3670 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
3671 if (parent == folder_store)
3672 ok_sensitive = FALSE;
3673 g_object_unref (parent);
3676 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
3677 /* Do not allow to move to an account unless it's the
3678 local folders account */
3679 if (!is_local_account)
3680 ok_sensitive = FALSE;
3683 if (ok_sensitive && (moved_folder == folder_store)) {
3684 /* Do not allow to move to itself */
3685 ok_sensitive = FALSE;
3687 g_object_unref (moved_folder);
3689 TnyHeader *header = NULL;
3690 TnyFolder *src_folder = NULL;
3692 /* Moving a message */
3693 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
3694 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (user_data));
3695 src_folder = tny_header_get_folder (header);
3696 g_object_unref (header);
3699 TNY_FOLDER (modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view)));
3702 /* Do not allow to move the msg to the same folder */
3703 /* Do not allow to move the msg to an account */
3704 if ((gpointer) src_folder == (gpointer) folder_store ||
3705 TNY_IS_ACCOUNT (folder_store))
3706 ok_sensitive = FALSE;
3707 g_object_unref (src_folder);
3711 /* Set sensitivity of the OK button */
3712 gtk_widget_set_sensitive (ok_button, ok_sensitive);
3713 /* Set sensitivity of the NEW button */
3714 gtk_widget_set_sensitive (new_button, new_sensitive);
3718 create_move_to_dialog (GtkWindow *win,
3719 GtkWidget *folder_view,
3720 GtkWidget **tree_view)
3722 GtkWidget *dialog, *scroll;
3723 GtkWidget *new_button;
3725 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3727 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3730 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
3731 /* We do this manually so GTK+ does not associate a response ID for
3733 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
3734 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3735 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
3737 /* Create scrolled window */
3738 scroll = gtk_scrolled_window_new (NULL, NULL);
3739 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3740 GTK_POLICY_AUTOMATIC,
3741 GTK_POLICY_AUTOMATIC);
3743 /* Create folder view */
3744 *tree_view = modest_platform_create_folder_view (NULL);
3746 /* Track changes in the selection to
3747 * disable the OK button whenever "Move to" is not possible
3748 * disbale NEW button whenever New is not possible */
3749 g_signal_connect (*tree_view,
3750 "folder_selection_changed",
3751 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
3754 /* Listen to clicks on New button */
3755 g_signal_connect (G_OBJECT (new_button),
3757 G_CALLBACK(create_move_to_dialog_on_new_folder),
3760 /* It could happen that we're trying to move a message from a
3761 window (msg window for example) after the main window was
3762 closed, so we can not just get the model of the folder
3764 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
3765 const gchar *visible_id = NULL;
3767 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
3768 MODEST_FOLDER_VIEW(*tree_view));
3771 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
3773 /* Show the same account than the one that is shown in the main window */
3774 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
3777 const gchar *active_account_name = NULL;
3778 ModestAccountMgr *mgr = NULL;
3779 ModestAccountData *acc_data = NULL;
3781 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3782 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3784 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
3785 mgr = modest_runtime_get_account_mgr ();
3786 acc_data = modest_account_mgr_get_account_data (mgr, active_account_name);
3788 /* Set the new visible & active account */
3789 if (acc_data && acc_data->store_account) {
3790 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
3791 acc_data->store_account->account_name);
3792 modest_account_mgr_free_account_data (mgr, acc_data);
3796 /* Hide special folders */
3797 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3799 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3801 /* Add scroll to dialog */
3802 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3803 scroll, TRUE, TRUE, 0);
3805 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3806 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3812 * Returns TRUE if at least one of the headers of the list belongs to
3813 * a message that has been fully retrieved.
3815 #if 0 /* no longer in use. delete in 2007.10 */
3817 has_retrieved_msgs (TnyList *list)
3820 gboolean found = FALSE;
3822 iter = tny_list_create_iterator (list);
3823 while (!tny_iterator_is_done (iter) && !found) {
3825 TnyHeaderFlags flags = 0;
3827 header = TNY_HEADER (tny_iterator_get_current (iter));
3829 flags = tny_header_get_flags (header);
3830 if (flags & TNY_HEADER_FLAG_CACHED)
3831 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3834 g_object_unref (header);
3838 tny_iterator_next (iter);
3840 g_object_unref (iter);
3848 * Shows a confirmation dialog to the user when we're moving messages
3849 * from a remote server to the local storage. Returns the dialog
3850 * response. If it's other kind of movement then it always returns
3853 * This one is used by the next functions:
3854 * modest_ui_actions_on_paste - commented out
3855 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
3858 modest_ui_actions_msgs_move_to_confirmation (GtkWindow *win,
3859 TnyFolder *dest_folder,
3863 gint response = GTK_RESPONSE_OK;
3865 /* return with OK if the destination is a remote folder */
3866 if (modest_tny_folder_is_remote_folder (dest_folder))
3867 return GTK_RESPONSE_OK;
3869 TnyFolder *src_folder = NULL;
3870 TnyIterator *iter = NULL;
3871 TnyHeader *header = NULL;
3873 /* Get source folder */
3874 iter = tny_list_create_iterator (headers);
3875 header = TNY_HEADER (tny_iterator_get_current (iter));
3877 src_folder = tny_header_get_folder (header);
3878 g_object_unref (header);
3880 g_object_unref (iter);
3882 /* if no src_folder, message may be an attahcment */
3883 if (src_folder == NULL)
3884 return GTK_RESPONSE_CANCEL;
3886 /* If the source is a local or MMC folder */
3887 if (!modest_tny_folder_is_remote_folder (src_folder)) {
3888 g_object_unref (src_folder);
3889 return GTK_RESPONSE_OK;
3891 g_object_unref (src_folder);
3893 /* now if offline we ask the user */
3894 if(connect_to_get_msg( GTK_WINDOW (win),
3895 tny_list_get_length (headers)))
3896 response = GTK_RESPONSE_OK;
3898 response = GTK_RESPONSE_CANCEL;
3906 move_to_cb (ModestMailOperation *mail_op, gpointer user_data)
3908 MoveToHelper *helper = (MoveToHelper *) user_data;
3910 /* Note that the operation could have failed, in that case do
3912 if (modest_mail_operation_get_status (mail_op) ==
3913 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
3915 GObject *object = modest_mail_operation_get_source (mail_op);
3916 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
3917 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
3919 if (!modest_msg_view_window_select_next_message (self))
3920 if (!modest_msg_view_window_select_previous_message (self))
3921 /* No more messages to view, so close this window */
3922 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3923 } else if (MODEST_IS_MAIN_WINDOW (object) && helper->reference != NULL) {
3924 GtkWidget *header_view;
3926 GtkTreeSelection *sel;
3928 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
3929 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3930 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
3931 path = gtk_tree_row_reference_get_path (helper->reference);
3932 gtk_tree_selection_select_path (sel, path);
3933 gtk_tree_path_free (path);
3935 g_object_unref (object);
3938 /* Close the "Pasting" information banner */
3939 gtk_widget_destroy (GTK_WIDGET(helper->banner));
3940 if (helper->reference != NULL)
3941 gtk_tree_row_reference_free (helper->reference);
3946 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3949 ModestWindow *main_window = NULL;
3950 GtkWidget *folder_view = NULL;
3951 GObject *win = modest_mail_operation_get_source (mail_op);
3952 const GError *error = NULL;
3953 const gchar *message = NULL;
3955 /* Get error message */
3956 error = modest_mail_operation_get_error (mail_op);
3957 if (error != NULL && error->message != NULL) {
3958 message = error->message;
3960 message = _("mail_in_ui_folder_move_target_error");
3963 /* Disable next automatic folder selection */
3964 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ());
3965 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
3966 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3967 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
3969 if (user_data && TNY_IS_FOLDER (user_data)) {
3970 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3971 TNY_FOLDER (user_data), FALSE);
3974 /* Show notification dialog */
3975 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3976 g_object_unref (win);
3980 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3983 GObject *win = modest_mail_operation_get_source (mail_op);
3984 const GError *error = modest_mail_operation_get_error (mail_op);
3986 g_return_if_fail (error != NULL);
3987 if (error->message != NULL)
3988 g_printerr ("modest: %s\n", error->message);
3990 g_printerr ("modest: unkonw error on send&receive operation");
3992 /* Show error message */
3993 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3994 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3995 /* _CS("sfil_ib_unable_to_receive")); */
3997 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3998 /* _CS("sfil_ib_unable_to_send")); */
3999 g_object_unref (win);
4003 open_msg_for_purge_cb (ModestMailOperation *mail_op,
4010 gint pending_purges = 0;
4011 gboolean some_purged = FALSE;
4012 ModestWindow *win = MODEST_WINDOW (user_data);
4013 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
4015 /* If there was any error */
4016 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
4017 modest_window_mgr_unregister_header (mgr, header);
4021 /* Once the message has been retrieved for purging, we check if
4022 * it's all ok for purging */
4024 parts = tny_simple_list_new ();
4025 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
4026 iter = tny_list_create_iterator (parts);
4028 while (!tny_iterator_is_done (iter)) {
4030 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4031 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
4032 if (tny_mime_part_is_purged (part))
4039 g_object_unref (part);
4041 tny_iterator_next (iter);
4043 g_object_unref (iter);
4046 if (pending_purges>0) {
4048 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
4050 if (response == GTK_RESPONSE_OK) {
4051 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
4052 iter = tny_list_create_iterator (parts);
4053 while (!tny_iterator_is_done (iter)) {
4056 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4057 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
4058 tny_mime_part_set_purged (part);
4061 g_object_unref (part);
4063 tny_iterator_next (iter);
4066 tny_msg_rewrite_cache (msg);
4069 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
4071 g_object_unref (iter);
4073 modest_window_mgr_unregister_header (mgr, header);
4075 g_object_unref (parts);
4079 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
4080 ModestMainWindow *win)
4082 GtkWidget *header_view;
4083 TnyList *header_list;
4086 TnyHeaderFlags flags;
4087 ModestWindow *msg_view_window = NULL;
4090 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4092 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4093 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4095 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
4097 if (tny_list_get_length (header_list) == 1) {
4098 iter = tny_list_create_iterator (header_list);
4099 header = TNY_HEADER (tny_iterator_get_current (iter));
4100 g_object_unref (iter);
4105 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
4106 header, &msg_view_window);
4107 flags = tny_header_get_flags (header);
4108 if (!(flags & TNY_HEADER_FLAG_CACHED))
4111 if (msg_view_window != NULL)
4112 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
4114 /* do nothing; uid was registered before, so window is probably on it's way */
4115 g_warning ("debug: header %p has already been registered", header);
4118 ModestMailOperation *mail_op = NULL;
4119 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
4120 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
4121 modest_ui_actions_get_msgs_full_error_handler,
4123 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4124 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
4126 g_object_unref (mail_op);
4129 g_object_unref (header);
4131 g_object_unref (header_list);
4135 * Utility function that transfer messages from both the main window
4136 * and the msg view window when using the "Move to" dialog
4139 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
4142 TnyList *headers = NULL;
4143 TnyAccount *dst_account = NULL;
4144 const gchar *proto_str = NULL;
4145 gboolean dst_is_pop = FALSE;
4147 if (!TNY_IS_FOLDER (dst_folder)) {
4148 modest_platform_information_banner (GTK_WIDGET (win),
4150 _CS("ckdg_ib_unable_to_move_to_current_location"));
4154 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
4155 proto_str = tny_account_get_proto (dst_account);
4157 /* tinymail will return NULL for local folders it seems */
4158 dst_is_pop = proto_str &&
4159 (modest_protocol_info_get_transport_store_protocol (proto_str) ==
4160 MODEST_PROTOCOL_STORE_POP);
4162 g_object_unref (dst_account);
4164 /* Get selected headers */
4165 headers = get_selected_headers (MODEST_WINDOW (win));
4168 modest_platform_information_banner (GTK_WIDGET (win),
4170 ngettext("mail_in_ui_folder_move_target_error",
4171 "mail_in_ui_folder_move_targets_error",
4172 tny_list_get_length (headers)));
4173 g_object_unref (headers);
4177 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4178 helper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4179 _CS("ckct_nw_pasting"));
4180 if (helper->banner != NULL) {
4181 gtk_window_set_modal (GTK_WINDOW(helper->banner), FALSE);
4182 gtk_widget_show (GTK_WIDGET(helper->banner));
4185 if (MODEST_IS_MAIN_WINDOW (win)) {
4186 GtkWidget *header_view =
4187 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
4188 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4189 helper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
4192 ModestMailOperation *mail_op =
4193 modest_mail_operation_new_with_error_handling (G_OBJECT(win),
4194 modest_ui_actions_move_folder_error_handler,
4196 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4199 modest_mail_operation_xfer_msgs (mail_op,
4201 TNY_FOLDER (dst_folder),
4206 g_object_unref (G_OBJECT (mail_op));
4207 g_object_unref (headers);
4211 * UI handler for the "Move to" action when invoked from the
4215 modest_ui_actions_on_main_window_move_to (GtkAction *action,
4216 GtkWidget *folder_view,
4217 TnyFolderStore *dst_folder,
4218 ModestMainWindow *win)
4220 ModestHeaderView *header_view = NULL;
4221 ModestMailOperation *mail_op = NULL;
4222 TnyFolderStore *src_folder;
4223 gboolean online = (tny_device_is_online (modest_runtime_get_device()));
4225 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4227 /* Get the source folder */
4228 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4230 /* Get header view */
4231 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
4233 /* Get folder or messages to transfer */
4234 if (gtk_widget_is_focus (folder_view)) {
4235 GtkTreeSelection *sel;
4236 gboolean do_xfer = TRUE;
4238 /* Allow only to transfer folders to the local root folder */
4239 if (TNY_IS_ACCOUNT (dst_folder) &&
4240 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder)) {
4242 } else if (!TNY_IS_FOLDER (src_folder)) {
4243 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
4245 } else if (!online && modest_platform_is_network_folderstore(src_folder)) {
4246 guint num_headers = tny_folder_get_all_count(TNY_FOLDER(src_folder));
4247 if (!connect_to_get_msg(GTK_WINDOW(win), num_headers)) {
4253 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4254 helper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4255 _CS("ckct_nw_pasting"));
4256 if (helper->banner != NULL) {
4257 gtk_window_set_modal (GTK_WINDOW(helper->banner), FALSE);
4258 gtk_widget_show (GTK_WIDGET(helper->banner));
4260 /* Clean folder on header view before moving it */
4261 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
4262 gtk_tree_selection_unselect_all (sel);
4265 modest_mail_operation_new_with_error_handling (G_OBJECT(win),
4266 modest_ui_actions_move_folder_error_handler,
4268 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4271 /* Select *after* the changes */
4272 /* TODO: this function hangs UI after transfer */
4273 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
4274 /* TNY_FOLDER (src_folder), TRUE); */
4276 modest_mail_operation_xfer_folder (mail_op,
4277 TNY_FOLDER (src_folder),
4282 /* Unref mail operation */
4283 g_object_unref (G_OBJECT (mail_op));
4285 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
4286 gboolean do_xfer = TRUE;
4287 /* Ask for confirmation if the source folder is remote and we're not connected */
4288 if (!online && modest_platform_is_network_folderstore(src_folder)) {
4289 TnyList *headers = modest_header_view_get_selected_headers(header_view);
4290 if (!msgs_already_deleted_from_server(headers, src_folder)) {
4291 guint num_headers = tny_list_get_length(headers);
4292 if (!connect_to_get_msg(GTK_WINDOW(win), num_headers)) {
4296 g_object_unref(headers);
4298 if (do_xfer) /* Transfer messages */
4299 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4303 g_object_unref (src_folder);
4308 * UI handler for the "Move to" action when invoked from the
4309 * ModestMsgViewWindow
4312 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
4313 TnyFolderStore *dst_folder,
4314 ModestMsgViewWindow *win)
4316 TnyHeader *header = NULL;
4317 TnyFolderStore *src_folder;
4319 /* Create header list */
4320 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
4321 src_folder = TNY_FOLDER_STORE(tny_header_get_folder(header));
4322 g_object_unref (header);
4324 /* Transfer the message if online or confirmed by the user */
4325 if (tny_device_is_online (modest_runtime_get_device()) || remote_folder_is_pop(src_folder) ||
4326 (modest_platform_is_network_folderstore(src_folder) && connect_to_get_msg(GTK_WINDOW(win), 1))) {
4327 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4330 g_object_unref (src_folder);
4334 modest_ui_actions_on_move_to (GtkAction *action,
4337 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
4339 TnyFolderStore *dst_folder = NULL;
4340 ModestMainWindow *main_window;
4342 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
4343 MODEST_IS_MSG_VIEW_WINDOW (win));
4345 /* Get the main window if exists */
4346 if (MODEST_IS_MAIN_WINDOW (win))
4347 main_window = MODEST_MAIN_WINDOW (win);
4350 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
4352 /* Get the folder view widget if exists */
4354 folder_view = modest_main_window_get_child_widget (main_window,
4355 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4359 /* Create and run the dialog */
4360 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
4361 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
4362 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4363 result = gtk_dialog_run (GTK_DIALOG(dialog));
4364 g_object_ref (tree_view);
4365 gtk_widget_destroy (dialog);
4367 if (result != GTK_RESPONSE_ACCEPT)
4370 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
4371 /* Do window specific stuff */
4372 if (MODEST_IS_MAIN_WINDOW (win)) {
4373 modest_ui_actions_on_main_window_move_to (action,
4376 MODEST_MAIN_WINDOW (win));
4378 modest_ui_actions_on_msg_view_window_move_to (action,
4380 MODEST_MSG_VIEW_WINDOW (win));
4384 g_object_unref (dst_folder);
4388 * Calls #HeadersFunc for each header already selected in the main
4389 * window or the message currently being shown in the msg view window
4392 do_headers_action (ModestWindow *win,
4396 TnyList *headers_list = NULL;
4397 TnyIterator *iter = NULL;
4398 TnyHeader *header = NULL;
4399 TnyFolder *folder = NULL;
4402 headers_list = get_selected_headers (win);
4406 /* Get the folder */
4407 iter = tny_list_create_iterator (headers_list);
4408 header = TNY_HEADER (tny_iterator_get_current (iter));
4410 folder = tny_header_get_folder (header);
4411 g_object_unref (header);
4414 /* Call the function for each header */
4415 while (!tny_iterator_is_done (iter)) {
4416 header = TNY_HEADER (tny_iterator_get_current (iter));
4417 func (header, win, user_data);
4418 g_object_unref (header);
4419 tny_iterator_next (iter);
4422 /* Trick: do a poke status in order to speed up the signaling
4424 tny_folder_poke_status (folder);
4427 g_object_unref (folder);
4428 g_object_unref (iter);
4429 g_object_unref (headers_list);
4433 modest_ui_actions_view_attachment (GtkAction *action,
4434 ModestWindow *window)
4436 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4437 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4439 /* not supported window for this action */
4440 g_return_if_reached ();
4445 modest_ui_actions_save_attachments (GtkAction *action,
4446 ModestWindow *window)
4448 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4449 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4451 /* not supported window for this action */
4452 g_return_if_reached ();
4457 modest_ui_actions_remove_attachments (GtkAction *action,
4458 ModestWindow *window)
4460 if (MODEST_IS_MAIN_WINDOW (window)) {
4461 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4462 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4463 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4465 /* not supported window for this action */
4466 g_return_if_reached ();
4471 modest_ui_actions_on_settings (GtkAction *action,
4476 dialog = modest_platform_get_global_settings_dialog ();
4477 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4478 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4479 gtk_widget_show_all (dialog);
4481 gtk_dialog_run (GTK_DIALOG (dialog));
4483 gtk_widget_destroy (dialog);
4487 modest_ui_actions_on_help (GtkAction *action,
4490 const gchar *help_id = NULL;
4492 if (MODEST_IS_MAIN_WINDOW (win)) {
4493 GtkWidget *folder_view;
4494 TnyFolderStore *folder_store;
4496 /* Get selected folder */
4497 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4498 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4499 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4501 /* Switch help_id */
4502 if (TNY_IS_FOLDER (folder_store)) {
4503 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4504 case TNY_FOLDER_TYPE_NORMAL:
4505 help_id = "applications_email_managefolders";
4507 case TNY_FOLDER_TYPE_INBOX:
4508 help_id = "applications_email_inbox";
4510 case TNY_FOLDER_TYPE_OUTBOX:
4511 help_id = "applications_email_outbox";
4513 case TNY_FOLDER_TYPE_SENT:
4514 help_id = "applications_email_sent";
4516 case TNY_FOLDER_TYPE_DRAFTS:
4517 help_id = "applications_email_drafts";
4519 case TNY_FOLDER_TYPE_ARCHIVE:
4520 help_id = "applications_email_managefolders";
4523 help_id = "applications_email_managefolders";
4526 help_id = "applications_email_mainview";
4528 g_object_unref (folder_store);
4529 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4530 help_id = "applications_email_viewer";
4531 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4532 help_id = "applications_email_editor";
4534 modest_platform_show_help (GTK_WINDOW (win), help_id);
4538 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4539 ModestWindow *window)
4541 ModestMailOperation *mail_op;
4545 headers = get_selected_headers (window);
4549 /* Create mail operation */
4550 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (window),
4551 modest_ui_actions_get_msgs_full_error_handler,
4553 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4554 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4557 g_object_unref (headers);
4558 g_object_unref (mail_op);
4562 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4563 ModestWindow *window)
4565 g_return_if_fail (MODEST_IS_WINDOW (window));
4568 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4572 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4573 ModestWindow *window)
4575 g_return_if_fail (MODEST_IS_WINDOW (window));
4578 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4582 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4583 ModestWindow *window)
4585 g_return_if_fail (MODEST_IS_WINDOW (window));
4588 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4592 modest_ui_actions_on_format_menu_activated (GtkAction *action,
4593 ModestWindow *window)
4595 g_return_if_fail (MODEST_IS_WINDOW (window));
4598 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4602 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4603 ModestWindow *window)
4605 g_return_if_fail (MODEST_IS_WINDOW (window));
4608 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4612 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4613 ModestWindow *window)
4615 g_return_if_fail (MODEST_IS_WINDOW (window));
4618 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4622 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4623 ModestWindow *window)
4625 g_return_if_fail (MODEST_IS_WINDOW (window));
4628 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4632 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4633 ModestWindow *window)
4635 g_return_if_fail (MODEST_IS_WINDOW (window));
4638 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4642 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4643 ModestWindow *window)
4645 g_return_if_fail (MODEST_IS_WINDOW (window));
4648 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4652 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4654 g_return_if_fail (MODEST_IS_WINDOW (window));
4657 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4661 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4663 g_return_if_fail (MODEST_IS_WINDOW (window));
4665 modest_platform_show_search_messages (GTK_WINDOW (window));
4669 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4671 g_return_if_fail (MODEST_IS_WINDOW (win));
4672 modest_platform_show_addressbook (GTK_WINDOW (win));
4677 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4678 ModestWindow *window)
4680 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4682 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4686 on_send_receive_finished (ModestMailOperation *mail_op,
4689 /* Set send/receive operation finished */
4690 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW (user_data));
4695 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
4701 const gchar* server_name = NULL;
4702 TnyTransportAccount *server_account;
4703 gchar *message = NULL;
4705 /* Don't show anything if the user cancelled something */
4706 if (err->code == TNY_TRANSPORT_ACCOUNT_ERROR_SEND_USER_CANCEL)
4709 /* Get the server name: */
4711 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
4712 if (server_account) {
4713 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
4715 g_object_unref (server_account);
4716 server_account = NULL;
4719 g_return_if_fail (server_name);
4721 /* Show the appropriate message text for the GError: */
4722 switch (err->code) {
4723 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_HOST_LOOKUP_FAILED:
4724 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4726 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_SERVICE_UNAVAILABLE:
4727 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4729 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_AUTHENTICATION_NOT_SUPPORTED:
4730 message = g_strdup_printf (_("emev_ni_ui_smtp_authentication_fail_error"), server_name);
4732 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND:
4733 message = g_strdup (_("emev_ib_ui_smtp_send_error"));
4736 g_return_if_reached ();
4739 /* TODO if the username or the password where not defined we
4740 should show the Accounts Settings dialog or the Connection
4741 specific SMTP server window */
4743 modest_platform_run_information_dialog (NULL, message);
4748 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
4753 ModestMainWindow *main_window = NULL;
4754 ModestWindowMgr *mgr = NULL;
4755 GtkWidget *folder_view = NULL, *header_view = NULL;
4756 TnyFolderStore *selected_folder = NULL;
4757 TnyFolderType folder_type;
4759 mgr = modest_runtime_get_window_mgr ();
4760 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr));
4765 /* Check if selected folder is OUTBOX */
4766 folder_view = modest_main_window_get_child_widget (main_window,
4767 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4768 header_view = modest_main_window_get_child_widget (main_window,
4769 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4771 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4772 if (!TNY_IS_FOLDER (selected_folder))
4775 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
4776 #if GTK_CHECK_VERSION(2, 8, 0)
4777 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
4778 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
4779 GtkTreeViewColumn *tree_column;
4781 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
4782 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
4783 gtk_tree_view_column_queue_resize (tree_column);
4786 gtk_widget_queue_draw (header_view);
4791 if (selected_folder != NULL)
4792 g_object_unref (selected_folder);