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 /* Offer the connection dialog, if necessary: */
2207 if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
2210 /* FIXME: Code added just for testing. The final version will
2211 use the send queue provided by tinymail and some
2213 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2214 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2216 account_name = modest_account_mgr_get_default_account (account_mgr);
2218 if (!account_name) {
2219 /* Run account setup wizard */
2220 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window)))
2224 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2226 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2227 account_name = g_strdup (data->account_name);
2230 /* Get the currently-active transport account for this modest account: */
2231 TnyTransportAccount *transport_account =
2232 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2233 (modest_runtime_get_account_store(),
2235 if (!transport_account) {
2236 /* Run account setup wizard */
2237 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2241 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2243 /* Create the mail operation */
2244 ModestMailOperation *mail_operation = modest_mail_operation_new (G_OBJECT(edit_window));
2245 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2247 modest_mail_operation_send_new_mail (mail_operation,
2259 data->priority_flags);
2263 g_free (account_name);
2264 g_object_unref (G_OBJECT (transport_account));
2265 g_object_unref (G_OBJECT (mail_operation));
2267 modest_msg_edit_window_free_msg_data (edit_window, data);
2268 modest_msg_edit_window_set_sent (edit_window, TRUE);
2270 /* Save settings and close the window: */
2271 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2275 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2276 ModestMsgEditWindow *window)
2278 ModestMsgEditFormatState *format_state = NULL;
2280 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2281 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2283 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2286 format_state = modest_msg_edit_window_get_format_state (window);
2287 g_return_if_fail (format_state != NULL);
2289 format_state->bold = gtk_toggle_action_get_active (action);
2290 modest_msg_edit_window_set_format_state (window, format_state);
2291 g_free (format_state);
2296 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2297 ModestMsgEditWindow *window)
2299 ModestMsgEditFormatState *format_state = NULL;
2301 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2302 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2304 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2307 format_state = modest_msg_edit_window_get_format_state (window);
2308 g_return_if_fail (format_state != NULL);
2310 format_state->italics = gtk_toggle_action_get_active (action);
2311 modest_msg_edit_window_set_format_state (window, format_state);
2312 g_free (format_state);
2317 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2318 ModestMsgEditWindow *window)
2320 ModestMsgEditFormatState *format_state = NULL;
2322 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2323 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2325 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2328 format_state = modest_msg_edit_window_get_format_state (window);
2329 g_return_if_fail (format_state != NULL);
2331 format_state->bullet = gtk_toggle_action_get_active (action);
2332 modest_msg_edit_window_set_format_state (window, format_state);
2333 g_free (format_state);
2338 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2339 GtkRadioAction *selected,
2340 ModestMsgEditWindow *window)
2342 ModestMsgEditFormatState *format_state = NULL;
2343 GtkJustification value;
2345 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2347 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2350 value = gtk_radio_action_get_current_value (selected);
2352 format_state = modest_msg_edit_window_get_format_state (window);
2353 g_return_if_fail (format_state != NULL);
2355 format_state->justification = value;
2356 modest_msg_edit_window_set_format_state (window, format_state);
2357 g_free (format_state);
2361 modest_ui_actions_on_select_editor_color (GtkAction *action,
2362 ModestMsgEditWindow *window)
2364 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2365 g_return_if_fail (GTK_IS_ACTION (action));
2367 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2370 modest_msg_edit_window_select_color (window);
2374 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2375 ModestMsgEditWindow *window)
2377 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2378 g_return_if_fail (GTK_IS_ACTION (action));
2380 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2383 modest_msg_edit_window_select_background_color (window);
2387 modest_ui_actions_on_insert_image (GtkAction *action,
2388 ModestMsgEditWindow *window)
2390 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2391 g_return_if_fail (GTK_IS_ACTION (action));
2393 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2396 modest_msg_edit_window_insert_image (window);
2400 modest_ui_actions_on_attach_file (GtkAction *action,
2401 ModestMsgEditWindow *window)
2403 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2404 g_return_if_fail (GTK_IS_ACTION (action));
2406 modest_msg_edit_window_offer_attach_file (window);
2410 modest_ui_actions_on_remove_attachments (GtkAction *action,
2411 ModestMsgEditWindow *window)
2413 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2414 g_return_if_fail (GTK_IS_ACTION (action));
2416 modest_msg_edit_window_remove_attachments (window, NULL);
2420 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2423 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2424 const GError *error = modest_mail_operation_get_error (mail_op);
2427 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2428 _("mail_in_ui_folder_create_error"));
2433 modest_ui_actions_create_folder(GtkWidget *parent_window,
2434 GtkWidget *folder_view)
2436 TnyFolderStore *parent_folder;
2438 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2440 if (parent_folder) {
2441 gboolean finished = FALSE;
2443 gchar *folder_name = NULL, *suggested_name = NULL;
2444 const gchar *proto_str = NULL;
2445 TnyAccount *account;
2447 if (TNY_IS_ACCOUNT (parent_folder))
2448 account = g_object_ref (parent_folder);
2450 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2451 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2453 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2454 MODEST_PROTOCOL_STORE_POP) {
2456 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2458 g_object_unref (account);
2460 /* Run the new folder dialog */
2462 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2467 g_free (suggested_name);
2468 suggested_name = NULL;
2470 if (result == GTK_RESPONSE_REJECT) {
2473 ModestMailOperation *mail_op;
2474 TnyFolder *new_folder = NULL;
2476 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
2477 modest_ui_actions_new_folder_error_handler,
2480 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2482 new_folder = modest_mail_operation_create_folder (mail_op,
2484 (const gchar *) folder_name);
2486 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2489 g_object_unref (new_folder);
2492 g_object_unref (mail_op);
2495 suggested_name = folder_name;
2499 g_object_unref (parent_folder);
2504 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2506 GtkWidget *folder_view;
2508 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2510 folder_view = modest_main_window_get_child_widget (main_window,
2511 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2515 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2519 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2522 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2523 const GError *error = NULL;
2524 const gchar *message = NULL;
2526 /* Get error message */
2527 error = modest_mail_operation_get_error (mail_op);
2529 g_return_if_reached ();
2531 switch (error->code) {
2532 case MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS:
2533 message = _CS("ckdg_ib_folder_already_exists");
2536 g_return_if_reached ();
2539 modest_platform_information_banner (GTK_WIDGET (window), NULL, message);
2543 modest_ui_actions_on_rename_folder (GtkAction *action,
2544 ModestMainWindow *main_window)
2546 TnyFolderStore *folder;
2547 GtkWidget *folder_view;
2548 GtkWidget *header_view;
2550 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2552 folder_view = modest_main_window_get_child_widget (main_window,
2553 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2557 header_view = modest_main_window_get_child_widget (main_window,
2558 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2563 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2568 if (TNY_IS_FOLDER (folder)) {
2571 const gchar *current_name;
2572 TnyFolderStore *parent;
2573 gboolean do_rename = TRUE;
2575 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2576 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
2577 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
2578 parent, current_name,
2580 g_object_unref (parent);
2582 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
2584 } else if (modest_platform_is_network_folderstore(folder) &&
2585 !tny_device_is_online (modest_runtime_get_device())) {
2586 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2587 do_rename = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2588 g_object_unref(account);
2592 ModestMailOperation *mail_op;
2593 GtkTreeSelection *sel = NULL;
2596 modest_mail_operation_new_with_error_handling (G_OBJECT(main_window),
2597 modest_ui_actions_rename_folder_error_handler,
2600 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2603 /* Clear the headers view */
2604 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2605 gtk_tree_selection_unselect_all (sel);
2607 /* Select *after* the changes */
2608 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2609 TNY_FOLDER(folder), TRUE);
2611 /* Actually rename the folder */
2612 modest_mail_operation_rename_folder (mail_op,
2613 TNY_FOLDER (folder),
2614 (const gchar *) folder_name);
2616 g_object_unref (mail_op);
2617 g_free (folder_name);
2620 g_object_unref (folder);
2624 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2627 GObject *win = modest_mail_operation_get_source (mail_op);
2629 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2630 _("mail_in_ui_folder_delete_error"));
2631 g_object_unref (win);
2635 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2637 TnyFolderStore *folder;
2638 GtkWidget *folder_view;
2641 gboolean do_delete = TRUE;
2643 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (main_window), FALSE);
2645 folder_view = modest_main_window_get_child_widget (main_window,
2646 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2650 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2652 /* Show an error if it's an account */
2653 if (!TNY_IS_FOLDER (folder)) {
2654 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2655 _("mail_in_ui_folder_delete_error"));
2656 g_object_unref (G_OBJECT (folder));
2661 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2662 tny_folder_get_name (TNY_FOLDER (folder)));
2663 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2664 (const gchar *) message);
2667 if (response != GTK_RESPONSE_OK) {
2669 } else if (modest_platform_is_network_folderstore(folder) &&
2670 !tny_device_is_online (modest_runtime_get_device())) {
2671 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2672 do_delete = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2673 g_object_unref(account);
2677 ModestMailOperation *mail_op;
2678 GtkTreeSelection *sel;
2680 /* Unselect the folder before deleting it to free the headers */
2681 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2682 gtk_tree_selection_unselect_all (sel);
2684 /* Create the mail operation */
2686 modest_mail_operation_new_with_error_handling (G_OBJECT(main_window),
2687 modest_ui_actions_delete_folder_error_handler,
2690 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2692 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2693 g_object_unref (G_OBJECT (mail_op));
2696 g_object_unref (G_OBJECT (folder));
2702 modest_ui_actions_on_delete_folder (GtkAction *action,
2703 ModestMainWindow *main_window)
2705 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2707 if (delete_folder (main_window, FALSE)) {
2708 GtkWidget *folder_view;
2710 folder_view = modest_main_window_get_child_widget (main_window,
2711 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2712 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2717 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2719 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2721 delete_folder (main_window, TRUE);
2726 show_error (GtkWidget *parent_widget, const gchar* text)
2728 hildon_banner_show_information(parent_widget, NULL, text);
2731 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2733 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2740 gtk_dialog_run (dialog);
2741 gtk_widget_destroy (GTK_WIDGET (dialog));
2746 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2747 const gchar* server_account_name,
2752 ModestMainWindow *main_window)
2754 g_return_if_fail(server_account_name);
2755 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2757 /* Initalize output parameters: */
2764 #ifdef MODEST_PLATFORM_MAEMO
2765 /* Maemo uses a different (awkward) button order,
2766 * It should probably just use gtk_alternative_dialog_button_order ().
2768 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2771 _("mcen_bd_dialog_ok"),
2772 GTK_RESPONSE_ACCEPT,
2773 _("mcen_bd_dialog_cancel"),
2774 GTK_RESPONSE_REJECT,
2777 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2781 GTK_RESPONSE_REJECT,
2783 GTK_RESPONSE_ACCEPT,
2785 #endif /* MODEST_PLATFORM_MAEMO */
2787 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2789 gchar *server_name = modest_account_mgr_get_server_account_hostname (
2790 modest_runtime_get_account_mgr(), server_account_name);
2791 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2792 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2797 /* This causes a warning because the logical ID has no %s in it,
2798 * though the translation does, but there is not much we can do about that: */
2799 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2800 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2803 g_free (server_name);
2807 gchar *initial_username = modest_account_mgr_get_server_account_username (
2808 modest_runtime_get_account_mgr(), server_account_name);
2810 GtkWidget *entry_username = gtk_entry_new ();
2811 if (initial_username)
2812 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2813 /* Dim this if a connection has ever succeeded with this username,
2814 * as per the UI spec: */
2815 const gboolean username_known =
2816 modest_account_mgr_get_server_account_username_has_succeeded(
2817 modest_runtime_get_account_mgr(), server_account_name);
2818 gtk_widget_set_sensitive (entry_username, !username_known);
2820 #ifdef MODEST_PLATFORM_MAEMO
2821 /* Auto-capitalization is the default, so let's turn it off: */
2822 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2824 /* Create a size group to be used by all captions.
2825 * Note that HildonCaption does not create a default size group if we do not specify one.
2826 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2827 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2829 GtkWidget *caption = hildon_caption_new (sizegroup,
2830 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2831 gtk_widget_show (entry_username);
2832 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2833 FALSE, FALSE, MODEST_MARGIN_HALF);
2834 gtk_widget_show (caption);
2836 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2838 #endif /* MODEST_PLATFORM_MAEMO */
2841 GtkWidget *entry_password = gtk_entry_new ();
2842 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2843 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2845 #ifdef MODEST_PLATFORM_MAEMO
2846 /* Auto-capitalization is the default, so let's turn it off: */
2847 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2848 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2850 caption = hildon_caption_new (sizegroup,
2851 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2852 gtk_widget_show (entry_password);
2853 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2854 FALSE, FALSE, MODEST_MARGIN_HALF);
2855 gtk_widget_show (caption);
2856 g_object_unref (sizegroup);
2858 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2860 #endif /* MODEST_PLATFORM_MAEMO */
2862 if (initial_username != NULL)
2863 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
2865 /* This is not in the Maemo UI spec:
2866 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2867 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2871 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2873 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2875 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2877 modest_account_mgr_set_server_account_username (
2878 modest_runtime_get_account_mgr(), server_account_name,
2881 const gboolean username_was_changed =
2882 (strcmp (*username, initial_username) != 0);
2883 if (username_was_changed) {
2884 g_warning ("%s: tinymail does not yet support changing the "
2885 "username in the get_password() callback.\n", __FUNCTION__);
2890 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2892 /* We do not save the password in the configuration,
2893 * because this function is only called for passwords that should
2894 * not be remembered:
2895 modest_server_account_set_password (
2896 modest_runtime_get_account_mgr(), server_account_name,
2905 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2917 /* This is not in the Maemo UI spec:
2918 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2924 gtk_widget_destroy (dialog);
2926 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2930 modest_ui_actions_on_cut (GtkAction *action,
2931 ModestWindow *window)
2933 GtkWidget *focused_widget;
2934 GtkClipboard *clipboard;
2936 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2937 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2938 if (GTK_IS_EDITABLE (focused_widget)) {
2939 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2940 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2941 gtk_clipboard_store (clipboard);
2942 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2943 GtkTextBuffer *buffer;
2945 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2946 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2947 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2948 gtk_clipboard_store (clipboard);
2949 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2950 TnyList *header_list = modest_header_view_get_selected_headers (
2951 MODEST_HEADER_VIEW (focused_widget));
2952 gboolean continue_download = FALSE;
2953 gint num_of_unc_msgs;
2955 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
2957 if (num_of_unc_msgs)
2958 continue_download = connect_to_get_msg(
2959 GTK_WINDOW (window),
2962 if (num_of_unc_msgs == 0 || continue_download) {
2963 /* modest_platform_information_banner (
2964 NULL, NULL, _CS("mcen_ib_getting_items"));*/
2965 modest_header_view_cut_selection (
2966 MODEST_HEADER_VIEW (focused_widget));
2969 g_object_unref (header_list);
2970 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2971 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2976 modest_ui_actions_on_copy (GtkAction *action,
2977 ModestWindow *window)
2979 GtkClipboard *clipboard;
2980 GtkWidget *focused_widget;
2981 gboolean copied = TRUE;
2983 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2984 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2986 if (GTK_IS_LABEL (focused_widget)) {
2987 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2988 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2989 gtk_clipboard_store (clipboard);
2990 } else if (GTK_IS_EDITABLE (focused_widget)) {
2991 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2992 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2993 gtk_clipboard_store (clipboard);
2994 } else if (GTK_IS_HTML (focused_widget)) {
2995 gtk_html_copy (GTK_HTML (focused_widget));
2996 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2997 gtk_clipboard_store (clipboard);
2998 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2999 GtkTextBuffer *buffer;
3000 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3001 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3002 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3003 gtk_clipboard_store (clipboard);
3004 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3005 TnyList *header_list = modest_header_view_get_selected_headers (
3006 MODEST_HEADER_VIEW (focused_widget));
3007 gboolean continue_download = FALSE;
3008 gint num_of_unc_msgs;
3010 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3012 if (num_of_unc_msgs)
3013 continue_download = connect_to_get_msg(
3014 GTK_WINDOW (window),
3017 if (num_of_unc_msgs == 0 || continue_download) {
3018 modest_platform_information_banner (
3019 NULL, NULL, _CS("mcen_ib_getting_items"));
3020 modest_header_view_copy_selection (
3021 MODEST_HEADER_VIEW (focused_widget));
3025 g_object_unref (header_list);
3027 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3028 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3031 /* Show information banner if there was a copy to clipboard */
3033 modest_platform_information_banner (
3034 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3038 modest_ui_actions_on_undo (GtkAction *action,
3039 ModestWindow *window)
3041 ModestEmailClipboard *clipboard = NULL;
3043 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3044 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3045 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3046 /* Clear clipboard source */
3047 clipboard = modest_runtime_get_email_clipboard ();
3048 modest_email_clipboard_clear (clipboard);
3051 g_return_if_reached ();
3056 modest_ui_actions_on_redo (GtkAction *action,
3057 ModestWindow *window)
3059 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3060 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3063 g_return_if_reached ();
3069 destroy_information_note (ModestMailOperation *mail_op, gpointer user_data)
3071 /* destroy information note */
3072 gtk_widget_destroy (GTK_WIDGET(user_data));
3077 paste_as_attachment_free (gpointer data)
3079 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3081 gtk_widget_destroy (helper->banner);
3082 g_object_unref (helper->banner);
3087 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3092 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3093 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3098 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3103 modest_ui_actions_on_paste (GtkAction *action,
3104 ModestWindow *window)
3106 GtkWidget *focused_widget = NULL;
3107 GtkWidget *inf_note = NULL;
3108 ModestMailOperation *mail_op = NULL;
3110 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3111 if (GTK_IS_EDITABLE (focused_widget)) {
3112 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3113 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3114 ModestEmailClipboard *e_clipboard = NULL;
3115 e_clipboard = modest_runtime_get_email_clipboard ();
3116 if (modest_email_clipboard_cleared (e_clipboard)) {
3117 GtkTextBuffer *buffer;
3118 GtkClipboard *clipboard;
3120 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3121 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3122 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3123 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3124 ModestMailOperation *mail_op;
3125 TnyFolder *src_folder;
3128 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3129 helper->window = MODEST_MSG_EDIT_WINDOW (window);
3130 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3131 _CS("ckct_nw_pasting"));
3132 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
3133 mail_op = modest_mail_operation_new (G_OBJECT (window));
3134 if (helper->banner != NULL) {
3135 g_object_ref (G_OBJECT (helper->banner));
3136 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
3137 gtk_widget_show (GTK_WIDGET (helper->banner));
3141 modest_mail_operation_get_msgs_full (mail_op,
3143 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
3145 paste_as_attachment_free);
3148 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3149 ModestEmailClipboard *clipboard = NULL;
3150 TnyFolder *src_folder = NULL;
3151 TnyFolderStore *folder_store = NULL;
3152 TnyList *data = NULL;
3153 gboolean delete = FALSE;
3155 /* Check clipboard source */
3156 clipboard = modest_runtime_get_email_clipboard ();
3157 if (modest_email_clipboard_cleared (clipboard))
3160 /* Get elements to paste */
3161 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
3163 /* Create a new mail operation */
3164 mail_op = modest_mail_operation_new (G_OBJECT(window));
3166 /* Get destination folder */
3167 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
3169 /* transfer messages */
3173 /* Ask for user confirmation */
3175 modest_ui_actions_msgs_move_to_confirmation (GTK_WINDOW (window),
3176 TNY_FOLDER (folder_store),
3180 if (response == GTK_RESPONSE_OK) {
3181 /* Launch notification */
3182 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3183 _CS("ckct_nw_pasting"));
3184 if (inf_note != NULL) {
3185 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3186 gtk_widget_show (GTK_WIDGET(inf_note));
3189 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3190 modest_mail_operation_xfer_msgs (mail_op,
3192 TNY_FOLDER (folder_store),
3194 destroy_information_note,
3197 g_object_unref (mail_op);
3200 } else if (src_folder != NULL) {
3201 /* Launch notification */
3202 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3203 _CS("ckct_nw_pasting"));
3204 if (inf_note != NULL) {
3205 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3206 gtk_widget_show (GTK_WIDGET(inf_note));
3209 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3210 modest_mail_operation_xfer_folder (mail_op,
3214 destroy_information_note,
3220 g_object_unref (data);
3221 if (src_folder != NULL)
3222 g_object_unref (src_folder);
3223 if (folder_store != NULL)
3224 g_object_unref (folder_store);
3230 modest_ui_actions_on_select_all (GtkAction *action,
3231 ModestWindow *window)
3233 GtkWidget *focused_widget;
3235 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3236 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3237 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3238 } else if (GTK_IS_LABEL (focused_widget)) {
3239 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3240 } else if (GTK_IS_EDITABLE (focused_widget)) {
3241 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3242 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3243 GtkTextBuffer *buffer;
3244 GtkTextIter start, end;
3246 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3247 gtk_text_buffer_get_start_iter (buffer, &start);
3248 gtk_text_buffer_get_end_iter (buffer, &end);
3249 gtk_text_buffer_select_range (buffer, &start, &end);
3250 } else if (GTK_IS_HTML (focused_widget)) {
3251 gtk_html_select_all (GTK_HTML (focused_widget));
3252 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3253 GtkWidget *header_view = focused_widget;
3254 GtkTreeSelection *selection = NULL;
3256 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
3257 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3258 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3261 /* Disable window dimming management */
3262 modest_window_disable_dimming (MODEST_WINDOW(window));
3264 /* Select all messages */
3265 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3266 gtk_tree_selection_select_all (selection);
3268 /* Set focuse on header view */
3269 gtk_widget_grab_focus (header_view);
3272 /* Enable window dimming management */
3273 modest_window_enable_dimming (MODEST_WINDOW(window));
3274 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3280 modest_ui_actions_on_mark_as_read (GtkAction *action,
3281 ModestWindow *window)
3283 g_return_if_fail (MODEST_IS_WINDOW(window));
3285 /* Mark each header as read */
3286 do_headers_action (window, headers_action_mark_as_read, NULL);
3290 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3291 ModestWindow *window)
3293 g_return_if_fail (MODEST_IS_WINDOW(window));
3295 /* Mark each header as read */
3296 do_headers_action (window, headers_action_mark_as_unread, NULL);
3300 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3301 GtkRadioAction *selected,
3302 ModestWindow *window)
3306 value = gtk_radio_action_get_current_value (selected);
3307 if (MODEST_IS_WINDOW (window)) {
3308 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3313 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3314 GtkRadioAction *selected,
3315 ModestWindow *window)
3317 TnyHeaderFlags flags;
3318 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3320 flags = gtk_radio_action_get_current_value (selected);
3321 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3325 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3326 GtkRadioAction *selected,
3327 ModestWindow *window)
3331 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3333 file_format = gtk_radio_action_get_current_value (selected);
3334 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3339 modest_ui_actions_on_zoom_plus (GtkAction *action,
3340 ModestWindow *window)
3342 g_return_if_fail (MODEST_IS_WINDOW (window));
3344 modest_window_zoom_plus (MODEST_WINDOW (window));
3348 modest_ui_actions_on_zoom_minus (GtkAction *action,
3349 ModestWindow *window)
3351 g_return_if_fail (MODEST_IS_WINDOW (window));
3353 modest_window_zoom_minus (MODEST_WINDOW (window));
3357 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3358 ModestWindow *window)
3360 ModestWindowMgr *mgr;
3361 gboolean fullscreen, active;
3362 g_return_if_fail (MODEST_IS_WINDOW (window));
3364 mgr = modest_runtime_get_window_mgr ();
3366 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3367 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3369 if (active != fullscreen) {
3370 modest_window_mgr_set_fullscreen_mode (mgr, active);
3371 gtk_window_present (GTK_WINDOW (window));
3376 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3377 ModestWindow *window)
3379 ModestWindowMgr *mgr;
3380 gboolean fullscreen;
3382 g_return_if_fail (MODEST_IS_WINDOW (window));
3384 mgr = modest_runtime_get_window_mgr ();
3385 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3386 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3388 gtk_window_present (GTK_WINDOW (window));
3392 * Used by modest_ui_actions_on_details to call do_headers_action
3395 headers_action_show_details (TnyHeader *header,
3396 ModestWindow *window,
3403 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3406 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3407 gtk_widget_show_all (dialog);
3408 gtk_dialog_run (GTK_DIALOG (dialog));
3410 gtk_widget_destroy (dialog);
3414 * Show the folder details in a ModestDetailsDialog widget
3417 show_folder_details (TnyFolder *folder,
3423 dialog = modest_details_dialog_new_with_folder (window, folder);
3426 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3427 gtk_widget_show_all (dialog);
3428 gtk_dialog_run (GTK_DIALOG (dialog));
3430 gtk_widget_destroy (dialog);
3434 * Show the header details in a ModestDetailsDialog widget
3437 modest_ui_actions_on_details (GtkAction *action,
3440 TnyList * headers_list;
3444 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3447 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3450 g_object_unref (msg);
3452 headers_list = get_selected_headers (win);
3456 iter = tny_list_create_iterator (headers_list);
3458 header = TNY_HEADER (tny_iterator_get_current (iter));
3460 headers_action_show_details (header, win, NULL);
3461 g_object_unref (header);
3464 g_object_unref (iter);
3465 g_object_unref (headers_list);
3467 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3468 GtkWidget *folder_view, *header_view;
3470 /* Check which widget has the focus */
3471 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3472 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3473 if (gtk_widget_is_focus (folder_view)) {
3474 TnyFolderStore *folder_store
3475 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3476 if (!folder_store) {
3477 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3480 /* Show only when it's a folder */
3481 /* This function should not be called for account items,
3482 * because we dim the menu item for them. */
3483 if (TNY_IS_FOLDER (folder_store)) {
3484 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3487 g_object_unref (folder_store);
3490 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3491 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3492 /* Show details of each header */
3493 do_headers_action (win, headers_action_show_details, header_view);
3499 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3500 ModestMsgEditWindow *window)
3502 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3504 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3508 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3509 ModestMsgEditWindow *window)
3511 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3513 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3517 modest_ui_actions_toggle_folders_view (GtkAction *action,
3518 ModestMainWindow *main_window)
3520 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3522 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3523 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3525 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3529 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3530 ModestWindow *window)
3532 gboolean active, fullscreen = FALSE;
3533 ModestWindowMgr *mgr;
3535 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3537 /* Check if we want to toggle the toolbar vuew in fullscreen
3539 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3540 "ViewShowToolbarFullScreen")) {
3544 /* Toggle toolbar */
3545 mgr = modest_runtime_get_window_mgr ();
3546 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
3550 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3551 ModestMsgEditWindow *window)
3553 modest_msg_edit_window_select_font (window);
3557 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3558 const gchar *display_name,
3561 /* Do not change the application name if the widget has not
3562 the focus. This callback could be called even if the folder
3563 view has not the focus, because the handled signal could be
3564 emitted when the folder view is redrawn */
3565 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3567 gtk_window_set_title (window, display_name);
3569 gtk_window_set_title (window, " ");
3574 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3576 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3577 modest_msg_edit_window_select_contacts (window);
3581 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3583 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3584 modest_msg_edit_window_check_names (window, FALSE);
3588 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3590 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3591 GTK_WIDGET (user_data));
3595 * This function is used to track changes in the selection of the
3596 * folder view that is inside the "move to" dialog to enable/disable
3597 * the OK button because we do not want the user to select a disallowed
3598 * destination for a folder.
3599 * The user also not desired to be able to use NEW button on items where
3600 * folder creation is not possibel.
3603 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
3604 TnyFolderStore *folder_store,
3608 GtkWidget *dialog = NULL;
3609 GtkWidget *ok_button = NULL, *new_button = NULL;
3610 GList *children = NULL;
3611 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
3612 gboolean moving_folder = FALSE;
3613 gboolean is_local_account = TRUE;
3614 GtkWidget *folder_view = NULL;
3615 ModestTnyFolderRules rules;
3620 /* Get the OK button */
3621 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
3625 children = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
3626 ok_button = GTK_WIDGET (children->next->next->data);
3627 new_button = GTK_WIDGET (children->next->data);
3628 g_list_free (children);
3630 /* check if folder_store is an remote account */
3631 if (TNY_IS_ACCOUNT (folder_store)) {
3632 TnyAccount *local_account = NULL;
3633 ModestTnyAccountStore *account_store = NULL;
3635 account_store = modest_runtime_get_account_store ();
3636 local_account = modest_tny_account_store_get_local_folders_account (account_store);
3638 if ((gpointer) local_account != (gpointer) folder_store) {
3639 is_local_account = FALSE;
3640 /* New button should be dimmed on remote
3642 new_sensitive = FALSE;
3644 g_object_unref (local_account);
3647 /* Check the target folder rules */
3648 if (TNY_IS_FOLDER (folder_store)) {
3649 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
3650 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
3651 ok_sensitive = FALSE;
3652 new_sensitive = FALSE;
3657 /* Check if we're moving a folder */
3658 if (MODEST_IS_MAIN_WINDOW (user_data)) {
3659 /* Get the widgets */
3660 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
3661 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3662 if (gtk_widget_is_focus (folder_view))
3663 moving_folder = TRUE;
3666 if (moving_folder) {
3667 TnyFolderStore *moved_folder = NULL, *parent = NULL;
3669 /* Get the folder to move */
3670 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3672 /* Check that we're not moving to the same folder */
3673 if (TNY_IS_FOLDER (moved_folder)) {
3674 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
3675 if (parent == folder_store)
3676 ok_sensitive = FALSE;
3677 g_object_unref (parent);
3680 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
3681 /* Do not allow to move to an account unless it's the
3682 local folders account */
3683 if (!is_local_account)
3684 ok_sensitive = FALSE;
3687 if (ok_sensitive && (moved_folder == folder_store)) {
3688 /* Do not allow to move to itself */
3689 ok_sensitive = FALSE;
3691 g_object_unref (moved_folder);
3693 TnyHeader *header = NULL;
3694 TnyFolder *src_folder = NULL;
3696 /* Moving a message */
3697 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
3698 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (user_data));
3699 src_folder = tny_header_get_folder (header);
3700 g_object_unref (header);
3703 TNY_FOLDER (modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view)));
3706 /* Do not allow to move the msg to the same folder */
3707 /* Do not allow to move the msg to an account */
3708 if ((gpointer) src_folder == (gpointer) folder_store ||
3709 TNY_IS_ACCOUNT (folder_store))
3710 ok_sensitive = FALSE;
3711 g_object_unref (src_folder);
3715 /* Set sensitivity of the OK button */
3716 gtk_widget_set_sensitive (ok_button, ok_sensitive);
3717 /* Set sensitivity of the NEW button */
3718 gtk_widget_set_sensitive (new_button, new_sensitive);
3722 create_move_to_dialog (GtkWindow *win,
3723 GtkWidget *folder_view,
3724 GtkWidget **tree_view)
3726 GtkWidget *dialog, *scroll;
3727 GtkWidget *new_button;
3729 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3731 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3734 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
3735 /* We do this manually so GTK+ does not associate a response ID for
3737 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
3738 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3739 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
3741 /* Create scrolled window */
3742 scroll = gtk_scrolled_window_new (NULL, NULL);
3743 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3744 GTK_POLICY_AUTOMATIC,
3745 GTK_POLICY_AUTOMATIC);
3747 /* Create folder view */
3748 *tree_view = modest_platform_create_folder_view (NULL);
3750 /* Track changes in the selection to
3751 * disable the OK button whenever "Move to" is not possible
3752 * disbale NEW button whenever New is not possible */
3753 g_signal_connect (*tree_view,
3754 "folder_selection_changed",
3755 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
3758 /* Listen to clicks on New button */
3759 g_signal_connect (G_OBJECT (new_button),
3761 G_CALLBACK(create_move_to_dialog_on_new_folder),
3764 /* It could happen that we're trying to move a message from a
3765 window (msg window for example) after the main window was
3766 closed, so we can not just get the model of the folder
3768 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
3769 const gchar *visible_id = NULL;
3771 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
3772 MODEST_FOLDER_VIEW(*tree_view));
3775 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
3777 /* Show the same account than the one that is shown in the main window */
3778 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
3781 const gchar *active_account_name = NULL;
3782 ModestAccountMgr *mgr = NULL;
3783 ModestAccountData *acc_data = NULL;
3785 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3786 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3788 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
3789 mgr = modest_runtime_get_account_mgr ();
3790 acc_data = modest_account_mgr_get_account_data (mgr, active_account_name);
3792 /* Set the new visible & active account */
3793 if (acc_data && acc_data->store_account) {
3794 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
3795 acc_data->store_account->account_name);
3796 modest_account_mgr_free_account_data (mgr, acc_data);
3800 /* Hide special folders */
3801 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3803 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3805 /* Add scroll to dialog */
3806 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3807 scroll, TRUE, TRUE, 0);
3809 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3810 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3816 * Returns TRUE if at least one of the headers of the list belongs to
3817 * a message that has been fully retrieved.
3819 #if 0 /* no longer in use. delete in 2007.10 */
3821 has_retrieved_msgs (TnyList *list)
3824 gboolean found = FALSE;
3826 iter = tny_list_create_iterator (list);
3827 while (!tny_iterator_is_done (iter) && !found) {
3829 TnyHeaderFlags flags = 0;
3831 header = TNY_HEADER (tny_iterator_get_current (iter));
3833 flags = tny_header_get_flags (header);
3834 if (flags & TNY_HEADER_FLAG_CACHED)
3835 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3838 g_object_unref (header);
3842 tny_iterator_next (iter);
3844 g_object_unref (iter);
3852 * Shows a confirmation dialog to the user when we're moving messages
3853 * from a remote server to the local storage. Returns the dialog
3854 * response. If it's other kind of movement then it always returns
3857 * This one is used by the next functions:
3858 * modest_ui_actions_on_paste - commented out
3859 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
3862 modest_ui_actions_msgs_move_to_confirmation (GtkWindow *win,
3863 TnyFolder *dest_folder,
3867 gint response = GTK_RESPONSE_OK;
3869 /* return with OK if the destination is a remote folder */
3870 if (modest_tny_folder_is_remote_folder (dest_folder))
3871 return GTK_RESPONSE_OK;
3873 TnyFolder *src_folder = NULL;
3874 TnyIterator *iter = NULL;
3875 TnyHeader *header = NULL;
3877 /* Get source folder */
3878 iter = tny_list_create_iterator (headers);
3879 header = TNY_HEADER (tny_iterator_get_current (iter));
3881 src_folder = tny_header_get_folder (header);
3882 g_object_unref (header);
3884 g_object_unref (iter);
3886 /* if no src_folder, message may be an attahcment */
3887 if (src_folder == NULL)
3888 return GTK_RESPONSE_CANCEL;
3890 /* If the source is a local or MMC folder */
3891 if (!modest_tny_folder_is_remote_folder (src_folder)) {
3892 g_object_unref (src_folder);
3893 return GTK_RESPONSE_OK;
3895 g_object_unref (src_folder);
3897 /* now if offline we ask the user */
3898 if(connect_to_get_msg( GTK_WINDOW (win),
3899 tny_list_get_length (headers)))
3900 response = GTK_RESPONSE_OK;
3902 response = GTK_RESPONSE_CANCEL;
3910 move_to_cb (ModestMailOperation *mail_op, gpointer user_data)
3912 MoveToHelper *helper = (MoveToHelper *) user_data;
3914 /* Note that the operation could have failed, in that case do
3916 if (modest_mail_operation_get_status (mail_op) ==
3917 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
3919 GObject *object = modest_mail_operation_get_source (mail_op);
3920 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
3921 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
3923 if (!modest_msg_view_window_select_next_message (self))
3924 if (!modest_msg_view_window_select_previous_message (self))
3925 /* No more messages to view, so close this window */
3926 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3927 } else if (MODEST_IS_MAIN_WINDOW (object) && helper->reference != NULL) {
3928 GtkWidget *header_view;
3930 GtkTreeSelection *sel;
3932 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
3933 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3934 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
3935 path = gtk_tree_row_reference_get_path (helper->reference);
3936 gtk_tree_selection_select_path (sel, path);
3937 gtk_tree_path_free (path);
3939 g_object_unref (object);
3942 /* Close the "Pasting" information banner */
3943 gtk_widget_destroy (GTK_WIDGET(helper->banner));
3944 if (helper->reference != NULL)
3945 gtk_tree_row_reference_free (helper->reference);
3950 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3953 ModestWindow *main_window = NULL;
3954 GtkWidget *folder_view = NULL;
3955 GObject *win = modest_mail_operation_get_source (mail_op);
3956 const GError *error = NULL;
3957 const gchar *message = NULL;
3959 /* Get error message */
3960 error = modest_mail_operation_get_error (mail_op);
3961 if (error != NULL && error->message != NULL) {
3962 message = error->message;
3964 message = _("mail_in_ui_folder_move_target_error");
3967 /* Disable next automatic folder selection */
3968 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ());
3969 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
3970 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3971 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
3973 if (user_data && TNY_IS_FOLDER (user_data)) {
3974 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3975 TNY_FOLDER (user_data), FALSE);
3978 /* Show notification dialog */
3979 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3980 g_object_unref (win);
3984 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3987 GObject *win = modest_mail_operation_get_source (mail_op);
3988 const GError *error = modest_mail_operation_get_error (mail_op);
3990 g_return_if_fail (error != NULL);
3991 if (error->message != NULL)
3992 g_printerr ("modest: %s\n", error->message);
3994 g_printerr ("modest: unkonw error on send&receive operation");
3996 /* Show error message */
3997 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3998 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3999 /* _CS("sfil_ib_unable_to_receive")); */
4001 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
4002 /* _CS("sfil_ib_unable_to_send")); */
4003 g_object_unref (win);
4007 open_msg_for_purge_cb (ModestMailOperation *mail_op,
4014 gint pending_purges = 0;
4015 gboolean some_purged = FALSE;
4016 ModestWindow *win = MODEST_WINDOW (user_data);
4017 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
4019 /* If there was any error */
4020 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
4021 modest_window_mgr_unregister_header (mgr, header);
4025 /* Once the message has been retrieved for purging, we check if
4026 * it's all ok for purging */
4028 parts = tny_simple_list_new ();
4029 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
4030 iter = tny_list_create_iterator (parts);
4032 while (!tny_iterator_is_done (iter)) {
4034 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4035 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
4036 if (tny_mime_part_is_purged (part))
4043 g_object_unref (part);
4045 tny_iterator_next (iter);
4047 g_object_unref (iter);
4050 if (pending_purges>0) {
4052 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
4054 if (response == GTK_RESPONSE_OK) {
4055 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
4056 iter = tny_list_create_iterator (parts);
4057 while (!tny_iterator_is_done (iter)) {
4060 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4061 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
4062 tny_mime_part_set_purged (part);
4065 g_object_unref (part);
4067 tny_iterator_next (iter);
4070 tny_msg_rewrite_cache (msg);
4073 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
4075 g_object_unref (iter);
4077 modest_window_mgr_unregister_header (mgr, header);
4079 g_object_unref (parts);
4083 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
4084 ModestMainWindow *win)
4086 GtkWidget *header_view;
4087 TnyList *header_list;
4090 TnyHeaderFlags flags;
4091 ModestWindow *msg_view_window = NULL;
4094 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4096 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4097 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4099 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
4101 if (tny_list_get_length (header_list) == 1) {
4102 iter = tny_list_create_iterator (header_list);
4103 header = TNY_HEADER (tny_iterator_get_current (iter));
4104 g_object_unref (iter);
4109 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
4110 header, &msg_view_window);
4111 flags = tny_header_get_flags (header);
4112 if (!(flags & TNY_HEADER_FLAG_CACHED))
4115 if (msg_view_window != NULL)
4116 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
4118 /* do nothing; uid was registered before, so window is probably on it's way */
4119 g_warning ("debug: header %p has already been registered", header);
4122 ModestMailOperation *mail_op = NULL;
4123 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
4124 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
4125 modest_ui_actions_get_msgs_full_error_handler,
4127 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4128 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
4130 g_object_unref (mail_op);
4133 g_object_unref (header);
4135 g_object_unref (header_list);
4139 * Utility function that transfer messages from both the main window
4140 * and the msg view window when using the "Move to" dialog
4143 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
4146 TnyList *headers = NULL;
4147 TnyAccount *dst_account = NULL;
4148 const gchar *proto_str = NULL;
4149 gboolean dst_is_pop = FALSE;
4151 if (!TNY_IS_FOLDER (dst_folder)) {
4152 modest_platform_information_banner (GTK_WIDGET (win),
4154 _CS("ckdg_ib_unable_to_move_to_current_location"));
4158 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
4159 proto_str = tny_account_get_proto (dst_account);
4161 /* tinymail will return NULL for local folders it seems */
4162 dst_is_pop = proto_str &&
4163 (modest_protocol_info_get_transport_store_protocol (proto_str) ==
4164 MODEST_PROTOCOL_STORE_POP);
4166 g_object_unref (dst_account);
4168 /* Get selected headers */
4169 headers = get_selected_headers (MODEST_WINDOW (win));
4172 modest_platform_information_banner (GTK_WIDGET (win),
4174 ngettext("mail_in_ui_folder_move_target_error",
4175 "mail_in_ui_folder_move_targets_error",
4176 tny_list_get_length (headers)));
4177 g_object_unref (headers);
4181 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4182 helper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4183 _CS("ckct_nw_pasting"));
4184 if (helper->banner != NULL) {
4185 gtk_window_set_modal (GTK_WINDOW(helper->banner), FALSE);
4186 gtk_widget_show (GTK_WIDGET(helper->banner));
4189 if (MODEST_IS_MAIN_WINDOW (win)) {
4190 GtkWidget *header_view =
4191 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
4192 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4193 helper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
4196 ModestMailOperation *mail_op =
4197 modest_mail_operation_new_with_error_handling (G_OBJECT(win),
4198 modest_ui_actions_move_folder_error_handler,
4200 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4203 modest_mail_operation_xfer_msgs (mail_op,
4205 TNY_FOLDER (dst_folder),
4210 g_object_unref (G_OBJECT (mail_op));
4211 g_object_unref (headers);
4215 * UI handler for the "Move to" action when invoked from the
4219 modest_ui_actions_on_main_window_move_to (GtkAction *action,
4220 GtkWidget *folder_view,
4221 TnyFolderStore *dst_folder,
4222 ModestMainWindow *win)
4224 ModestHeaderView *header_view = NULL;
4225 ModestMailOperation *mail_op = NULL;
4226 TnyFolderStore *src_folder;
4227 gboolean online = (tny_device_is_online (modest_runtime_get_device()));
4229 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4231 /* Get the source folder */
4232 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4234 /* Get header view */
4235 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
4237 /* Get folder or messages to transfer */
4238 if (gtk_widget_is_focus (folder_view)) {
4239 GtkTreeSelection *sel;
4240 gboolean do_xfer = TRUE;
4242 /* Allow only to transfer folders to the local root folder */
4243 if (TNY_IS_ACCOUNT (dst_folder) &&
4244 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder)) {
4246 } else if (!TNY_IS_FOLDER (src_folder)) {
4247 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
4249 } else if (!online && modest_platform_is_network_folderstore(src_folder)) {
4250 guint num_headers = tny_folder_get_all_count(TNY_FOLDER(src_folder));
4251 if (!connect_to_get_msg(GTK_WINDOW(win), num_headers)) {
4257 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4258 helper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4259 _CS("ckct_nw_pasting"));
4260 if (helper->banner != NULL) {
4261 gtk_window_set_modal (GTK_WINDOW(helper->banner), FALSE);
4262 gtk_widget_show (GTK_WIDGET(helper->banner));
4264 /* Clean folder on header view before moving it */
4265 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
4266 gtk_tree_selection_unselect_all (sel);
4269 modest_mail_operation_new_with_error_handling (G_OBJECT(win),
4270 modest_ui_actions_move_folder_error_handler,
4272 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4275 /* Select *after* the changes */
4276 /* TODO: this function hangs UI after transfer */
4277 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
4278 /* TNY_FOLDER (src_folder), TRUE); */
4280 modest_mail_operation_xfer_folder (mail_op,
4281 TNY_FOLDER (src_folder),
4286 /* Unref mail operation */
4287 g_object_unref (G_OBJECT (mail_op));
4289 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
4290 gboolean do_xfer = TRUE;
4291 /* Ask for confirmation if the source folder is remote and we're not connected */
4292 if (!online && modest_platform_is_network_folderstore(src_folder)) {
4293 TnyList *headers = modest_header_view_get_selected_headers(header_view);
4294 if (!msgs_already_deleted_from_server(headers, src_folder)) {
4295 guint num_headers = tny_list_get_length(headers);
4296 if (!connect_to_get_msg(GTK_WINDOW(win), num_headers)) {
4300 g_object_unref(headers);
4302 if (do_xfer) /* Transfer messages */
4303 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4307 g_object_unref (src_folder);
4312 * UI handler for the "Move to" action when invoked from the
4313 * ModestMsgViewWindow
4316 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
4317 TnyFolderStore *dst_folder,
4318 ModestMsgViewWindow *win)
4320 TnyHeader *header = NULL;
4321 TnyFolderStore *src_folder;
4323 /* Create header list */
4324 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
4325 src_folder = TNY_FOLDER_STORE(tny_header_get_folder(header));
4326 g_object_unref (header);
4328 /* Transfer the message if online or confirmed by the user */
4329 if (tny_device_is_online (modest_runtime_get_device()) || remote_folder_is_pop(src_folder) ||
4330 (modest_platform_is_network_folderstore(src_folder) && connect_to_get_msg(GTK_WINDOW(win), 1))) {
4331 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4334 g_object_unref (src_folder);
4338 modest_ui_actions_on_move_to (GtkAction *action,
4341 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
4343 TnyFolderStore *dst_folder = NULL;
4344 ModestMainWindow *main_window;
4346 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
4347 MODEST_IS_MSG_VIEW_WINDOW (win));
4349 /* Get the main window if exists */
4350 if (MODEST_IS_MAIN_WINDOW (win))
4351 main_window = MODEST_MAIN_WINDOW (win);
4354 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
4356 /* Get the folder view widget if exists */
4358 folder_view = modest_main_window_get_child_widget (main_window,
4359 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4363 /* Create and run the dialog */
4364 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
4365 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
4366 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4367 result = gtk_dialog_run (GTK_DIALOG(dialog));
4368 g_object_ref (tree_view);
4369 gtk_widget_destroy (dialog);
4371 if (result != GTK_RESPONSE_ACCEPT)
4374 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
4375 /* Do window specific stuff */
4376 if (MODEST_IS_MAIN_WINDOW (win)) {
4377 modest_ui_actions_on_main_window_move_to (action,
4380 MODEST_MAIN_WINDOW (win));
4382 modest_ui_actions_on_msg_view_window_move_to (action,
4384 MODEST_MSG_VIEW_WINDOW (win));
4388 g_object_unref (dst_folder);
4392 * Calls #HeadersFunc for each header already selected in the main
4393 * window or the message currently being shown in the msg view window
4396 do_headers_action (ModestWindow *win,
4400 TnyList *headers_list = NULL;
4401 TnyIterator *iter = NULL;
4402 TnyHeader *header = NULL;
4403 TnyFolder *folder = NULL;
4406 headers_list = get_selected_headers (win);
4410 /* Get the folder */
4411 iter = tny_list_create_iterator (headers_list);
4412 header = TNY_HEADER (tny_iterator_get_current (iter));
4414 folder = tny_header_get_folder (header);
4415 g_object_unref (header);
4418 /* Call the function for each header */
4419 while (!tny_iterator_is_done (iter)) {
4420 header = TNY_HEADER (tny_iterator_get_current (iter));
4421 func (header, win, user_data);
4422 g_object_unref (header);
4423 tny_iterator_next (iter);
4426 /* Trick: do a poke status in order to speed up the signaling
4428 tny_folder_poke_status (folder);
4431 g_object_unref (folder);
4432 g_object_unref (iter);
4433 g_object_unref (headers_list);
4437 modest_ui_actions_view_attachment (GtkAction *action,
4438 ModestWindow *window)
4440 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4441 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4443 /* not supported window for this action */
4444 g_return_if_reached ();
4449 modest_ui_actions_save_attachments (GtkAction *action,
4450 ModestWindow *window)
4452 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4453 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4455 /* not supported window for this action */
4456 g_return_if_reached ();
4461 modest_ui_actions_remove_attachments (GtkAction *action,
4462 ModestWindow *window)
4464 if (MODEST_IS_MAIN_WINDOW (window)) {
4465 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4466 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4467 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4469 /* not supported window for this action */
4470 g_return_if_reached ();
4475 modest_ui_actions_on_settings (GtkAction *action,
4480 dialog = modest_platform_get_global_settings_dialog ();
4481 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4482 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4483 gtk_widget_show_all (dialog);
4485 gtk_dialog_run (GTK_DIALOG (dialog));
4487 gtk_widget_destroy (dialog);
4491 modest_ui_actions_on_help (GtkAction *action,
4494 const gchar *help_id = NULL;
4496 if (MODEST_IS_MAIN_WINDOW (win)) {
4497 GtkWidget *folder_view;
4498 TnyFolderStore *folder_store;
4500 /* Get selected folder */
4501 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4502 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4503 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4505 /* Switch help_id */
4506 if (TNY_IS_FOLDER (folder_store)) {
4507 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4508 case TNY_FOLDER_TYPE_NORMAL:
4509 help_id = "applications_email_managefolders";
4511 case TNY_FOLDER_TYPE_INBOX:
4512 help_id = "applications_email_inbox";
4514 case TNY_FOLDER_TYPE_OUTBOX:
4515 help_id = "applications_email_outbox";
4517 case TNY_FOLDER_TYPE_SENT:
4518 help_id = "applications_email_sent";
4520 case TNY_FOLDER_TYPE_DRAFTS:
4521 help_id = "applications_email_drafts";
4523 case TNY_FOLDER_TYPE_ARCHIVE:
4524 help_id = "applications_email_managefolders";
4527 help_id = "applications_email_managefolders";
4530 help_id = "applications_email_mainview";
4532 g_object_unref (folder_store);
4533 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4534 help_id = "applications_email_viewer";
4535 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4536 help_id = "applications_email_editor";
4538 modest_platform_show_help (GTK_WINDOW (win), help_id);
4542 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4543 ModestWindow *window)
4545 ModestMailOperation *mail_op;
4549 headers = get_selected_headers (window);
4553 /* Create mail operation */
4554 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (window),
4555 modest_ui_actions_get_msgs_full_error_handler,
4557 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4558 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4561 g_object_unref (headers);
4562 g_object_unref (mail_op);
4566 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4567 ModestWindow *window)
4569 g_return_if_fail (MODEST_IS_WINDOW (window));
4572 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4576 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4577 ModestWindow *window)
4579 g_return_if_fail (MODEST_IS_WINDOW (window));
4582 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4586 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4587 ModestWindow *window)
4589 g_return_if_fail (MODEST_IS_WINDOW (window));
4592 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4596 modest_ui_actions_on_format_menu_activated (GtkAction *action,
4597 ModestWindow *window)
4599 g_return_if_fail (MODEST_IS_WINDOW (window));
4602 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4606 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4607 ModestWindow *window)
4609 g_return_if_fail (MODEST_IS_WINDOW (window));
4612 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4616 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4617 ModestWindow *window)
4619 g_return_if_fail (MODEST_IS_WINDOW (window));
4622 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4626 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4627 ModestWindow *window)
4629 g_return_if_fail (MODEST_IS_WINDOW (window));
4632 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4636 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4637 ModestWindow *window)
4639 g_return_if_fail (MODEST_IS_WINDOW (window));
4642 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4646 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4647 ModestWindow *window)
4649 g_return_if_fail (MODEST_IS_WINDOW (window));
4652 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4656 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4658 g_return_if_fail (MODEST_IS_WINDOW (window));
4661 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4665 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4667 g_return_if_fail (MODEST_IS_WINDOW (window));
4669 modest_platform_show_search_messages (GTK_WINDOW (window));
4673 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4675 g_return_if_fail (MODEST_IS_WINDOW (win));
4676 modest_platform_show_addressbook (GTK_WINDOW (win));
4681 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4682 ModestWindow *window)
4684 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4686 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4690 on_send_receive_finished (ModestMailOperation *mail_op,
4693 /* Set send/receive operation finished */
4694 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW (user_data));
4699 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
4705 const gchar* server_name = NULL;
4706 TnyTransportAccount *server_account;
4707 gchar *message = NULL;
4709 /* Don't show anything if the user cancelled something */
4710 if (err->code == TNY_TRANSPORT_ACCOUNT_ERROR_SEND_USER_CANCEL)
4713 /* Get the server name: */
4715 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
4716 if (server_account) {
4717 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
4719 g_object_unref (server_account);
4720 server_account = NULL;
4723 g_return_if_fail (server_name);
4725 /* Show the appropriate message text for the GError: */
4726 switch (err->code) {
4727 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_HOST_LOOKUP_FAILED:
4728 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4730 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_SERVICE_UNAVAILABLE:
4731 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4733 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_AUTHENTICATION_NOT_SUPPORTED:
4734 message = g_strdup_printf (_("emev_ni_ui_smtp_authentication_fail_error"), server_name);
4736 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND:
4737 message = g_strdup (_("emev_ib_ui_smtp_send_error"));
4740 g_return_if_reached ();
4743 /* TODO if the username or the password where not defined we
4744 should show the Accounts Settings dialog or the Connection
4745 specific SMTP server window */
4747 modest_platform_run_information_dialog (NULL, message);
4752 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
4757 ModestMainWindow *main_window = NULL;
4758 ModestWindowMgr *mgr = NULL;
4759 GtkWidget *folder_view = NULL, *header_view = NULL;
4760 TnyFolderStore *selected_folder = NULL;
4761 TnyFolderType folder_type;
4763 mgr = modest_runtime_get_window_mgr ();
4764 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr));
4769 /* Check if selected folder is OUTBOX */
4770 folder_view = modest_main_window_get_child_widget (main_window,
4771 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4772 header_view = modest_main_window_get_child_widget (main_window,
4773 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4775 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4776 if (!TNY_IS_FOLDER (selected_folder))
4779 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
4780 #if GTK_CHECK_VERSION(2, 8, 0)
4781 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
4782 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
4783 GtkTreeViewColumn *tree_column;
4785 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
4786 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
4787 gtk_tree_view_column_queue_resize (tree_column);
4790 gtk_widget_queue_draw (header_view);
4795 if (selected_folder != NULL)
4796 g_object_unref (selected_folder);