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);
148 static gboolean connect_to_get_msg (ModestWindow *win,
149 gint num_of_uncached_msgs,
150 TnyAccount *account);
152 static gboolean remote_folder_is_pop (const TnyFolderStore *folder);
154 static gboolean msgs_already_deleted_from_server ( TnyList *headers,
155 const TnyFolderStore *src_folder);
159 * This function checks whether a TnyFolderStore is a pop account
162 remote_folder_is_pop (const TnyFolderStore *folder)
164 const gchar *proto = NULL;
165 TnyAccount *account = NULL;
167 g_return_val_if_fail (TNY_IS_FOLDER_STORE(folder), FALSE);
169 if (TNY_IS_ACCOUNT (folder)) {
170 account = TNY_ACCOUNT(folder);
171 g_object_ref(account);
172 } else if (TNY_IS_FOLDER (folder)) {
173 account = tny_folder_get_account(TNY_FOLDER(folder));
176 proto = tny_account_get_proto(account);
177 g_object_unref (account);
180 (modest_protocol_info_get_transport_store_protocol (proto) == MODEST_PROTOCOL_STORE_POP);
184 * This functions checks whether if a list of messages are already
185 * deleted from the server: that is, if the server is a POP account
186 * and all messages are already cached.
189 msgs_already_deleted_from_server (TnyList *headers, const TnyFolderStore *src_folder)
191 g_return_val_if_fail (TNY_IS_FOLDER_STORE(src_folder), FALSE);
192 g_return_val_if_fail (TNY_IS_LIST(headers), FALSE);
194 gboolean src_is_pop = remote_folder_is_pop (src_folder);
195 gint uncached_msgs = header_list_count_uncached_msgs (headers);
197 return (src_is_pop && !uncached_msgs);
201 /* FIXME: this should be merged with the similar code in modest-account-view-window */
202 /* Show the account creation wizard dialog.
203 * returns: TRUE if an account was created. FALSE if the user cancelled.
206 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
208 gboolean result = FALSE;
209 GtkWindow *dialog, *wizard;
210 gint dialog_response;
212 /* Show the easy-setup wizard: */
213 dialog = modest_window_mgr_get_modal (modest_runtime_get_window_mgr());
214 if (dialog && MODEST_IS_EASYSETUP_WIZARD_DIALOG(dialog)) {
215 /* old wizard is active already;
217 gtk_window_present (GTK_WINDOW(dialog));
222 /* there is no such wizard yet */
223 wizard = GTK_WINDOW (modest_easysetup_wizard_dialog_new ());
224 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), wizard);
226 /* always present a main window in the background
227 * we do it here, so we cannot end up with to wizards (as this
228 * function might be called in modest_window_mgr_get_main_window as well */
230 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr());
232 /* make sure the mainwindow is visible */
233 gtk_widget_show_all (GTK_WIDGET(win));
234 gtk_window_present (GTK_WINDOW(win));
236 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
237 gtk_widget_destroy (GTK_WIDGET (wizard));
238 if (gtk_events_pending ())
239 gtk_main_iteration ();
241 if (dialog_response == GTK_RESPONSE_CANCEL) {
244 /* Check whether an account was created: */
245 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
253 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
256 const gchar *authors[] = {
257 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
260 about = gtk_about_dialog_new ();
261 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
262 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
263 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
264 _("Copyright (c) 2006, Nokia Corporation\n"
265 "All rights reserved."));
266 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
267 _("a modest e-mail client\n\n"
268 "design and implementation: Dirk-Jan C. Binnema\n"
269 "contributions from the fine people at KC and Ig\n"
270 "uses the tinymail email framework written by Philip van Hoof"));
271 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
272 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
273 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
274 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
276 gtk_dialog_run (GTK_DIALOG (about));
277 gtk_widget_destroy(about);
281 * Gets the list of currently selected messages. If the win is the
282 * main window, then it returns a newly allocated list of the headers
283 * selected in the header view. If win is the msg view window, then
284 * the value returned is a list with just a single header.
286 * The caller of this funcion must free the list.
289 get_selected_headers (ModestWindow *win)
291 if (MODEST_IS_MAIN_WINDOW(win)) {
292 GtkWidget *header_view;
294 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
295 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
296 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
298 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
299 /* for MsgViewWindows, we simply return a list with one element */
301 TnyList *list = NULL;
303 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
304 if (header != NULL) {
305 list = tny_simple_list_new ();
306 tny_list_prepend (list, G_OBJECT(header));
307 g_object_unref (G_OBJECT(header));
316 static GtkTreeRowReference *
317 get_next_after_selected_headers (ModestHeaderView *header_view)
319 GtkTreeSelection *sel;
320 GList *selected_rows, *node;
322 GtkTreeRowReference *result;
325 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
326 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
327 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
329 if (selected_rows == NULL)
332 node = g_list_last (selected_rows);
333 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
334 gtk_tree_path_next (path);
336 result = gtk_tree_row_reference_new (model, path);
338 gtk_tree_path_free (path);
339 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
340 g_list_free (selected_rows);
346 headers_action_mark_as_read (TnyHeader *header,
350 TnyHeaderFlags flags;
352 g_return_if_fail (TNY_IS_HEADER(header));
354 flags = tny_header_get_flags (header);
355 if (flags & TNY_HEADER_FLAG_SEEN) return;
356 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
360 headers_action_mark_as_unread (TnyHeader *header,
364 TnyHeaderFlags flags;
366 g_return_if_fail (TNY_IS_HEADER(header));
368 flags = tny_header_get_flags (header);
369 if (flags & TNY_HEADER_FLAG_SEEN) {
370 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
374 /** A convenience method, because deleting a message is
375 * otherwise complicated, and it's best to change it in one place
378 void modest_do_messages_delete (TnyList *headers, ModestWindow *win)
380 ModestMailOperation *mail_op = NULL;
381 mail_op = modest_mail_operation_new (win ? G_OBJECT(win) : NULL);
382 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
385 /* Always delete. TODO: Move to trash still not supported */
386 modest_mail_operation_remove_msgs (mail_op, headers, FALSE);
387 g_object_unref (G_OBJECT (mail_op));
390 /** After deleing a message that is currently visible in a window,
391 * show the next message from the list, or close the window if there are no more messages.
394 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
396 /* Close msg view window or select next */
397 if (modest_msg_view_window_last_message_selected (win) &&
398 modest_msg_view_window_first_message_selected (win)) {
399 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
400 } else if (!modest_msg_view_window_select_next_message (win)) {
402 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
407 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
409 TnyList *header_list = NULL;
410 TnyIterator *iter = NULL;
411 TnyHeader *header = NULL;
412 gchar *message = NULL;
415 ModestWindowMgr *mgr;
416 GtkWidget *header_view = NULL;
418 g_return_if_fail (MODEST_IS_WINDOW(win));
420 /* Check first if the header view has the focus */
421 if (MODEST_IS_MAIN_WINDOW (win)) {
423 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
424 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
425 if (!gtk_widget_is_focus (header_view))
429 /* Get the headers, either from the header view (if win is the main window),
430 * or from the message view window: */
431 header_list = get_selected_headers (win);
432 if (!header_list) return;
434 /* Check if any of the headers are already opened, or in the process of being opened */
435 if (MODEST_IS_MAIN_WINDOW (win)) {
436 gint opened_headers = 0;
438 iter = tny_list_create_iterator (header_list);
439 mgr = modest_runtime_get_window_mgr ();
440 while (!tny_iterator_is_done (iter)) {
441 header = TNY_HEADER (tny_iterator_get_current (iter));
443 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
445 g_object_unref (header);
447 tny_iterator_next (iter);
449 g_object_unref (iter);
451 if (opened_headers > 0) {
454 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
457 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
460 g_object_unref (header_list);
466 if (tny_list_get_length(header_list) == 1) {
467 iter = tny_list_create_iterator (header_list);
468 header = TNY_HEADER (tny_iterator_get_current (iter));
470 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
471 g_object_unref (header);
474 g_object_unref (iter);
476 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
477 tny_list_get_length(header_list)), desc);
479 /* Confirmation dialog */
480 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
484 if (response == GTK_RESPONSE_OK) {
485 ModestWindow *main_window = NULL;
486 ModestWindowMgr *mgr = NULL;
487 GtkTreeModel *model = NULL;
488 GtkTreeSelection *sel = NULL;
489 GList *sel_list = NULL, *tmp = NULL;
490 GtkTreeRowReference *next_row_reference = NULL;
491 GtkTreeRowReference *prev_row_reference = NULL;
492 GtkTreePath *next_path = NULL;
493 GtkTreePath *prev_path = NULL;
496 /* Find last selected row */
497 if (MODEST_IS_MAIN_WINDOW (win)) {
498 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
499 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
500 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
501 for (tmp=sel_list; tmp; tmp=tmp->next) {
502 if (tmp->next == NULL) {
503 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
504 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
506 gtk_tree_path_prev (prev_path);
507 gtk_tree_path_next (next_path);
509 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
510 next_row_reference = gtk_tree_row_reference_new (model, next_path);
515 /* Disable window dimming management */
516 modest_window_disable_dimming (MODEST_WINDOW(win));
518 /* Remove each header. If it's a view window header_view == NULL */
519 modest_do_messages_delete (header_list, win);
521 /* Enable window dimming management */
523 gtk_tree_selection_unselect_all (sel);
525 modest_window_enable_dimming (MODEST_WINDOW(win));
527 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
528 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
530 /* Get main window */
531 mgr = modest_runtime_get_window_mgr ();
532 main_window = modest_window_mgr_get_main_window (mgr);
535 /* Move cursor to next row */
538 /* Select next or previous row */
539 if (gtk_tree_row_reference_valid (next_row_reference)) {
540 /* next_path = gtk_tree_row_reference_get_path (row_reference); */
541 gtk_tree_selection_select_path (sel, next_path);
543 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
544 gtk_tree_selection_select_path (sel, prev_path);
548 if (next_row_reference != NULL)
549 gtk_tree_row_reference_free (next_row_reference);
550 if (next_path != NULL)
551 gtk_tree_path_free (next_path);
552 if (prev_row_reference != NULL)
553 gtk_tree_row_reference_free (prev_row_reference);
554 if (prev_path != NULL)
555 gtk_tree_path_free (prev_path);
559 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, err->code, err->message);
563 /* Update toolbar dimming state */
564 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
567 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
568 g_list_free (sel_list);
574 g_object_unref (header_list);
580 /* delete either message or folder, based on where we are */
582 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
584 g_return_if_fail (MODEST_IS_WINDOW(win));
586 /* Check first if the header view has the focus */
587 if (MODEST_IS_MAIN_WINDOW (win)) {
589 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
590 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
591 if (gtk_widget_is_focus (w)) {
592 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
596 modest_ui_actions_on_delete_message (action, win);
602 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
604 ModestWindowMgr *mgr = NULL;
606 #ifdef MODEST_PLATFORM_MAEMO
607 modest_osso_save_state();
608 #endif /* MODEST_PLATFORM_MAEMO */
610 g_debug ("closing down, clearing %d item(s) from operation queue",
611 modest_mail_operation_queue_num_elements
612 (modest_runtime_get_mail_operation_queue()));
614 /* cancel all outstanding operations */
615 modest_mail_operation_queue_cancel_all
616 (modest_runtime_get_mail_operation_queue());
618 g_debug ("queue has been cleared");
621 /* Check if there are opened editing windows */
622 mgr = modest_runtime_get_window_mgr ();
623 modest_window_mgr_close_all_windows (mgr);
625 /* note: when modest-tny-account-store is finalized,
626 it will automatically set all network connections
629 /* gtk_main_quit (); */
633 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
637 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
639 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
640 /* gtk_widget_destroy (GTK_WIDGET (win)); */
641 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
642 /* gboolean ret_value; */
643 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
644 /* } else if (MODEST_IS_WINDOW (win)) { */
645 /* gtk_widget_destroy (GTK_WIDGET (win)); */
647 /* g_return_if_reached (); */
652 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
654 GtkClipboard *clipboard = NULL;
655 gchar *selection = NULL;
657 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
658 selection = gtk_clipboard_wait_for_text (clipboard);
660 /* Question: why is the clipboard being used here?
661 * It doesn't really make a lot of sense. */
665 modest_address_book_add_address (selection);
671 modest_ui_actions_on_accounts (GtkAction *action,
674 /* This is currently only implemented for Maemo */
675 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
676 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
677 modest_ui_actions_run_account_setup_wizard (win);
680 /* Show the list of accounts */
681 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
682 gtk_window_set_transient_for (account_win, GTK_WINDOW (win));
684 /* The accounts dialog must be modal */
685 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), account_win);
686 modest_maemo_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
689 GtkWidget *dialog, *label;
691 /* Create the widgets */
693 dialog = gtk_dialog_new_with_buttons ("Message",
695 GTK_DIALOG_DESTROY_WITH_PARENT,
699 label = gtk_label_new ("Hello World!");
701 /* Ensure that the dialog box is destroyed when the user responds. */
703 g_signal_connect_swapped (dialog, "response",
704 G_CALLBACK (gtk_widget_destroy),
707 /* Add the label, and show everything we've added to the dialog. */
709 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
711 gtk_widget_show_all (dialog);
712 #endif /* MODEST_PLATFORM_MAEMO */
716 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
718 /* Save any changes. */
719 modest_connection_specific_smtp_window_save_server_accounts (
720 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window));
721 gtk_widget_destroy (GTK_WIDGET (window));
727 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
729 /* This is currently only implemented for Maemo,
730 * because it requires an API (libconic) to detect different connection
733 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
735 /* Create the window if necessary: */
736 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
737 modest_connection_specific_smtp_window_fill_with_connections (
738 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
739 modest_runtime_get_account_mgr());
741 /* Show the window: */
742 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
743 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
744 gtk_widget_show (specific_window);
746 /* Save changes when the window is hidden: */
747 g_signal_connect (specific_window, "hide",
748 G_CALLBACK (on_smtp_servers_window_hide), win);
749 #endif /* MODEST_PLATFORM_MAEMO */
753 modest_ui_actions_compose_msg(ModestWindow *win,
756 const gchar *bcc_str,
757 const gchar *subject_str,
758 const gchar *body_str,
761 gchar *account_name = NULL;
763 TnyAccount *account = NULL;
764 TnyFolder *folder = NULL;
765 gchar *from_str = NULL, *signature = NULL, *body = NULL;
766 gboolean use_signature = FALSE;
767 ModestWindow *msg_win = NULL;
768 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
769 ModestTnyAccountStore *store = modest_runtime_get_account_store();
771 if (win) account_name = g_strdup (modest_window_get_active_account (win));
772 if (!account_name) account_name = modest_account_mgr_get_default_account(mgr);
774 g_printerr ("modest: no account found\n");
777 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
779 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
782 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
784 g_printerr ("modest: failed to find Drafts folder\n");
787 from_str = modest_account_mgr_get_from_string (mgr, account_name);
789 g_printerr ("modest: failed get from string for '%s'\n", account_name);
793 signature = modest_account_mgr_get_signature (mgr, account_name, &use_signature);
794 if (body_str != NULL) {
795 body = use_signature ? g_strconcat(body_str, "\n", signature, NULL) : g_strdup(body_str);
797 body = use_signature ? g_strconcat("\n", signature, NULL) : g_strdup("");
800 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, body, NULL);
802 g_printerr ("modest: failed to create new msg\n");
806 /* Create and register edit window */
807 /* This is destroyed by TODO. */
808 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
809 while (attachments) {
810 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
812 attachments = g_slist_next(attachments);
814 modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win);
817 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
820 gtk_widget_show_all (GTK_WIDGET (msg_win));
826 g_free (account_name);
827 if (account) g_object_unref (G_OBJECT(account));
828 if (folder) g_object_unref (G_OBJECT(folder));
829 if (msg_win) g_object_unref (G_OBJECT(msg_win));
830 if (msg) g_object_unref (G_OBJECT(msg));
834 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
836 /* if there are no accounts yet, just show the wizard */
837 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
838 if (!modest_ui_actions_run_account_setup_wizard (win)) return;
841 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL);
845 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
849 ModestMailOperationStatus status;
851 /* If there is no message or the operation was not successful */
852 status = modest_mail_operation_get_status (mail_op);
853 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
855 /* Remove the header from the preregistered uids */
856 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
866 open_msg_cb (ModestMailOperation *mail_op, TnyHeader *header, TnyMsg *msg, gpointer user_data)
868 ModestWindowMgr *mgr = NULL;
869 ModestWindow *parent_win = NULL;
870 ModestWindow *win = NULL;
871 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
872 gchar *account = NULL;
874 gboolean open_in_editor = FALSE;
876 /* Do nothing if there was any problem with the mail
877 operation. The error will be shown by the error_handler of
878 the mail operation */
879 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
882 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
883 folder = tny_header_get_folder (header);
885 /* Mark header as read */
886 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
888 /* Gets folder type (OUTBOX headers will be opened in edit window */
889 if (modest_tny_folder_is_local_folder (folder)) {
890 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
893 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
894 TnyTransportAccount *traccount = NULL;
895 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
896 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
898 ModestTnySendQueue *send_queue = NULL;
899 ModestTnySendQueueStatus status;
901 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
902 TNY_ACCOUNT(traccount)));
903 send_queue = modest_runtime_get_send_queue(traccount);
904 msg_id = modest_tny_send_queue_get_msg_id (header);
905 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
906 /* Only open messages in outbox with the editor if they are in Failed state */
907 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
908 open_in_editor = TRUE;
911 g_object_unref(traccount);
913 g_warning("Cannot get transport account for message in outbox!!");
915 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
916 open_in_editor = TRUE; /* Open in editor if the message is in the Drafts folder */
921 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
923 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
925 if (open_in_editor) {
926 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
927 const gchar *from_header = NULL;
929 from_header = tny_header_get_from (header);
931 /* we cannot edit without a valid account... */
932 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
933 if (!modest_ui_actions_run_account_setup_wizard(parent_win))
938 GSList *accounts = modest_account_mgr_account_names (mgr, TRUE);
940 for (node = accounts; node != NULL; node = g_slist_next (node)) {
941 gchar *from = modest_account_mgr_get_from_string (mgr, node->data);
943 if (from && (strcmp (from_header, from) == 0)) {
945 account = g_strdup (node->data);
951 g_slist_foreach (accounts, (GFunc) g_free, NULL);
952 g_slist_free (accounts);
955 win = modest_msg_edit_window_new (msg, account, TRUE);
959 modest_platform_information_banner (NULL, NULL, _("mail_ib_opening_draft_message"));
962 gchar *uid = modest_tny_folder_get_header_unique_id (header);
964 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
965 GtkWidget *header_view;
966 GtkTreeSelection *sel;
967 GList *sel_list = NULL;
970 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
971 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
973 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
974 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
976 if (sel_list != NULL) {
977 GtkTreeRowReference *row_reference;
979 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
980 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
981 g_list_free (sel_list);
983 win = modest_msg_view_window_new_with_header_model (
984 msg, account, (const gchar*) uid,
985 model, row_reference);
986 gtk_tree_row_reference_free (row_reference);
988 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
991 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
996 /* Register and show new window */
998 mgr = modest_runtime_get_window_mgr ();
999 modest_window_mgr_register_window (mgr, win);
1000 g_object_unref (win);
1001 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
1002 gtk_widget_show_all (GTK_WIDGET(win));
1005 /* Update toolbar dimming state */
1006 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1007 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1013 g_object_unref (parent_win);
1014 g_object_unref (folder);
1019 open_msg_error_handler (ModestMailOperation *mail_op,
1022 /* Show the message error */
1023 GObject *win = modest_mail_operation_get_source (mail_op);
1025 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1026 (gchar *) user_data);
1028 g_object_unref (win);
1032 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
1035 const GError *error;
1036 GObject *win = modest_mail_operation_get_source (mail_op);
1038 error = modest_mail_operation_get_error (mail_op);
1040 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
1042 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1045 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1046 _("mail_ni_ui_folder_get_msg_folder_error"));
1050 g_object_unref (win);
1054 * Returns the account a list of headers belongs to. It returns a
1055 * *new* reference so don't forget to unref it
1058 get_account_from_header_list (TnyList *headers)
1060 TnyAccount *account = NULL;
1062 if (tny_list_get_length (headers) > 0) {
1063 TnyIterator *iter = tny_list_create_iterator (headers);
1064 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1065 TnyFolder *folder = tny_header_get_folder (header);
1066 account = tny_folder_get_account (folder);
1067 g_object_unref (folder);
1068 g_object_unref (header);
1069 g_object_unref (iter);
1075 * This function is used by both modest_ui_actions_on_open and
1076 * modest_ui_actions_on_header_activated. This way we always do the
1077 * same when trying to open messages.
1080 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
1082 ModestWindowMgr *mgr = NULL;
1083 TnyIterator *iter = NULL, *iter_not_opened = NULL;
1084 ModestMailOperation *mail_op = NULL;
1085 TnyList *not_opened_headers = NULL;
1086 TnyHeaderFlags flags = 0;
1087 TnyAccount *account;
1089 g_return_if_fail (headers != NULL);
1091 /* Check that only one message is selected for opening */
1092 if (tny_list_get_length (headers) != 1) {
1093 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1094 _("mcen_ib_select_one_message"));
1098 mgr = modest_runtime_get_window_mgr ();
1099 iter = tny_list_create_iterator (headers);
1101 /* Get the account */
1102 account = get_account_from_header_list (headers);
1104 /* Look if we already have a message view for each header. If
1105 true, then remove the header from the list of headers to
1107 not_opened_headers = tny_simple_list_new ();
1108 while (!tny_iterator_is_done (iter)) {
1110 ModestWindow *window = NULL;
1111 TnyHeader *header = NULL;
1112 gboolean found = FALSE;
1114 header = TNY_HEADER (tny_iterator_get_current (iter));
1116 flags = tny_header_get_flags (header);
1119 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1121 /* Do not open again the message and present the
1122 window to the user */
1125 gtk_window_present (GTK_WINDOW (window));
1127 /* the header has been registered already, we don't do
1128 * anything but wait for the window to come up*/
1129 g_debug ("header %p already registered, waiting for window", header);
1131 tny_list_append (not_opened_headers, G_OBJECT (header));
1135 g_object_unref (header);
1137 tny_iterator_next (iter);
1139 g_object_unref (iter);
1142 /* Open each message */
1143 if (tny_list_get_length (not_opened_headers) == 0)
1146 /* If some messages would have to be downloaded, ask the user to
1147 * make a connection. It's generally easier to do this here (in the mainloop)
1148 * than later in a thread:
1150 if (tny_list_get_length (not_opened_headers) > 0) {
1152 gboolean found = FALSE;
1154 iter = tny_list_create_iterator (not_opened_headers);
1155 while (!tny_iterator_is_done (iter) && !found) {
1156 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1157 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1160 tny_iterator_next (iter);
1162 g_object_unref (header);
1164 g_object_unref (iter);
1166 /* Ask the user if there are any uncached messages */
1167 if (found && !connect_to_get_msg (win,
1168 header_list_count_uncached_msgs (not_opened_headers),
1173 /* Register the headers before actually creating the windows: */
1174 iter_not_opened = tny_list_create_iterator (not_opened_headers);
1175 while (!tny_iterator_is_done (iter_not_opened)) {
1176 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1178 modest_window_mgr_register_header (mgr, header, NULL);
1179 g_object_unref (header);
1181 tny_iterator_next (iter_not_opened);
1183 g_object_unref (iter_not_opened);
1184 iter_not_opened = NULL;
1186 /* Create the mail operation */
1187 if (tny_list_get_length (not_opened_headers) > 1) {
1188 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
1189 modest_ui_actions_get_msgs_full_error_handler,
1191 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1193 modest_mail_operation_get_msgs_full (mail_op,
1199 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1200 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1201 const gchar *proto_name;
1203 ModestTransportStoreProtocol proto;
1205 /* Get the error message depending on the protocol */
1206 proto_name = tny_account_get_proto (account);
1207 if (proto_name != NULL) {
1208 proto = modest_protocol_info_get_transport_store_protocol (proto_name);
1210 proto = MODEST_PROTOCOL_STORE_MAILDIR;
1213 if (proto == MODEST_PROTOCOL_STORE_POP) {
1214 error_msg = g_strdup (_("emev_ni_ui_pop3_msg_recv_error"));
1215 } else if (proto == MODEST_PROTOCOL_STORE_IMAP) {
1216 error_msg = g_strdup_printf (_("emev_ni_ui_imap_message_not_available_in_server"),
1217 tny_header_get_subject (header));
1219 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1222 /* Create and call the mail operation */
1223 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
1224 open_msg_error_handler,
1227 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1229 modest_mail_operation_get_msg (mail_op, header, open_msg_cb, NULL);
1231 g_object_unref (header);
1232 g_object_unref (iter);
1234 g_object_unref (mail_op);
1239 g_object_unref (account);
1240 if (not_opened_headers)
1241 g_object_unref (not_opened_headers);
1245 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1250 headers = get_selected_headers (win);
1255 _modest_ui_actions_open (headers, win);
1257 g_object_unref(headers);
1262 free_reply_forward_helper (gpointer data)
1264 ReplyForwardHelper *helper;
1266 helper = (ReplyForwardHelper *) data;
1267 g_free (helper->account_name);
1268 g_slice_free (ReplyForwardHelper, helper);
1272 reply_forward_cb (ModestMailOperation *mail_op, TnyHeader *header, TnyMsg *msg,
1276 ReplyForwardHelper *rf_helper;
1277 ModestWindow *msg_win = NULL;
1278 ModestEditType edit_type;
1280 TnyAccount *account = NULL;
1281 ModestWindowMgr *mgr = NULL;
1282 gchar *signature = NULL;
1283 gboolean use_signature;
1285 /* If there was any error. The mail operation could be NULL,
1286 this means that we already have the message downloaded and
1287 that we didn't do a mail operation to retrieve it */
1288 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1291 g_return_if_fail (user_data != NULL);
1292 rf_helper = (ReplyForwardHelper *) user_data;
1294 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1295 rf_helper->account_name);
1296 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr(),
1297 rf_helper->account_name,
1300 /* Create reply mail */
1301 switch (rf_helper->action) {
1304 modest_tny_msg_create_reply_msg (msg, header, from, signature,
1305 rf_helper->reply_forward_type,
1306 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1308 case ACTION_REPLY_TO_ALL:
1310 modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1311 MODEST_TNY_MSG_REPLY_MODE_ALL);
1312 edit_type = MODEST_EDIT_TYPE_REPLY;
1314 case ACTION_FORWARD:
1316 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1317 edit_type = MODEST_EDIT_TYPE_FORWARD;
1320 g_return_if_reached ();
1327 g_printerr ("modest: failed to create message\n");
1331 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1332 rf_helper->account_name,
1333 TNY_ACCOUNT_TYPE_STORE);
1335 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1339 /* Create and register the windows */
1340 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1341 mgr = modest_runtime_get_window_mgr ();
1342 modest_window_mgr_register_window (mgr, msg_win);
1344 if (rf_helper->parent_window != NULL) {
1345 gdouble parent_zoom;
1347 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1348 modest_window_set_zoom (msg_win, parent_zoom);
1351 /* Show edit window */
1352 gtk_widget_show_all (GTK_WIDGET (msg_win));
1356 g_object_unref (msg_win);
1358 g_object_unref (G_OBJECT (new_msg));
1360 g_object_unref (G_OBJECT (account));
1361 /* g_object_unref (msg); */
1362 free_reply_forward_helper (rf_helper);
1365 /* Checks a list of headers. If any of them are not currently
1366 * downloaded (CACHED) then returns TRUE else returns FALSE.
1369 header_list_count_uncached_msgs (TnyList *header_list)
1372 gint uncached_messages = 0;
1374 iter = tny_list_create_iterator (header_list);
1375 while (!tny_iterator_is_done (iter)) {
1378 header = TNY_HEADER (tny_iterator_get_current (iter));
1380 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1381 uncached_messages ++;
1382 g_object_unref (header);
1385 tny_iterator_next (iter);
1387 g_object_unref (iter);
1389 return uncached_messages;
1392 /* Returns FALSE if the user does not want to download the
1393 * messages. Returns TRUE if the user allowed the download.
1396 connect_to_get_msg (ModestWindow *win,
1397 gint num_of_uncached_msgs,
1398 TnyAccount *account)
1400 GtkResponseType response;
1402 /* Allways download if we are online. */
1403 if (tny_device_is_online (modest_runtime_get_device ()))
1406 /* If offline, then ask for user permission to download the messages */
1407 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1408 ngettext("mcen_nc_get_msg",
1410 num_of_uncached_msgs));
1412 if (response == GTK_RESPONSE_CANCEL)
1415 return modest_platform_connect_and_wait(GTK_WINDOW (win), account);
1419 * Common code for the reply and forward actions
1422 reply_forward (ReplyForwardAction action, ModestWindow *win)
1424 ModestMailOperation *mail_op = NULL;
1425 TnyList *header_list = NULL;
1426 ReplyForwardHelper *rf_helper = NULL;
1427 guint reply_forward_type;
1428 gboolean continue_download = TRUE;
1429 gboolean do_retrieve = TRUE;
1431 g_return_if_fail (MODEST_IS_WINDOW(win));
1433 /* we need an account when editing */
1434 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1435 if (!modest_ui_actions_run_account_setup_wizard (win))
1439 header_list = get_selected_headers (win);
1443 reply_forward_type =
1444 modest_conf_get_int (modest_runtime_get_conf (),
1445 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1448 /* check if we need to download msg before asking about it */
1449 do_retrieve = (action == ACTION_FORWARD) ||
1450 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1453 gint num_of_unc_msgs;
1455 /* check that the messages have been previously downloaded */
1456 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
1457 /* If there are any uncached message ask the user
1458 * whether he/she wants to download them. */
1459 if (num_of_unc_msgs) {
1460 TnyAccount *account = get_account_from_header_list (header_list);
1461 continue_download = connect_to_get_msg (win, num_of_unc_msgs, account);
1462 g_object_unref (account);
1466 if (!continue_download) {
1467 g_object_unref (header_list);
1471 /* We assume that we can only select messages of the
1472 same folder and that we reply all of them from the
1473 same account. In fact the interface currently only
1474 allows single selection */
1477 rf_helper = g_slice_new0 (ReplyForwardHelper);
1478 rf_helper->reply_forward_type = reply_forward_type;
1479 rf_helper->action = action;
1480 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1482 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1483 rf_helper->parent_window = GTK_WIDGET (win);
1484 if (!rf_helper->account_name)
1485 rf_helper->account_name =
1486 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1488 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1491 /* Get header and message. Do not free them here, the
1492 reply_forward_cb must do it */
1493 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1494 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1495 if (!msg || !header) {
1497 g_object_unref (msg);
1498 g_printerr ("modest: no message found\n");
1501 reply_forward_cb (NULL, header, msg, rf_helper);
1504 g_object_unref (header);
1509 /* Only reply/forward to one message */
1510 iter = tny_list_create_iterator (header_list);
1511 header = TNY_HEADER (tny_iterator_get_current (iter));
1512 g_object_unref (iter);
1515 /* Retrieve messages */
1518 modest_mail_operation_new_with_error_handling (G_OBJECT(win),
1519 modest_ui_actions_get_msgs_full_error_handler,
1521 modest_mail_operation_queue_add (
1522 modest_runtime_get_mail_operation_queue (), mail_op);
1524 modest_mail_operation_get_msg (mail_op,
1529 g_object_unref(mail_op);
1531 /* we put a ref here to prevent double unref as the reply
1532 * forward callback unrefs the header at its end */
1533 reply_forward_cb (NULL, header, NULL, rf_helper);
1537 g_object_unref (header);
1543 g_object_unref (header_list);
1547 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1549 g_return_if_fail (MODEST_IS_WINDOW(win));
1551 reply_forward (ACTION_REPLY, win);
1555 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1557 g_return_if_fail (MODEST_IS_WINDOW(win));
1559 reply_forward (ACTION_FORWARD, win);
1563 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1565 g_return_if_fail (MODEST_IS_WINDOW(win));
1567 reply_forward (ACTION_REPLY_TO_ALL, win);
1571 modest_ui_actions_on_next (GtkAction *action,
1572 ModestWindow *window)
1574 if (MODEST_IS_MAIN_WINDOW (window)) {
1575 GtkWidget *header_view;
1577 header_view = modest_main_window_get_child_widget (
1578 MODEST_MAIN_WINDOW(window),
1579 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1583 modest_header_view_select_next (
1584 MODEST_HEADER_VIEW(header_view));
1585 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1586 modest_msg_view_window_select_next_message (
1587 MODEST_MSG_VIEW_WINDOW (window));
1589 g_return_if_reached ();
1594 modest_ui_actions_on_prev (GtkAction *action,
1595 ModestWindow *window)
1597 g_return_if_fail (MODEST_IS_WINDOW(window));
1599 if (MODEST_IS_MAIN_WINDOW (window)) {
1600 GtkWidget *header_view;
1601 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1602 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1606 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1607 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1608 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1610 g_return_if_reached ();
1615 modest_ui_actions_on_sort (GtkAction *action,
1616 ModestWindow *window)
1618 g_return_if_fail (MODEST_IS_WINDOW(window));
1620 if (MODEST_IS_MAIN_WINDOW (window)) {
1621 GtkWidget *header_view;
1622 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1623 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1625 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1630 /* Show sorting dialog */
1631 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1636 new_messages_arrived (ModestMailOperation *self,
1637 TnyList *new_headers,
1640 /* Notify new messages have been downloaded */
1641 if ((new_headers != NULL) && (tny_list_get_length (new_headers) > 0))
1642 modest_platform_on_new_headers_received (new_headers);
1646 * This function performs the send & receive required actions. The
1647 * window is used to create the mail operation. Typically it should
1648 * always be the main window, but we pass it as argument in order to
1652 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1654 gchar *acc_name = NULL;
1655 ModestMailOperation *mail_op;
1656 TnyAccount *store_account = NULL;
1658 /* If no account name was provided then get the current account, and if
1659 there is no current account then pick the default one: */
1660 if (!account_name) {
1661 acc_name = g_strdup (modest_window_get_active_account(win));
1663 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1665 g_printerr ("modest: cannot get default account\n");
1669 acc_name = g_strdup (account_name);
1673 /* Ensure that we have a connection available */
1675 modest_tny_account_store_get_server_account (modest_runtime_get_account_store (),
1677 TNY_ACCOUNT_TYPE_STORE);
1678 if (!modest_platform_connect_and_wait (NULL, TNY_ACCOUNT (store_account))) {
1679 g_object_unref (store_account);
1682 g_object_unref (store_account);
1684 /* Set send/receive operation in progress */
1685 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1687 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
1688 modest_ui_actions_send_receive_error_handler,
1691 g_signal_connect (G_OBJECT(mail_op), "operation-finished",
1692 G_CALLBACK (on_send_receive_finished),
1695 /* Send & receive. */
1696 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1697 /* Receive and then send. The operation is tagged initially as
1698 a receive operation because the account update performs a
1699 receive and then a send. The operation changes its type
1700 internally, so the progress objects will receive the proper
1701 progress information */
1702 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1703 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, win);
1704 g_object_unref (G_OBJECT (mail_op));
1712 modest_ui_actions_do_cancel_send (const gchar *account_name,
1715 TnyTransportAccount *transport_account;
1716 TnySendQueue *send_queue = NULL;
1717 GError *error = NULL;
1719 /* Get transport account */
1721 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1722 (modest_runtime_get_account_store(),
1724 TNY_ACCOUNT_TYPE_TRANSPORT));
1725 if (!transport_account) {
1726 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1731 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1732 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1733 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1734 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1735 "modest: could not find send queue for account\n");
1737 /* Keeep messages in outbox folder */
1738 tny_send_queue_cancel (send_queue, FALSE, &error);
1742 if (transport_account != NULL)
1743 g_object_unref (G_OBJECT (transport_account));
1747 modest_ui_actions_cancel_send_all (ModestWindow *win)
1749 GSList *account_names, *iter;
1751 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1754 iter = account_names;
1756 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1757 iter = g_slist_next (iter);
1760 modest_account_mgr_free_account_names (account_names);
1761 account_names = NULL;
1765 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1768 /* Check if accounts exist */
1769 gboolean accounts_exist =
1770 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1772 /* If not, allow the user to create an account before trying to send/receive. */
1773 if (!accounts_exist)
1774 modest_ui_actions_on_accounts (NULL, win);
1776 /* Cancel all sending operaitons */
1777 modest_ui_actions_cancel_send_all (win);
1781 * Refreshes all accounts. This function will be used by automatic
1785 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1787 GSList *account_names, *iter;
1789 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1792 iter = account_names;
1794 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1795 iter = g_slist_next (iter);
1798 modest_account_mgr_free_account_names (account_names);
1799 account_names = NULL;
1803 refresh_current_folder(ModestWindow *win)
1805 /* Refresh currently selected folder. Note that if we only
1806 want to retreive the headers, then the refresh only will
1807 invoke a poke_status over all folders, i.e., only the
1808 total/unread count will be updated */
1809 if (MODEST_IS_MAIN_WINDOW (win)) {
1810 GtkWidget *header_view, *folder_view;
1811 TnyFolderStore *folder_store;
1813 /* Get folder and header view */
1815 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1816 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1820 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1822 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1824 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1825 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1827 /* We do not need to set the contents style
1828 because it hasn't changed. We also do not
1829 need to save the widget status. Just force
1831 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1832 TNY_FOLDER (folder_store),
1833 folder_refreshed_cb,
1834 MODEST_MAIN_WINDOW (win));
1838 g_object_unref (folder_store);
1844 * Handler of the click on Send&Receive button in the main toolbar
1847 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1849 /* Check if accounts exist */
1850 gboolean accounts_exist =
1851 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1853 /* If not, allow the user to create an account before trying to send/receive. */
1854 if (!accounts_exist)
1855 modest_ui_actions_on_accounts (NULL, win);
1857 /* Refresh the current folder if we're viewing a window */
1859 refresh_current_folder (win);
1861 /* Refresh the active account */
1862 modest_ui_actions_do_send_receive (NULL, win);
1867 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1870 GtkWidget *header_view;
1872 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1874 header_view = modest_main_window_get_child_widget (main_window,
1875 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1879 conf = modest_runtime_get_conf ();
1881 /* what is saved/restored is depending on the style; thus; we save with
1882 * old style, then update the style, and restore for this new style
1884 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1886 if (modest_header_view_get_style
1887 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1888 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1889 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1891 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1892 MODEST_HEADER_VIEW_STYLE_DETAILS);
1894 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1895 MODEST_CONF_HEADER_VIEW_KEY);
1900 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1902 ModestMainWindow *main_window)
1904 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1905 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1907 /* in the case the folder is empty, show the empty folder message and focus
1909 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1910 if (modest_header_view_is_empty (header_view)) {
1911 TnyFolder *folder = modest_header_view_get_folder (header_view);
1912 GtkWidget *folder_view =
1913 modest_main_window_get_child_widget (main_window,
1914 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1916 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1917 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1921 /* If no header has been selected then exit */
1926 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1927 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1929 /* Update toolbar dimming state */
1930 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1934 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1936 ModestMainWindow *main_window)
1940 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1945 if (modest_header_view_count_selected_headers (header_view) > 1) {
1946 hildon_banner_show_information (NULL, NULL, _("mcen_ib_select_one_message"));
1951 /* headers = tny_simple_list_new (); */
1952 /* tny_list_prepend (headers, G_OBJECT (header)); */
1953 headers = modest_header_view_get_selected_headers (header_view);
1955 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1957 g_object_unref (headers);
1961 set_active_account_from_tny_account (TnyAccount *account,
1962 ModestWindow *window)
1964 const gchar *server_acc_name = tny_account_get_id (account);
1966 /* We need the TnyAccount provided by the
1967 account store because that is the one that
1968 knows the name of the Modest account */
1969 TnyAccount *modest_server_account = modest_server_account =
1970 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1971 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1973 if (!modest_server_account) {
1974 g_warning ("%s: could not get tny account\n", __FUNCTION__);
1978 /* Update active account, but only if it's not a pseudo-account */
1979 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
1980 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
1981 const gchar *modest_acc_name =
1982 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1983 if (modest_acc_name)
1984 modest_window_set_active_account (window, modest_acc_name);
1987 g_object_unref (modest_server_account);
1992 folder_refreshed_cb (ModestMailOperation *mail_op,
1996 ModestMainWindow *win = NULL;
1997 GtkWidget *header_view;
1998 gboolean folder_empty = FALSE;
1999 gboolean all_marked_as_deleted = FALSE;
2001 g_return_if_fail (TNY_IS_FOLDER (folder));
2003 win = MODEST_MAIN_WINDOW (user_data);
2005 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2008 TnyFolder *current_folder;
2010 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
2011 if (current_folder != NULL && folder != current_folder) {
2012 g_object_unref (current_folder);
2015 g_object_unref (current_folder);
2018 /* Check if folder is empty and set headers view contents style */
2019 folder_empty = (tny_folder_get_all_count (folder) == 0);
2020 all_marked_as_deleted = modest_header_view_is_empty (MODEST_HEADER_VIEW(header_view));
2021 if (folder_empty || all_marked_as_deleted)
2022 modest_main_window_set_contents_style (win,
2023 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2027 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2028 TnyFolderStore *folder_store,
2030 ModestMainWindow *main_window)
2033 GtkWidget *header_view;
2035 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2037 header_view = modest_main_window_get_child_widget(main_window,
2038 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2042 conf = modest_runtime_get_conf ();
2044 if (TNY_IS_ACCOUNT (folder_store)) {
2046 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2048 /* Show account details */
2049 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2052 if (TNY_IS_FOLDER (folder_store) && selected) {
2054 /* Update the active account */
2055 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2057 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2058 g_object_unref (account);
2062 /* Set the header style by default, it could
2063 be changed later by the refresh callback to
2065 modest_main_window_set_contents_style (main_window,
2066 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2068 /* Set folder on header view. This function
2069 will call tny_folder_refresh_async so we
2070 pass a callback that will be called when
2071 finished. We use that callback to set the
2072 empty view if there are no messages */
2073 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2074 TNY_FOLDER (folder_store),
2075 folder_refreshed_cb,
2078 /* Restore configuration. We need to do this
2079 *after* the set_folder because the widget
2080 memory asks the header view about its
2082 modest_widget_memory_restore (modest_runtime_get_conf (),
2083 G_OBJECT(header_view),
2084 MODEST_CONF_HEADER_VIEW_KEY);
2086 /* Update the active account */
2087 //modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
2088 /* Save only if we're seeing headers */
2089 if (modest_main_window_get_contents_style (main_window) ==
2090 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2091 modest_widget_memory_save (conf, G_OBJECT (header_view),
2092 MODEST_CONF_HEADER_VIEW_KEY);
2093 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2097 /* Update toolbar dimming state */
2098 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2102 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2109 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2111 online = tny_device_is_online (modest_runtime_get_device());
2114 /* already online -- the item is simply not there... */
2115 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2117 GTK_MESSAGE_WARNING,
2119 _("The %s you selected cannot be found"),
2121 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2122 gtk_dialog_run (GTK_DIALOG(dialog));
2124 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2127 _("mcen_bd_dialog_cancel"),
2128 GTK_RESPONSE_REJECT,
2129 _("mcen_bd_dialog_ok"),
2130 GTK_RESPONSE_ACCEPT,
2132 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2133 "Do you want to get online?"), item);
2134 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2135 gtk_label_new (txt), FALSE, FALSE, 0);
2136 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2139 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2140 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2141 /* TODO: Comment about why is this commented out: */
2142 /* modest_platform_connect_and_wait (); */
2145 gtk_widget_destroy (dialog);
2149 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2152 /* g_message ("%s %s", __FUNCTION__, link); */
2157 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2160 modest_platform_activate_uri (link);
2164 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2167 modest_platform_show_uri_popup (link);
2171 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2174 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2178 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2179 const gchar *address,
2182 /* g_message ("%s %s", __FUNCTION__, address); */
2186 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2187 TnyMsg *saved_draft,
2190 ModestMsgEditWindow *edit_window;
2192 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2194 /* If there was any error do nothing */
2195 if (modest_mail_operation_get_error (mail_op) != NULL)
2198 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2202 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2204 TnyTransportAccount *transport_account;
2205 ModestMailOperation *mail_operation;
2207 gchar *account_name, *from;
2208 ModestAccountMgr *account_mgr;
2209 gchar *info_text = NULL;
2211 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2213 data = modest_msg_edit_window_get_msg_data (edit_window);
2215 account_name = g_strdup (data->account_name);
2216 account_mgr = modest_runtime_get_account_mgr();
2218 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2220 account_name = modest_account_mgr_get_default_account (account_mgr);
2221 if (!account_name) {
2222 g_printerr ("modest: no account found\n");
2223 modest_msg_edit_window_free_msg_data (edit_window, data);
2227 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2228 account_name = g_strdup (data->account_name);
2232 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2233 (modest_runtime_get_account_store(),
2235 TNY_ACCOUNT_TYPE_TRANSPORT));
2236 if (!transport_account) {
2237 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2238 g_free (account_name);
2239 modest_msg_edit_window_free_msg_data (edit_window, data);
2242 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2244 /* Create the mail operation */
2245 mail_operation = modest_mail_operation_new (G_OBJECT(edit_window));
2246 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2248 modest_mail_operation_save_to_drafts (mail_operation,
2260 data->priority_flags,
2261 on_save_to_drafts_cb,
2265 g_free (account_name);
2266 g_object_unref (G_OBJECT (transport_account));
2267 g_object_unref (G_OBJECT (mail_operation));
2269 modest_msg_edit_window_free_msg_data (edit_window, data);
2271 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2272 modest_platform_information_banner (NULL, NULL, info_text);
2273 modest_msg_edit_window_reset_modified (edit_window);
2277 /* For instance, when clicking the Send toolbar button when editing a message: */
2279 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2281 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2283 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2286 /* FIXME: Code added just for testing. The final version will
2287 use the send queue provided by tinymail and some
2289 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2291 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2292 gchar *account_name = g_strdup (data->account_name);
2294 g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2297 account_name = modest_account_mgr_get_default_account (account_mgr);
2299 if (!account_name) {
2300 modest_msg_edit_window_free_msg_data (edit_window, data);
2301 /* Run account setup wizard */
2302 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window)))
2306 /* Get the currently-active transport account for this modest account: */
2307 TnyTransportAccount *transport_account =
2308 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2309 (modest_runtime_get_account_store(),
2311 if (!transport_account) {
2312 /* Run account setup wizard */
2313 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2317 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2319 /* Create the mail operation */
2320 ModestMailOperation *mail_operation = modest_mail_operation_new (G_OBJECT(edit_window));
2321 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2323 modest_mail_operation_send_new_mail (mail_operation,
2335 data->priority_flags);
2339 g_free (account_name);
2340 g_object_unref (G_OBJECT (transport_account));
2341 g_object_unref (G_OBJECT (mail_operation));
2343 modest_msg_edit_window_free_msg_data (edit_window, data);
2344 modest_msg_edit_window_set_sent (edit_window, TRUE);
2346 /* Save settings and close the window: */
2347 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2351 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2352 ModestMsgEditWindow *window)
2354 ModestMsgEditFormatState *format_state = NULL;
2356 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2357 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2359 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2362 format_state = modest_msg_edit_window_get_format_state (window);
2363 g_return_if_fail (format_state != NULL);
2365 format_state->bold = gtk_toggle_action_get_active (action);
2366 modest_msg_edit_window_set_format_state (window, format_state);
2367 g_free (format_state);
2372 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2373 ModestMsgEditWindow *window)
2375 ModestMsgEditFormatState *format_state = NULL;
2377 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2378 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2380 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2383 format_state = modest_msg_edit_window_get_format_state (window);
2384 g_return_if_fail (format_state != NULL);
2386 format_state->italics = gtk_toggle_action_get_active (action);
2387 modest_msg_edit_window_set_format_state (window, format_state);
2388 g_free (format_state);
2393 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2394 ModestMsgEditWindow *window)
2396 ModestMsgEditFormatState *format_state = NULL;
2398 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2399 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2401 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2404 format_state = modest_msg_edit_window_get_format_state (window);
2405 g_return_if_fail (format_state != NULL);
2407 format_state->bullet = gtk_toggle_action_get_active (action);
2408 modest_msg_edit_window_set_format_state (window, format_state);
2409 g_free (format_state);
2414 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2415 GtkRadioAction *selected,
2416 ModestMsgEditWindow *window)
2418 ModestMsgEditFormatState *format_state = NULL;
2419 GtkJustification value;
2421 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2423 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2426 value = gtk_radio_action_get_current_value (selected);
2428 format_state = modest_msg_edit_window_get_format_state (window);
2429 g_return_if_fail (format_state != NULL);
2431 format_state->justification = value;
2432 modest_msg_edit_window_set_format_state (window, format_state);
2433 g_free (format_state);
2437 modest_ui_actions_on_select_editor_color (GtkAction *action,
2438 ModestMsgEditWindow *window)
2440 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2441 g_return_if_fail (GTK_IS_ACTION (action));
2443 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2446 modest_msg_edit_window_select_color (window);
2450 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2451 ModestMsgEditWindow *window)
2453 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2454 g_return_if_fail (GTK_IS_ACTION (action));
2456 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2459 modest_msg_edit_window_select_background_color (window);
2463 modest_ui_actions_on_insert_image (GtkAction *action,
2464 ModestMsgEditWindow *window)
2466 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2467 g_return_if_fail (GTK_IS_ACTION (action));
2469 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2472 modest_msg_edit_window_insert_image (window);
2476 modest_ui_actions_on_attach_file (GtkAction *action,
2477 ModestMsgEditWindow *window)
2479 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2480 g_return_if_fail (GTK_IS_ACTION (action));
2482 modest_msg_edit_window_offer_attach_file (window);
2486 modest_ui_actions_on_remove_attachments (GtkAction *action,
2487 ModestMsgEditWindow *window)
2489 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2490 g_return_if_fail (GTK_IS_ACTION (action));
2492 modest_msg_edit_window_remove_attachments (window, NULL);
2496 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2499 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2500 const GError *error = modest_mail_operation_get_error (mail_op);
2503 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2504 _("mail_in_ui_folder_create_error"));
2509 modest_ui_actions_create_folder(GtkWidget *parent_window,
2510 GtkWidget *folder_view)
2512 TnyFolderStore *parent_folder;
2514 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2516 if (parent_folder) {
2517 gboolean finished = FALSE;
2519 gchar *folder_name = NULL, *suggested_name = NULL;
2520 const gchar *proto_str = NULL;
2521 TnyAccount *account;
2523 if (TNY_IS_ACCOUNT (parent_folder))
2524 account = g_object_ref (parent_folder);
2526 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2527 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2529 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2530 MODEST_PROTOCOL_STORE_POP) {
2532 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2534 g_object_unref (account);
2536 /* Run the new folder dialog */
2538 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2543 g_free (suggested_name);
2544 suggested_name = NULL;
2546 if (result == GTK_RESPONSE_ACCEPT) {
2547 ModestMailOperation *mail_op;
2548 TnyFolder *new_folder = NULL;
2550 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
2551 modest_ui_actions_new_folder_error_handler,
2552 parent_window, NULL);
2554 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2556 new_folder = modest_mail_operation_create_folder (mail_op,
2558 (const gchar *) folder_name);
2560 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2563 g_object_unref (new_folder);
2566 g_object_unref (mail_op);
2571 suggested_name = folder_name;
2575 g_object_unref (parent_folder);
2580 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2582 GtkWidget *folder_view;
2584 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2586 folder_view = modest_main_window_get_child_widget (main_window,
2587 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2591 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2595 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2598 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2599 const GError *error = NULL;
2600 const gchar *message = NULL;
2602 /* Get error message */
2603 error = modest_mail_operation_get_error (mail_op);
2605 g_return_if_reached ();
2607 switch (error->code) {
2608 case MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS:
2609 message = _CS("ckdg_ib_folder_already_exists");
2612 g_return_if_reached ();
2615 modest_platform_information_banner (GTK_WIDGET (window), NULL, message);
2619 modest_ui_actions_on_rename_folder (GtkAction *action,
2620 ModestMainWindow *main_window)
2622 TnyFolderStore *folder;
2623 GtkWidget *folder_view;
2624 GtkWidget *header_view;
2626 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2628 folder_view = modest_main_window_get_child_widget (main_window,
2629 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2633 header_view = modest_main_window_get_child_widget (main_window,
2634 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2639 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2644 if (TNY_IS_FOLDER (folder)) {
2647 const gchar *current_name;
2648 TnyFolderStore *parent;
2649 gboolean do_rename = TRUE;
2651 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2652 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
2653 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
2654 parent, current_name,
2656 g_object_unref (parent);
2658 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
2660 } else if (modest_platform_is_network_folderstore(folder) &&
2661 !tny_device_is_online (modest_runtime_get_device())) {
2662 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2663 do_rename = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2664 g_object_unref(account);
2668 ModestMailOperation *mail_op;
2669 GtkTreeSelection *sel = NULL;
2672 modest_mail_operation_new_with_error_handling (G_OBJECT(main_window),
2673 modest_ui_actions_rename_folder_error_handler,
2676 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2679 /* Clear the headers view */
2680 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2681 gtk_tree_selection_unselect_all (sel);
2683 /* Select *after* the changes */
2684 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2685 TNY_FOLDER(folder), TRUE);
2687 /* Actually rename the folder */
2688 modest_mail_operation_rename_folder (mail_op,
2689 TNY_FOLDER (folder),
2690 (const gchar *) folder_name);
2692 g_object_unref (mail_op);
2693 g_free (folder_name);
2696 g_object_unref (folder);
2700 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2703 GObject *win = modest_mail_operation_get_source (mail_op);
2705 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2706 _("mail_in_ui_folder_delete_error"));
2707 g_object_unref (win);
2711 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2713 TnyFolderStore *folder;
2714 GtkWidget *folder_view;
2717 gboolean do_delete = TRUE;
2719 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (main_window), FALSE);
2721 folder_view = modest_main_window_get_child_widget (main_window,
2722 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2726 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2728 /* Show an error if it's an account */
2729 if (!TNY_IS_FOLDER (folder)) {
2730 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2731 _("mail_in_ui_folder_delete_error"));
2732 g_object_unref (G_OBJECT (folder));
2737 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2738 tny_folder_get_name (TNY_FOLDER (folder)));
2739 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2740 (const gchar *) message);
2743 if (response != GTK_RESPONSE_OK) {
2745 } else if (modest_platform_is_network_folderstore(folder) &&
2746 !tny_device_is_online (modest_runtime_get_device())) {
2747 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2748 do_delete = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2749 g_object_unref(account);
2753 ModestMailOperation *mail_op;
2754 GtkTreeSelection *sel;
2756 /* Unselect the folder before deleting it to free the headers */
2757 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2758 gtk_tree_selection_unselect_all (sel);
2760 /* Create the mail operation */
2762 modest_mail_operation_new_with_error_handling (G_OBJECT(main_window),
2763 modest_ui_actions_delete_folder_error_handler,
2766 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2768 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2769 g_object_unref (G_OBJECT (mail_op));
2772 g_object_unref (G_OBJECT (folder));
2778 modest_ui_actions_on_delete_folder (GtkAction *action,
2779 ModestMainWindow *main_window)
2781 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2783 if (delete_folder (main_window, FALSE)) {
2784 GtkWidget *folder_view;
2786 folder_view = modest_main_window_get_child_widget (main_window,
2787 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2788 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2793 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2795 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2797 delete_folder (main_window, TRUE);
2802 show_error (GtkWidget *parent_widget, const gchar* text)
2804 hildon_banner_show_information(parent_widget, NULL, text);
2807 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2809 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2816 gtk_dialog_run (dialog);
2817 gtk_widget_destroy (GTK_WIDGET (dialog));
2822 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2823 const gchar* server_account_name,
2828 ModestMainWindow *main_window)
2830 g_return_if_fail(server_account_name);
2831 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2833 /* Initalize output parameters: */
2840 #ifdef MODEST_PLATFORM_MAEMO
2841 /* Maemo uses a different (awkward) button order,
2842 * It should probably just use gtk_alternative_dialog_button_order ().
2844 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2847 _("mcen_bd_dialog_ok"),
2848 GTK_RESPONSE_ACCEPT,
2849 _("mcen_bd_dialog_cancel"),
2850 GTK_RESPONSE_REJECT,
2853 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2857 GTK_RESPONSE_REJECT,
2859 GTK_RESPONSE_ACCEPT,
2861 #endif /* MODEST_PLATFORM_MAEMO */
2863 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2865 gchar *server_name = modest_account_mgr_get_server_account_hostname (
2866 modest_runtime_get_account_mgr(), server_account_name);
2867 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2868 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2873 /* This causes a warning because the logical ID has no %s in it,
2874 * though the translation does, but there is not much we can do about that: */
2875 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2876 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2879 g_free (server_name);
2883 gchar *initial_username = modest_account_mgr_get_server_account_username (
2884 modest_runtime_get_account_mgr(), server_account_name);
2886 GtkWidget *entry_username = gtk_entry_new ();
2887 if (initial_username)
2888 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2889 /* Dim this if a connection has ever succeeded with this username,
2890 * as per the UI spec: */
2891 const gboolean username_known =
2892 modest_account_mgr_get_server_account_username_has_succeeded(
2893 modest_runtime_get_account_mgr(), server_account_name);
2894 gtk_widget_set_sensitive (entry_username, !username_known);
2896 #ifdef MODEST_PLATFORM_MAEMO
2897 /* Auto-capitalization is the default, so let's turn it off: */
2898 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2900 /* Create a size group to be used by all captions.
2901 * Note that HildonCaption does not create a default size group if we do not specify one.
2902 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2903 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2905 GtkWidget *caption = hildon_caption_new (sizegroup,
2906 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2907 gtk_widget_show (entry_username);
2908 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2909 FALSE, FALSE, MODEST_MARGIN_HALF);
2910 gtk_widget_show (caption);
2912 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2914 #endif /* MODEST_PLATFORM_MAEMO */
2917 GtkWidget *entry_password = gtk_entry_new ();
2918 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2919 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2921 #ifdef MODEST_PLATFORM_MAEMO
2922 /* Auto-capitalization is the default, so let's turn it off: */
2923 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2924 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2926 caption = hildon_caption_new (sizegroup,
2927 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2928 gtk_widget_show (entry_password);
2929 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2930 FALSE, FALSE, MODEST_MARGIN_HALF);
2931 gtk_widget_show (caption);
2932 g_object_unref (sizegroup);
2934 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2936 #endif /* MODEST_PLATFORM_MAEMO */
2938 if (initial_username != NULL)
2939 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
2941 /* This is not in the Maemo UI spec:
2942 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2943 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2947 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2949 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2951 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2953 modest_account_mgr_set_server_account_username (
2954 modest_runtime_get_account_mgr(), server_account_name,
2957 const gboolean username_was_changed =
2958 (strcmp (*username, initial_username) != 0);
2959 if (username_was_changed) {
2960 g_warning ("%s: tinymail does not yet support changing the "
2961 "username in the get_password() callback.\n", __FUNCTION__);
2966 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2968 /* We do not save the password in the configuration,
2969 * because this function is only called for passwords that should
2970 * not be remembered:
2971 modest_server_account_set_password (
2972 modest_runtime_get_account_mgr(), server_account_name,
2981 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2993 /* This is not in the Maemo UI spec:
2994 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3000 gtk_widget_destroy (dialog);
3002 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3006 modest_ui_actions_on_cut (GtkAction *action,
3007 ModestWindow *window)
3009 GtkWidget *focused_widget;
3010 GtkClipboard *clipboard;
3012 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3013 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3014 if (GTK_IS_EDITABLE (focused_widget)) {
3015 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3016 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3017 gtk_clipboard_store (clipboard);
3018 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3019 GtkTextBuffer *buffer;
3021 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3022 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3023 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3024 gtk_clipboard_store (clipboard);
3025 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3026 TnyList *header_list = modest_header_view_get_selected_headers (
3027 MODEST_HEADER_VIEW (focused_widget));
3028 gboolean continue_download = FALSE;
3029 gint num_of_unc_msgs;
3031 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3033 if (num_of_unc_msgs) {
3034 TnyAccount *account = get_account_from_header_list (header_list);
3035 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3036 g_object_unref (account);
3039 if (num_of_unc_msgs == 0 || continue_download) {
3040 /* modest_platform_information_banner (
3041 NULL, NULL, _CS("mcen_ib_getting_items"));*/
3042 modest_header_view_cut_selection (
3043 MODEST_HEADER_VIEW (focused_widget));
3046 g_object_unref (header_list);
3047 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3048 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3053 modest_ui_actions_on_copy (GtkAction *action,
3054 ModestWindow *window)
3056 GtkClipboard *clipboard;
3057 GtkWidget *focused_widget;
3058 gboolean copied = TRUE;
3060 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3061 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3063 if (GTK_IS_LABEL (focused_widget)) {
3064 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
3065 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3066 gtk_clipboard_store (clipboard);
3067 } else if (GTK_IS_EDITABLE (focused_widget)) {
3068 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3069 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3070 gtk_clipboard_store (clipboard);
3071 } else if (GTK_IS_HTML (focused_widget)) {
3072 gtk_html_copy (GTK_HTML (focused_widget));
3073 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3074 gtk_clipboard_store (clipboard);
3075 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3076 GtkTextBuffer *buffer;
3077 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3078 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3079 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3080 gtk_clipboard_store (clipboard);
3081 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3082 TnyList *header_list = modest_header_view_get_selected_headers (
3083 MODEST_HEADER_VIEW (focused_widget));
3084 gboolean continue_download = FALSE;
3085 gint num_of_unc_msgs;
3087 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3089 if (num_of_unc_msgs) {
3090 TnyAccount *account = get_account_from_header_list (header_list);
3091 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3092 g_object_unref (account);
3095 if (num_of_unc_msgs == 0 || continue_download) {
3096 modest_platform_information_banner (
3097 NULL, NULL, _CS("mcen_ib_getting_items"));
3098 modest_header_view_copy_selection (
3099 MODEST_HEADER_VIEW (focused_widget));
3103 g_object_unref (header_list);
3105 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3106 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3109 /* Show information banner if there was a copy to clipboard */
3111 modest_platform_information_banner (
3112 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3116 modest_ui_actions_on_undo (GtkAction *action,
3117 ModestWindow *window)
3119 ModestEmailClipboard *clipboard = NULL;
3121 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3122 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3123 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3124 /* Clear clipboard source */
3125 clipboard = modest_runtime_get_email_clipboard ();
3126 modest_email_clipboard_clear (clipboard);
3129 g_return_if_reached ();
3134 modest_ui_actions_on_redo (GtkAction *action,
3135 ModestWindow *window)
3137 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3138 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3141 g_return_if_reached ();
3147 destroy_information_note (ModestMailOperation *mail_op, gpointer user_data)
3149 /* destroy information note */
3150 gtk_widget_destroy (GTK_WIDGET(user_data));
3155 paste_as_attachment_free (gpointer data)
3157 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3159 gtk_widget_destroy (helper->banner);
3160 g_object_unref (helper->banner);
3165 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3170 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3171 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3176 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3181 modest_ui_actions_on_paste (GtkAction *action,
3182 ModestWindow *window)
3184 GtkWidget *focused_widget = NULL;
3185 GtkWidget *inf_note = NULL;
3186 ModestMailOperation *mail_op = NULL;
3188 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3189 if (GTK_IS_EDITABLE (focused_widget)) {
3190 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3191 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3192 ModestEmailClipboard *e_clipboard = NULL;
3193 e_clipboard = modest_runtime_get_email_clipboard ();
3194 if (modest_email_clipboard_cleared (e_clipboard)) {
3195 GtkTextBuffer *buffer;
3196 GtkClipboard *clipboard;
3198 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3199 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3200 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3201 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3202 ModestMailOperation *mail_op;
3203 TnyFolder *src_folder;
3206 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3207 helper->window = MODEST_MSG_EDIT_WINDOW (window);
3208 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3209 _CS("ckct_nw_pasting"));
3210 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
3211 mail_op = modest_mail_operation_new (G_OBJECT (window));
3212 if (helper->banner != NULL) {
3213 g_object_ref (G_OBJECT (helper->banner));
3214 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
3215 gtk_widget_show (GTK_WIDGET (helper->banner));
3219 modest_mail_operation_get_msgs_full (mail_op,
3221 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
3223 paste_as_attachment_free);
3226 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3227 ModestEmailClipboard *clipboard = NULL;
3228 TnyFolder *src_folder = NULL;
3229 TnyFolderStore *folder_store = NULL;
3230 TnyList *data = NULL;
3231 gboolean delete = FALSE;
3233 /* Check clipboard source */
3234 clipboard = modest_runtime_get_email_clipboard ();
3235 if (modest_email_clipboard_cleared (clipboard))
3238 /* Get elements to paste */
3239 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
3241 /* Create a new mail operation */
3242 mail_op = modest_mail_operation_new (G_OBJECT(window));
3244 /* Get destination folder */
3245 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
3247 /* transfer messages */
3251 /* Ask for user confirmation */
3253 modest_ui_actions_msgs_move_to_confirmation (window,
3254 TNY_FOLDER (folder_store),
3258 if (response == GTK_RESPONSE_OK) {
3259 /* Launch notification */
3260 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3261 _CS("ckct_nw_pasting"));
3262 if (inf_note != NULL) {
3263 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3264 gtk_widget_show (GTK_WIDGET(inf_note));
3267 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3268 modest_mail_operation_xfer_msgs (mail_op,
3270 TNY_FOLDER (folder_store),
3272 destroy_information_note,
3275 g_object_unref (mail_op);
3278 } else if (src_folder != NULL) {
3279 /* Launch notification */
3280 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3281 _CS("ckct_nw_pasting"));
3282 if (inf_note != NULL) {
3283 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3284 gtk_widget_show (GTK_WIDGET(inf_note));
3287 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3288 modest_mail_operation_xfer_folder (mail_op,
3292 destroy_information_note,
3298 g_object_unref (data);
3299 if (src_folder != NULL)
3300 g_object_unref (src_folder);
3301 if (folder_store != NULL)
3302 g_object_unref (folder_store);
3308 modest_ui_actions_on_select_all (GtkAction *action,
3309 ModestWindow *window)
3311 GtkWidget *focused_widget;
3313 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3314 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3315 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3316 } else if (GTK_IS_LABEL (focused_widget)) {
3317 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3318 } else if (GTK_IS_EDITABLE (focused_widget)) {
3319 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3320 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3321 GtkTextBuffer *buffer;
3322 GtkTextIter start, end;
3324 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3325 gtk_text_buffer_get_start_iter (buffer, &start);
3326 gtk_text_buffer_get_end_iter (buffer, &end);
3327 gtk_text_buffer_select_range (buffer, &start, &end);
3328 } else if (GTK_IS_HTML (focused_widget)) {
3329 gtk_html_select_all (GTK_HTML (focused_widget));
3330 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3331 GtkWidget *header_view = focused_widget;
3332 GtkTreeSelection *selection = NULL;
3334 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
3335 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3336 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3339 /* Disable window dimming management */
3340 modest_window_disable_dimming (MODEST_WINDOW(window));
3342 /* Select all messages */
3343 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3344 gtk_tree_selection_select_all (selection);
3346 /* Set focuse on header view */
3347 gtk_widget_grab_focus (header_view);
3350 /* Enable window dimming management */
3351 modest_window_enable_dimming (MODEST_WINDOW(window));
3352 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3358 modest_ui_actions_on_mark_as_read (GtkAction *action,
3359 ModestWindow *window)
3361 g_return_if_fail (MODEST_IS_WINDOW(window));
3363 /* Mark each header as read */
3364 do_headers_action (window, headers_action_mark_as_read, NULL);
3368 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3369 ModestWindow *window)
3371 g_return_if_fail (MODEST_IS_WINDOW(window));
3373 /* Mark each header as read */
3374 do_headers_action (window, headers_action_mark_as_unread, NULL);
3378 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3379 GtkRadioAction *selected,
3380 ModestWindow *window)
3384 value = gtk_radio_action_get_current_value (selected);
3385 if (MODEST_IS_WINDOW (window)) {
3386 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3391 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3392 GtkRadioAction *selected,
3393 ModestWindow *window)
3395 TnyHeaderFlags flags;
3396 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3398 flags = gtk_radio_action_get_current_value (selected);
3399 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3403 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3404 GtkRadioAction *selected,
3405 ModestWindow *window)
3409 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3411 file_format = gtk_radio_action_get_current_value (selected);
3412 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3417 modest_ui_actions_on_zoom_plus (GtkAction *action,
3418 ModestWindow *window)
3420 g_return_if_fail (MODEST_IS_WINDOW (window));
3422 modest_window_zoom_plus (MODEST_WINDOW (window));
3426 modest_ui_actions_on_zoom_minus (GtkAction *action,
3427 ModestWindow *window)
3429 g_return_if_fail (MODEST_IS_WINDOW (window));
3431 modest_window_zoom_minus (MODEST_WINDOW (window));
3435 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3436 ModestWindow *window)
3438 ModestWindowMgr *mgr;
3439 gboolean fullscreen, active;
3440 g_return_if_fail (MODEST_IS_WINDOW (window));
3442 mgr = modest_runtime_get_window_mgr ();
3444 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3445 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3447 if (active != fullscreen) {
3448 modest_window_mgr_set_fullscreen_mode (mgr, active);
3449 gtk_window_present (GTK_WINDOW (window));
3454 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3455 ModestWindow *window)
3457 ModestWindowMgr *mgr;
3458 gboolean fullscreen;
3460 g_return_if_fail (MODEST_IS_WINDOW (window));
3462 mgr = modest_runtime_get_window_mgr ();
3463 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3464 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3466 gtk_window_present (GTK_WINDOW (window));
3470 * Used by modest_ui_actions_on_details to call do_headers_action
3473 headers_action_show_details (TnyHeader *header,
3474 ModestWindow *window,
3481 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3484 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3485 gtk_widget_show_all (dialog);
3486 gtk_dialog_run (GTK_DIALOG (dialog));
3488 gtk_widget_destroy (dialog);
3492 * Show the folder details in a ModestDetailsDialog widget
3495 show_folder_details (TnyFolder *folder,
3501 dialog = modest_details_dialog_new_with_folder (window, folder);
3504 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3505 gtk_widget_show_all (dialog);
3506 gtk_dialog_run (GTK_DIALOG (dialog));
3508 gtk_widget_destroy (dialog);
3512 * Show the header details in a ModestDetailsDialog widget
3515 modest_ui_actions_on_details (GtkAction *action,
3518 TnyList * headers_list;
3522 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3525 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3528 g_object_unref (msg);
3530 headers_list = get_selected_headers (win);
3534 iter = tny_list_create_iterator (headers_list);
3536 header = TNY_HEADER (tny_iterator_get_current (iter));
3538 headers_action_show_details (header, win, NULL);
3539 g_object_unref (header);
3542 g_object_unref (iter);
3543 g_object_unref (headers_list);
3545 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3546 GtkWidget *folder_view, *header_view;
3548 /* Check which widget has the focus */
3549 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3550 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3551 if (gtk_widget_is_focus (folder_view)) {
3552 TnyFolderStore *folder_store
3553 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3554 if (!folder_store) {
3555 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3558 /* Show only when it's a folder */
3559 /* This function should not be called for account items,
3560 * because we dim the menu item for them. */
3561 if (TNY_IS_FOLDER (folder_store)) {
3562 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3565 g_object_unref (folder_store);
3568 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3569 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3570 /* Show details of each header */
3571 do_headers_action (win, headers_action_show_details, header_view);
3577 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3578 ModestMsgEditWindow *window)
3580 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3582 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3586 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3587 ModestMsgEditWindow *window)
3589 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3591 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3595 modest_ui_actions_toggle_folders_view (GtkAction *action,
3596 ModestMainWindow *main_window)
3598 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3600 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3601 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3603 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3607 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3608 ModestWindow *window)
3610 gboolean active, fullscreen = FALSE;
3611 ModestWindowMgr *mgr;
3613 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3615 /* Check if we want to toggle the toolbar vuew in fullscreen
3617 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3618 "ViewShowToolbarFullScreen")) {
3622 /* Toggle toolbar */
3623 mgr = modest_runtime_get_window_mgr ();
3624 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
3628 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3629 ModestMsgEditWindow *window)
3631 modest_msg_edit_window_select_font (window);
3635 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3636 const gchar *display_name,
3639 /* Do not change the application name if the widget has not
3640 the focus. This callback could be called even if the folder
3641 view has not the focus, because the handled signal could be
3642 emitted when the folder view is redrawn */
3643 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3645 gtk_window_set_title (window, display_name);
3647 gtk_window_set_title (window, " ");
3652 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3654 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3655 modest_msg_edit_window_select_contacts (window);
3659 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3661 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3662 modest_msg_edit_window_check_names (window, FALSE);
3666 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3668 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3669 GTK_WIDGET (user_data));
3673 * This function is used to track changes in the selection of the
3674 * folder view that is inside the "move to" dialog to enable/disable
3675 * the OK button because we do not want the user to select a disallowed
3676 * destination for a folder.
3677 * The user also not desired to be able to use NEW button on items where
3678 * folder creation is not possibel.
3681 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
3682 TnyFolderStore *folder_store,
3686 GtkWidget *dialog = NULL;
3687 GtkWidget *ok_button = NULL, *new_button = NULL;
3688 GList *children = NULL;
3689 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
3690 gboolean moving_folder = FALSE;
3691 gboolean is_local_account = TRUE;
3692 GtkWidget *folder_view = NULL;
3693 ModestTnyFolderRules rules;
3698 /* Get the OK button */
3699 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
3703 children = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
3704 ok_button = GTK_WIDGET (children->next->next->data);
3705 new_button = GTK_WIDGET (children->next->data);
3706 g_list_free (children);
3708 /* check if folder_store is an remote account */
3709 if (TNY_IS_ACCOUNT (folder_store)) {
3710 TnyAccount *local_account = NULL;
3711 ModestTnyAccountStore *account_store = NULL;
3713 account_store = modest_runtime_get_account_store ();
3714 local_account = modest_tny_account_store_get_local_folders_account (account_store);
3716 if ((gpointer) local_account != (gpointer) folder_store) {
3717 is_local_account = FALSE;
3718 /* New button should be dimmed on remote
3720 new_sensitive = FALSE;
3722 g_object_unref (local_account);
3725 /* Check the target folder rules */
3726 if (TNY_IS_FOLDER (folder_store)) {
3727 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
3728 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
3729 ok_sensitive = FALSE;
3730 new_sensitive = FALSE;
3735 /* Check if we're moving a folder */
3736 if (MODEST_IS_MAIN_WINDOW (user_data)) {
3737 /* Get the widgets */
3738 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
3739 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3740 if (gtk_widget_is_focus (folder_view))
3741 moving_folder = TRUE;
3744 if (moving_folder) {
3745 TnyFolderStore *moved_folder = NULL, *parent = NULL;
3747 /* Get the folder to move */
3748 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3750 /* Check that we're not moving to the same folder */
3751 if (TNY_IS_FOLDER (moved_folder)) {
3752 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
3753 if (parent == folder_store)
3754 ok_sensitive = FALSE;
3755 g_object_unref (parent);
3758 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
3759 /* Do not allow to move to an account unless it's the
3760 local folders account */
3761 if (!is_local_account)
3762 ok_sensitive = FALSE;
3765 if (ok_sensitive && (moved_folder == folder_store)) {
3766 /* Do not allow to move to itself */
3767 ok_sensitive = FALSE;
3769 g_object_unref (moved_folder);
3771 TnyHeader *header = NULL;
3772 TnyFolder *src_folder = NULL;
3774 /* Moving a message */
3775 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
3776 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (user_data));
3777 src_folder = tny_header_get_folder (header);
3778 g_object_unref (header);
3781 TNY_FOLDER (modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view)));
3784 /* Do not allow to move the msg to the same folder */
3785 /* Do not allow to move the msg to an account */
3786 if ((gpointer) src_folder == (gpointer) folder_store ||
3787 TNY_IS_ACCOUNT (folder_store))
3788 ok_sensitive = FALSE;
3789 g_object_unref (src_folder);
3793 /* Set sensitivity of the OK button */
3794 gtk_widget_set_sensitive (ok_button, ok_sensitive);
3795 /* Set sensitivity of the NEW button */
3796 gtk_widget_set_sensitive (new_button, new_sensitive);
3800 create_move_to_dialog (GtkWindow *win,
3801 GtkWidget *folder_view,
3802 GtkWidget **tree_view)
3804 GtkWidget *dialog, *scroll;
3805 GtkWidget *new_button;
3807 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3809 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3812 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
3813 /* We do this manually so GTK+ does not associate a response ID for
3815 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
3816 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3817 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
3819 /* Create scrolled window */
3820 scroll = gtk_scrolled_window_new (NULL, NULL);
3821 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3822 GTK_POLICY_AUTOMATIC,
3823 GTK_POLICY_AUTOMATIC);
3825 /* Create folder view */
3826 *tree_view = modest_platform_create_folder_view (NULL);
3828 /* Track changes in the selection to
3829 * disable the OK button whenever "Move to" is not possible
3830 * disbale NEW button whenever New is not possible */
3831 g_signal_connect (*tree_view,
3832 "folder_selection_changed",
3833 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
3836 /* Listen to clicks on New button */
3837 g_signal_connect (G_OBJECT (new_button),
3839 G_CALLBACK(create_move_to_dialog_on_new_folder),
3842 /* It could happen that we're trying to move a message from a
3843 window (msg window for example) after the main window was
3844 closed, so we can not just get the model of the folder
3846 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
3847 const gchar *visible_id = NULL;
3849 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
3850 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
3851 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
3852 MODEST_FOLDER_VIEW(*tree_view));
3855 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
3857 /* Show the same account than the one that is shown in the main window */
3858 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
3861 const gchar *active_account_name = NULL;
3862 ModestAccountMgr *mgr = NULL;
3863 ModestAccountData *acc_data = NULL;
3865 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
3866 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
3867 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3868 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3870 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
3871 mgr = modest_runtime_get_account_mgr ();
3872 acc_data = modest_account_mgr_get_account_data (mgr, active_account_name);
3874 /* Set the new visible & active account */
3875 if (acc_data && acc_data->store_account) {
3876 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
3877 acc_data->store_account->account_name);
3878 modest_account_mgr_free_account_data (mgr, acc_data);
3882 /* Hide special folders */
3883 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3885 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3887 /* Add scroll to dialog */
3888 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3889 scroll, TRUE, TRUE, 0);
3891 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3892 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3898 * Returns TRUE if at least one of the headers of the list belongs to
3899 * a message that has been fully retrieved.
3901 #if 0 /* no longer in use. delete in 2007.10 */
3903 has_retrieved_msgs (TnyList *list)
3906 gboolean found = FALSE;
3908 iter = tny_list_create_iterator (list);
3909 while (!tny_iterator_is_done (iter) && !found) {
3911 TnyHeaderFlags flags = 0;
3913 header = TNY_HEADER (tny_iterator_get_current (iter));
3915 flags = tny_header_get_flags (header);
3916 if (flags & TNY_HEADER_FLAG_CACHED)
3917 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3920 g_object_unref (header);
3924 tny_iterator_next (iter);
3926 g_object_unref (iter);
3934 * Shows a confirmation dialog to the user when we're moving messages
3935 * from a remote server to the local storage. Returns the dialog
3936 * response. If it's other kind of movement then it always returns
3939 * This one is used by the next functions:
3940 * modest_ui_actions_on_paste - commented out
3941 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
3944 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
3945 TnyFolder *dest_folder,
3949 gint response = GTK_RESPONSE_OK;
3950 TnyAccount *account = NULL;
3951 TnyFolder *src_folder = NULL;
3952 TnyIterator *iter = NULL;
3953 TnyHeader *header = NULL;
3955 /* return with OK if the destination is a remote folder */
3956 if (modest_tny_folder_is_remote_folder (dest_folder))
3957 return GTK_RESPONSE_OK;
3959 /* Get source folder */
3960 iter = tny_list_create_iterator (headers);
3961 header = TNY_HEADER (tny_iterator_get_current (iter));
3963 src_folder = tny_header_get_folder (header);
3964 g_object_unref (header);
3966 g_object_unref (iter);
3968 /* if no src_folder, message may be an attahcment */
3969 if (src_folder == NULL)
3970 return GTK_RESPONSE_CANCEL;
3972 /* If the source is a local or MMC folder */
3973 if (!modest_tny_folder_is_remote_folder (src_folder)) {
3974 g_object_unref (src_folder);
3975 return GTK_RESPONSE_OK;
3978 /* Get the account */
3979 account = tny_folder_get_account (src_folder);
3981 /* now if offline we ask the user */
3982 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
3983 response = GTK_RESPONSE_OK;
3985 response = GTK_RESPONSE_CANCEL;
3988 g_object_unref (src_folder);
3989 g_object_unref (account);
3997 move_to_cb (ModestMailOperation *mail_op, gpointer user_data)
3999 MoveToHelper *helper = (MoveToHelper *) user_data;
4001 /* Note that the operation could have failed, in that case do
4003 if (modest_mail_operation_get_status (mail_op) ==
4004 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
4006 GObject *object = modest_mail_operation_get_source (mail_op);
4007 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4008 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4010 if (!modest_msg_view_window_select_next_message (self))
4011 if (!modest_msg_view_window_select_previous_message (self))
4012 /* No more messages to view, so close this window */
4013 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4014 } else if (MODEST_IS_MAIN_WINDOW (object) && helper->reference != NULL) {
4015 GtkWidget *header_view;
4017 GtkTreeSelection *sel;
4019 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4020 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4021 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
4022 path = gtk_tree_row_reference_get_path (helper->reference);
4023 gtk_tree_selection_select_path (sel, path);
4024 gtk_tree_path_free (path);
4026 g_object_unref (object);
4029 /* Close the "Pasting" information banner */
4030 gtk_widget_destroy (GTK_WIDGET(helper->banner));
4031 if (helper->reference != NULL)
4032 gtk_tree_row_reference_free (helper->reference);
4037 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
4040 ModestWindow *main_window = NULL;
4041 GtkWidget *folder_view = NULL;
4042 GObject *win = modest_mail_operation_get_source (mail_op);
4043 const GError *error = NULL;
4044 const gchar *message = NULL;
4046 /* Get error message */
4047 error = modest_mail_operation_get_error (mail_op);
4048 if (error != NULL && error->message != NULL) {
4049 message = error->message;
4051 message = _("mail_in_ui_folder_move_target_error");
4054 /* Disable next automatic folder selection */
4055 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ());
4056 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
4057 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4058 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
4060 if (user_data && TNY_IS_FOLDER (user_data)) {
4061 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
4062 TNY_FOLDER (user_data), FALSE);
4065 /* Show notification dialog */
4066 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
4067 g_object_unref (win);
4071 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
4074 GObject *win = modest_mail_operation_get_source (mail_op);
4075 const GError *error = modest_mail_operation_get_error (mail_op);
4077 g_return_if_fail (error != NULL);
4078 if (error->message != NULL)
4079 g_printerr ("modest: %s\n", error->message);
4081 g_printerr ("modest: unkonw error on send&receive operation");
4083 /* Show error message */
4084 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
4085 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
4086 /* _CS("sfil_ib_unable_to_receive")); */
4088 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
4089 /* _CS("sfil_ib_unable_to_send")); */
4090 g_object_unref (win);
4094 open_msg_for_purge_cb (ModestMailOperation *mail_op,
4101 gint pending_purges = 0;
4102 gboolean some_purged = FALSE;
4103 ModestWindow *win = MODEST_WINDOW (user_data);
4104 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
4106 /* If there was any error */
4107 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
4108 modest_window_mgr_unregister_header (mgr, header);
4112 /* Once the message has been retrieved for purging, we check if
4113 * it's all ok for purging */
4115 parts = tny_simple_list_new ();
4116 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
4117 iter = tny_list_create_iterator (parts);
4119 while (!tny_iterator_is_done (iter)) {
4121 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4122 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
4123 if (tny_mime_part_is_purged (part))
4130 g_object_unref (part);
4132 tny_iterator_next (iter);
4134 g_object_unref (iter);
4137 if (pending_purges>0) {
4139 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
4141 if (response == GTK_RESPONSE_OK) {
4142 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
4143 iter = tny_list_create_iterator (parts);
4144 while (!tny_iterator_is_done (iter)) {
4147 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4148 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
4149 tny_mime_part_set_purged (part);
4152 g_object_unref (part);
4154 tny_iterator_next (iter);
4157 tny_msg_rewrite_cache (msg);
4160 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
4162 g_object_unref (iter);
4164 modest_window_mgr_unregister_header (mgr, header);
4166 g_object_unref (parts);
4170 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
4171 ModestMainWindow *win)
4173 GtkWidget *header_view;
4174 TnyList *header_list;
4177 TnyHeaderFlags flags;
4178 ModestWindow *msg_view_window = NULL;
4181 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4183 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4184 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4186 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
4188 if (tny_list_get_length (header_list) == 1) {
4189 iter = tny_list_create_iterator (header_list);
4190 header = TNY_HEADER (tny_iterator_get_current (iter));
4191 g_object_unref (iter);
4196 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
4197 header, &msg_view_window);
4198 flags = tny_header_get_flags (header);
4199 if (!(flags & TNY_HEADER_FLAG_CACHED))
4202 if (msg_view_window != NULL)
4203 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
4205 /* do nothing; uid was registered before, so window is probably on it's way */
4206 g_warning ("debug: header %p has already been registered", header);
4209 ModestMailOperation *mail_op = NULL;
4210 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
4211 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
4212 modest_ui_actions_get_msgs_full_error_handler,
4214 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4215 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
4217 g_object_unref (mail_op);
4220 g_object_unref (header);
4222 g_object_unref (header_list);
4226 * Utility function that transfer messages from both the main window
4227 * and the msg view window when using the "Move to" dialog
4230 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
4233 TnyList *headers = NULL;
4234 TnyAccount *dst_account = NULL;
4235 const gchar *proto_str = NULL;
4236 gboolean dst_is_pop = FALSE;
4238 if (!TNY_IS_FOLDER (dst_folder)) {
4239 modest_platform_information_banner (GTK_WIDGET (win),
4241 _CS("ckdg_ib_unable_to_move_to_current_location"));
4245 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
4246 proto_str = tny_account_get_proto (dst_account);
4248 /* tinymail will return NULL for local folders it seems */
4249 dst_is_pop = proto_str &&
4250 (modest_protocol_info_get_transport_store_protocol (proto_str) ==
4251 MODEST_PROTOCOL_STORE_POP);
4253 g_object_unref (dst_account);
4255 /* Get selected headers */
4256 headers = get_selected_headers (MODEST_WINDOW (win));
4259 modest_platform_information_banner (GTK_WIDGET (win),
4261 ngettext("mail_in_ui_folder_move_target_error",
4262 "mail_in_ui_folder_move_targets_error",
4263 tny_list_get_length (headers)));
4264 g_object_unref (headers);
4268 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4269 helper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4270 _CS("ckct_nw_pasting"));
4271 if (helper->banner != NULL) {
4272 gtk_window_set_modal (GTK_WINDOW(helper->banner), FALSE);
4273 gtk_widget_show (GTK_WIDGET(helper->banner));
4276 if (MODEST_IS_MAIN_WINDOW (win)) {
4277 GtkWidget *header_view =
4278 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
4279 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4280 helper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
4283 ModestMailOperation *mail_op =
4284 modest_mail_operation_new_with_error_handling (G_OBJECT(win),
4285 modest_ui_actions_move_folder_error_handler,
4287 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4290 modest_mail_operation_xfer_msgs (mail_op,
4292 TNY_FOLDER (dst_folder),
4297 g_object_unref (G_OBJECT (mail_op));
4298 g_object_unref (headers);
4302 * UI handler for the "Move to" action when invoked from the
4306 modest_ui_actions_on_main_window_move_to (GtkAction *action,
4307 GtkWidget *folder_view,
4308 TnyFolderStore *dst_folder,
4309 ModestMainWindow *win)
4311 ModestHeaderView *header_view = NULL;
4312 ModestMailOperation *mail_op = NULL;
4313 TnyFolderStore *src_folder;
4314 gboolean online = (tny_device_is_online (modest_runtime_get_device()));
4316 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4318 /* Get the source folder */
4319 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4321 /* Get header view */
4322 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
4324 /* Get folder or messages to transfer */
4325 if (gtk_widget_is_focus (folder_view)) {
4326 GtkTreeSelection *sel;
4327 gboolean do_xfer = TRUE;
4329 /* Allow only to transfer folders to the local root folder */
4330 if (TNY_IS_ACCOUNT (dst_folder) &&
4331 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder)) {
4333 } else if (!TNY_IS_FOLDER (src_folder)) {
4334 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
4336 } else if (!online && modest_platform_is_network_folderstore(src_folder)) {
4337 guint num_headers = tny_folder_get_all_count(TNY_FOLDER (src_folder));
4338 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (src_folder));
4339 if (!connect_to_get_msg(MODEST_WINDOW (win), num_headers, account))
4341 g_object_unref (account);
4345 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4346 helper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4347 _CS("ckct_nw_pasting"));
4348 if (helper->banner != NULL) {
4349 gtk_window_set_modal (GTK_WINDOW(helper->banner), FALSE);
4350 gtk_widget_show (GTK_WIDGET(helper->banner));
4352 /* Clean folder on header view before moving it */
4353 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
4354 gtk_tree_selection_unselect_all (sel);
4357 modest_mail_operation_new_with_error_handling (G_OBJECT(win),
4358 modest_ui_actions_move_folder_error_handler,
4360 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4363 /* Select *after* the changes */
4364 /* TODO: this function hangs UI after transfer */
4365 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
4366 /* TNY_FOLDER (src_folder), TRUE); */
4368 modest_mail_operation_xfer_folder (mail_op,
4369 TNY_FOLDER (src_folder),
4374 /* Unref mail operation */
4375 g_object_unref (G_OBJECT (mail_op));
4377 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
4378 gboolean do_xfer = TRUE;
4379 /* Ask for confirmation if the source folder is remote and we're not connected */
4380 if (!online && modest_platform_is_network_folderstore(src_folder)) {
4381 TnyList *headers = modest_header_view_get_selected_headers(header_view);
4382 if (!msgs_already_deleted_from_server(headers, src_folder)) {
4383 guint num_headers = tny_list_get_length(headers);
4384 TnyAccount *account = get_account_from_header_list (headers);
4385 if (!connect_to_get_msg(MODEST_WINDOW (win), num_headers, account))
4387 g_object_unref (account);
4389 g_object_unref(headers);
4391 if (do_xfer) /* Transfer messages */
4392 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4396 g_object_unref (src_folder);
4401 * UI handler for the "Move to" action when invoked from the
4402 * ModestMsgViewWindow
4405 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
4406 TnyFolderStore *dst_folder,
4407 ModestMsgViewWindow *win)
4409 TnyHeader *header = NULL;
4410 TnyFolder *src_folder = NULL;
4411 TnyAccount *account = NULL;
4413 /* Create header list */
4414 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
4415 src_folder = TNY_FOLDER (tny_header_get_folder(header));
4416 g_object_unref (header);
4418 /* Transfer the message if online or confirmed by the user */
4419 account = tny_folder_get_account (src_folder);
4420 if (remote_folder_is_pop(TNY_FOLDER_STORE (src_folder)) ||
4421 (modest_platform_is_network_folderstore(TNY_FOLDER_STORE (src_folder)) &&
4422 connect_to_get_msg(MODEST_WINDOW (win), 1, account))) {
4423 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4425 g_object_unref (account);
4426 g_object_unref (src_folder);
4430 modest_ui_actions_on_move_to (GtkAction *action,
4433 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
4435 TnyFolderStore *dst_folder = NULL;
4436 ModestMainWindow *main_window;
4438 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
4439 MODEST_IS_MSG_VIEW_WINDOW (win));
4441 /* Get the main window if exists */
4442 if (MODEST_IS_MAIN_WINDOW (win))
4443 main_window = MODEST_MAIN_WINDOW (win);
4446 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
4448 /* Get the folder view widget if exists */
4450 folder_view = modest_main_window_get_child_widget (main_window,
4451 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4455 /* Create and run the dialog */
4456 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
4457 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
4458 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4459 result = gtk_dialog_run (GTK_DIALOG(dialog));
4460 g_object_ref (tree_view);
4461 gtk_widget_destroy (dialog);
4463 if (result != GTK_RESPONSE_ACCEPT)
4466 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
4467 /* Do window specific stuff */
4468 if (MODEST_IS_MAIN_WINDOW (win)) {
4469 modest_ui_actions_on_main_window_move_to (action,
4472 MODEST_MAIN_WINDOW (win));
4474 modest_ui_actions_on_msg_view_window_move_to (action,
4476 MODEST_MSG_VIEW_WINDOW (win));
4480 g_object_unref (dst_folder);
4484 * Calls #HeadersFunc for each header already selected in the main
4485 * window or the message currently being shown in the msg view window
4488 do_headers_action (ModestWindow *win,
4492 TnyList *headers_list = NULL;
4493 TnyIterator *iter = NULL;
4494 TnyHeader *header = NULL;
4495 TnyFolder *folder = NULL;
4498 headers_list = get_selected_headers (win);
4502 /* Get the folder */
4503 iter = tny_list_create_iterator (headers_list);
4504 header = TNY_HEADER (tny_iterator_get_current (iter));
4506 folder = tny_header_get_folder (header);
4507 g_object_unref (header);
4510 /* Call the function for each header */
4511 while (!tny_iterator_is_done (iter)) {
4512 header = TNY_HEADER (tny_iterator_get_current (iter));
4513 func (header, win, user_data);
4514 g_object_unref (header);
4515 tny_iterator_next (iter);
4518 /* Trick: do a poke status in order to speed up the signaling
4520 tny_folder_poke_status (folder);
4523 g_object_unref (folder);
4524 g_object_unref (iter);
4525 g_object_unref (headers_list);
4529 modest_ui_actions_view_attachment (GtkAction *action,
4530 ModestWindow *window)
4532 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4533 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4535 /* not supported window for this action */
4536 g_return_if_reached ();
4541 modest_ui_actions_save_attachments (GtkAction *action,
4542 ModestWindow *window)
4544 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4545 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4547 /* not supported window for this action */
4548 g_return_if_reached ();
4553 modest_ui_actions_remove_attachments (GtkAction *action,
4554 ModestWindow *window)
4556 if (MODEST_IS_MAIN_WINDOW (window)) {
4557 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4558 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4559 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4561 /* not supported window for this action */
4562 g_return_if_reached ();
4567 modest_ui_actions_on_settings (GtkAction *action,
4572 dialog = modest_platform_get_global_settings_dialog ();
4573 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4574 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4575 gtk_widget_show_all (dialog);
4577 gtk_dialog_run (GTK_DIALOG (dialog));
4579 gtk_widget_destroy (dialog);
4583 modest_ui_actions_on_help (GtkAction *action,
4586 const gchar *help_id = NULL;
4588 if (MODEST_IS_MAIN_WINDOW (win)) {
4589 GtkWidget *folder_view;
4590 TnyFolderStore *folder_store;
4592 /* Get selected folder */
4593 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4594 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4595 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4597 /* Switch help_id */
4598 if (TNY_IS_FOLDER (folder_store)) {
4599 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4600 case TNY_FOLDER_TYPE_NORMAL:
4601 help_id = "applications_email_managefolders";
4603 case TNY_FOLDER_TYPE_INBOX:
4604 help_id = "applications_email_inbox";
4606 case TNY_FOLDER_TYPE_OUTBOX:
4607 help_id = "applications_email_outbox";
4609 case TNY_FOLDER_TYPE_SENT:
4610 help_id = "applications_email_sent";
4612 case TNY_FOLDER_TYPE_DRAFTS:
4613 help_id = "applications_email_drafts";
4615 case TNY_FOLDER_TYPE_ARCHIVE:
4616 help_id = "applications_email_managefolders";
4619 help_id = "applications_email_managefolders";
4622 help_id = "applications_email_mainview";
4624 g_object_unref (folder_store);
4625 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4626 help_id = "applications_email_viewer";
4627 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4628 help_id = "applications_email_editor";
4630 modest_platform_show_help (GTK_WINDOW (win), help_id);
4634 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4635 ModestWindow *window)
4637 ModestMailOperation *mail_op;
4641 headers = get_selected_headers (window);
4645 /* Create mail operation */
4646 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (window),
4647 modest_ui_actions_get_msgs_full_error_handler,
4649 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4650 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4653 g_object_unref (headers);
4654 g_object_unref (mail_op);
4658 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4659 ModestWindow *window)
4661 g_return_if_fail (MODEST_IS_WINDOW (window));
4664 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4668 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4669 ModestWindow *window)
4671 g_return_if_fail (MODEST_IS_WINDOW (window));
4674 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4678 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4679 ModestWindow *window)
4681 g_return_if_fail (MODEST_IS_WINDOW (window));
4684 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4688 modest_ui_actions_on_format_menu_activated (GtkAction *action,
4689 ModestWindow *window)
4691 g_return_if_fail (MODEST_IS_WINDOW (window));
4694 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4698 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4699 ModestWindow *window)
4701 g_return_if_fail (MODEST_IS_WINDOW (window));
4704 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4708 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4709 ModestWindow *window)
4711 g_return_if_fail (MODEST_IS_WINDOW (window));
4714 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4718 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4719 ModestWindow *window)
4721 g_return_if_fail (MODEST_IS_WINDOW (window));
4724 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4728 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4729 ModestWindow *window)
4731 g_return_if_fail (MODEST_IS_WINDOW (window));
4734 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4738 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4739 ModestWindow *window)
4741 g_return_if_fail (MODEST_IS_WINDOW (window));
4744 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4748 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4750 g_return_if_fail (MODEST_IS_WINDOW (window));
4753 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4757 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4759 g_return_if_fail (MODEST_IS_WINDOW (window));
4761 modest_platform_show_search_messages (GTK_WINDOW (window));
4765 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4767 g_return_if_fail (MODEST_IS_WINDOW (win));
4768 modest_platform_show_addressbook (GTK_WINDOW (win));
4773 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4774 ModestWindow *window)
4776 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4778 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4782 on_send_receive_finished (ModestMailOperation *mail_op,
4785 /* Set send/receive operation finished */
4786 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW (user_data));
4791 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
4797 const gchar* server_name = NULL;
4798 TnyTransportAccount *server_account;
4799 gchar *message = NULL;
4801 /* Don't show anything if the user cancelled something */
4802 if (err->code == TNY_TRANSPORT_ACCOUNT_ERROR_SEND_USER_CANCEL)
4805 /* Get the server name: */
4807 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
4808 if (server_account) {
4809 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
4811 g_object_unref (server_account);
4812 server_account = NULL;
4815 g_return_if_fail (server_name);
4817 /* Show the appropriate message text for the GError: */
4818 switch (err->code) {
4819 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_HOST_LOOKUP_FAILED:
4820 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4822 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_SERVICE_UNAVAILABLE:
4823 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4825 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_AUTHENTICATION_NOT_SUPPORTED:
4826 message = g_strdup_printf (_("emev_ni_ui_smtp_authentication_fail_error"), server_name);
4828 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND:
4829 message = g_strdup (_("emev_ib_ui_smtp_send_error"));
4832 g_return_if_reached ();
4835 /* TODO if the username or the password where not defined we
4836 should show the Accounts Settings dialog or the Connection
4837 specific SMTP server window */
4839 modest_platform_run_information_dialog (NULL, message);
4844 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
4849 ModestMainWindow *main_window = NULL;
4850 ModestWindowMgr *mgr = NULL;
4851 GtkWidget *folder_view = NULL, *header_view = NULL;
4852 TnyFolderStore *selected_folder = NULL;
4853 TnyFolderType folder_type;
4855 mgr = modest_runtime_get_window_mgr ();
4856 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr));
4861 /* Check if selected folder is OUTBOX */
4862 folder_view = modest_main_window_get_child_widget (main_window,
4863 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4864 header_view = modest_main_window_get_child_widget (main_window,
4865 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4867 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4868 if (!TNY_IS_FOLDER (selected_folder))
4871 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
4872 #if GTK_CHECK_VERSION(2, 8, 0)
4873 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
4874 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
4875 GtkTreeViewColumn *tree_column;
4877 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
4878 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
4879 gtk_tree_view_column_queue_resize (tree_column);
4882 gtk_widget_queue_draw (header_view);
4887 if (selected_folder != NULL)
4888 g_object_unref (selected_folder);