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 two wizards (as this
228 * function might be called in modest_window_mgr_get_main_window as well */
230 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
231 TRUE); /* create if not existent */
233 /* make sure the mainwindow is visible */
234 gtk_widget_show_all (GTK_WIDGET(win));
235 gtk_window_present (GTK_WINDOW(win));
237 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
238 gtk_widget_destroy (GTK_WIDGET (wizard));
239 if (gtk_events_pending ())
240 gtk_main_iteration ();
242 if (dialog_response == GTK_RESPONSE_CANCEL) {
245 /* Check whether an account was created: */
246 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
254 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
257 const gchar *authors[] = {
258 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
261 about = gtk_about_dialog_new ();
262 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
263 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
264 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
265 _("Copyright (c) 2006, Nokia Corporation\n"
266 "All rights reserved."));
267 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
268 _("a modest e-mail client\n\n"
269 "design and implementation: Dirk-Jan C. Binnema\n"
270 "contributions from the fine people at KC and Ig\n"
271 "uses the tinymail email framework written by Philip van Hoof"));
272 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
273 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
274 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
275 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
277 gtk_dialog_run (GTK_DIALOG (about));
278 gtk_widget_destroy(about);
282 * Gets the list of currently selected messages. If the win is the
283 * main window, then it returns a newly allocated list of the headers
284 * selected in the header view. If win is the msg view window, then
285 * the value returned is a list with just a single header.
287 * The caller of this funcion must free the list.
290 get_selected_headers (ModestWindow *win)
292 if (MODEST_IS_MAIN_WINDOW(win)) {
293 GtkWidget *header_view;
295 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
296 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
297 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
299 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
300 /* for MsgViewWindows, we simply return a list with one element */
302 TnyList *list = NULL;
304 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
305 if (header != NULL) {
306 list = tny_simple_list_new ();
307 tny_list_prepend (list, G_OBJECT(header));
308 g_object_unref (G_OBJECT(header));
317 static GtkTreeRowReference *
318 get_next_after_selected_headers (ModestHeaderView *header_view)
320 GtkTreeSelection *sel;
321 GList *selected_rows, *node;
323 GtkTreeRowReference *result;
326 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
327 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
328 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
330 if (selected_rows == NULL)
333 node = g_list_last (selected_rows);
334 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
335 gtk_tree_path_next (path);
337 result = gtk_tree_row_reference_new (model, path);
339 gtk_tree_path_free (path);
340 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
341 g_list_free (selected_rows);
347 headers_action_mark_as_read (TnyHeader *header,
351 TnyHeaderFlags flags;
353 g_return_if_fail (TNY_IS_HEADER(header));
355 flags = tny_header_get_flags (header);
356 if (flags & TNY_HEADER_FLAG_SEEN) return;
357 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
361 headers_action_mark_as_unread (TnyHeader *header,
365 TnyHeaderFlags flags;
367 g_return_if_fail (TNY_IS_HEADER(header));
369 flags = tny_header_get_flags (header);
370 if (flags & TNY_HEADER_FLAG_SEEN) {
371 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
375 /** A convenience method, because deleting a message is
376 * otherwise complicated, and it's best to change it in one place
379 void modest_do_messages_delete (TnyList *headers, ModestWindow *win)
381 ModestMailOperation *mail_op = NULL;
382 mail_op = modest_mail_operation_new (win ? G_OBJECT(win) : NULL);
383 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
386 /* Always delete. TODO: Move to trash still not supported */
387 modest_mail_operation_remove_msgs (mail_op, headers, FALSE);
388 g_object_unref (G_OBJECT (mail_op));
391 /** After deleing a message that is currently visible in a window,
392 * show the next message from the list, or close the window if there are no more messages.
395 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
397 /* Close msg view window or select next */
398 if (modest_msg_view_window_last_message_selected (win) &&
399 modest_msg_view_window_first_message_selected (win)) {
400 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
401 } else if (!modest_msg_view_window_select_next_message (win)) {
403 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
409 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
411 TnyList *header_list = NULL;
412 TnyIterator *iter = NULL;
413 TnyHeader *header = NULL;
414 gchar *message = NULL;
417 ModestWindowMgr *mgr;
418 GtkWidget *header_view = NULL;
420 g_return_if_fail (MODEST_IS_WINDOW(win));
422 /* Check first if the header view has the focus */
423 if (MODEST_IS_MAIN_WINDOW (win)) {
425 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
426 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
427 if (!gtk_widget_is_focus (header_view))
431 /* Get the headers, either from the header view (if win is the main window),
432 * or from the message view window: */
433 header_list = get_selected_headers (win);
434 if (!header_list) return;
436 /* Check if any of the headers are already opened, or in the process of being opened */
437 if (MODEST_IS_MAIN_WINDOW (win)) {
438 gint opened_headers = 0;
440 iter = tny_list_create_iterator (header_list);
441 mgr = modest_runtime_get_window_mgr ();
442 while (!tny_iterator_is_done (iter)) {
443 header = TNY_HEADER (tny_iterator_get_current (iter));
445 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
447 g_object_unref (header);
449 tny_iterator_next (iter);
451 g_object_unref (iter);
453 if (opened_headers > 0) {
456 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
459 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
462 g_object_unref (header_list);
468 if (tny_list_get_length(header_list) == 1) {
469 iter = tny_list_create_iterator (header_list);
470 header = TNY_HEADER (tny_iterator_get_current (iter));
472 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
473 g_object_unref (header);
476 g_object_unref (iter);
478 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
479 tny_list_get_length(header_list)), desc);
481 /* Confirmation dialog */
482 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
486 if (response == GTK_RESPONSE_OK) {
487 ModestWindow *main_window = NULL;
488 ModestWindowMgr *mgr = NULL;
489 GtkTreeModel *model = NULL;
490 GtkTreeSelection *sel = NULL;
491 GList *sel_list = NULL, *tmp = NULL;
492 GtkTreeRowReference *next_row_reference = NULL;
493 GtkTreeRowReference *prev_row_reference = NULL;
494 GtkTreePath *next_path = NULL;
495 GtkTreePath *prev_path = NULL;
498 /* Find last selected row */
499 if (MODEST_IS_MAIN_WINDOW (win)) {
500 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
501 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
502 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
503 for (tmp=sel_list; tmp; tmp=tmp->next) {
504 if (tmp->next == NULL) {
505 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
506 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
508 gtk_tree_path_prev (prev_path);
509 gtk_tree_path_next (next_path);
511 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
512 next_row_reference = gtk_tree_row_reference_new (model, next_path);
517 /* Disable window dimming management */
518 modest_window_disable_dimming (MODEST_WINDOW(win));
520 /* Remove each header. If it's a view window header_view == NULL */
521 modest_do_messages_delete (header_list, win);
523 /* Enable window dimming management */
525 gtk_tree_selection_unselect_all (sel);
527 modest_window_enable_dimming (MODEST_WINDOW(win));
529 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
530 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
532 /* Get main window */
533 mgr = modest_runtime_get_window_mgr ();
534 main_window = modest_window_mgr_get_main_window (mgr, FALSE); /* don't create */
536 /* Move cursor to next row */
539 /* Select next or previous row */
540 if (gtk_tree_row_reference_valid (next_row_reference)) {
541 /* next_path = gtk_tree_row_reference_get_path (row_reference); */
542 gtk_tree_selection_select_path (sel, next_path);
544 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
545 gtk_tree_selection_select_path (sel, prev_path);
549 if (next_row_reference != NULL)
550 gtk_tree_row_reference_free (next_row_reference);
551 if (next_path != NULL)
552 gtk_tree_path_free (next_path);
553 if (prev_row_reference != NULL)
554 gtk_tree_row_reference_free (prev_row_reference);
555 if (prev_path != NULL)
556 gtk_tree_path_free (prev_path);
560 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, err->code, err->message);
564 /* Update toolbar dimming state */
565 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
568 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
569 g_list_free (sel_list);
575 g_object_unref (header_list);
581 /* delete either message or folder, based on where we are */
583 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
585 g_return_if_fail (MODEST_IS_WINDOW(win));
587 /* Check first if the header view has the focus */
588 if (MODEST_IS_MAIN_WINDOW (win)) {
590 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
591 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
592 if (gtk_widget_is_focus (w)) {
593 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
597 modest_ui_actions_on_delete_message (action, win);
603 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
605 ModestWindowMgr *mgr = NULL;
607 #ifdef MODEST_PLATFORM_MAEMO
608 modest_osso_save_state();
609 #endif /* MODEST_PLATFORM_MAEMO */
611 g_debug ("closing down, clearing %d item(s) from operation queue",
612 modest_mail_operation_queue_num_elements
613 (modest_runtime_get_mail_operation_queue()));
615 /* cancel all outstanding operations */
616 modest_mail_operation_queue_cancel_all
617 (modest_runtime_get_mail_operation_queue());
619 g_debug ("queue has been cleared");
622 /* Check if there are opened editing windows */
623 mgr = modest_runtime_get_window_mgr ();
624 modest_window_mgr_close_all_windows (mgr);
626 /* note: when modest-tny-account-store is finalized,
627 it will automatically set all network connections
630 /* gtk_main_quit (); */
634 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
638 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
640 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
641 /* gtk_widget_destroy (GTK_WIDGET (win)); */
642 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
643 /* gboolean ret_value; */
644 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
645 /* } else if (MODEST_IS_WINDOW (win)) { */
646 /* gtk_widget_destroy (GTK_WIDGET (win)); */
648 /* g_return_if_reached (); */
653 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
655 GtkClipboard *clipboard = NULL;
656 gchar *selection = NULL;
658 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
659 selection = gtk_clipboard_wait_for_text (clipboard);
661 /* Question: why is the clipboard being used here?
662 * It doesn't really make a lot of sense. */
666 modest_address_book_add_address (selection);
672 modest_ui_actions_on_accounts (GtkAction *action,
675 /* This is currently only implemented for Maemo */
676 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
677 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
678 modest_ui_actions_run_account_setup_wizard (win);
681 /* Show the list of accounts */
682 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
683 gtk_window_set_transient_for (account_win, GTK_WINDOW (win));
685 /* The accounts dialog must be modal */
686 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), account_win);
687 modest_maemo_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
690 GtkWidget *dialog, *label;
692 /* Create the widgets */
694 dialog = gtk_dialog_new_with_buttons ("Message",
696 GTK_DIALOG_DESTROY_WITH_PARENT,
700 label = gtk_label_new ("Hello World!");
702 /* Ensure that the dialog box is destroyed when the user responds. */
704 g_signal_connect_swapped (dialog, "response",
705 G_CALLBACK (gtk_widget_destroy),
708 /* Add the label, and show everything we've added to the dialog. */
710 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
712 gtk_widget_show_all (dialog);
713 #endif /* MODEST_PLATFORM_MAEMO */
717 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
719 /* Save any changes. */
720 modest_connection_specific_smtp_window_save_server_accounts (
721 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window));
722 gtk_widget_destroy (GTK_WIDGET (window));
728 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
730 /* This is currently only implemented for Maemo,
731 * because it requires an API (libconic) to detect different connection
734 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
736 /* Create the window if necessary: */
737 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
738 modest_connection_specific_smtp_window_fill_with_connections (
739 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
740 modest_runtime_get_account_mgr());
742 /* Show the window: */
743 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
744 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
745 gtk_widget_show (specific_window);
747 /* Save changes when the window is hidden: */
748 g_signal_connect (specific_window, "hide",
749 G_CALLBACK (on_smtp_servers_window_hide), win);
750 #endif /* MODEST_PLATFORM_MAEMO */
754 modest_ui_actions_compose_msg(ModestWindow *win,
757 const gchar *bcc_str,
758 const gchar *subject_str,
759 const gchar *body_str,
762 gchar *account_name = NULL;
764 TnyAccount *account = NULL;
765 TnyFolder *folder = NULL;
766 gchar *from_str = NULL, *signature = NULL, *body = NULL;
767 gboolean use_signature = FALSE;
768 ModestWindow *msg_win = NULL;
769 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
770 ModestTnyAccountStore *store = modest_runtime_get_account_store();
772 if (win) account_name = g_strdup (modest_window_get_active_account (win));
773 if (!account_name) account_name = modest_account_mgr_get_default_account(mgr);
775 g_printerr ("modest: no account found\n");
778 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
780 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
783 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
785 g_printerr ("modest: failed to find Drafts folder\n");
788 from_str = modest_account_mgr_get_from_string (mgr, account_name);
790 g_printerr ("modest: failed get from string for '%s'\n", account_name);
794 signature = modest_account_mgr_get_signature (mgr, account_name, &use_signature);
795 if (body_str != NULL) {
796 body = use_signature ? g_strconcat(body_str, "\n", signature, NULL) : g_strdup(body_str);
798 body = use_signature ? g_strconcat("\n", signature, NULL) : g_strdup("");
801 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, body, NULL);
803 g_printerr ("modest: failed to create new msg\n");
807 /* Create and register edit window */
808 /* This is destroyed by TODO. */
809 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
810 while (attachments) {
811 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
813 attachments = g_slist_next(attachments);
815 modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win);
818 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
821 gtk_widget_show_all (GTK_WIDGET (msg_win));
827 g_free (account_name);
828 if (account) g_object_unref (G_OBJECT(account));
829 if (folder) g_object_unref (G_OBJECT(folder));
830 if (msg_win) g_object_unref (G_OBJECT(msg_win));
831 if (msg) g_object_unref (G_OBJECT(msg));
835 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
837 /* if there are no accounts yet, just show the wizard */
838 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
839 if (!modest_ui_actions_run_account_setup_wizard (win)) return;
842 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL);
846 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
850 ModestMailOperationStatus status;
852 /* If there is no message or the operation was not successful */
853 status = modest_mail_operation_get_status (mail_op);
854 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
856 /* Remove the header from the preregistered uids */
857 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
867 open_msg_cb (ModestMailOperation *mail_op, TnyHeader *header, TnyMsg *msg, gpointer user_data)
869 ModestWindowMgr *mgr = NULL;
870 ModestWindow *parent_win = NULL;
871 ModestWindow *win = NULL;
872 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
873 gchar *account = NULL;
875 gboolean open_in_editor = FALSE;
877 /* Do nothing if there was any problem with the mail
878 operation. The error will be shown by the error_handler of
879 the mail operation */
880 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
883 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
884 folder = tny_header_get_folder (header);
886 /* Mark header as read */
887 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
889 /* Gets folder type (OUTBOX headers will be opened in edit window */
890 if (modest_tny_folder_is_local_folder (folder)) {
891 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
892 if (folder_type == TNY_FOLDER_TYPE_INVALID)
893 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
897 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
898 TnyTransportAccount *traccount = NULL;
899 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
900 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
902 ModestTnySendQueue *send_queue = NULL;
903 ModestTnySendQueueStatus status;
905 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
906 TNY_ACCOUNT(traccount)));
907 send_queue = modest_runtime_get_send_queue(traccount);
908 msg_id = modest_tny_send_queue_get_msg_id (header);
909 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
910 /* Only open messages in outbox with the editor if they are in Failed state */
911 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
912 open_in_editor = TRUE;
915 g_object_unref(traccount);
917 g_warning("Cannot get transport account for message in outbox!!");
919 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
920 open_in_editor = TRUE; /* Open in editor if the message is in the Drafts folder */
925 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
927 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
929 if (open_in_editor) {
930 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
931 const gchar *from_header = NULL;
933 from_header = tny_header_get_from (header);
935 /* we cannot edit without a valid account... */
936 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
937 if (!modest_ui_actions_run_account_setup_wizard(parent_win))
942 GSList *accounts = modest_account_mgr_account_names (mgr, TRUE);
944 for (node = accounts; node != NULL; node = g_slist_next (node)) {
945 gchar *from = modest_account_mgr_get_from_string (mgr, node->data);
947 if (from && (strcmp (from_header, from) == 0)) {
949 account = g_strdup (node->data);
955 g_slist_foreach (accounts, (GFunc) g_free, NULL);
956 g_slist_free (accounts);
959 win = modest_msg_edit_window_new (msg, account, TRUE);
963 modest_platform_information_banner (NULL, NULL, _("mail_ib_opening_draft_message"));
966 gchar *uid = modest_tny_folder_get_header_unique_id (header);
968 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
969 GtkWidget *header_view;
970 GtkTreeSelection *sel;
971 GList *sel_list = NULL;
974 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
975 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
977 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
978 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
980 if (sel_list != NULL) {
981 GtkTreeRowReference *row_reference;
983 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
984 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
985 g_list_free (sel_list);
987 win = modest_msg_view_window_new_with_header_model (
988 msg, account, (const gchar*) uid,
989 model, row_reference);
990 gtk_tree_row_reference_free (row_reference);
992 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
995 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
1000 /* Register and show new window */
1002 mgr = modest_runtime_get_window_mgr ();
1003 modest_window_mgr_register_window (mgr, win);
1004 g_object_unref (win);
1005 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
1006 gtk_widget_show_all (GTK_WIDGET(win));
1009 /* Update toolbar dimming state */
1010 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1011 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1017 g_object_unref (parent_win);
1018 g_object_unref (folder);
1023 open_msg_error_handler (ModestMailOperation *mail_op,
1026 /* Show the message error */
1027 GObject *win = modest_mail_operation_get_source (mail_op);
1029 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1030 (gchar *) user_data);
1032 g_object_unref (win);
1036 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
1039 const GError *error;
1040 GObject *win = modest_mail_operation_get_source (mail_op);
1042 error = modest_mail_operation_get_error (mail_op);
1044 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
1046 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1049 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1050 _("mail_ni_ui_folder_get_msg_folder_error"));
1054 g_object_unref (win);
1058 * Returns the account a list of headers belongs to. It returns a
1059 * *new* reference so don't forget to unref it
1062 get_account_from_header_list (TnyList *headers)
1064 TnyAccount *account = NULL;
1066 if (tny_list_get_length (headers) > 0) {
1067 TnyIterator *iter = tny_list_create_iterator (headers);
1068 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1069 TnyFolder *folder = tny_header_get_folder (header);
1070 account = tny_folder_get_account (folder);
1071 g_object_unref (folder);
1072 g_object_unref (header);
1073 g_object_unref (iter);
1079 * This function is used by both modest_ui_actions_on_open and
1080 * modest_ui_actions_on_header_activated. This way we always do the
1081 * same when trying to open messages.
1084 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
1086 ModestWindowMgr *mgr = NULL;
1087 TnyIterator *iter = NULL, *iter_not_opened = NULL;
1088 ModestMailOperation *mail_op = NULL;
1089 TnyList *not_opened_headers = NULL;
1090 TnyHeaderFlags flags = 0;
1091 TnyAccount *account;
1093 g_return_if_fail (headers != NULL);
1095 /* Check that only one message is selected for opening */
1096 if (tny_list_get_length (headers) != 1) {
1097 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1098 _("mcen_ib_select_one_message"));
1102 mgr = modest_runtime_get_window_mgr ();
1103 iter = tny_list_create_iterator (headers);
1105 /* Get the account */
1106 account = get_account_from_header_list (headers);
1108 /* Look if we already have a message view for each header. If
1109 true, then remove the header from the list of headers to
1111 not_opened_headers = tny_simple_list_new ();
1112 while (!tny_iterator_is_done (iter)) {
1114 ModestWindow *window = NULL;
1115 TnyHeader *header = NULL;
1116 gboolean found = FALSE;
1118 header = TNY_HEADER (tny_iterator_get_current (iter));
1120 flags = tny_header_get_flags (header);
1123 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1125 /* Do not open again the message and present the
1126 window to the user */
1129 gtk_window_present (GTK_WINDOW (window));
1131 /* the header has been registered already, we don't do
1132 * anything but wait for the window to come up*/
1133 g_debug ("header %p already registered, waiting for window", header);
1135 tny_list_append (not_opened_headers, G_OBJECT (header));
1139 g_object_unref (header);
1141 tny_iterator_next (iter);
1143 g_object_unref (iter);
1146 /* Open each message */
1147 if (tny_list_get_length (not_opened_headers) == 0)
1150 /* If some messages would have to be downloaded, ask the user to
1151 * make a connection. It's generally easier to do this here (in the mainloop)
1152 * than later in a thread:
1154 if (tny_list_get_length (not_opened_headers) > 0) {
1156 gboolean found = FALSE;
1158 iter = tny_list_create_iterator (not_opened_headers);
1159 while (!tny_iterator_is_done (iter) && !found) {
1160 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1161 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1164 tny_iterator_next (iter);
1166 g_object_unref (header);
1168 g_object_unref (iter);
1170 /* Ask the user if there are any uncached messages */
1171 if (found && !connect_to_get_msg (win,
1172 header_list_count_uncached_msgs (not_opened_headers),
1177 /* Register the headers before actually creating the windows: */
1178 iter_not_opened = tny_list_create_iterator (not_opened_headers);
1179 while (!tny_iterator_is_done (iter_not_opened)) {
1180 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1182 modest_window_mgr_register_header (mgr, header, NULL);
1183 g_object_unref (header);
1185 tny_iterator_next (iter_not_opened);
1187 g_object_unref (iter_not_opened);
1188 iter_not_opened = NULL;
1190 /* Create the mail operation */
1191 if (tny_list_get_length (not_opened_headers) > 1) {
1192 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
1193 modest_ui_actions_get_msgs_full_error_handler,
1195 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1197 modest_mail_operation_get_msgs_full (mail_op,
1203 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1204 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1205 const gchar *proto_name;
1207 ModestTransportStoreProtocol proto;
1209 /* Get the error message depending on the protocol */
1210 proto_name = tny_account_get_proto (account);
1211 if (proto_name != NULL) {
1212 proto = modest_protocol_info_get_transport_store_protocol (proto_name);
1214 proto = MODEST_PROTOCOL_STORE_MAILDIR;
1217 if (proto == MODEST_PROTOCOL_STORE_POP) {
1218 error_msg = g_strdup (_("emev_ni_ui_pop3_msg_recv_error"));
1219 } else if (proto == MODEST_PROTOCOL_STORE_IMAP) {
1220 error_msg = g_strdup_printf (_("emev_ni_ui_imap_message_not_available_in_server"),
1221 tny_header_get_subject (header));
1223 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1226 /* Create and call the mail operation */
1227 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
1228 open_msg_error_handler,
1231 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1233 modest_mail_operation_get_msg (mail_op, header, open_msg_cb, NULL);
1235 g_object_unref (header);
1236 g_object_unref (iter);
1238 g_object_unref (mail_op);
1243 g_object_unref (account);
1244 if (not_opened_headers)
1245 g_object_unref (not_opened_headers);
1249 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1254 headers = get_selected_headers (win);
1259 _modest_ui_actions_open (headers, win);
1261 g_object_unref(headers);
1266 free_reply_forward_helper (gpointer data)
1268 ReplyForwardHelper *helper;
1270 helper = (ReplyForwardHelper *) data;
1271 g_free (helper->account_name);
1272 g_slice_free (ReplyForwardHelper, helper);
1276 reply_forward_cb (ModestMailOperation *mail_op, TnyHeader *header, TnyMsg *msg,
1280 ReplyForwardHelper *rf_helper;
1281 ModestWindow *msg_win = NULL;
1282 ModestEditType edit_type;
1284 TnyAccount *account = NULL;
1285 ModestWindowMgr *mgr = NULL;
1286 gchar *signature = NULL;
1287 gboolean use_signature;
1289 /* If there was any error. The mail operation could be NULL,
1290 this means that we already have the message downloaded and
1291 that we didn't do a mail operation to retrieve it */
1292 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1295 g_return_if_fail (user_data != NULL);
1296 rf_helper = (ReplyForwardHelper *) user_data;
1298 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1299 rf_helper->account_name);
1300 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr(),
1301 rf_helper->account_name,
1304 /* Create reply mail */
1305 switch (rf_helper->action) {
1308 modest_tny_msg_create_reply_msg (msg, header, from, signature,
1309 rf_helper->reply_forward_type,
1310 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1312 case ACTION_REPLY_TO_ALL:
1314 modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1315 MODEST_TNY_MSG_REPLY_MODE_ALL);
1316 edit_type = MODEST_EDIT_TYPE_REPLY;
1318 case ACTION_FORWARD:
1320 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1321 edit_type = MODEST_EDIT_TYPE_FORWARD;
1324 g_return_if_reached ();
1331 g_printerr ("modest: failed to create message\n");
1335 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1336 rf_helper->account_name,
1337 TNY_ACCOUNT_TYPE_STORE);
1339 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1343 /* Create and register the windows */
1344 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1345 mgr = modest_runtime_get_window_mgr ();
1346 modest_window_mgr_register_window (mgr, msg_win);
1348 if (rf_helper->parent_window != NULL) {
1349 gdouble parent_zoom;
1351 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1352 modest_window_set_zoom (msg_win, parent_zoom);
1355 /* Show edit window */
1356 gtk_widget_show_all (GTK_WIDGET (msg_win));
1360 g_object_unref (msg_win);
1362 g_object_unref (G_OBJECT (new_msg));
1364 g_object_unref (G_OBJECT (account));
1365 /* g_object_unref (msg); */
1366 free_reply_forward_helper (rf_helper);
1369 /* Checks a list of headers. If any of them are not currently
1370 * downloaded (CACHED) then returns TRUE else returns FALSE.
1373 header_list_count_uncached_msgs (TnyList *header_list)
1376 gint uncached_messages = 0;
1378 iter = tny_list_create_iterator (header_list);
1379 while (!tny_iterator_is_done (iter)) {
1382 header = TNY_HEADER (tny_iterator_get_current (iter));
1384 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1385 uncached_messages ++;
1386 g_object_unref (header);
1389 tny_iterator_next (iter);
1391 g_object_unref (iter);
1393 return uncached_messages;
1396 /* Returns FALSE if the user does not want to download the
1397 * messages. Returns TRUE if the user allowed the download.
1400 connect_to_get_msg (ModestWindow *win,
1401 gint num_of_uncached_msgs,
1402 TnyAccount *account)
1404 GtkResponseType response;
1406 /* Allways download if we are online. */
1407 if (tny_device_is_online (modest_runtime_get_device ()))
1410 /* If offline, then ask for user permission to download the messages */
1411 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1412 ngettext("mcen_nc_get_msg",
1414 num_of_uncached_msgs));
1416 if (response == GTK_RESPONSE_CANCEL)
1419 return modest_platform_connect_and_wait(GTK_WINDOW (win), account);
1423 * Common code for the reply and forward actions
1426 reply_forward (ReplyForwardAction action, ModestWindow *win)
1428 ModestMailOperation *mail_op = NULL;
1429 TnyList *header_list = NULL;
1430 ReplyForwardHelper *rf_helper = NULL;
1431 guint reply_forward_type;
1432 gboolean continue_download = TRUE;
1433 gboolean do_retrieve = TRUE;
1435 g_return_if_fail (MODEST_IS_WINDOW(win));
1437 /* we need an account when editing */
1438 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1439 if (!modest_ui_actions_run_account_setup_wizard (win))
1443 header_list = get_selected_headers (win);
1447 reply_forward_type =
1448 modest_conf_get_int (modest_runtime_get_conf (),
1449 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1452 /* check if we need to download msg before asking about it */
1453 do_retrieve = (action == ACTION_FORWARD) ||
1454 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1457 gint num_of_unc_msgs;
1459 /* check that the messages have been previously downloaded */
1460 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
1461 /* If there are any uncached message ask the user
1462 * whether he/she wants to download them. */
1463 if (num_of_unc_msgs) {
1464 TnyAccount *account = get_account_from_header_list (header_list);
1465 continue_download = connect_to_get_msg (win, num_of_unc_msgs, account);
1466 g_object_unref (account);
1470 if (!continue_download) {
1471 g_object_unref (header_list);
1475 /* We assume that we can only select messages of the
1476 same folder and that we reply all of them from the
1477 same account. In fact the interface currently only
1478 allows single selection */
1481 rf_helper = g_slice_new0 (ReplyForwardHelper);
1482 rf_helper->reply_forward_type = reply_forward_type;
1483 rf_helper->action = action;
1484 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1486 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1487 rf_helper->parent_window = GTK_WIDGET (win);
1488 if (!rf_helper->account_name)
1489 rf_helper->account_name =
1490 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1492 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1495 /* Get header and message. Do not free them here, the
1496 reply_forward_cb must do it */
1497 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1498 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1499 if (!msg || !header) {
1501 g_object_unref (msg);
1502 g_printerr ("modest: no message found\n");
1505 reply_forward_cb (NULL, header, msg, rf_helper);
1508 g_object_unref (header);
1513 /* Only reply/forward to one message */
1514 iter = tny_list_create_iterator (header_list);
1515 header = TNY_HEADER (tny_iterator_get_current (iter));
1516 g_object_unref (iter);
1519 /* Retrieve messages */
1522 modest_mail_operation_new_with_error_handling (G_OBJECT(win),
1523 modest_ui_actions_get_msgs_full_error_handler,
1525 modest_mail_operation_queue_add (
1526 modest_runtime_get_mail_operation_queue (), mail_op);
1528 modest_mail_operation_get_msg (mail_op,
1533 g_object_unref(mail_op);
1535 /* we put a ref here to prevent double unref as the reply
1536 * forward callback unrefs the header at its end */
1537 reply_forward_cb (NULL, header, NULL, rf_helper);
1541 g_object_unref (header);
1547 g_object_unref (header_list);
1551 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1553 g_return_if_fail (MODEST_IS_WINDOW(win));
1555 reply_forward (ACTION_REPLY, win);
1559 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1561 g_return_if_fail (MODEST_IS_WINDOW(win));
1563 reply_forward (ACTION_FORWARD, win);
1567 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1569 g_return_if_fail (MODEST_IS_WINDOW(win));
1571 reply_forward (ACTION_REPLY_TO_ALL, win);
1575 modest_ui_actions_on_next (GtkAction *action,
1576 ModestWindow *window)
1578 if (MODEST_IS_MAIN_WINDOW (window)) {
1579 GtkWidget *header_view;
1581 header_view = modest_main_window_get_child_widget (
1582 MODEST_MAIN_WINDOW(window),
1583 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1587 modest_header_view_select_next (
1588 MODEST_HEADER_VIEW(header_view));
1589 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1590 modest_msg_view_window_select_next_message (
1591 MODEST_MSG_VIEW_WINDOW (window));
1593 g_return_if_reached ();
1598 modest_ui_actions_on_prev (GtkAction *action,
1599 ModestWindow *window)
1601 g_return_if_fail (MODEST_IS_WINDOW(window));
1603 if (MODEST_IS_MAIN_WINDOW (window)) {
1604 GtkWidget *header_view;
1605 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1606 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1610 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1611 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1612 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1614 g_return_if_reached ();
1619 modest_ui_actions_on_sort (GtkAction *action,
1620 ModestWindow *window)
1622 g_return_if_fail (MODEST_IS_WINDOW(window));
1624 if (MODEST_IS_MAIN_WINDOW (window)) {
1625 GtkWidget *header_view;
1626 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1627 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1629 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1634 /* Show sorting dialog */
1635 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1640 new_messages_arrived (ModestMailOperation *self,
1641 TnyList *new_headers,
1644 /* Notify new messages have been downloaded */
1645 if ((new_headers != NULL) && (tny_list_get_length (new_headers) > 0))
1646 modest_platform_on_new_headers_received (new_headers);
1650 * This function performs the send & receive required actions. The
1651 * window is used to create the mail operation. Typically it should
1652 * always be the main window, but we pass it as argument in order to
1656 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1658 gchar *acc_name = NULL;
1659 ModestMailOperation *mail_op;
1660 TnyAccount *store_account = NULL;
1662 /* If no account name was provided then get the current account, and if
1663 there is no current account then pick the default one: */
1664 if (!account_name) {
1665 acc_name = g_strdup (modest_window_get_active_account(win));
1667 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1669 g_printerr ("modest: cannot get default account\n");
1673 acc_name = g_strdup (account_name);
1677 /* Ensure that we have a connection available */
1679 modest_tny_account_store_get_server_account (modest_runtime_get_account_store (),
1681 TNY_ACCOUNT_TYPE_STORE);
1682 if (!modest_platform_connect_and_wait (NULL, TNY_ACCOUNT (store_account))) {
1683 g_object_unref (store_account);
1686 g_object_unref (store_account);
1688 /* Set send/receive operation in progress */
1689 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1691 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
1692 modest_ui_actions_send_receive_error_handler,
1695 g_signal_connect (G_OBJECT(mail_op), "operation-finished",
1696 G_CALLBACK (on_send_receive_finished),
1699 /* Send & receive. */
1700 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1701 /* Receive and then send. The operation is tagged initially as
1702 a receive operation because the account update performs a
1703 receive and then a send. The operation changes its type
1704 internally, so the progress objects will receive the proper
1705 progress information */
1706 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1707 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, win);
1708 g_object_unref (G_OBJECT (mail_op));
1716 modest_ui_actions_do_cancel_send (const gchar *account_name,
1719 TnyTransportAccount *transport_account;
1720 TnySendQueue *send_queue = NULL;
1721 GError *error = NULL;
1723 /* Get transport account */
1725 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1726 (modest_runtime_get_account_store(),
1728 TNY_ACCOUNT_TYPE_TRANSPORT));
1729 if (!transport_account) {
1730 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1735 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1736 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1737 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1738 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1739 "modest: could not find send queue for account\n");
1741 /* Keeep messages in outbox folder */
1742 tny_send_queue_cancel (send_queue, FALSE, &error);
1746 if (transport_account != NULL)
1747 g_object_unref (G_OBJECT (transport_account));
1751 modest_ui_actions_cancel_send_all (ModestWindow *win)
1753 GSList *account_names, *iter;
1755 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1758 iter = account_names;
1760 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1761 iter = g_slist_next (iter);
1764 modest_account_mgr_free_account_names (account_names);
1765 account_names = NULL;
1769 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1772 /* Check if accounts exist */
1773 gboolean accounts_exist =
1774 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1776 /* If not, allow the user to create an account before trying to send/receive. */
1777 if (!accounts_exist)
1778 modest_ui_actions_on_accounts (NULL, win);
1780 /* Cancel all sending operaitons */
1781 modest_ui_actions_cancel_send_all (win);
1785 * Refreshes all accounts. This function will be used by automatic
1789 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1791 GSList *account_names, *iter;
1793 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1796 iter = account_names;
1798 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1799 iter = g_slist_next (iter);
1802 modest_account_mgr_free_account_names (account_names);
1803 account_names = NULL;
1807 refresh_current_folder(ModestWindow *win)
1809 /* Refresh currently selected folder. Note that if we only
1810 want to retreive the headers, then the refresh only will
1811 invoke a poke_status over all folders, i.e., only the
1812 total/unread count will be updated */
1813 if (MODEST_IS_MAIN_WINDOW (win)) {
1814 GtkWidget *header_view, *folder_view;
1815 TnyFolderStore *folder_store;
1817 /* Get folder and header view */
1819 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1820 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1824 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1826 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1828 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1829 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1831 /* We do not need to set the contents style
1832 because it hasn't changed. We also do not
1833 need to save the widget status. Just force
1835 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1836 TNY_FOLDER (folder_store),
1837 folder_refreshed_cb,
1838 MODEST_MAIN_WINDOW (win));
1842 g_object_unref (folder_store);
1848 * Handler of the click on Send&Receive button in the main toolbar
1851 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1853 /* Check if accounts exist */
1854 gboolean accounts_exist =
1855 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1857 /* If not, allow the user to create an account before trying to send/receive. */
1858 if (!accounts_exist)
1859 modest_ui_actions_on_accounts (NULL, win);
1861 /* Refresh the current folder if we're viewing a window */
1863 refresh_current_folder (win);
1865 /* Refresh the active account */
1866 modest_ui_actions_do_send_receive (NULL, win);
1871 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1874 GtkWidget *header_view;
1876 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1878 header_view = modest_main_window_get_child_widget (main_window,
1879 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1883 conf = modest_runtime_get_conf ();
1885 /* what is saved/restored is depending on the style; thus; we save with
1886 * old style, then update the style, and restore for this new style
1888 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1890 if (modest_header_view_get_style
1891 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1892 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1893 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1895 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1896 MODEST_HEADER_VIEW_STYLE_DETAILS);
1898 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1899 MODEST_CONF_HEADER_VIEW_KEY);
1904 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1906 ModestMainWindow *main_window)
1908 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1909 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1911 /* in the case the folder is empty, show the empty folder message and focus
1913 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1914 if (modest_header_view_is_empty (header_view)) {
1915 TnyFolder *folder = modest_header_view_get_folder (header_view);
1916 GtkWidget *folder_view =
1917 modest_main_window_get_child_widget (main_window,
1918 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1920 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1921 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1925 /* If no header has been selected then exit */
1930 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1931 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1933 /* Update toolbar dimming state */
1934 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1938 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1940 ModestMainWindow *main_window)
1944 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1949 if (modest_header_view_count_selected_headers (header_view) > 1) {
1950 hildon_banner_show_information (NULL, NULL, _("mcen_ib_select_one_message"));
1955 /* headers = tny_simple_list_new (); */
1956 /* tny_list_prepend (headers, G_OBJECT (header)); */
1957 headers = modest_header_view_get_selected_headers (header_view);
1959 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1961 g_object_unref (headers);
1965 set_active_account_from_tny_account (TnyAccount *account,
1966 ModestWindow *window)
1968 const gchar *server_acc_name = tny_account_get_id (account);
1970 /* We need the TnyAccount provided by the
1971 account store because that is the one that
1972 knows the name of the Modest account */
1973 TnyAccount *modest_server_account = modest_server_account =
1974 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1975 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1977 if (!modest_server_account) {
1978 g_warning ("%s: could not get tny account\n", __FUNCTION__);
1982 /* Update active account, but only if it's not a pseudo-account */
1983 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
1984 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
1985 const gchar *modest_acc_name =
1986 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1987 if (modest_acc_name)
1988 modest_window_set_active_account (window, modest_acc_name);
1991 g_object_unref (modest_server_account);
1996 folder_refreshed_cb (ModestMailOperation *mail_op,
2000 ModestMainWindow *win = NULL;
2001 GtkWidget *header_view;
2002 gboolean folder_empty = FALSE;
2003 gboolean all_marked_as_deleted = FALSE;
2005 g_return_if_fail (TNY_IS_FOLDER (folder));
2007 win = MODEST_MAIN_WINDOW (user_data);
2009 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2012 TnyFolder *current_folder;
2014 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
2015 if (current_folder != NULL && folder != current_folder) {
2016 g_object_unref (current_folder);
2019 g_object_unref (current_folder);
2022 /* Check if folder is empty and set headers view contents style */
2023 folder_empty = (tny_folder_get_all_count (folder) == 0);
2024 all_marked_as_deleted = modest_header_view_is_empty (MODEST_HEADER_VIEW(header_view));
2025 if (folder_empty || all_marked_as_deleted)
2026 modest_main_window_set_contents_style (win,
2027 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2031 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2032 TnyFolderStore *folder_store,
2034 ModestMainWindow *main_window)
2037 GtkWidget *header_view;
2039 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2041 header_view = modest_main_window_get_child_widget(main_window,
2042 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2046 conf = modest_runtime_get_conf ();
2048 if (TNY_IS_ACCOUNT (folder_store)) {
2050 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2052 /* Show account details */
2053 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2056 if (TNY_IS_FOLDER (folder_store) && selected) {
2058 /* Update the active account */
2059 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2061 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2062 g_object_unref (account);
2066 /* Set the header style by default, it could
2067 be changed later by the refresh callback to
2069 modest_main_window_set_contents_style (main_window,
2070 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2072 /* Set folder on header view. This function
2073 will call tny_folder_refresh_async so we
2074 pass a callback that will be called when
2075 finished. We use that callback to set the
2076 empty view if there are no messages */
2077 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2078 TNY_FOLDER (folder_store),
2079 folder_refreshed_cb,
2082 /* Restore configuration. We need to do this
2083 *after* the set_folder because the widget
2084 memory asks the header view about its
2086 modest_widget_memory_restore (modest_runtime_get_conf (),
2087 G_OBJECT(header_view),
2088 MODEST_CONF_HEADER_VIEW_KEY);
2090 /* Update the active account */
2091 //modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
2092 /* Save only if we're seeing headers */
2093 if (modest_main_window_get_contents_style (main_window) ==
2094 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2095 modest_widget_memory_save (conf, G_OBJECT (header_view),
2096 MODEST_CONF_HEADER_VIEW_KEY);
2097 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2101 /* Update toolbar dimming state */
2102 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2106 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2113 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2115 online = tny_device_is_online (modest_runtime_get_device());
2118 /* already online -- the item is simply not there... */
2119 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2121 GTK_MESSAGE_WARNING,
2123 _("The %s you selected cannot be found"),
2125 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2126 gtk_dialog_run (GTK_DIALOG(dialog));
2128 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2131 _("mcen_bd_dialog_cancel"),
2132 GTK_RESPONSE_REJECT,
2133 _("mcen_bd_dialog_ok"),
2134 GTK_RESPONSE_ACCEPT,
2136 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2137 "Do you want to get online?"), item);
2138 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2139 gtk_label_new (txt), FALSE, FALSE, 0);
2140 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2143 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2144 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2145 /* TODO: Comment about why is this commented out: */
2146 /* modest_platform_connect_and_wait (); */
2149 gtk_widget_destroy (dialog);
2153 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2156 /* g_message ("%s %s", __FUNCTION__, link); */
2161 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2164 modest_platform_activate_uri (link);
2168 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2171 modest_platform_show_uri_popup (link);
2175 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2178 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2182 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2183 const gchar *address,
2186 /* g_message ("%s %s", __FUNCTION__, address); */
2190 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2191 TnyMsg *saved_draft,
2194 ModestMsgEditWindow *edit_window;
2196 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2198 /* If there was any error do nothing */
2199 if (modest_mail_operation_get_error (mail_op) != NULL)
2202 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2206 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2208 TnyTransportAccount *transport_account;
2209 ModestMailOperation *mail_operation;
2211 gchar *account_name, *from;
2212 ModestAccountMgr *account_mgr;
2213 gchar *info_text = NULL;
2215 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2217 data = modest_msg_edit_window_get_msg_data (edit_window);
2219 account_name = g_strdup (data->account_name);
2220 account_mgr = modest_runtime_get_account_mgr();
2222 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2224 account_name = modest_account_mgr_get_default_account (account_mgr);
2225 if (!account_name) {
2226 g_printerr ("modest: no account found\n");
2227 modest_msg_edit_window_free_msg_data (edit_window, data);
2231 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2232 account_name = g_strdup (data->account_name);
2236 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2237 (modest_runtime_get_account_store(),
2239 TNY_ACCOUNT_TYPE_TRANSPORT));
2240 if (!transport_account) {
2241 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2242 g_free (account_name);
2243 modest_msg_edit_window_free_msg_data (edit_window, data);
2246 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2248 /* Create the mail operation */
2249 mail_operation = modest_mail_operation_new (G_OBJECT(edit_window));
2250 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2252 modest_mail_operation_save_to_drafts (mail_operation,
2264 data->priority_flags,
2265 on_save_to_drafts_cb,
2269 g_free (account_name);
2270 g_object_unref (G_OBJECT (transport_account));
2271 g_object_unref (G_OBJECT (mail_operation));
2273 modest_msg_edit_window_free_msg_data (edit_window, data);
2275 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2276 modest_platform_information_banner (NULL, NULL, info_text);
2277 modest_msg_edit_window_reset_modified (edit_window);
2281 /* For instance, when clicking the Send toolbar button when editing a message: */
2283 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2285 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2287 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2290 /* FIXME: Code added just for testing. The final version will
2291 use the send queue provided by tinymail and some
2293 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2295 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2296 gchar *account_name = g_strdup (data->account_name);
2298 g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2301 account_name = modest_account_mgr_get_default_account (account_mgr);
2303 if (!account_name) {
2304 modest_msg_edit_window_free_msg_data (edit_window, data);
2305 /* Run account setup wizard */
2306 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window)))
2310 /* Get the currently-active transport account for this modest account: */
2311 TnyTransportAccount *transport_account =
2312 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2313 (modest_runtime_get_account_store(),
2315 if (!transport_account) {
2316 /* Run account setup wizard */
2317 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2321 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2323 /* Create the mail operation */
2324 ModestMailOperation *mail_operation = modest_mail_operation_new (G_OBJECT(edit_window));
2325 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2327 modest_mail_operation_send_new_mail (mail_operation,
2339 data->priority_flags);
2343 g_free (account_name);
2344 g_object_unref (G_OBJECT (transport_account));
2345 g_object_unref (G_OBJECT (mail_operation));
2347 modest_msg_edit_window_free_msg_data (edit_window, data);
2348 modest_msg_edit_window_set_sent (edit_window, TRUE);
2350 /* Save settings and close the window: */
2351 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2355 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2356 ModestMsgEditWindow *window)
2358 ModestMsgEditFormatState *format_state = NULL;
2360 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2361 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2363 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2366 format_state = modest_msg_edit_window_get_format_state (window);
2367 g_return_if_fail (format_state != NULL);
2369 format_state->bold = gtk_toggle_action_get_active (action);
2370 modest_msg_edit_window_set_format_state (window, format_state);
2371 g_free (format_state);
2376 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2377 ModestMsgEditWindow *window)
2379 ModestMsgEditFormatState *format_state = NULL;
2381 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2382 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2384 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2387 format_state = modest_msg_edit_window_get_format_state (window);
2388 g_return_if_fail (format_state != NULL);
2390 format_state->italics = gtk_toggle_action_get_active (action);
2391 modest_msg_edit_window_set_format_state (window, format_state);
2392 g_free (format_state);
2397 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2398 ModestMsgEditWindow *window)
2400 ModestMsgEditFormatState *format_state = NULL;
2402 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2403 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2405 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2408 format_state = modest_msg_edit_window_get_format_state (window);
2409 g_return_if_fail (format_state != NULL);
2411 format_state->bullet = gtk_toggle_action_get_active (action);
2412 modest_msg_edit_window_set_format_state (window, format_state);
2413 g_free (format_state);
2418 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2419 GtkRadioAction *selected,
2420 ModestMsgEditWindow *window)
2422 ModestMsgEditFormatState *format_state = NULL;
2423 GtkJustification value;
2425 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2427 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2430 value = gtk_radio_action_get_current_value (selected);
2432 format_state = modest_msg_edit_window_get_format_state (window);
2433 g_return_if_fail (format_state != NULL);
2435 format_state->justification = value;
2436 modest_msg_edit_window_set_format_state (window, format_state);
2437 g_free (format_state);
2441 modest_ui_actions_on_select_editor_color (GtkAction *action,
2442 ModestMsgEditWindow *window)
2444 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2445 g_return_if_fail (GTK_IS_ACTION (action));
2447 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2450 modest_msg_edit_window_select_color (window);
2454 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2455 ModestMsgEditWindow *window)
2457 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2458 g_return_if_fail (GTK_IS_ACTION (action));
2460 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2463 modest_msg_edit_window_select_background_color (window);
2467 modest_ui_actions_on_insert_image (GtkAction *action,
2468 ModestMsgEditWindow *window)
2470 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2471 g_return_if_fail (GTK_IS_ACTION (action));
2473 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2476 modest_msg_edit_window_insert_image (window);
2480 modest_ui_actions_on_attach_file (GtkAction *action,
2481 ModestMsgEditWindow *window)
2483 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2484 g_return_if_fail (GTK_IS_ACTION (action));
2486 modest_msg_edit_window_offer_attach_file (window);
2490 modest_ui_actions_on_remove_attachments (GtkAction *action,
2491 ModestMsgEditWindow *window)
2493 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2494 g_return_if_fail (GTK_IS_ACTION (action));
2496 modest_msg_edit_window_remove_attachments (window, NULL);
2500 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2503 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2504 const GError *error = modest_mail_operation_get_error (mail_op);
2507 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2508 _("mail_in_ui_folder_create_error"));
2513 modest_ui_actions_create_folder(GtkWidget *parent_window,
2514 GtkWidget *folder_view)
2516 TnyFolderStore *parent_folder;
2518 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2520 if (parent_folder) {
2521 gboolean finished = FALSE;
2523 gchar *folder_name = NULL, *suggested_name = NULL;
2524 const gchar *proto_str = NULL;
2525 TnyAccount *account;
2527 if (TNY_IS_ACCOUNT (parent_folder))
2528 account = g_object_ref (parent_folder);
2530 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2531 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2533 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2534 MODEST_PROTOCOL_STORE_POP) {
2536 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2538 g_object_unref (account);
2540 /* Run the new folder dialog */
2542 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2547 g_free (suggested_name);
2548 suggested_name = NULL;
2550 if (result == GTK_RESPONSE_ACCEPT) {
2551 ModestMailOperation *mail_op;
2552 TnyFolder *new_folder = NULL;
2554 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
2555 modest_ui_actions_new_folder_error_handler,
2556 parent_window, NULL);
2558 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2560 new_folder = modest_mail_operation_create_folder (mail_op,
2562 (const gchar *) folder_name);
2564 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2567 g_object_unref (new_folder);
2570 g_object_unref (mail_op);
2575 suggested_name = folder_name;
2579 g_object_unref (parent_folder);
2584 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2586 GtkWidget *folder_view;
2588 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2590 folder_view = modest_main_window_get_child_widget (main_window,
2591 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2595 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2599 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2602 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2603 const GError *error = NULL;
2604 const gchar *message = NULL;
2606 /* Get error message */
2607 error = modest_mail_operation_get_error (mail_op);
2609 g_return_if_reached ();
2611 switch (error->code) {
2612 case MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS:
2613 message = _CS("ckdg_ib_folder_already_exists");
2616 g_warning ("%s: BUG: unexpected error:[%d]: %s", __FUNCTION__,
2617 error->code, error->message);
2621 modest_platform_information_banner (GTK_WIDGET (window), NULL, message);
2625 modest_ui_actions_on_rename_folder (GtkAction *action,
2626 ModestMainWindow *main_window)
2628 TnyFolderStore *folder;
2629 GtkWidget *folder_view;
2630 GtkWidget *header_view;
2632 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2634 folder_view = modest_main_window_get_child_widget (main_window,
2635 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2639 header_view = modest_main_window_get_child_widget (main_window,
2640 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2645 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2650 if (TNY_IS_FOLDER (folder)) {
2653 const gchar *current_name;
2654 TnyFolderStore *parent;
2655 gboolean do_rename = TRUE;
2657 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2658 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
2659 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
2660 parent, current_name,
2662 g_object_unref (parent);
2664 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
2666 } else if (modest_platform_is_network_folderstore(folder) &&
2667 !tny_device_is_online (modest_runtime_get_device())) {
2668 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2669 do_rename = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2670 g_object_unref(account);
2674 ModestMailOperation *mail_op;
2675 GtkTreeSelection *sel = NULL;
2678 modest_mail_operation_new_with_error_handling (G_OBJECT(main_window),
2679 modest_ui_actions_rename_folder_error_handler,
2682 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2685 /* Clear the headers view */
2686 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2687 gtk_tree_selection_unselect_all (sel);
2689 /* Select *after* the changes */
2690 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2691 TNY_FOLDER(folder), TRUE);
2693 /* Actually rename the folder */
2694 modest_mail_operation_rename_folder (mail_op,
2695 TNY_FOLDER (folder),
2696 (const gchar *) folder_name);
2698 g_object_unref (mail_op);
2699 g_free (folder_name);
2702 g_object_unref (folder);
2706 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2709 GObject *win = modest_mail_operation_get_source (mail_op);
2711 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2712 _("mail_in_ui_folder_delete_error"));
2713 g_object_unref (win);
2717 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2719 TnyFolderStore *folder;
2720 GtkWidget *folder_view;
2723 gboolean do_delete = TRUE;
2725 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (main_window), FALSE);
2727 folder_view = modest_main_window_get_child_widget (main_window,
2728 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2732 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2734 /* Show an error if it's an account */
2735 if (!TNY_IS_FOLDER (folder)) {
2736 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2737 _("mail_in_ui_folder_delete_error"));
2738 g_object_unref (G_OBJECT (folder));
2743 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2744 tny_folder_get_name (TNY_FOLDER (folder)));
2745 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2746 (const gchar *) message);
2749 if (response != GTK_RESPONSE_OK) {
2751 } else if (modest_platform_is_network_folderstore(folder) &&
2752 !tny_device_is_online (modest_runtime_get_device())) {
2753 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2754 do_delete = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2755 g_object_unref(account);
2759 ModestMailOperation *mail_op;
2760 GtkTreeSelection *sel;
2762 /* Unselect the folder before deleting it to free the headers */
2763 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2764 gtk_tree_selection_unselect_all (sel);
2766 /* Create the mail operation */
2768 modest_mail_operation_new_with_error_handling (G_OBJECT(main_window),
2769 modest_ui_actions_delete_folder_error_handler,
2772 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2774 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2775 g_object_unref (G_OBJECT (mail_op));
2778 g_object_unref (G_OBJECT (folder));
2784 modest_ui_actions_on_delete_folder (GtkAction *action,
2785 ModestMainWindow *main_window)
2787 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2789 if (delete_folder (main_window, FALSE)) {
2790 GtkWidget *folder_view;
2792 folder_view = modest_main_window_get_child_widget (main_window,
2793 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2794 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2799 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2801 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2803 delete_folder (main_window, TRUE);
2808 show_error (GtkWidget *parent_widget, const gchar* text)
2810 hildon_banner_show_information(parent_widget, NULL, text);
2813 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2815 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2822 gtk_dialog_run (dialog);
2823 gtk_widget_destroy (GTK_WIDGET (dialog));
2828 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2829 const gchar* server_account_name,
2834 ModestMainWindow *main_window)
2836 g_return_if_fail(server_account_name);
2837 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2839 /* Initalize output parameters: */
2846 #ifdef MODEST_PLATFORM_MAEMO
2847 /* Maemo uses a different (awkward) button order,
2848 * It should probably just use gtk_alternative_dialog_button_order ().
2850 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2853 _("mcen_bd_dialog_ok"),
2854 GTK_RESPONSE_ACCEPT,
2855 _("mcen_bd_dialog_cancel"),
2856 GTK_RESPONSE_REJECT,
2859 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2863 GTK_RESPONSE_REJECT,
2865 GTK_RESPONSE_ACCEPT,
2867 #endif /* MODEST_PLATFORM_MAEMO */
2869 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2871 gchar *server_name = modest_account_mgr_get_server_account_hostname (
2872 modest_runtime_get_account_mgr(), server_account_name);
2873 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2874 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2879 /* This causes a warning because the logical ID has no %s in it,
2880 * though the translation does, but there is not much we can do about that: */
2881 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2882 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2885 g_free (server_name);
2889 gchar *initial_username = modest_account_mgr_get_server_account_username (
2890 modest_runtime_get_account_mgr(), server_account_name);
2892 GtkWidget *entry_username = gtk_entry_new ();
2893 if (initial_username)
2894 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2895 /* Dim this if a connection has ever succeeded with this username,
2896 * as per the UI spec: */
2897 const gboolean username_known =
2898 modest_account_mgr_get_server_account_username_has_succeeded(
2899 modest_runtime_get_account_mgr(), server_account_name);
2900 gtk_widget_set_sensitive (entry_username, !username_known);
2902 #ifdef MODEST_PLATFORM_MAEMO
2903 /* Auto-capitalization is the default, so let's turn it off: */
2904 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2906 /* Create a size group to be used by all captions.
2907 * Note that HildonCaption does not create a default size group if we do not specify one.
2908 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2909 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2911 GtkWidget *caption = hildon_caption_new (sizegroup,
2912 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2913 gtk_widget_show (entry_username);
2914 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2915 FALSE, FALSE, MODEST_MARGIN_HALF);
2916 gtk_widget_show (caption);
2918 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2920 #endif /* MODEST_PLATFORM_MAEMO */
2923 GtkWidget *entry_password = gtk_entry_new ();
2924 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2925 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2927 #ifdef MODEST_PLATFORM_MAEMO
2928 /* Auto-capitalization is the default, so let's turn it off: */
2929 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2930 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2932 caption = hildon_caption_new (sizegroup,
2933 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2934 gtk_widget_show (entry_password);
2935 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2936 FALSE, FALSE, MODEST_MARGIN_HALF);
2937 gtk_widget_show (caption);
2938 g_object_unref (sizegroup);
2940 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2942 #endif /* MODEST_PLATFORM_MAEMO */
2944 if (initial_username != NULL)
2945 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
2947 /* This is not in the Maemo UI spec:
2948 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2949 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2953 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2955 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2957 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2959 modest_account_mgr_set_server_account_username (
2960 modest_runtime_get_account_mgr(), server_account_name,
2963 const gboolean username_was_changed =
2964 (strcmp (*username, initial_username) != 0);
2965 if (username_was_changed) {
2966 g_warning ("%s: tinymail does not yet support changing the "
2967 "username in the get_password() callback.\n", __FUNCTION__);
2972 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2974 /* We do not save the password in the configuration,
2975 * because this function is only called for passwords that should
2976 * not be remembered:
2977 modest_server_account_set_password (
2978 modest_runtime_get_account_mgr(), server_account_name,
2987 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2999 /* This is not in the Maemo UI spec:
3000 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3006 gtk_widget_destroy (dialog);
3008 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3012 modest_ui_actions_on_cut (GtkAction *action,
3013 ModestWindow *window)
3015 GtkWidget *focused_widget;
3016 GtkClipboard *clipboard;
3018 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3019 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3020 if (GTK_IS_EDITABLE (focused_widget)) {
3021 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3022 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3023 gtk_clipboard_store (clipboard);
3024 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3025 GtkTextBuffer *buffer;
3027 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3028 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3029 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3030 gtk_clipboard_store (clipboard);
3031 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3032 TnyList *header_list = modest_header_view_get_selected_headers (
3033 MODEST_HEADER_VIEW (focused_widget));
3034 gboolean continue_download = FALSE;
3035 gint num_of_unc_msgs;
3037 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3039 if (num_of_unc_msgs) {
3040 TnyAccount *account = get_account_from_header_list (header_list);
3041 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3042 g_object_unref (account);
3045 if (num_of_unc_msgs == 0 || continue_download) {
3046 /* modest_platform_information_banner (
3047 NULL, NULL, _CS("mcen_ib_getting_items"));*/
3048 modest_header_view_cut_selection (
3049 MODEST_HEADER_VIEW (focused_widget));
3052 g_object_unref (header_list);
3053 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3054 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3059 modest_ui_actions_on_copy (GtkAction *action,
3060 ModestWindow *window)
3062 GtkClipboard *clipboard;
3063 GtkWidget *focused_widget;
3064 gboolean copied = TRUE;
3066 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3067 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3069 if (GTK_IS_LABEL (focused_widget)) {
3070 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
3071 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3072 gtk_clipboard_store (clipboard);
3073 } else if (GTK_IS_EDITABLE (focused_widget)) {
3074 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3075 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3076 gtk_clipboard_store (clipboard);
3077 } else if (GTK_IS_HTML (focused_widget)) {
3078 gtk_html_copy (GTK_HTML (focused_widget));
3079 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3080 gtk_clipboard_store (clipboard);
3081 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3082 GtkTextBuffer *buffer;
3083 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3084 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3085 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3086 gtk_clipboard_store (clipboard);
3087 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3088 TnyList *header_list = modest_header_view_get_selected_headers (
3089 MODEST_HEADER_VIEW (focused_widget));
3090 gboolean continue_download = FALSE;
3091 gint num_of_unc_msgs;
3093 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3095 if (num_of_unc_msgs) {
3096 TnyAccount *account = get_account_from_header_list (header_list);
3097 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3098 g_object_unref (account);
3101 if (num_of_unc_msgs == 0 || continue_download) {
3102 modest_platform_information_banner (
3103 NULL, NULL, _CS("mcen_ib_getting_items"));
3104 modest_header_view_copy_selection (
3105 MODEST_HEADER_VIEW (focused_widget));
3109 g_object_unref (header_list);
3111 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3112 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3115 /* Show information banner if there was a copy to clipboard */
3117 modest_platform_information_banner (
3118 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3122 modest_ui_actions_on_undo (GtkAction *action,
3123 ModestWindow *window)
3125 ModestEmailClipboard *clipboard = NULL;
3127 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3128 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3129 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3130 /* Clear clipboard source */
3131 clipboard = modest_runtime_get_email_clipboard ();
3132 modest_email_clipboard_clear (clipboard);
3135 g_return_if_reached ();
3140 modest_ui_actions_on_redo (GtkAction *action,
3141 ModestWindow *window)
3143 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3144 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3147 g_return_if_reached ();
3153 destroy_information_note (ModestMailOperation *mail_op, gpointer user_data)
3155 /* destroy information note */
3156 gtk_widget_destroy (GTK_WIDGET(user_data));
3161 paste_as_attachment_free (gpointer data)
3163 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3165 gtk_widget_destroy (helper->banner);
3166 g_object_unref (helper->banner);
3171 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3176 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3177 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3182 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3187 modest_ui_actions_on_paste (GtkAction *action,
3188 ModestWindow *window)
3190 GtkWidget *focused_widget = NULL;
3191 GtkWidget *inf_note = NULL;
3192 ModestMailOperation *mail_op = NULL;
3194 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3195 if (GTK_IS_EDITABLE (focused_widget)) {
3196 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3197 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3198 ModestEmailClipboard *e_clipboard = NULL;
3199 e_clipboard = modest_runtime_get_email_clipboard ();
3200 if (modest_email_clipboard_cleared (e_clipboard)) {
3201 GtkTextBuffer *buffer;
3202 GtkClipboard *clipboard;
3204 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3205 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3206 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3207 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3208 ModestMailOperation *mail_op;
3209 TnyFolder *src_folder;
3212 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3213 helper->window = MODEST_MSG_EDIT_WINDOW (window);
3214 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3215 _CS("ckct_nw_pasting"));
3216 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
3217 mail_op = modest_mail_operation_new (G_OBJECT (window));
3218 if (helper->banner != NULL) {
3219 g_object_ref (G_OBJECT (helper->banner));
3220 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
3221 gtk_widget_show (GTK_WIDGET (helper->banner));
3225 modest_mail_operation_get_msgs_full (mail_op,
3227 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
3229 paste_as_attachment_free);
3232 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3233 ModestEmailClipboard *clipboard = NULL;
3234 TnyFolder *src_folder = NULL;
3235 TnyFolderStore *folder_store = NULL;
3236 TnyList *data = NULL;
3237 gboolean delete = FALSE;
3239 /* Check clipboard source */
3240 clipboard = modest_runtime_get_email_clipboard ();
3241 if (modest_email_clipboard_cleared (clipboard))
3244 /* Get elements to paste */
3245 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
3247 /* Create a new mail operation */
3248 mail_op = modest_mail_operation_new (G_OBJECT(window));
3250 /* Get destination folder */
3251 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
3253 /* transfer messages */
3257 /* Ask for user confirmation */
3259 modest_ui_actions_msgs_move_to_confirmation (window,
3260 TNY_FOLDER (folder_store),
3264 if (response == GTK_RESPONSE_OK) {
3265 /* Launch notification */
3266 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3267 _CS("ckct_nw_pasting"));
3268 if (inf_note != NULL) {
3269 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3270 gtk_widget_show (GTK_WIDGET(inf_note));
3273 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3274 modest_mail_operation_xfer_msgs (mail_op,
3276 TNY_FOLDER (folder_store),
3278 destroy_information_note,
3281 g_object_unref (mail_op);
3284 } else if (src_folder != NULL) {
3285 /* Launch notification */
3286 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3287 _CS("ckct_nw_pasting"));
3288 if (inf_note != NULL) {
3289 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3290 gtk_widget_show (GTK_WIDGET(inf_note));
3293 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3294 modest_mail_operation_xfer_folder (mail_op,
3298 destroy_information_note,
3304 g_object_unref (data);
3305 if (src_folder != NULL)
3306 g_object_unref (src_folder);
3307 if (folder_store != NULL)
3308 g_object_unref (folder_store);
3314 modest_ui_actions_on_select_all (GtkAction *action,
3315 ModestWindow *window)
3317 GtkWidget *focused_widget;
3319 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3320 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3321 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3322 } else if (GTK_IS_LABEL (focused_widget)) {
3323 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3324 } else if (GTK_IS_EDITABLE (focused_widget)) {
3325 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3326 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3327 GtkTextBuffer *buffer;
3328 GtkTextIter start, end;
3330 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3331 gtk_text_buffer_get_start_iter (buffer, &start);
3332 gtk_text_buffer_get_end_iter (buffer, &end);
3333 gtk_text_buffer_select_range (buffer, &start, &end);
3334 } else if (GTK_IS_HTML (focused_widget)) {
3335 gtk_html_select_all (GTK_HTML (focused_widget));
3336 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3337 GtkWidget *header_view = focused_widget;
3338 GtkTreeSelection *selection = NULL;
3340 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
3341 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3342 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3345 /* Disable window dimming management */
3346 modest_window_disable_dimming (MODEST_WINDOW(window));
3348 /* Select all messages */
3349 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3350 gtk_tree_selection_select_all (selection);
3352 /* Set focuse on header view */
3353 gtk_widget_grab_focus (header_view);
3356 /* Enable window dimming management */
3357 modest_window_enable_dimming (MODEST_WINDOW(window));
3358 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3364 modest_ui_actions_on_mark_as_read (GtkAction *action,
3365 ModestWindow *window)
3367 g_return_if_fail (MODEST_IS_WINDOW(window));
3369 /* Mark each header as read */
3370 do_headers_action (window, headers_action_mark_as_read, NULL);
3374 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3375 ModestWindow *window)
3377 g_return_if_fail (MODEST_IS_WINDOW(window));
3379 /* Mark each header as read */
3380 do_headers_action (window, headers_action_mark_as_unread, NULL);
3384 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3385 GtkRadioAction *selected,
3386 ModestWindow *window)
3390 value = gtk_radio_action_get_current_value (selected);
3391 if (MODEST_IS_WINDOW (window)) {
3392 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3397 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3398 GtkRadioAction *selected,
3399 ModestWindow *window)
3401 TnyHeaderFlags flags;
3402 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3404 flags = gtk_radio_action_get_current_value (selected);
3405 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3409 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3410 GtkRadioAction *selected,
3411 ModestWindow *window)
3415 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3417 file_format = gtk_radio_action_get_current_value (selected);
3418 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3423 modest_ui_actions_on_zoom_plus (GtkAction *action,
3424 ModestWindow *window)
3426 g_return_if_fail (MODEST_IS_WINDOW (window));
3428 modest_window_zoom_plus (MODEST_WINDOW (window));
3432 modest_ui_actions_on_zoom_minus (GtkAction *action,
3433 ModestWindow *window)
3435 g_return_if_fail (MODEST_IS_WINDOW (window));
3437 modest_window_zoom_minus (MODEST_WINDOW (window));
3441 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3442 ModestWindow *window)
3444 ModestWindowMgr *mgr;
3445 gboolean fullscreen, active;
3446 g_return_if_fail (MODEST_IS_WINDOW (window));
3448 mgr = modest_runtime_get_window_mgr ();
3450 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3451 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3453 if (active != fullscreen) {
3454 modest_window_mgr_set_fullscreen_mode (mgr, active);
3455 gtk_window_present (GTK_WINDOW (window));
3460 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3461 ModestWindow *window)
3463 ModestWindowMgr *mgr;
3464 gboolean fullscreen;
3466 g_return_if_fail (MODEST_IS_WINDOW (window));
3468 mgr = modest_runtime_get_window_mgr ();
3469 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3470 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3472 gtk_window_present (GTK_WINDOW (window));
3476 * Used by modest_ui_actions_on_details to call do_headers_action
3479 headers_action_show_details (TnyHeader *header,
3480 ModestWindow *window,
3487 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3490 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3491 gtk_widget_show_all (dialog);
3492 gtk_dialog_run (GTK_DIALOG (dialog));
3494 gtk_widget_destroy (dialog);
3498 * Show the folder details in a ModestDetailsDialog widget
3501 show_folder_details (TnyFolder *folder,
3507 dialog = modest_details_dialog_new_with_folder (window, folder);
3510 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3511 gtk_widget_show_all (dialog);
3512 gtk_dialog_run (GTK_DIALOG (dialog));
3514 gtk_widget_destroy (dialog);
3518 * Show the header details in a ModestDetailsDialog widget
3521 modest_ui_actions_on_details (GtkAction *action,
3524 TnyList * headers_list;
3528 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3531 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3534 g_object_unref (msg);
3536 headers_list = get_selected_headers (win);
3540 iter = tny_list_create_iterator (headers_list);
3542 header = TNY_HEADER (tny_iterator_get_current (iter));
3544 headers_action_show_details (header, win, NULL);
3545 g_object_unref (header);
3548 g_object_unref (iter);
3549 g_object_unref (headers_list);
3551 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3552 GtkWidget *folder_view, *header_view;
3554 /* Check which widget has the focus */
3555 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3556 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3557 if (gtk_widget_is_focus (folder_view)) {
3558 TnyFolderStore *folder_store
3559 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3560 if (!folder_store) {
3561 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3564 /* Show only when it's a folder */
3565 /* This function should not be called for account items,
3566 * because we dim the menu item for them. */
3567 if (TNY_IS_FOLDER (folder_store)) {
3568 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3571 g_object_unref (folder_store);
3574 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3575 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3576 /* Show details of each header */
3577 do_headers_action (win, headers_action_show_details, header_view);
3583 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3584 ModestMsgEditWindow *window)
3586 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3588 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3592 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3593 ModestMsgEditWindow *window)
3595 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3597 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3601 modest_ui_actions_toggle_folders_view (GtkAction *action,
3602 ModestMainWindow *main_window)
3604 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3606 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3607 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3609 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3613 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3614 ModestWindow *window)
3616 gboolean active, fullscreen = FALSE;
3617 ModestWindowMgr *mgr;
3619 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3621 /* Check if we want to toggle the toolbar vuew in fullscreen
3623 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3624 "ViewShowToolbarFullScreen")) {
3628 /* Toggle toolbar */
3629 mgr = modest_runtime_get_window_mgr ();
3630 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
3634 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3635 ModestMsgEditWindow *window)
3637 modest_msg_edit_window_select_font (window);
3641 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3642 const gchar *display_name,
3645 /* Do not change the application name if the widget has not
3646 the focus. This callback could be called even if the folder
3647 view has not the focus, because the handled signal could be
3648 emitted when the folder view is redrawn */
3649 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3651 gtk_window_set_title (window, display_name);
3653 gtk_window_set_title (window, " ");
3658 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3660 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3661 modest_msg_edit_window_select_contacts (window);
3665 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3667 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3668 modest_msg_edit_window_check_names (window, FALSE);
3672 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3674 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3675 GTK_WIDGET (user_data));
3679 * This function is used to track changes in the selection of the
3680 * folder view that is inside the "move to" dialog to enable/disable
3681 * the OK button because we do not want the user to select a disallowed
3682 * destination for a folder.
3683 * The user also not desired to be able to use NEW button on items where
3684 * folder creation is not possibel.
3687 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
3688 TnyFolderStore *folder_store,
3692 GtkWidget *dialog = NULL;
3693 GtkWidget *ok_button = NULL, *new_button = NULL;
3694 GList *children = NULL;
3695 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
3696 gboolean moving_folder = FALSE;
3697 gboolean is_local_account = TRUE;
3698 GtkWidget *folder_view = NULL;
3699 ModestTnyFolderRules rules;
3704 /* Get the OK button */
3705 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
3709 children = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
3710 ok_button = GTK_WIDGET (children->next->next->data);
3711 new_button = GTK_WIDGET (children->next->data);
3712 g_list_free (children);
3714 /* check if folder_store is an remote account */
3715 if (TNY_IS_ACCOUNT (folder_store)) {
3716 TnyAccount *local_account = NULL;
3717 ModestTnyAccountStore *account_store = NULL;
3719 account_store = modest_runtime_get_account_store ();
3720 local_account = modest_tny_account_store_get_local_folders_account (account_store);
3722 if ((gpointer) local_account != (gpointer) folder_store) {
3723 is_local_account = FALSE;
3724 /* New button should be dimmed on remote
3726 new_sensitive = FALSE;
3728 g_object_unref (local_account);
3731 /* Check the target folder rules */
3732 if (TNY_IS_FOLDER (folder_store)) {
3733 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
3734 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
3735 ok_sensitive = FALSE;
3736 new_sensitive = FALSE;
3741 /* Check if we're moving a folder */
3742 if (MODEST_IS_MAIN_WINDOW (user_data)) {
3743 /* Get the widgets */
3744 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
3745 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3746 if (gtk_widget_is_focus (folder_view))
3747 moving_folder = TRUE;
3750 if (moving_folder) {
3751 TnyFolderStore *moved_folder = NULL, *parent = NULL;
3753 /* Get the folder to move */
3754 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3756 /* Check that we're not moving to the same folder */
3757 if (TNY_IS_FOLDER (moved_folder)) {
3758 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
3759 if (parent == folder_store)
3760 ok_sensitive = FALSE;
3761 g_object_unref (parent);
3764 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
3765 /* Do not allow to move to an account unless it's the
3766 local folders account */
3767 if (!is_local_account)
3768 ok_sensitive = FALSE;
3771 if (ok_sensitive && (moved_folder == folder_store)) {
3772 /* Do not allow to move to itself */
3773 ok_sensitive = FALSE;
3775 g_object_unref (moved_folder);
3777 TnyHeader *header = NULL;
3778 TnyFolder *src_folder = NULL;
3780 /* Moving a message */
3781 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
3782 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (user_data));
3783 src_folder = tny_header_get_folder (header);
3784 g_object_unref (header);
3787 TNY_FOLDER (modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view)));
3790 /* Do not allow to move the msg to the same folder */
3791 /* Do not allow to move the msg to an account */
3792 if ((gpointer) src_folder == (gpointer) folder_store ||
3793 TNY_IS_ACCOUNT (folder_store))
3794 ok_sensitive = FALSE;
3795 g_object_unref (src_folder);
3799 /* Set sensitivity of the OK button */
3800 gtk_widget_set_sensitive (ok_button, ok_sensitive);
3801 /* Set sensitivity of the NEW button */
3802 gtk_widget_set_sensitive (new_button, new_sensitive);
3806 create_move_to_dialog (GtkWindow *win,
3807 GtkWidget *folder_view,
3808 GtkWidget **tree_view)
3810 GtkWidget *dialog, *scroll;
3811 GtkWidget *new_button;
3813 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3815 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3818 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
3819 /* We do this manually so GTK+ does not associate a response ID for
3821 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
3822 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3823 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
3825 /* Create scrolled window */
3826 scroll = gtk_scrolled_window_new (NULL, NULL);
3827 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3828 GTK_POLICY_AUTOMATIC,
3829 GTK_POLICY_AUTOMATIC);
3831 /* Create folder view */
3832 *tree_view = modest_platform_create_folder_view (NULL);
3834 /* Track changes in the selection to
3835 * disable the OK button whenever "Move to" is not possible
3836 * disbale NEW button whenever New is not possible */
3837 g_signal_connect (*tree_view,
3838 "folder_selection_changed",
3839 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
3842 /* Listen to clicks on New button */
3843 g_signal_connect (G_OBJECT (new_button),
3845 G_CALLBACK(create_move_to_dialog_on_new_folder),
3848 /* It could happen that we're trying to move a message from a
3849 window (msg window for example) after the main window was
3850 closed, so we can not just get the model of the folder
3852 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
3853 const gchar *visible_id = NULL;
3855 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
3856 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
3857 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
3858 MODEST_FOLDER_VIEW(*tree_view));
3861 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
3863 /* Show the same account than the one that is shown in the main window */
3864 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
3867 const gchar *active_account_name = NULL;
3868 ModestAccountMgr *mgr = NULL;
3869 ModestAccountData *acc_data = NULL;
3871 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
3872 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
3873 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3874 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3876 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
3877 mgr = modest_runtime_get_account_mgr ();
3878 acc_data = modest_account_mgr_get_account_data (mgr, active_account_name);
3880 /* Set the new visible & active account */
3881 if (acc_data && acc_data->store_account) {
3882 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
3883 acc_data->store_account->account_name);
3884 modest_account_mgr_free_account_data (mgr, acc_data);
3888 /* Hide special folders */
3889 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3891 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3893 /* Add scroll to dialog */
3894 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3895 scroll, TRUE, TRUE, 0);
3897 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3898 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3904 * Returns TRUE if at least one of the headers of the list belongs to
3905 * a message that has been fully retrieved.
3907 #if 0 /* no longer in use. delete in 2007.10 */
3909 has_retrieved_msgs (TnyList *list)
3912 gboolean found = FALSE;
3914 iter = tny_list_create_iterator (list);
3915 while (!tny_iterator_is_done (iter) && !found) {
3917 TnyHeaderFlags flags = 0;
3919 header = TNY_HEADER (tny_iterator_get_current (iter));
3921 flags = tny_header_get_flags (header);
3922 if (flags & TNY_HEADER_FLAG_CACHED)
3923 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3926 g_object_unref (header);
3930 tny_iterator_next (iter);
3932 g_object_unref (iter);
3940 * Shows a confirmation dialog to the user when we're moving messages
3941 * from a remote server to the local storage. Returns the dialog
3942 * response. If it's other kind of movement then it always returns
3945 * This one is used by the next functions:
3946 * modest_ui_actions_on_paste - commented out
3947 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
3950 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
3951 TnyFolder *dest_folder,
3955 gint response = GTK_RESPONSE_OK;
3956 TnyAccount *account = NULL;
3957 TnyFolder *src_folder = NULL;
3958 TnyIterator *iter = NULL;
3959 TnyHeader *header = NULL;
3961 /* return with OK if the destination is a remote folder */
3962 if (modest_tny_folder_is_remote_folder (dest_folder))
3963 return GTK_RESPONSE_OK;
3965 /* Get source folder */
3966 iter = tny_list_create_iterator (headers);
3967 header = TNY_HEADER (tny_iterator_get_current (iter));
3969 src_folder = tny_header_get_folder (header);
3970 g_object_unref (header);
3972 g_object_unref (iter);
3974 /* if no src_folder, message may be an attahcment */
3975 if (src_folder == NULL)
3976 return GTK_RESPONSE_CANCEL;
3978 /* If the source is a local or MMC folder */
3979 if (!modest_tny_folder_is_remote_folder (src_folder)) {
3980 g_object_unref (src_folder);
3981 return GTK_RESPONSE_OK;
3984 /* Get the account */
3985 account = tny_folder_get_account (src_folder);
3987 /* now if offline we ask the user */
3988 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
3989 response = GTK_RESPONSE_OK;
3991 response = GTK_RESPONSE_CANCEL;
3994 g_object_unref (src_folder);
3995 g_object_unref (account);
4003 move_to_cb (ModestMailOperation *mail_op, gpointer user_data)
4005 MoveToHelper *helper = (MoveToHelper *) user_data;
4007 /* Note that the operation could have failed, in that case do
4009 if (modest_mail_operation_get_status (mail_op) ==
4010 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
4012 GObject *object = modest_mail_operation_get_source (mail_op);
4013 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4014 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4016 if (!modest_msg_view_window_select_next_message (self))
4017 if (!modest_msg_view_window_select_previous_message (self))
4018 /* No more messages to view, so close this window */
4019 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4020 } else if (MODEST_IS_MAIN_WINDOW (object) && helper->reference != NULL) {
4021 GtkWidget *header_view;
4023 GtkTreeSelection *sel;
4025 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4026 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4027 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
4028 path = gtk_tree_row_reference_get_path (helper->reference);
4029 gtk_tree_selection_select_path (sel, path);
4030 gtk_tree_path_free (path);
4032 g_object_unref (object);
4035 /* Close the "Pasting" information banner */
4036 gtk_widget_destroy (GTK_WIDGET(helper->banner));
4037 if (helper->reference != NULL)
4038 gtk_tree_row_reference_free (helper->reference);
4043 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
4046 ModestWindow *main_window = NULL;
4047 GtkWidget *folder_view = NULL;
4048 GObject *win = modest_mail_operation_get_source (mail_op);
4049 const GError *error = NULL;
4050 const gchar *message = NULL;
4052 /* Get error message */
4053 error = modest_mail_operation_get_error (mail_op);
4054 if (error != NULL && error->message != NULL) {
4055 message = error->message;
4057 message = _("mail_in_ui_folder_move_target_error");
4060 /* Disable next automatic folder selection */
4061 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
4062 FALSE); /* don't create */
4064 g_warning ("%s: BUG: no main window", __FUNCTION__);
4066 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
4067 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4068 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
4070 if (user_data && TNY_IS_FOLDER (user_data)) {
4071 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
4072 TNY_FOLDER (user_data), FALSE);
4075 /* Show notification dialog */
4076 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
4077 g_object_unref (win);
4081 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
4084 GObject *win = modest_mail_operation_get_source (mail_op);
4085 const GError *error = modest_mail_operation_get_error (mail_op);
4087 g_return_if_fail (error != NULL);
4088 if (error->message != NULL)
4089 g_printerr ("modest: %s\n", error->message);
4091 g_printerr ("modest: unkonw error on send&receive operation");
4093 /* Show error message */
4094 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
4095 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
4096 /* _CS("sfil_ib_unable_to_receive")); */
4098 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
4099 /* _CS("sfil_ib_unable_to_send")); */
4100 g_object_unref (win);
4104 open_msg_for_purge_cb (ModestMailOperation *mail_op,
4111 gint pending_purges = 0;
4112 gboolean some_purged = FALSE;
4113 ModestWindow *win = MODEST_WINDOW (user_data);
4114 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
4116 /* If there was any error */
4117 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
4118 modest_window_mgr_unregister_header (mgr, header);
4122 /* Once the message has been retrieved for purging, we check if
4123 * it's all ok for purging */
4125 parts = tny_simple_list_new ();
4126 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
4127 iter = tny_list_create_iterator (parts);
4129 while (!tny_iterator_is_done (iter)) {
4131 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4132 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
4133 if (tny_mime_part_is_purged (part))
4140 g_object_unref (part);
4142 tny_iterator_next (iter);
4144 g_object_unref (iter);
4147 if (pending_purges>0) {
4149 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
4151 if (response == GTK_RESPONSE_OK) {
4152 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
4153 iter = tny_list_create_iterator (parts);
4154 while (!tny_iterator_is_done (iter)) {
4157 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4158 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
4159 tny_mime_part_set_purged (part);
4162 g_object_unref (part);
4164 tny_iterator_next (iter);
4167 tny_msg_rewrite_cache (msg);
4170 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
4172 g_object_unref (iter);
4174 modest_window_mgr_unregister_header (mgr, header);
4176 g_object_unref (parts);
4180 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
4181 ModestMainWindow *win)
4183 GtkWidget *header_view;
4184 TnyList *header_list;
4187 TnyHeaderFlags flags;
4188 ModestWindow *msg_view_window = NULL;
4191 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4193 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4194 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4196 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
4198 if (tny_list_get_length (header_list) == 1) {
4199 iter = tny_list_create_iterator (header_list);
4200 header = TNY_HEADER (tny_iterator_get_current (iter));
4201 g_object_unref (iter);
4206 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
4207 header, &msg_view_window);
4208 flags = tny_header_get_flags (header);
4209 if (!(flags & TNY_HEADER_FLAG_CACHED))
4212 if (msg_view_window != NULL)
4213 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
4215 /* do nothing; uid was registered before, so window is probably on it's way */
4216 g_warning ("debug: header %p has already been registered", header);
4219 ModestMailOperation *mail_op = NULL;
4220 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
4221 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
4222 modest_ui_actions_get_msgs_full_error_handler,
4224 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4225 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
4227 g_object_unref (mail_op);
4230 g_object_unref (header);
4232 g_object_unref (header_list);
4236 * Utility function that transfer messages from both the main window
4237 * and the msg view window when using the "Move to" dialog
4240 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
4243 TnyList *headers = NULL;
4244 TnyAccount *dst_account = NULL;
4245 const gchar *proto_str = NULL;
4246 gboolean dst_is_pop = FALSE;
4248 if (!TNY_IS_FOLDER (dst_folder)) {
4249 modest_platform_information_banner (GTK_WIDGET (win),
4251 _CS("ckdg_ib_unable_to_move_to_current_location"));
4255 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
4256 proto_str = tny_account_get_proto (dst_account);
4258 /* tinymail will return NULL for local folders it seems */
4259 dst_is_pop = proto_str &&
4260 (modest_protocol_info_get_transport_store_protocol (proto_str) ==
4261 MODEST_PROTOCOL_STORE_POP);
4263 g_object_unref (dst_account);
4265 /* Get selected headers */
4266 headers = get_selected_headers (MODEST_WINDOW (win));
4269 modest_platform_information_banner (GTK_WIDGET (win),
4271 ngettext("mail_in_ui_folder_move_target_error",
4272 "mail_in_ui_folder_move_targets_error",
4273 tny_list_get_length (headers)));
4274 g_object_unref (headers);
4278 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4279 helper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4280 _CS("ckct_nw_pasting"));
4281 if (helper->banner != NULL) {
4282 gtk_window_set_modal (GTK_WINDOW(helper->banner), FALSE);
4283 gtk_widget_show (GTK_WIDGET(helper->banner));
4286 if (MODEST_IS_MAIN_WINDOW (win)) {
4287 GtkWidget *header_view =
4288 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
4289 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4290 helper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
4293 ModestMailOperation *mail_op =
4294 modest_mail_operation_new_with_error_handling (G_OBJECT(win),
4295 modest_ui_actions_move_folder_error_handler,
4297 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4300 modest_mail_operation_xfer_msgs (mail_op,
4302 TNY_FOLDER (dst_folder),
4307 g_object_unref (G_OBJECT (mail_op));
4308 g_object_unref (headers);
4312 * UI handler for the "Move to" action when invoked from the
4316 modest_ui_actions_on_main_window_move_to (GtkAction *action,
4317 GtkWidget *folder_view,
4318 TnyFolderStore *dst_folder,
4319 ModestMainWindow *win)
4321 ModestHeaderView *header_view = NULL;
4322 ModestMailOperation *mail_op = NULL;
4323 TnyFolderStore *src_folder;
4324 gboolean online = (tny_device_is_online (modest_runtime_get_device()));
4326 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4328 /* Get the source folder */
4329 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4331 /* Get header view */
4332 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
4334 /* Get folder or messages to transfer */
4335 if (gtk_widget_is_focus (folder_view)) {
4336 GtkTreeSelection *sel;
4337 gboolean do_xfer = TRUE;
4339 /* Allow only to transfer folders to the local root folder */
4340 if (TNY_IS_ACCOUNT (dst_folder) &&
4341 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder)) {
4343 } else if (!TNY_IS_FOLDER (src_folder)) {
4344 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
4346 } else if (!online && modest_platform_is_network_folderstore(src_folder)) {
4347 guint num_headers = tny_folder_get_all_count(TNY_FOLDER (src_folder));
4348 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (src_folder));
4349 if (!connect_to_get_msg(MODEST_WINDOW (win), num_headers, account))
4351 g_object_unref (account);
4355 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4356 helper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4357 _CS("ckct_nw_pasting"));
4358 if (helper->banner != NULL) {
4359 gtk_window_set_modal (GTK_WINDOW(helper->banner), FALSE);
4360 gtk_widget_show (GTK_WIDGET(helper->banner));
4362 /* Clean folder on header view before moving it */
4363 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
4364 gtk_tree_selection_unselect_all (sel);
4367 modest_mail_operation_new_with_error_handling (G_OBJECT(win),
4368 modest_ui_actions_move_folder_error_handler,
4370 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4373 /* Select *after* the changes */
4374 /* TODO: this function hangs UI after transfer */
4375 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
4376 /* TNY_FOLDER (src_folder), TRUE); */
4378 modest_mail_operation_xfer_folder (mail_op,
4379 TNY_FOLDER (src_folder),
4384 /* Unref mail operation */
4385 g_object_unref (G_OBJECT (mail_op));
4387 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
4388 gboolean do_xfer = TRUE;
4389 /* Ask for confirmation if the source folder is remote and we're not connected */
4390 if (!online && modest_platform_is_network_folderstore(src_folder)) {
4391 TnyList *headers = modest_header_view_get_selected_headers(header_view);
4392 if (!msgs_already_deleted_from_server(headers, src_folder)) {
4393 guint num_headers = tny_list_get_length(headers);
4394 TnyAccount *account = get_account_from_header_list (headers);
4395 if (!connect_to_get_msg(MODEST_WINDOW (win), num_headers, account))
4397 g_object_unref (account);
4399 g_object_unref(headers);
4401 if (do_xfer) /* Transfer messages */
4402 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4406 g_object_unref (src_folder);
4411 * UI handler for the "Move to" action when invoked from the
4412 * ModestMsgViewWindow
4415 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
4416 TnyFolderStore *dst_folder,
4417 ModestMsgViewWindow *win)
4419 TnyHeader *header = NULL;
4420 TnyFolder *src_folder = NULL;
4421 TnyAccount *account = NULL;
4423 /* Create header list */
4424 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
4425 src_folder = TNY_FOLDER (tny_header_get_folder(header));
4426 g_object_unref (header);
4428 /* Transfer the message if online or confirmed by the user */
4429 account = tny_folder_get_account (src_folder);
4430 if (remote_folder_is_pop(TNY_FOLDER_STORE (src_folder)) ||
4431 (modest_platform_is_network_folderstore(TNY_FOLDER_STORE (src_folder)) &&
4432 connect_to_get_msg(MODEST_WINDOW (win), 1, account))) {
4433 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4435 g_object_unref (account);
4436 g_object_unref (src_folder);
4440 modest_ui_actions_on_move_to (GtkAction *action,
4443 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
4445 TnyFolderStore *dst_folder = NULL;
4446 ModestMainWindow *main_window;
4448 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
4449 MODEST_IS_MSG_VIEW_WINDOW (win));
4451 /* Get the main window if exists */
4452 if (MODEST_IS_MAIN_WINDOW (win))
4453 main_window = MODEST_MAIN_WINDOW (win);
4456 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
4457 FALSE)); /* don't create */
4459 /* Get the folder view widget if exists */
4461 folder_view = modest_main_window_get_child_widget (main_window,
4462 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4466 /* Create and run the dialog */
4467 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
4468 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
4469 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4470 result = gtk_dialog_run (GTK_DIALOG(dialog));
4471 g_object_ref (tree_view);
4472 gtk_widget_destroy (dialog);
4474 if (result != GTK_RESPONSE_ACCEPT)
4477 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
4478 /* Do window specific stuff */
4479 if (MODEST_IS_MAIN_WINDOW (win)) {
4480 modest_ui_actions_on_main_window_move_to (action,
4483 MODEST_MAIN_WINDOW (win));
4485 modest_ui_actions_on_msg_view_window_move_to (action,
4487 MODEST_MSG_VIEW_WINDOW (win));
4491 g_object_unref (dst_folder);
4495 * Calls #HeadersFunc for each header already selected in the main
4496 * window or the message currently being shown in the msg view window
4499 do_headers_action (ModestWindow *win,
4503 TnyList *headers_list = NULL;
4504 TnyIterator *iter = NULL;
4505 TnyHeader *header = NULL;
4506 TnyFolder *folder = NULL;
4509 headers_list = get_selected_headers (win);
4513 /* Get the folder */
4514 iter = tny_list_create_iterator (headers_list);
4515 header = TNY_HEADER (tny_iterator_get_current (iter));
4517 folder = tny_header_get_folder (header);
4518 g_object_unref (header);
4521 /* Call the function for each header */
4522 while (!tny_iterator_is_done (iter)) {
4523 header = TNY_HEADER (tny_iterator_get_current (iter));
4524 func (header, win, user_data);
4525 g_object_unref (header);
4526 tny_iterator_next (iter);
4529 /* Trick: do a poke status in order to speed up the signaling
4531 tny_folder_poke_status (folder);
4534 g_object_unref (folder);
4535 g_object_unref (iter);
4536 g_object_unref (headers_list);
4540 modest_ui_actions_view_attachment (GtkAction *action,
4541 ModestWindow *window)
4543 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4544 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4546 /* not supported window for this action */
4547 g_return_if_reached ();
4552 modest_ui_actions_save_attachments (GtkAction *action,
4553 ModestWindow *window)
4555 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4556 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4558 /* not supported window for this action */
4559 g_return_if_reached ();
4564 modest_ui_actions_remove_attachments (GtkAction *action,
4565 ModestWindow *window)
4567 if (MODEST_IS_MAIN_WINDOW (window)) {
4568 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4569 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4570 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4572 /* not supported window for this action */
4573 g_return_if_reached ();
4578 modest_ui_actions_on_settings (GtkAction *action,
4583 dialog = modest_platform_get_global_settings_dialog ();
4584 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4585 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4586 gtk_widget_show_all (dialog);
4588 gtk_dialog_run (GTK_DIALOG (dialog));
4590 gtk_widget_destroy (dialog);
4594 modest_ui_actions_on_help (GtkAction *action,
4597 const gchar *help_id;
4599 g_return_if_fail (action);
4600 g_return_if_fail (win && GTK_IS_WINDOW(win));
4602 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
4605 modest_platform_show_help (GTK_WINDOW (win), help_id);
4607 g_warning ("%s: no help for window %p", __FUNCTION__, win);
4611 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4612 ModestWindow *window)
4614 ModestMailOperation *mail_op;
4618 headers = get_selected_headers (window);
4622 /* Create mail operation */
4623 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (window),
4624 modest_ui_actions_get_msgs_full_error_handler,
4626 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4627 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4630 g_object_unref (headers);
4631 g_object_unref (mail_op);
4635 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4636 ModestWindow *window)
4638 g_return_if_fail (MODEST_IS_WINDOW (window));
4641 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4645 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4646 ModestWindow *window)
4648 g_return_if_fail (MODEST_IS_WINDOW (window));
4651 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4655 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4656 ModestWindow *window)
4658 g_return_if_fail (MODEST_IS_WINDOW (window));
4661 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4665 modest_ui_actions_on_format_menu_activated (GtkAction *action,
4666 ModestWindow *window)
4668 g_return_if_fail (MODEST_IS_WINDOW (window));
4671 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4675 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4676 ModestWindow *window)
4678 g_return_if_fail (MODEST_IS_WINDOW (window));
4681 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4685 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4686 ModestWindow *window)
4688 g_return_if_fail (MODEST_IS_WINDOW (window));
4691 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4695 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4696 ModestWindow *window)
4698 g_return_if_fail (MODEST_IS_WINDOW (window));
4701 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4705 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4706 ModestWindow *window)
4708 g_return_if_fail (MODEST_IS_WINDOW (window));
4711 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4715 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4716 ModestWindow *window)
4718 g_return_if_fail (MODEST_IS_WINDOW (window));
4721 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4725 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4727 g_return_if_fail (MODEST_IS_WINDOW (window));
4730 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4734 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4736 g_return_if_fail (MODEST_IS_WINDOW (window));
4738 modest_platform_show_search_messages (GTK_WINDOW (window));
4742 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4744 g_return_if_fail (MODEST_IS_WINDOW (win));
4745 modest_platform_show_addressbook (GTK_WINDOW (win));
4750 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4751 ModestWindow *window)
4753 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4755 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4759 on_send_receive_finished (ModestMailOperation *mail_op,
4762 /* Set send/receive operation finished */
4763 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW (user_data));
4768 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
4774 const gchar* server_name = NULL;
4775 TnyTransportAccount *server_account;
4776 gchar *message = NULL;
4778 /* Don't show anything if the user cancelled something */
4779 if (err->code == TNY_TRANSPORT_ACCOUNT_ERROR_SEND_USER_CANCEL)
4782 /* Get the server name: */
4784 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
4785 if (server_account) {
4786 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
4788 g_object_unref (server_account);
4789 server_account = NULL;
4792 g_return_if_fail (server_name);
4794 /* Show the appropriate message text for the GError: */
4795 switch (err->code) {
4796 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_HOST_LOOKUP_FAILED:
4797 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4799 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_SERVICE_UNAVAILABLE:
4800 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4802 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_AUTHENTICATION_NOT_SUPPORTED:
4803 message = g_strdup_printf (_("emev_ni_ui_smtp_authentication_fail_error"), server_name);
4805 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND:
4806 message = g_strdup (_("emev_ib_ui_smtp_send_error"));
4809 g_return_if_reached ();
4812 /* TODO if the username or the password where not defined we
4813 should show the Accounts Settings dialog or the Connection
4814 specific SMTP server window */
4816 modest_platform_run_information_dialog (NULL, message);
4821 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
4826 ModestMainWindow *main_window = NULL;
4827 ModestWindowMgr *mgr = NULL;
4828 GtkWidget *folder_view = NULL, *header_view = NULL;
4829 TnyFolderStore *selected_folder = NULL;
4830 TnyFolderType folder_type;
4832 mgr = modest_runtime_get_window_mgr ();
4833 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr,
4834 FALSE));/* don't create */
4838 /* Check if selected folder is OUTBOX */
4839 folder_view = modest_main_window_get_child_widget (main_window,
4840 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4841 header_view = modest_main_window_get_child_widget (main_window,
4842 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4844 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4845 if (!TNY_IS_FOLDER (selected_folder))
4848 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
4849 #if GTK_CHECK_VERSION(2, 8, 0)
4850 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
4851 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
4852 GtkTreeViewColumn *tree_column;
4854 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
4855 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
4856 gtk_tree_view_column_queue_resize (tree_column);
4859 gtk_widget_queue_draw (header_view);
4864 if (selected_folder != NULL)
4865 g_object_unref (selected_folder);