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 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2110 TnyTransportAccount *transport_account;
2111 ModestMailOperation *mail_operation;
2113 gchar *account_name, *from;
2114 ModestAccountMgr *account_mgr;
2115 gchar *info_text = NULL;
2117 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2119 data = modest_msg_edit_window_get_msg_data (edit_window);
2121 account_mgr = modest_runtime_get_account_mgr();
2122 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2124 account_name = modest_account_mgr_get_default_account (account_mgr);
2125 if (!account_name) {
2126 g_printerr ("modest: no account found\n");
2127 modest_msg_edit_window_free_msg_data (edit_window, data);
2131 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2132 account_name = g_strdup (data->account_name);
2136 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2137 (modest_runtime_get_account_store(),
2139 TNY_ACCOUNT_TYPE_TRANSPORT));
2140 if (!transport_account) {
2141 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2142 g_free (account_name);
2143 modest_msg_edit_window_free_msg_data (edit_window, data);
2146 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2148 /* Create the mail operation */
2149 mail_operation = modest_mail_operation_new (G_OBJECT(edit_window));
2150 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2152 modest_mail_operation_save_to_drafts (mail_operation,
2165 data->priority_flags);
2168 g_free (account_name);
2169 g_object_unref (G_OBJECT (transport_account));
2170 g_object_unref (G_OBJECT (mail_operation));
2172 modest_msg_edit_window_free_msg_data (edit_window, data);
2174 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2175 modest_platform_information_banner (NULL, NULL, info_text);
2176 modest_msg_edit_window_reset_modified (edit_window);
2180 /* For instance, when clicking the Send toolbar button when editing a message: */
2182 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2184 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2186 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2189 /* Offer the connection dialog, if necessary: */
2190 if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
2193 /* FIXME: Code added just for testing. The final version will
2194 use the send queue provided by tinymail and some
2196 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2197 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2199 account_name = modest_account_mgr_get_default_account (account_mgr);
2201 if (!account_name) {
2202 /* Run account setup wizard */
2203 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window)))
2207 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2209 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2210 account_name = g_strdup (data->account_name);
2213 /* Get the currently-active transport account for this modest account: */
2214 TnyTransportAccount *transport_account =
2215 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2216 (modest_runtime_get_account_store(),
2218 if (!transport_account) {
2219 /* Run account setup wizard */
2220 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2224 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2226 /* Create the mail operation */
2227 ModestMailOperation *mail_operation = modest_mail_operation_new (G_OBJECT(edit_window));
2228 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2230 modest_mail_operation_send_new_mail (mail_operation,
2242 data->priority_flags);
2246 g_free (account_name);
2247 g_object_unref (G_OBJECT (transport_account));
2248 g_object_unref (G_OBJECT (mail_operation));
2250 modest_msg_edit_window_free_msg_data (edit_window, data);
2251 modest_msg_edit_window_set_sent (edit_window, TRUE);
2253 /* Save settings and close the window: */
2254 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2258 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2259 ModestMsgEditWindow *window)
2261 ModestMsgEditFormatState *format_state = NULL;
2263 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2264 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2266 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2269 format_state = modest_msg_edit_window_get_format_state (window);
2270 g_return_if_fail (format_state != NULL);
2272 format_state->bold = gtk_toggle_action_get_active (action);
2273 modest_msg_edit_window_set_format_state (window, format_state);
2274 g_free (format_state);
2279 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2280 ModestMsgEditWindow *window)
2282 ModestMsgEditFormatState *format_state = NULL;
2284 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2285 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2287 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2290 format_state = modest_msg_edit_window_get_format_state (window);
2291 g_return_if_fail (format_state != NULL);
2293 format_state->italics = gtk_toggle_action_get_active (action);
2294 modest_msg_edit_window_set_format_state (window, format_state);
2295 g_free (format_state);
2300 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2301 ModestMsgEditWindow *window)
2303 ModestMsgEditFormatState *format_state = NULL;
2305 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2306 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2308 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2311 format_state = modest_msg_edit_window_get_format_state (window);
2312 g_return_if_fail (format_state != NULL);
2314 format_state->bullet = gtk_toggle_action_get_active (action);
2315 modest_msg_edit_window_set_format_state (window, format_state);
2316 g_free (format_state);
2321 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2322 GtkRadioAction *selected,
2323 ModestMsgEditWindow *window)
2325 ModestMsgEditFormatState *format_state = NULL;
2326 GtkJustification value;
2328 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2330 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2333 value = gtk_radio_action_get_current_value (selected);
2335 format_state = modest_msg_edit_window_get_format_state (window);
2336 g_return_if_fail (format_state != NULL);
2338 format_state->justification = value;
2339 modest_msg_edit_window_set_format_state (window, format_state);
2340 g_free (format_state);
2344 modest_ui_actions_on_select_editor_color (GtkAction *action,
2345 ModestMsgEditWindow *window)
2347 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2348 g_return_if_fail (GTK_IS_ACTION (action));
2350 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2353 modest_msg_edit_window_select_color (window);
2357 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2358 ModestMsgEditWindow *window)
2360 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2361 g_return_if_fail (GTK_IS_ACTION (action));
2363 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2366 modest_msg_edit_window_select_background_color (window);
2370 modest_ui_actions_on_insert_image (GtkAction *action,
2371 ModestMsgEditWindow *window)
2373 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2374 g_return_if_fail (GTK_IS_ACTION (action));
2376 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2379 modest_msg_edit_window_insert_image (window);
2383 modest_ui_actions_on_attach_file (GtkAction *action,
2384 ModestMsgEditWindow *window)
2386 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2387 g_return_if_fail (GTK_IS_ACTION (action));
2389 modest_msg_edit_window_offer_attach_file (window);
2393 modest_ui_actions_on_remove_attachments (GtkAction *action,
2394 ModestMsgEditWindow *window)
2396 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2397 g_return_if_fail (GTK_IS_ACTION (action));
2399 modest_msg_edit_window_remove_attachments (window, NULL);
2403 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2406 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2407 const GError *error = modest_mail_operation_get_error (mail_op);
2410 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2411 _("mail_in_ui_folder_create_error"));
2416 modest_ui_actions_create_folder(GtkWidget *parent_window,
2417 GtkWidget *folder_view)
2419 TnyFolderStore *parent_folder;
2421 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2423 if (parent_folder) {
2424 gboolean finished = FALSE;
2426 gchar *folder_name = NULL, *suggested_name = NULL;
2427 const gchar *proto_str = NULL;
2428 TnyAccount *account;
2430 if (TNY_IS_ACCOUNT (parent_folder))
2431 account = g_object_ref (parent_folder);
2433 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2434 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2436 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2437 MODEST_PROTOCOL_STORE_POP) {
2439 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2441 g_object_unref (account);
2443 /* Run the new folder dialog */
2445 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2450 g_free (suggested_name);
2451 suggested_name = NULL;
2453 if (result == GTK_RESPONSE_REJECT) {
2456 ModestMailOperation *mail_op;
2457 TnyFolder *new_folder = NULL;
2459 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
2460 modest_ui_actions_new_folder_error_handler,
2463 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2465 new_folder = modest_mail_operation_create_folder (mail_op,
2467 (const gchar *) folder_name);
2469 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2472 g_object_unref (new_folder);
2475 g_object_unref (mail_op);
2478 suggested_name = folder_name;
2482 g_object_unref (parent_folder);
2487 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2489 GtkWidget *folder_view;
2491 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2493 folder_view = modest_main_window_get_child_widget (main_window,
2494 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2498 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2502 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2505 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2506 const GError *error = NULL;
2507 const gchar *message = NULL;
2509 /* Get error message */
2510 error = modest_mail_operation_get_error (mail_op);
2512 g_return_if_reached ();
2514 switch (error->code) {
2515 case MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS:
2516 message = _CS("ckdg_ib_folder_already_exists");
2519 g_return_if_reached ();
2522 modest_platform_information_banner (GTK_WIDGET (window), NULL, message);
2526 modest_ui_actions_on_rename_folder (GtkAction *action,
2527 ModestMainWindow *main_window)
2529 TnyFolderStore *folder;
2530 GtkWidget *folder_view;
2531 GtkWidget *header_view;
2533 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2535 folder_view = modest_main_window_get_child_widget (main_window,
2536 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2540 header_view = modest_main_window_get_child_widget (main_window,
2541 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2546 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2551 if (TNY_IS_FOLDER (folder)) {
2554 const gchar *current_name;
2555 TnyFolderStore *parent;
2556 gboolean do_rename = TRUE;
2558 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2559 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
2560 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
2561 parent, current_name,
2563 g_object_unref (parent);
2565 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
2567 } else if (modest_platform_is_network_folderstore(folder) &&
2568 !tny_device_is_online (modest_runtime_get_device())) {
2569 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2570 do_rename = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2571 g_object_unref(account);
2575 ModestMailOperation *mail_op;
2576 GtkTreeSelection *sel = NULL;
2579 modest_mail_operation_new_with_error_handling (G_OBJECT(main_window),
2580 modest_ui_actions_rename_folder_error_handler,
2583 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2586 /* Clear the headers view */
2587 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2588 gtk_tree_selection_unselect_all (sel);
2590 /* Select *after* the changes */
2591 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2592 TNY_FOLDER(folder), TRUE);
2594 /* Actually rename the folder */
2595 modest_mail_operation_rename_folder (mail_op,
2596 TNY_FOLDER (folder),
2597 (const gchar *) folder_name);
2599 g_object_unref (mail_op);
2600 g_free (folder_name);
2603 g_object_unref (folder);
2607 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2610 GObject *win = modest_mail_operation_get_source (mail_op);
2612 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2613 _("mail_in_ui_folder_delete_error"));
2614 g_object_unref (win);
2618 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2620 TnyFolderStore *folder;
2621 GtkWidget *folder_view;
2624 gboolean do_delete = TRUE;
2626 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (main_window), FALSE);
2628 folder_view = modest_main_window_get_child_widget (main_window,
2629 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2633 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2635 /* Show an error if it's an account */
2636 if (!TNY_IS_FOLDER (folder)) {
2637 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2638 _("mail_in_ui_folder_delete_error"));
2639 g_object_unref (G_OBJECT (folder));
2644 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2645 tny_folder_get_name (TNY_FOLDER (folder)));
2646 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2647 (const gchar *) message);
2650 if (response != GTK_RESPONSE_OK) {
2652 } else if (modest_platform_is_network_folderstore(folder) &&
2653 !tny_device_is_online (modest_runtime_get_device())) {
2654 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2655 do_delete = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2656 g_object_unref(account);
2660 ModestMailOperation *mail_op;
2661 GtkTreeSelection *sel;
2663 /* Unselect the folder before deleting it to free the headers */
2664 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2665 gtk_tree_selection_unselect_all (sel);
2667 /* Create the mail operation */
2669 modest_mail_operation_new_with_error_handling (G_OBJECT(main_window),
2670 modest_ui_actions_delete_folder_error_handler,
2673 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2675 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2676 g_object_unref (G_OBJECT (mail_op));
2679 g_object_unref (G_OBJECT (folder));
2685 modest_ui_actions_on_delete_folder (GtkAction *action,
2686 ModestMainWindow *main_window)
2688 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2690 if (delete_folder (main_window, FALSE)) {
2691 GtkWidget *folder_view;
2693 folder_view = modest_main_window_get_child_widget (main_window,
2694 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2695 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2700 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2702 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2704 delete_folder (main_window, TRUE);
2709 show_error (GtkWidget *parent_widget, const gchar* text)
2711 hildon_banner_show_information(parent_widget, NULL, text);
2714 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2716 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2723 gtk_dialog_run (dialog);
2724 gtk_widget_destroy (GTK_WIDGET (dialog));
2729 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2730 const gchar* server_account_name,
2735 ModestMainWindow *main_window)
2737 g_return_if_fail(server_account_name);
2738 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2740 /* Initalize output parameters: */
2747 #ifdef MODEST_PLATFORM_MAEMO
2748 /* Maemo uses a different (awkward) button order,
2749 * It should probably just use gtk_alternative_dialog_button_order ().
2751 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2754 _("mcen_bd_dialog_ok"),
2755 GTK_RESPONSE_ACCEPT,
2756 _("mcen_bd_dialog_cancel"),
2757 GTK_RESPONSE_REJECT,
2760 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2764 GTK_RESPONSE_REJECT,
2766 GTK_RESPONSE_ACCEPT,
2768 #endif /* MODEST_PLATFORM_MAEMO */
2770 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2772 gchar *server_name = modest_account_mgr_get_server_account_hostname (
2773 modest_runtime_get_account_mgr(), server_account_name);
2774 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2775 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2780 /* This causes a warning because the logical ID has no %s in it,
2781 * though the translation does, but there is not much we can do about that: */
2782 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2783 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2786 g_free (server_name);
2790 gchar *initial_username = modest_account_mgr_get_server_account_username (
2791 modest_runtime_get_account_mgr(), server_account_name);
2793 GtkWidget *entry_username = gtk_entry_new ();
2794 if (initial_username)
2795 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2796 /* Dim this if a connection has ever succeeded with this username,
2797 * as per the UI spec: */
2798 const gboolean username_known =
2799 modest_account_mgr_get_server_account_username_has_succeeded(
2800 modest_runtime_get_account_mgr(), server_account_name);
2801 gtk_widget_set_sensitive (entry_username, !username_known);
2803 #ifdef MODEST_PLATFORM_MAEMO
2804 /* Auto-capitalization is the default, so let's turn it off: */
2805 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2807 /* Create a size group to be used by all captions.
2808 * Note that HildonCaption does not create a default size group if we do not specify one.
2809 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2810 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2812 GtkWidget *caption = hildon_caption_new (sizegroup,
2813 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2814 gtk_widget_show (entry_username);
2815 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2816 FALSE, FALSE, MODEST_MARGIN_HALF);
2817 gtk_widget_show (caption);
2819 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2821 #endif /* MODEST_PLATFORM_MAEMO */
2824 GtkWidget *entry_password = gtk_entry_new ();
2825 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2826 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2828 #ifdef MODEST_PLATFORM_MAEMO
2829 /* Auto-capitalization is the default, so let's turn it off: */
2830 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2831 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2833 caption = hildon_caption_new (sizegroup,
2834 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2835 gtk_widget_show (entry_password);
2836 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2837 FALSE, FALSE, MODEST_MARGIN_HALF);
2838 gtk_widget_show (caption);
2839 g_object_unref (sizegroup);
2841 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2843 #endif /* MODEST_PLATFORM_MAEMO */
2845 if (initial_username != NULL)
2846 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
2848 /* This is not in the Maemo UI spec:
2849 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2850 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2854 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2856 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2858 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2860 modest_account_mgr_set_server_account_username (
2861 modest_runtime_get_account_mgr(), server_account_name,
2864 const gboolean username_was_changed =
2865 (strcmp (*username, initial_username) != 0);
2866 if (username_was_changed) {
2867 g_warning ("%s: tinymail does not yet support changing the "
2868 "username in the get_password() callback.\n", __FUNCTION__);
2873 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2875 /* We do not save the password in the configuration,
2876 * because this function is only called for passwords that should
2877 * not be remembered:
2878 modest_server_account_set_password (
2879 modest_runtime_get_account_mgr(), server_account_name,
2888 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2900 /* This is not in the Maemo UI spec:
2901 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2907 gtk_widget_destroy (dialog);
2909 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2913 modest_ui_actions_on_cut (GtkAction *action,
2914 ModestWindow *window)
2916 GtkWidget *focused_widget;
2917 GtkClipboard *clipboard;
2919 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2920 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2921 if (GTK_IS_EDITABLE (focused_widget)) {
2922 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2923 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2924 gtk_clipboard_store (clipboard);
2925 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2926 GtkTextBuffer *buffer;
2928 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2929 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2930 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2931 gtk_clipboard_store (clipboard);
2932 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2933 TnyList *header_list = modest_header_view_get_selected_headers (
2934 MODEST_HEADER_VIEW (focused_widget));
2935 gboolean continue_download = FALSE;
2936 gint num_of_unc_msgs;
2938 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
2940 if (num_of_unc_msgs)
2941 continue_download = connect_to_get_msg(
2942 GTK_WINDOW (window),
2945 if (num_of_unc_msgs == 0 || continue_download) {
2946 /* modest_platform_information_banner (
2947 NULL, NULL, _CS("mcen_ib_getting_items"));*/
2948 modest_header_view_cut_selection (
2949 MODEST_HEADER_VIEW (focused_widget));
2952 g_object_unref (header_list);
2953 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2954 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2959 modest_ui_actions_on_copy (GtkAction *action,
2960 ModestWindow *window)
2962 GtkClipboard *clipboard;
2963 GtkWidget *focused_widget;
2964 gboolean copied = TRUE;
2966 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2967 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2969 if (GTK_IS_LABEL (focused_widget)) {
2970 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2971 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2972 gtk_clipboard_store (clipboard);
2973 } else if (GTK_IS_EDITABLE (focused_widget)) {
2974 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2975 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2976 gtk_clipboard_store (clipboard);
2977 } else if (GTK_IS_HTML (focused_widget)) {
2978 gtk_html_copy (GTK_HTML (focused_widget));
2979 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2980 gtk_clipboard_store (clipboard);
2981 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2982 GtkTextBuffer *buffer;
2983 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2984 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2985 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2986 gtk_clipboard_store (clipboard);
2987 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2988 TnyList *header_list = modest_header_view_get_selected_headers (
2989 MODEST_HEADER_VIEW (focused_widget));
2990 gboolean continue_download = FALSE;
2991 gint num_of_unc_msgs;
2993 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
2995 if (num_of_unc_msgs)
2996 continue_download = connect_to_get_msg(
2997 GTK_WINDOW (window),
3000 if (num_of_unc_msgs == 0 || continue_download) {
3001 modest_platform_information_banner (
3002 NULL, NULL, _CS("mcen_ib_getting_items"));
3003 modest_header_view_copy_selection (
3004 MODEST_HEADER_VIEW (focused_widget));
3008 g_object_unref (header_list);
3010 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3011 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3014 /* Show information banner if there was a copy to clipboard */
3016 modest_platform_information_banner (
3017 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3021 modest_ui_actions_on_undo (GtkAction *action,
3022 ModestWindow *window)
3024 ModestEmailClipboard *clipboard = NULL;
3026 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3027 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3028 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3029 /* Clear clipboard source */
3030 clipboard = modest_runtime_get_email_clipboard ();
3031 modest_email_clipboard_clear (clipboard);
3034 g_return_if_reached ();
3039 modest_ui_actions_on_redo (GtkAction *action,
3040 ModestWindow *window)
3042 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3043 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3046 g_return_if_reached ();
3052 destroy_information_note (ModestMailOperation *mail_op, gpointer user_data)
3054 /* destroy information note */
3055 gtk_widget_destroy (GTK_WIDGET(user_data));
3060 paste_as_attachment_free (gpointer data)
3062 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3064 gtk_widget_destroy (helper->banner);
3065 g_object_unref (helper->banner);
3070 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3075 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3076 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3081 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3086 modest_ui_actions_on_paste (GtkAction *action,
3087 ModestWindow *window)
3089 GtkWidget *focused_widget = NULL;
3090 GtkWidget *inf_note = NULL;
3091 ModestMailOperation *mail_op = NULL;
3093 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3094 if (GTK_IS_EDITABLE (focused_widget)) {
3095 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3096 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3097 ModestEmailClipboard *e_clipboard = NULL;
3098 e_clipboard = modest_runtime_get_email_clipboard ();
3099 if (modest_email_clipboard_cleared (e_clipboard)) {
3100 GtkTextBuffer *buffer;
3101 GtkClipboard *clipboard;
3103 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3104 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3105 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3106 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3107 ModestMailOperation *mail_op;
3108 TnyFolder *src_folder;
3111 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3112 helper->window = MODEST_MSG_EDIT_WINDOW (window);
3113 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3114 _CS("ckct_nw_pasting"));
3115 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
3116 mail_op = modest_mail_operation_new (G_OBJECT (window));
3117 if (helper->banner != NULL) {
3118 g_object_ref (G_OBJECT (helper->banner));
3119 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
3120 gtk_widget_show (GTK_WIDGET (helper->banner));
3124 modest_mail_operation_get_msgs_full (mail_op,
3126 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
3128 paste_as_attachment_free);
3131 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3132 ModestEmailClipboard *clipboard = NULL;
3133 TnyFolder *src_folder = NULL;
3134 TnyFolderStore *folder_store = NULL;
3135 TnyList *data = NULL;
3136 gboolean delete = FALSE;
3138 /* Check clipboard source */
3139 clipboard = modest_runtime_get_email_clipboard ();
3140 if (modest_email_clipboard_cleared (clipboard))
3143 /* Get elements to paste */
3144 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
3146 /* Create a new mail operation */
3147 mail_op = modest_mail_operation_new (G_OBJECT(window));
3149 /* Get destination folder */
3150 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
3152 /* transfer messages */
3156 /* Ask for user confirmation */
3158 modest_ui_actions_msgs_move_to_confirmation (GTK_WINDOW (window),
3159 TNY_FOLDER (folder_store),
3163 if (response == GTK_RESPONSE_OK) {
3164 /* Launch notification */
3165 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3166 _CS("ckct_nw_pasting"));
3167 if (inf_note != NULL) {
3168 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3169 gtk_widget_show (GTK_WIDGET(inf_note));
3172 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3173 modest_mail_operation_xfer_msgs (mail_op,
3175 TNY_FOLDER (folder_store),
3177 destroy_information_note,
3180 g_object_unref (mail_op);
3183 } else if (src_folder != NULL) {
3184 /* Launch notification */
3185 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3186 _CS("ckct_nw_pasting"));
3187 if (inf_note != NULL) {
3188 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3189 gtk_widget_show (GTK_WIDGET(inf_note));
3192 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3193 modest_mail_operation_xfer_folder (mail_op,
3197 destroy_information_note,
3203 g_object_unref (data);
3204 if (src_folder != NULL)
3205 g_object_unref (src_folder);
3206 if (folder_store != NULL)
3207 g_object_unref (folder_store);
3213 modest_ui_actions_on_select_all (GtkAction *action,
3214 ModestWindow *window)
3216 GtkWidget *focused_widget;
3218 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3219 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3220 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3221 } else if (GTK_IS_LABEL (focused_widget)) {
3222 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3223 } else if (GTK_IS_EDITABLE (focused_widget)) {
3224 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3225 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3226 GtkTextBuffer *buffer;
3227 GtkTextIter start, end;
3229 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3230 gtk_text_buffer_get_start_iter (buffer, &start);
3231 gtk_text_buffer_get_end_iter (buffer, &end);
3232 gtk_text_buffer_select_range (buffer, &start, &end);
3233 } else if (GTK_IS_HTML (focused_widget)) {
3234 gtk_html_select_all (GTK_HTML (focused_widget));
3235 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3236 GtkWidget *header_view = focused_widget;
3237 GtkTreeSelection *selection = NULL;
3239 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
3240 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3241 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3244 /* Disable window dimming management */
3245 modest_window_disable_dimming (MODEST_WINDOW(window));
3247 /* Select all messages */
3248 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3249 gtk_tree_selection_select_all (selection);
3251 /* Set focuse on header view */
3252 gtk_widget_grab_focus (header_view);
3255 /* Enable window dimming management */
3256 modest_window_enable_dimming (MODEST_WINDOW(window));
3257 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3263 modest_ui_actions_on_mark_as_read (GtkAction *action,
3264 ModestWindow *window)
3266 g_return_if_fail (MODEST_IS_WINDOW(window));
3268 /* Mark each header as read */
3269 do_headers_action (window, headers_action_mark_as_read, NULL);
3273 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3274 ModestWindow *window)
3276 g_return_if_fail (MODEST_IS_WINDOW(window));
3278 /* Mark each header as read */
3279 do_headers_action (window, headers_action_mark_as_unread, NULL);
3283 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3284 GtkRadioAction *selected,
3285 ModestWindow *window)
3289 value = gtk_radio_action_get_current_value (selected);
3290 if (MODEST_IS_WINDOW (window)) {
3291 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3296 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3297 GtkRadioAction *selected,
3298 ModestWindow *window)
3300 TnyHeaderFlags flags;
3301 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3303 flags = gtk_radio_action_get_current_value (selected);
3304 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3308 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3309 GtkRadioAction *selected,
3310 ModestWindow *window)
3314 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3316 file_format = gtk_radio_action_get_current_value (selected);
3317 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3322 modest_ui_actions_on_zoom_plus (GtkAction *action,
3323 ModestWindow *window)
3325 g_return_if_fail (MODEST_IS_WINDOW (window));
3327 modest_window_zoom_plus (MODEST_WINDOW (window));
3331 modest_ui_actions_on_zoom_minus (GtkAction *action,
3332 ModestWindow *window)
3334 g_return_if_fail (MODEST_IS_WINDOW (window));
3336 modest_window_zoom_minus (MODEST_WINDOW (window));
3340 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3341 ModestWindow *window)
3343 ModestWindowMgr *mgr;
3344 gboolean fullscreen, active;
3345 g_return_if_fail (MODEST_IS_WINDOW (window));
3347 mgr = modest_runtime_get_window_mgr ();
3349 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3350 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3352 if (active != fullscreen) {
3353 modest_window_mgr_set_fullscreen_mode (mgr, active);
3354 gtk_window_present (GTK_WINDOW (window));
3359 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3360 ModestWindow *window)
3362 ModestWindowMgr *mgr;
3363 gboolean fullscreen;
3365 g_return_if_fail (MODEST_IS_WINDOW (window));
3367 mgr = modest_runtime_get_window_mgr ();
3368 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3369 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3371 gtk_window_present (GTK_WINDOW (window));
3375 * Used by modest_ui_actions_on_details to call do_headers_action
3378 headers_action_show_details (TnyHeader *header,
3379 ModestWindow *window,
3386 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3389 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3390 gtk_widget_show_all (dialog);
3391 gtk_dialog_run (GTK_DIALOG (dialog));
3393 gtk_widget_destroy (dialog);
3397 * Show the folder details in a ModestDetailsDialog widget
3400 show_folder_details (TnyFolder *folder,
3406 dialog = modest_details_dialog_new_with_folder (window, folder);
3409 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3410 gtk_widget_show_all (dialog);
3411 gtk_dialog_run (GTK_DIALOG (dialog));
3413 gtk_widget_destroy (dialog);
3417 * Show the header details in a ModestDetailsDialog widget
3420 modest_ui_actions_on_details (GtkAction *action,
3423 TnyList * headers_list;
3427 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3430 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3433 g_object_unref (msg);
3435 headers_list = get_selected_headers (win);
3439 iter = tny_list_create_iterator (headers_list);
3441 header = TNY_HEADER (tny_iterator_get_current (iter));
3443 headers_action_show_details (header, win, NULL);
3444 g_object_unref (header);
3447 g_object_unref (iter);
3448 g_object_unref (headers_list);
3450 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3451 GtkWidget *folder_view, *header_view;
3453 /* Check which widget has the focus */
3454 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3455 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3456 if (gtk_widget_is_focus (folder_view)) {
3457 TnyFolderStore *folder_store
3458 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3459 if (!folder_store) {
3460 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3463 /* Show only when it's a folder */
3464 /* This function should not be called for account items,
3465 * because we dim the menu item for them. */
3466 if (TNY_IS_FOLDER (folder_store)) {
3467 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3470 g_object_unref (folder_store);
3473 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3474 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3475 /* Show details of each header */
3476 do_headers_action (win, headers_action_show_details, header_view);
3482 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3483 ModestMsgEditWindow *window)
3485 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3487 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3491 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3492 ModestMsgEditWindow *window)
3494 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3496 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3500 modest_ui_actions_toggle_folders_view (GtkAction *action,
3501 ModestMainWindow *main_window)
3503 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3505 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3506 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3508 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3512 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3513 ModestWindow *window)
3515 gboolean active, fullscreen = FALSE;
3516 ModestWindowMgr *mgr;
3518 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3520 /* Check if we want to toggle the toolbar vuew in fullscreen
3522 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3523 "ViewShowToolbarFullScreen")) {
3527 /* Toggle toolbar */
3528 mgr = modest_runtime_get_window_mgr ();
3529 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
3533 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3534 ModestMsgEditWindow *window)
3536 modest_msg_edit_window_select_font (window);
3540 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3541 const gchar *display_name,
3544 /* Do not change the application name if the widget has not
3545 the focus. This callback could be called even if the folder
3546 view has not the focus, because the handled signal could be
3547 emitted when the folder view is redrawn */
3548 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3550 gtk_window_set_title (window, display_name);
3552 gtk_window_set_title (window, " ");
3557 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3559 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3560 modest_msg_edit_window_select_contacts (window);
3564 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3566 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3567 modest_msg_edit_window_check_names (window, FALSE);
3571 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3573 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3574 GTK_WIDGET (user_data));
3578 * This function is used to track changes in the selection of the
3579 * folder view that is inside the "move to" dialog to enable/disable
3580 * the OK button because we do not want the user to select a disallowed
3581 * destination for a folder.
3582 * The user also not desired to be able to use NEW button on items where
3583 * folder creation is not possibel.
3586 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
3587 TnyFolderStore *folder_store,
3591 GtkWidget *dialog = NULL;
3592 GtkWidget *ok_button = NULL, *new_button = NULL;
3593 GList *children = NULL;
3594 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
3595 gboolean moving_folder = FALSE;
3596 gboolean is_local_account = TRUE;
3597 GtkWidget *folder_view = NULL;
3598 ModestTnyFolderRules rules;
3603 /* Get the OK button */
3604 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
3608 children = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
3609 ok_button = GTK_WIDGET (children->next->next->data);
3610 new_button = GTK_WIDGET (children->next->data);
3611 g_list_free (children);
3613 /* check if folder_store is an remote account */
3614 if (TNY_IS_ACCOUNT (folder_store)) {
3615 TnyAccount *local_account = NULL;
3616 ModestTnyAccountStore *account_store = NULL;
3618 account_store = modest_runtime_get_account_store ();
3619 local_account = modest_tny_account_store_get_local_folders_account (account_store);
3621 if ((gpointer) local_account != (gpointer) folder_store) {
3622 is_local_account = FALSE;
3623 /* New button should be dimmed on remote
3625 new_sensitive = FALSE;
3627 g_object_unref (local_account);
3630 /* Check the target folder rules */
3631 if (TNY_IS_FOLDER (folder_store)) {
3632 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
3633 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
3634 ok_sensitive = FALSE;
3635 new_sensitive = FALSE;
3640 /* Check if we're moving a folder */
3641 if (MODEST_IS_MAIN_WINDOW (user_data)) {
3642 /* Get the widgets */
3643 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
3644 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3645 if (gtk_widget_is_focus (folder_view))
3646 moving_folder = TRUE;
3649 if (moving_folder) {
3650 TnyFolderStore *moved_folder = NULL, *parent = NULL;
3652 /* Get the folder to move */
3653 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3655 /* Check that we're not moving to the same folder */
3656 if (TNY_IS_FOLDER (moved_folder)) {
3657 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
3658 if (parent == folder_store)
3659 ok_sensitive = FALSE;
3660 g_object_unref (parent);
3663 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
3664 /* Do not allow to move to an account unless it's the
3665 local folders account */
3666 if (!is_local_account)
3667 ok_sensitive = FALSE;
3670 if (ok_sensitive && (moved_folder == folder_store)) {
3671 /* Do not allow to move to itself */
3672 ok_sensitive = FALSE;
3674 g_object_unref (moved_folder);
3676 TnyHeader *header = NULL;
3677 TnyFolder *src_folder = NULL;
3679 /* Moving a message */
3680 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
3681 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (user_data));
3682 src_folder = tny_header_get_folder (header);
3683 g_object_unref (header);
3686 TNY_FOLDER (modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view)));
3689 /* Do not allow to move the msg to the same folder */
3690 /* Do not allow to move the msg to an account */
3691 if ((gpointer) src_folder == (gpointer) folder_store ||
3692 TNY_IS_ACCOUNT (folder_store))
3693 ok_sensitive = FALSE;
3694 g_object_unref (src_folder);
3698 /* Set sensitivity of the OK button */
3699 gtk_widget_set_sensitive (ok_button, ok_sensitive);
3700 /* Set sensitivity of the NEW button */
3701 gtk_widget_set_sensitive (new_button, new_sensitive);
3705 create_move_to_dialog (GtkWindow *win,
3706 GtkWidget *folder_view,
3707 GtkWidget **tree_view)
3709 GtkWidget *dialog, *scroll;
3710 GtkWidget *new_button;
3712 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3714 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3717 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
3718 /* We do this manually so GTK+ does not associate a response ID for
3720 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
3721 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3722 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
3724 /* Create scrolled window */
3725 scroll = gtk_scrolled_window_new (NULL, NULL);
3726 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3727 GTK_POLICY_AUTOMATIC,
3728 GTK_POLICY_AUTOMATIC);
3730 /* Create folder view */
3731 *tree_view = modest_platform_create_folder_view (NULL);
3733 /* Track changes in the selection to
3734 * disable the OK button whenever "Move to" is not possible
3735 * disbale NEW button whenever New is not possible */
3736 g_signal_connect (*tree_view,
3737 "folder_selection_changed",
3738 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
3741 /* Listen to clicks on New button */
3742 g_signal_connect (G_OBJECT (new_button),
3744 G_CALLBACK(create_move_to_dialog_on_new_folder),
3747 /* It could happen that we're trying to move a message from a
3748 window (msg window for example) after the main window was
3749 closed, so we can not just get the model of the folder
3751 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
3752 const gchar *visible_id = NULL;
3754 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
3755 MODEST_FOLDER_VIEW(*tree_view));
3758 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
3760 /* Show the same account than the one that is shown in the main window */
3761 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
3764 const gchar *active_account_name = NULL;
3765 ModestAccountMgr *mgr = NULL;
3766 ModestAccountData *acc_data = NULL;
3768 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3769 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3771 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
3772 mgr = modest_runtime_get_account_mgr ();
3773 acc_data = modest_account_mgr_get_account_data (mgr, active_account_name);
3775 /* Set the new visible & active account */
3776 if (acc_data && acc_data->store_account) {
3777 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
3778 acc_data->store_account->account_name);
3779 modest_account_mgr_free_account_data (mgr, acc_data);
3783 /* Hide special folders */
3784 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3786 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3788 /* Add scroll to dialog */
3789 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3790 scroll, TRUE, TRUE, 0);
3792 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3793 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3799 * Returns TRUE if at least one of the headers of the list belongs to
3800 * a message that has been fully retrieved.
3802 #if 0 /* no longer in use. delete in 2007.10 */
3804 has_retrieved_msgs (TnyList *list)
3807 gboolean found = FALSE;
3809 iter = tny_list_create_iterator (list);
3810 while (!tny_iterator_is_done (iter) && !found) {
3812 TnyHeaderFlags flags = 0;
3814 header = TNY_HEADER (tny_iterator_get_current (iter));
3816 flags = tny_header_get_flags (header);
3817 if (flags & TNY_HEADER_FLAG_CACHED)
3818 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3821 g_object_unref (header);
3825 tny_iterator_next (iter);
3827 g_object_unref (iter);
3835 * Shows a confirmation dialog to the user when we're moving messages
3836 * from a remote server to the local storage. Returns the dialog
3837 * response. If it's other kind of movement then it always returns
3840 * This one is used by the next functions:
3841 * modest_ui_actions_on_paste - commented out
3842 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
3845 modest_ui_actions_msgs_move_to_confirmation (GtkWindow *win,
3846 TnyFolder *dest_folder,
3850 gint response = GTK_RESPONSE_OK;
3852 /* return with OK if the destination is a remote folder */
3853 if (modest_tny_folder_is_remote_folder (dest_folder))
3854 return GTK_RESPONSE_OK;
3856 TnyFolder *src_folder = NULL;
3857 TnyIterator *iter = NULL;
3858 TnyHeader *header = NULL;
3860 /* Get source folder */
3861 iter = tny_list_create_iterator (headers);
3862 header = TNY_HEADER (tny_iterator_get_current (iter));
3864 src_folder = tny_header_get_folder (header);
3865 g_object_unref (header);
3867 g_object_unref (iter);
3869 /* if no src_folder, message may be an attahcment */
3870 if (src_folder == NULL)
3871 return GTK_RESPONSE_CANCEL;
3873 /* If the source is a local or MMC folder */
3874 if (!modest_tny_folder_is_remote_folder (src_folder)) {
3875 g_object_unref (src_folder);
3876 return GTK_RESPONSE_OK;
3878 g_object_unref (src_folder);
3880 /* now if offline we ask the user */
3881 if(connect_to_get_msg( GTK_WINDOW (win),
3882 tny_list_get_length (headers)))
3883 response = GTK_RESPONSE_OK;
3885 response = GTK_RESPONSE_CANCEL;
3893 move_to_cb (ModestMailOperation *mail_op, gpointer user_data)
3895 MoveToHelper *helper = (MoveToHelper *) user_data;
3897 /* Note that the operation could have failed, in that case do
3899 if (modest_mail_operation_get_status (mail_op) ==
3900 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
3902 GObject *object = modest_mail_operation_get_source (mail_op);
3903 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
3904 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
3906 if (!modest_msg_view_window_select_next_message (self))
3907 if (!modest_msg_view_window_select_previous_message (self))
3908 /* No more messages to view, so close this window */
3909 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3910 } else if (MODEST_IS_MAIN_WINDOW (object) && helper->reference != NULL) {
3911 GtkWidget *header_view;
3913 GtkTreeSelection *sel;
3915 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
3916 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3917 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
3918 path = gtk_tree_row_reference_get_path (helper->reference);
3919 gtk_tree_selection_select_path (sel, path);
3920 gtk_tree_path_free (path);
3922 g_object_unref (object);
3925 /* Close the "Pasting" information banner */
3926 gtk_widget_destroy (GTK_WIDGET(helper->banner));
3927 if (helper->reference != NULL)
3928 gtk_tree_row_reference_free (helper->reference);
3933 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3936 ModestWindow *main_window = NULL;
3937 GtkWidget *folder_view = NULL;
3938 GObject *win = modest_mail_operation_get_source (mail_op);
3939 const GError *error = NULL;
3940 const gchar *message = NULL;
3942 /* Get error message */
3943 error = modest_mail_operation_get_error (mail_op);
3944 if (error != NULL && error->message != NULL) {
3945 message = error->message;
3947 message = _("mail_in_ui_folder_move_target_error");
3950 /* Disable next automatic folder selection */
3951 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ());
3952 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
3953 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3954 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
3956 if (user_data && TNY_IS_FOLDER (user_data)) {
3957 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3958 TNY_FOLDER (user_data), FALSE);
3961 /* Show notification dialog */
3962 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3963 g_object_unref (win);
3967 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3970 GObject *win = modest_mail_operation_get_source (mail_op);
3971 const GError *error = modest_mail_operation_get_error (mail_op);
3973 g_return_if_fail (error != NULL);
3974 if (error->message != NULL)
3975 g_printerr ("modest: %s\n", error->message);
3977 g_printerr ("modest: unkonw error on send&receive operation");
3979 /* Show error message */
3980 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3981 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3982 /* _CS("sfil_ib_unable_to_receive")); */
3984 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3985 /* _CS("sfil_ib_unable_to_send")); */
3986 g_object_unref (win);
3990 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3997 gint pending_purges = 0;
3998 gboolean some_purged = FALSE;
3999 ModestWindow *win = MODEST_WINDOW (user_data);
4000 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
4002 /* If there was any error */
4003 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
4004 modest_window_mgr_unregister_header (mgr, header);
4008 /* Once the message has been retrieved for purging, we check if
4009 * it's all ok for purging */
4011 parts = tny_simple_list_new ();
4012 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
4013 iter = tny_list_create_iterator (parts);
4015 while (!tny_iterator_is_done (iter)) {
4017 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4018 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
4019 if (tny_mime_part_is_purged (part))
4026 g_object_unref (part);
4028 tny_iterator_next (iter);
4030 g_object_unref (iter);
4033 if (pending_purges>0) {
4035 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
4037 if (response == GTK_RESPONSE_OK) {
4038 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
4039 iter = tny_list_create_iterator (parts);
4040 while (!tny_iterator_is_done (iter)) {
4043 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4044 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
4045 tny_mime_part_set_purged (part);
4048 g_object_unref (part);
4050 tny_iterator_next (iter);
4053 tny_msg_rewrite_cache (msg);
4056 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
4058 g_object_unref (iter);
4060 modest_window_mgr_unregister_header (mgr, header);
4062 g_object_unref (parts);
4066 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
4067 ModestMainWindow *win)
4069 GtkWidget *header_view;
4070 TnyList *header_list;
4073 TnyHeaderFlags flags;
4074 ModestWindow *msg_view_window = NULL;
4077 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4079 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4080 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4082 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
4084 if (tny_list_get_length (header_list) == 1) {
4085 iter = tny_list_create_iterator (header_list);
4086 header = TNY_HEADER (tny_iterator_get_current (iter));
4087 g_object_unref (iter);
4092 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
4093 header, &msg_view_window);
4094 flags = tny_header_get_flags (header);
4095 if (!(flags & TNY_HEADER_FLAG_CACHED))
4098 if (msg_view_window != NULL)
4099 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
4101 /* do nothing; uid was registered before, so window is probably on it's way */
4102 g_warning ("debug: header %p has already been registered", header);
4105 ModestMailOperation *mail_op = NULL;
4106 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
4107 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
4108 modest_ui_actions_get_msgs_full_error_handler,
4110 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4111 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
4113 g_object_unref (mail_op);
4116 g_object_unref (header);
4118 g_object_unref (header_list);
4122 * Utility function that transfer messages from both the main window
4123 * and the msg view window when using the "Move to" dialog
4126 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
4129 TnyList *headers = NULL;
4130 TnyAccount *dst_account = NULL;
4131 const gchar *proto_str = NULL;
4132 gboolean dst_is_pop = FALSE;
4134 if (!TNY_IS_FOLDER (dst_folder)) {
4135 modest_platform_information_banner (GTK_WIDGET (win),
4137 _CS("ckdg_ib_unable_to_move_to_current_location"));
4141 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
4142 proto_str = tny_account_get_proto (dst_account);
4144 /* tinymail will return NULL for local folders it seems */
4145 dst_is_pop = proto_str &&
4146 (modest_protocol_info_get_transport_store_protocol (proto_str) ==
4147 MODEST_PROTOCOL_STORE_POP);
4149 g_object_unref (dst_account);
4151 /* Get selected headers */
4152 headers = get_selected_headers (MODEST_WINDOW (win));
4155 modest_platform_information_banner (GTK_WIDGET (win),
4157 ngettext("mail_in_ui_folder_move_target_error",
4158 "mail_in_ui_folder_move_targets_error",
4159 tny_list_get_length (headers)));
4160 g_object_unref (headers);
4164 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4165 helper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4166 _CS("ckct_nw_pasting"));
4167 if (helper->banner != NULL) {
4168 gtk_window_set_modal (GTK_WINDOW(helper->banner), FALSE);
4169 gtk_widget_show (GTK_WIDGET(helper->banner));
4172 if (MODEST_IS_MAIN_WINDOW (win)) {
4173 GtkWidget *header_view =
4174 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
4175 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4176 helper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
4179 ModestMailOperation *mail_op =
4180 modest_mail_operation_new_with_error_handling (G_OBJECT(win),
4181 modest_ui_actions_move_folder_error_handler,
4183 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4186 modest_mail_operation_xfer_msgs (mail_op,
4188 TNY_FOLDER (dst_folder),
4193 g_object_unref (G_OBJECT (mail_op));
4194 g_object_unref (headers);
4198 * UI handler for the "Move to" action when invoked from the
4202 modest_ui_actions_on_main_window_move_to (GtkAction *action,
4203 GtkWidget *folder_view,
4204 TnyFolderStore *dst_folder,
4205 ModestMainWindow *win)
4207 ModestHeaderView *header_view = NULL;
4208 ModestMailOperation *mail_op = NULL;
4209 TnyFolderStore *src_folder;
4210 gboolean online = (tny_device_is_online (modest_runtime_get_device()));
4212 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4214 /* Get the source folder */
4215 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4217 /* Get header view */
4218 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
4220 /* Get folder or messages to transfer */
4221 if (gtk_widget_is_focus (folder_view)) {
4222 GtkTreeSelection *sel;
4223 gboolean do_xfer = TRUE;
4225 /* Allow only to transfer folders to the local root folder */
4226 if (TNY_IS_ACCOUNT (dst_folder) &&
4227 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder)) {
4229 } else if (!TNY_IS_FOLDER (src_folder)) {
4230 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
4232 } else if (!online && modest_platform_is_network_folderstore(src_folder)) {
4233 guint num_headers = tny_folder_get_all_count(TNY_FOLDER(src_folder));
4234 if (!connect_to_get_msg(GTK_WINDOW(win), num_headers)) {
4240 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4241 helper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4242 _CS("ckct_nw_pasting"));
4243 if (helper->banner != NULL) {
4244 gtk_window_set_modal (GTK_WINDOW(helper->banner), FALSE);
4245 gtk_widget_show (GTK_WIDGET(helper->banner));
4247 /* Clean folder on header view before moving it */
4248 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
4249 gtk_tree_selection_unselect_all (sel);
4252 modest_mail_operation_new_with_error_handling (G_OBJECT(win),
4253 modest_ui_actions_move_folder_error_handler,
4255 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4258 /* Select *after* the changes */
4259 /* TODO: this function hangs UI after transfer */
4260 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
4261 /* TNY_FOLDER (src_folder), TRUE); */
4263 modest_mail_operation_xfer_folder (mail_op,
4264 TNY_FOLDER (src_folder),
4269 /* Unref mail operation */
4270 g_object_unref (G_OBJECT (mail_op));
4272 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
4273 gboolean do_xfer = TRUE;
4274 /* Ask for confirmation if the source folder is remote and we're not connected */
4275 if (!online && modest_platform_is_network_folderstore(src_folder)) {
4276 TnyList *headers = modest_header_view_get_selected_headers(header_view);
4277 if (!msgs_already_deleted_from_server(headers, src_folder)) {
4278 guint num_headers = tny_list_get_length(headers);
4279 if (!connect_to_get_msg(GTK_WINDOW(win), num_headers)) {
4283 g_object_unref(headers);
4285 if (do_xfer) /* Transfer messages */
4286 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4290 g_object_unref (src_folder);
4295 * UI handler for the "Move to" action when invoked from the
4296 * ModestMsgViewWindow
4299 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
4300 TnyFolderStore *dst_folder,
4301 ModestMsgViewWindow *win)
4303 TnyHeader *header = NULL;
4304 TnyFolderStore *src_folder;
4306 /* Create header list */
4307 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
4308 src_folder = TNY_FOLDER_STORE(tny_header_get_folder(header));
4309 g_object_unref (header);
4311 /* Transfer the message if online or confirmed by the user */
4312 if (tny_device_is_online (modest_runtime_get_device()) || remote_folder_is_pop(src_folder) ||
4313 (modest_platform_is_network_folderstore(src_folder) && connect_to_get_msg(GTK_WINDOW(win), 1))) {
4314 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4317 g_object_unref (src_folder);
4321 modest_ui_actions_on_move_to (GtkAction *action,
4324 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
4326 TnyFolderStore *dst_folder = NULL;
4327 ModestMainWindow *main_window;
4329 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
4330 MODEST_IS_MSG_VIEW_WINDOW (win));
4332 /* Get the main window if exists */
4333 if (MODEST_IS_MAIN_WINDOW (win))
4334 main_window = MODEST_MAIN_WINDOW (win);
4337 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
4339 /* Get the folder view widget if exists */
4341 folder_view = modest_main_window_get_child_widget (main_window,
4342 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4346 /* Create and run the dialog */
4347 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
4348 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
4349 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4350 result = gtk_dialog_run (GTK_DIALOG(dialog));
4351 g_object_ref (tree_view);
4352 gtk_widget_destroy (dialog);
4354 if (result != GTK_RESPONSE_ACCEPT)
4357 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
4358 /* Do window specific stuff */
4359 if (MODEST_IS_MAIN_WINDOW (win)) {
4360 modest_ui_actions_on_main_window_move_to (action,
4363 MODEST_MAIN_WINDOW (win));
4365 modest_ui_actions_on_msg_view_window_move_to (action,
4367 MODEST_MSG_VIEW_WINDOW (win));
4371 g_object_unref (dst_folder);
4375 * Calls #HeadersFunc for each header already selected in the main
4376 * window or the message currently being shown in the msg view window
4379 do_headers_action (ModestWindow *win,
4383 TnyList *headers_list = NULL;
4384 TnyIterator *iter = NULL;
4385 TnyHeader *header = NULL;
4386 TnyFolder *folder = NULL;
4389 headers_list = get_selected_headers (win);
4393 /* Get the folder */
4394 iter = tny_list_create_iterator (headers_list);
4395 header = TNY_HEADER (tny_iterator_get_current (iter));
4397 folder = tny_header_get_folder (header);
4398 g_object_unref (header);
4401 /* Call the function for each header */
4402 while (!tny_iterator_is_done (iter)) {
4403 header = TNY_HEADER (tny_iterator_get_current (iter));
4404 func (header, win, user_data);
4405 g_object_unref (header);
4406 tny_iterator_next (iter);
4409 /* Trick: do a poke status in order to speed up the signaling
4411 tny_folder_poke_status (folder);
4414 g_object_unref (folder);
4415 g_object_unref (iter);
4416 g_object_unref (headers_list);
4420 modest_ui_actions_view_attachment (GtkAction *action,
4421 ModestWindow *window)
4423 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4424 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4426 /* not supported window for this action */
4427 g_return_if_reached ();
4432 modest_ui_actions_save_attachments (GtkAction *action,
4433 ModestWindow *window)
4435 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4436 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4438 /* not supported window for this action */
4439 g_return_if_reached ();
4444 modest_ui_actions_remove_attachments (GtkAction *action,
4445 ModestWindow *window)
4447 if (MODEST_IS_MAIN_WINDOW (window)) {
4448 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4449 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4450 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4452 /* not supported window for this action */
4453 g_return_if_reached ();
4458 modest_ui_actions_on_settings (GtkAction *action,
4463 dialog = modest_platform_get_global_settings_dialog ();
4464 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4465 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4466 gtk_widget_show_all (dialog);
4468 gtk_dialog_run (GTK_DIALOG (dialog));
4470 gtk_widget_destroy (dialog);
4474 modest_ui_actions_on_help (GtkAction *action,
4477 const gchar *help_id = NULL;
4479 if (MODEST_IS_MAIN_WINDOW (win)) {
4480 GtkWidget *folder_view;
4481 TnyFolderStore *folder_store;
4483 /* Get selected folder */
4484 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4485 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4486 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4488 /* Switch help_id */
4489 if (TNY_IS_FOLDER (folder_store)) {
4490 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4491 case TNY_FOLDER_TYPE_NORMAL:
4492 help_id = "applications_email_managefolders";
4494 case TNY_FOLDER_TYPE_INBOX:
4495 help_id = "applications_email_inbox";
4497 case TNY_FOLDER_TYPE_OUTBOX:
4498 help_id = "applications_email_outbox";
4500 case TNY_FOLDER_TYPE_SENT:
4501 help_id = "applications_email_sent";
4503 case TNY_FOLDER_TYPE_DRAFTS:
4504 help_id = "applications_email_drafts";
4506 case TNY_FOLDER_TYPE_ARCHIVE:
4507 help_id = "applications_email_managefolders";
4510 help_id = "applications_email_managefolders";
4513 help_id = "applications_email_mainview";
4515 g_object_unref (folder_store);
4516 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4517 help_id = "applications_email_viewer";
4518 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4519 help_id = "applications_email_editor";
4521 modest_platform_show_help (GTK_WINDOW (win), help_id);
4525 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4526 ModestWindow *window)
4528 ModestMailOperation *mail_op;
4532 headers = get_selected_headers (window);
4536 /* Create mail operation */
4537 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (window),
4538 modest_ui_actions_get_msgs_full_error_handler,
4540 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4541 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4544 g_object_unref (headers);
4545 g_object_unref (mail_op);
4549 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4550 ModestWindow *window)
4552 g_return_if_fail (MODEST_IS_WINDOW (window));
4555 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4559 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4560 ModestWindow *window)
4562 g_return_if_fail (MODEST_IS_WINDOW (window));
4565 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4569 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4570 ModestWindow *window)
4572 g_return_if_fail (MODEST_IS_WINDOW (window));
4575 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4579 modest_ui_actions_on_format_menu_activated (GtkAction *action,
4580 ModestWindow *window)
4582 g_return_if_fail (MODEST_IS_WINDOW (window));
4585 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4589 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4590 ModestWindow *window)
4592 g_return_if_fail (MODEST_IS_WINDOW (window));
4595 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4599 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4600 ModestWindow *window)
4602 g_return_if_fail (MODEST_IS_WINDOW (window));
4605 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4609 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4610 ModestWindow *window)
4612 g_return_if_fail (MODEST_IS_WINDOW (window));
4615 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4619 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4620 ModestWindow *window)
4622 g_return_if_fail (MODEST_IS_WINDOW (window));
4625 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4629 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4630 ModestWindow *window)
4632 g_return_if_fail (MODEST_IS_WINDOW (window));
4635 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4639 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4641 g_return_if_fail (MODEST_IS_WINDOW (window));
4644 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4648 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4650 g_return_if_fail (MODEST_IS_WINDOW (window));
4652 modest_platform_show_search_messages (GTK_WINDOW (window));
4656 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4658 g_return_if_fail (MODEST_IS_WINDOW (win));
4659 modest_platform_show_addressbook (GTK_WINDOW (win));
4664 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4665 ModestWindow *window)
4667 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4669 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4673 on_send_receive_finished (ModestMailOperation *mail_op,
4676 /* Set send/receive operation finished */
4677 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW (user_data));
4682 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
4688 const gchar* server_name = NULL;
4689 TnyTransportAccount *server_account;
4690 gchar *message = NULL;
4692 /* Don't show anything if the user cancelled something */
4693 if (err->code == TNY_TRANSPORT_ACCOUNT_ERROR_SEND_USER_CANCEL)
4696 /* Get the server name: */
4698 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
4699 if (server_account) {
4700 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
4702 g_object_unref (server_account);
4703 server_account = NULL;
4706 g_return_if_fail (server_name);
4708 /* Show the appropriate message text for the GError: */
4709 switch (err->code) {
4710 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_HOST_LOOKUP_FAILED:
4711 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4713 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_SERVICE_UNAVAILABLE:
4714 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4716 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_AUTHENTICATION_NOT_SUPPORTED:
4717 message = g_strdup_printf (_("emev_ni_ui_smtp_authentication_fail_error"), server_name);
4719 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND:
4720 message = g_strdup (_("emev_ib_ui_smtp_send_error"));
4723 g_return_if_reached ();
4726 /* TODO if the username or the password where not defined we
4727 should show the Accounts Settings dialog or the Connection
4728 specific SMTP server window */
4730 modest_platform_run_information_dialog (NULL, message);
4735 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
4740 ModestMainWindow *main_window = NULL;
4741 ModestWindowMgr *mgr = NULL;
4742 GtkWidget *folder_view = NULL, *header_view = NULL;
4743 TnyFolderStore *selected_folder = NULL;
4744 TnyFolderType folder_type;
4746 mgr = modest_runtime_get_window_mgr ();
4747 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr));
4752 /* Check if selected folder is OUTBOX */
4753 folder_view = modest_main_window_get_child_widget (main_window,
4754 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4755 header_view = modest_main_window_get_child_widget (main_window,
4756 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4758 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4759 if (!TNY_IS_FOLDER (selected_folder))
4762 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
4763 #if GTK_CHECK_VERSION(2, 8, 0)
4764 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
4765 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
4766 GtkTreeViewColumn *tree_column;
4768 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
4769 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
4770 gtk_tree_view_column_queue_resize (tree_column);
4773 gtk_widget_queue_draw (header_view);
4778 if (selected_folder != NULL)
4779 g_object_unref (selected_folder);