1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #endif /*HAVE_CONFIG_H*/
34 #include <glib/gi18n.h>
35 #include <glib/gprintf.h>
37 #include <modest-runtime.h>
38 #include <modest-tny-folder.h>
39 #include <modest-tny-msg.h>
40 #include <modest-tny-account.h>
41 #include <modest-address-book.h>
42 #include "modest-error.h"
43 #include "modest-ui-actions.h"
45 #include "modest-tny-platform-factory.h"
46 #include "modest-platform.h"
47 #include <tny-mime-part.h>
48 #include <tny-camel-folder.h>
49 #include <tny-camel-imap-folder.h>
50 #include <tny-camel-pop-folder.h>
52 #ifdef MODEST_PLATFORM_MAEMO
53 #include "maemo/modest-osso-state-saving.h"
54 #include "maemo/modest-maemo-utils.h"
55 #include "maemo/modest-hildon-includes.h"
56 #endif /* MODEST_PLATFORM_MAEMO */
58 #include "widgets/modest-ui-constants.h"
59 #include <widgets/modest-main-window.h>
60 #include <widgets/modest-msg-view-window.h>
61 #include <widgets/modest-account-view-window.h>
62 #include <widgets/modest-details-dialog.h>
63 #include <widgets/modest-attachments-view.h>
64 #include "widgets/modest-folder-view.h"
65 #include "widgets/modest-global-settings-dialog.h"
66 #include "modest-connection-specific-smtp-window.h"
67 #include "modest-account-mgr-helpers.h"
68 #include "modest-mail-operation.h"
69 #include "modest-text-utils.h"
71 #ifdef MODEST_HAVE_EASYSETUP
72 #include "easysetup/modest-easysetup-wizard.h"
73 #endif /* MODEST_HAVE_EASYSETUP */
75 #include <modest-widget-memory.h>
76 #include <tny-error.h>
77 #include <tny-simple-list.h>
78 #include <tny-msg-view.h>
79 #include <tny-device.h>
80 #include <tny-merge-folder.h>
82 #include <gtkhtml/gtkhtml.h>
84 typedef struct _GetMsgAsyncHelper {
86 ModestMailOperation *mail_op;
93 typedef enum _ReplyForwardAction {
99 typedef struct _ReplyForwardHelper {
100 guint reply_forward_type;
101 ReplyForwardAction action;
103 GtkWidget *parent_window;
104 } ReplyForwardHelper;
106 typedef struct _MoveToHelper {
107 GtkTreeRowReference *reference;
111 typedef struct _PasteAsAttachmentHelper {
112 ModestMsgEditWindow *window;
114 } PasteAsAttachmentHelper;
118 * The do_headers_action uses this kind of functions to perform some
119 * action to each member of a list of headers
121 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
123 static void do_headers_action (ModestWindow *win,
127 static void open_msg_cb (ModestMailOperation *mail_op,
132 static void reply_forward_cb (ModestMailOperation *mail_op,
137 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
139 static void folder_refreshed_cb (ModestMailOperation *mail_op,
143 static void on_send_receive_finished (ModestMailOperation *mail_op,
146 static gint header_list_count_uncached_msgs (TnyList *header_list);
148 static gboolean connect_to_get_msg (ModestWindow *win,
149 gint num_of_uncached_msgs,
150 TnyAccount *account);
152 static gboolean remote_folder_is_pop (const TnyFolderStore *folder);
154 static gboolean msgs_already_deleted_from_server ( TnyList *headers,
155 const TnyFolderStore *src_folder);
159 * This function checks whether a TnyFolderStore is a pop account
162 remote_folder_is_pop (const TnyFolderStore *folder)
164 const gchar *proto = NULL;
165 TnyAccount *account = NULL;
167 g_return_val_if_fail (TNY_IS_FOLDER_STORE(folder), FALSE);
169 if (TNY_IS_ACCOUNT (folder)) {
170 account = TNY_ACCOUNT(folder);
171 g_object_ref(account);
172 } else if (TNY_IS_FOLDER (folder)) {
173 account = tny_folder_get_account(TNY_FOLDER(folder));
176 proto = tny_account_get_proto(account);
177 g_object_unref (account);
180 (modest_protocol_info_get_transport_store_protocol (proto) == MODEST_PROTOCOL_STORE_POP);
184 * This functions checks whether if a list of messages are already
185 * deleted from the server: that is, if the server is a POP account
186 * and all messages are already cached.
189 msgs_already_deleted_from_server (TnyList *headers, const TnyFolderStore *src_folder)
191 g_return_val_if_fail (TNY_IS_FOLDER_STORE(src_folder), FALSE);
192 g_return_val_if_fail (TNY_IS_LIST(headers), FALSE);
194 gboolean src_is_pop = remote_folder_is_pop (src_folder);
195 gint uncached_msgs = header_list_count_uncached_msgs (headers);
197 return (src_is_pop && !uncached_msgs);
201 /* FIXME: this should be merged with the similar code in modest-account-view-window */
202 /* Show the account creation wizard dialog.
203 * returns: TRUE if an account was created. FALSE if the user cancelled.
206 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
208 gboolean result = FALSE;
209 GtkWindow *dialog, *wizard;
210 gint dialog_response;
212 /* Show the easy-setup wizard: */
213 dialog = modest_window_mgr_get_modal (modest_runtime_get_window_mgr());
214 if (dialog && MODEST_IS_EASYSETUP_WIZARD_DIALOG(dialog)) {
215 /* old wizard is active already;
217 gtk_window_present (GTK_WINDOW(dialog));
222 /* there is no such wizard yet */
223 wizard = GTK_WINDOW (modest_easysetup_wizard_dialog_new ());
224 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), wizard);
226 /* always present a main window in the background
227 * we do it here, so we cannot end up with to wizards (as this
228 * function might be called in modest_window_mgr_get_main_window as well */
230 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr());
232 /* make sure the mainwindow is visible */
233 gtk_widget_show_all (GTK_WIDGET(win));
234 gtk_window_present (GTK_WINDOW(win));
236 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
237 gtk_widget_destroy (GTK_WIDGET (wizard));
238 if (gtk_events_pending ())
239 gtk_main_iteration ();
241 if (dialog_response == GTK_RESPONSE_CANCEL) {
244 /* Check whether an account was created: */
245 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
253 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
256 const gchar *authors[] = {
257 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
260 about = gtk_about_dialog_new ();
261 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
262 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
263 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
264 _("Copyright (c) 2006, Nokia Corporation\n"
265 "All rights reserved."));
266 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
267 _("a modest e-mail client\n\n"
268 "design and implementation: Dirk-Jan C. Binnema\n"
269 "contributions from the fine people at KC and Ig\n"
270 "uses the tinymail email framework written by Philip van Hoof"));
271 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
272 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
273 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
274 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
276 gtk_dialog_run (GTK_DIALOG (about));
277 gtk_widget_destroy(about);
281 * Gets the list of currently selected messages. If the win is the
282 * main window, then it returns a newly allocated list of the headers
283 * selected in the header view. If win is the msg view window, then
284 * the value returned is a list with just a single header.
286 * The caller of this funcion must free the list.
289 get_selected_headers (ModestWindow *win)
291 if (MODEST_IS_MAIN_WINDOW(win)) {
292 GtkWidget *header_view;
294 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
295 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
296 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
298 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
299 /* for MsgViewWindows, we simply return a list with one element */
301 TnyList *list = NULL;
303 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
304 if (header != NULL) {
305 list = tny_simple_list_new ();
306 tny_list_prepend (list, G_OBJECT(header));
307 g_object_unref (G_OBJECT(header));
316 static GtkTreeRowReference *
317 get_next_after_selected_headers (ModestHeaderView *header_view)
319 GtkTreeSelection *sel;
320 GList *selected_rows, *node;
322 GtkTreeRowReference *result;
325 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
326 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
327 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
329 if (selected_rows == NULL)
332 node = g_list_last (selected_rows);
333 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
334 gtk_tree_path_next (path);
336 result = gtk_tree_row_reference_new (model, path);
338 gtk_tree_path_free (path);
339 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
340 g_list_free (selected_rows);
346 headers_action_mark_as_read (TnyHeader *header,
350 TnyHeaderFlags flags;
352 g_return_if_fail (TNY_IS_HEADER(header));
354 flags = tny_header_get_flags (header);
355 if (flags & TNY_HEADER_FLAG_SEEN) return;
356 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
360 headers_action_mark_as_unread (TnyHeader *header,
364 TnyHeaderFlags flags;
366 g_return_if_fail (TNY_IS_HEADER(header));
368 flags = tny_header_get_flags (header);
369 if (flags & TNY_HEADER_FLAG_SEEN) {
370 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
374 /** A convenience method, because deleting a message is
375 * otherwise complicated, and it's best to change it in one place
378 void modest_do_message_delete (TnyHeader *header, ModestWindow *win)
380 ModestMailOperation *mail_op = NULL;
381 mail_op = modest_mail_operation_new (win ? G_OBJECT(win) : NULL);
382 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
385 /* Always delete. TODO: Move to trash still not supported */
386 modest_mail_operation_remove_msg (mail_op, header, FALSE);
387 g_object_unref (G_OBJECT (mail_op));
390 /** A convenience method, because deleting a message is
391 * otherwise complicated, and it's best to change it in one place
394 void modest_do_messages_delete (TnyList *headers, ModestWindow *win)
396 ModestMailOperation *mail_op = NULL;
397 mail_op = modest_mail_operation_new (win ? G_OBJECT(win) : NULL);
398 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
401 /* Always delete. TODO: Move to trash still not supported */
402 modest_mail_operation_remove_msgs (mail_op, headers, FALSE);
403 g_object_unref (G_OBJECT (mail_op));
406 /** After deleing a message that is currently visible in a window,
407 * show the next message from the list, or close the window if there are no more messages.
410 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
412 /* Close msg view window or select next */
413 if (modest_msg_view_window_last_message_selected (win) &&
414 modest_msg_view_window_first_message_selected (win)) {
415 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
416 } else if (!modest_msg_view_window_select_next_message (win)) {
418 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
423 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
425 TnyList *header_list = NULL;
426 TnyIterator *iter = NULL;
427 TnyHeader *header = NULL;
428 gchar *message = NULL;
431 ModestWindowMgr *mgr;
432 GtkWidget *header_view = NULL;
434 g_return_if_fail (MODEST_IS_WINDOW(win));
436 /* Check first if the header view has the focus */
437 if (MODEST_IS_MAIN_WINDOW (win)) {
439 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
440 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
441 if (!gtk_widget_is_focus (header_view))
445 /* Get the headers, either from the header view (if win is the main window),
446 * or from the message view window: */
447 header_list = get_selected_headers (win);
448 if (!header_list) return;
450 /* Check if any of the headers are already opened, or in the process of being opened */
451 if (MODEST_IS_MAIN_WINDOW (win)) {
452 gint opened_headers = 0;
454 iter = tny_list_create_iterator (header_list);
455 mgr = modest_runtime_get_window_mgr ();
456 while (!tny_iterator_is_done (iter)) {
457 header = TNY_HEADER (tny_iterator_get_current (iter));
459 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
461 g_object_unref (header);
463 tny_iterator_next (iter);
465 g_object_unref (iter);
467 if (opened_headers > 0) {
470 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
473 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
476 g_object_unref (header_list);
482 if (tny_list_get_length(header_list) == 1) {
483 iter = tny_list_create_iterator (header_list);
484 header = TNY_HEADER (tny_iterator_get_current (iter));
486 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
487 g_object_unref (header);
490 g_object_unref (iter);
492 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
493 tny_list_get_length(header_list)), desc);
495 /* Confirmation dialog */
496 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
500 if (response == GTK_RESPONSE_OK) {
501 ModestWindow *main_window = NULL;
502 ModestWindowMgr *mgr = NULL;
503 GtkTreeModel *model = NULL;
504 GtkTreeSelection *sel = NULL;
505 GList *sel_list = NULL, *tmp = NULL;
506 GtkTreeRowReference *next_row_reference = NULL;
507 GtkTreeRowReference *prev_row_reference = NULL;
508 GtkTreePath *next_path = NULL;
509 GtkTreePath *prev_path = NULL;
512 /* Find last selected row */
513 if (MODEST_IS_MAIN_WINDOW (win)) {
514 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
515 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
516 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
517 for (tmp=sel_list; tmp; tmp=tmp->next) {
518 if (tmp->next == NULL) {
519 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
520 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
522 gtk_tree_path_prev (prev_path);
523 gtk_tree_path_next (next_path);
525 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
526 next_row_reference = gtk_tree_row_reference_new (model, next_path);
531 /* Disable window dimming management */
532 modest_window_disable_dimming (MODEST_WINDOW(win));
534 /* Remove each header. If it's a view window header_view == NULL */
535 modest_do_messages_delete (header_list, win);
537 /* Enable window dimming management */
539 gtk_tree_selection_unselect_all (sel);
541 modest_window_enable_dimming (MODEST_WINDOW(win));
543 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
544 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
546 /* Get main window */
547 mgr = modest_runtime_get_window_mgr ();
548 main_window = modest_window_mgr_get_main_window (mgr);
551 /* Move cursor to next row */
554 /* Select next or previous row */
555 if (gtk_tree_row_reference_valid (next_row_reference)) {
556 /* next_path = gtk_tree_row_reference_get_path (row_reference); */
557 gtk_tree_selection_select_path (sel, next_path);
559 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
560 gtk_tree_selection_select_path (sel, prev_path);
564 if (next_row_reference != NULL)
565 gtk_tree_row_reference_free (next_row_reference);
566 if (next_path != NULL)
567 gtk_tree_path_free (next_path);
568 if (prev_row_reference != NULL)
569 gtk_tree_row_reference_free (prev_row_reference);
570 if (prev_path != NULL)
571 gtk_tree_path_free (prev_path);
575 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, err->code, err->message);
579 /* Update toolbar dimming state */
580 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
583 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
584 g_list_free (sel_list);
590 g_object_unref (header_list);
596 /* delete either message or folder, based on where we are */
598 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
600 g_return_if_fail (MODEST_IS_WINDOW(win));
602 /* Check first if the header view has the focus */
603 if (MODEST_IS_MAIN_WINDOW (win)) {
605 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
606 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
607 if (gtk_widget_is_focus (w)) {
608 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
612 modest_ui_actions_on_delete_message (action, win);
618 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
620 ModestWindowMgr *mgr = NULL;
622 #ifdef MODEST_PLATFORM_MAEMO
623 modest_osso_save_state();
624 #endif /* MODEST_PLATFORM_MAEMO */
626 g_debug ("closing down, clearing %d item(s) from operation queue",
627 modest_mail_operation_queue_num_elements
628 (modest_runtime_get_mail_operation_queue()));
630 /* cancel all outstanding operations */
631 modest_mail_operation_queue_cancel_all
632 (modest_runtime_get_mail_operation_queue());
634 g_debug ("queue has been cleared");
637 /* Check if there are opened editing windows */
638 mgr = modest_runtime_get_window_mgr ();
639 modest_window_mgr_close_all_windows (mgr);
641 /* note: when modest-tny-account-store is finalized,
642 it will automatically set all network connections
645 /* gtk_main_quit (); */
649 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
653 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
655 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
656 /* gtk_widget_destroy (GTK_WIDGET (win)); */
657 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
658 /* gboolean ret_value; */
659 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
660 /* } else if (MODEST_IS_WINDOW (win)) { */
661 /* gtk_widget_destroy (GTK_WIDGET (win)); */
663 /* g_return_if_reached (); */
668 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
670 GtkClipboard *clipboard = NULL;
671 gchar *selection = NULL;
673 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
674 selection = gtk_clipboard_wait_for_text (clipboard);
676 /* Question: why is the clipboard being used here?
677 * It doesn't really make a lot of sense. */
681 modest_address_book_add_address (selection);
687 modest_ui_actions_on_accounts (GtkAction *action,
690 /* This is currently only implemented for Maemo */
691 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
692 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
693 modest_ui_actions_run_account_setup_wizard (win);
696 /* Show the list of accounts */
697 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
698 gtk_window_set_transient_for (account_win, GTK_WINDOW (win));
700 /* The accounts dialog must be modal */
701 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), account_win);
702 modest_maemo_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
705 GtkWidget *dialog, *label;
707 /* Create the widgets */
709 dialog = gtk_dialog_new_with_buttons ("Message",
711 GTK_DIALOG_DESTROY_WITH_PARENT,
715 label = gtk_label_new ("Hello World!");
717 /* Ensure that the dialog box is destroyed when the user responds. */
719 g_signal_connect_swapped (dialog, "response",
720 G_CALLBACK (gtk_widget_destroy),
723 /* Add the label, and show everything we've added to the dialog. */
725 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
727 gtk_widget_show_all (dialog);
728 #endif /* MODEST_PLATFORM_MAEMO */
732 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
734 /* Save any changes. */
735 modest_connection_specific_smtp_window_save_server_accounts (
736 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window));
737 gtk_widget_destroy (GTK_WIDGET (window));
743 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
745 /* This is currently only implemented for Maemo,
746 * because it requires an API (libconic) to detect different connection
749 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
751 /* Create the window if necessary: */
752 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
753 modest_connection_specific_smtp_window_fill_with_connections (
754 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
755 modest_runtime_get_account_mgr());
757 /* Show the window: */
758 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
759 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
760 gtk_widget_show (specific_window);
762 /* Save changes when the window is hidden: */
763 g_signal_connect (specific_window, "hide",
764 G_CALLBACK (on_smtp_servers_window_hide), win);
765 #endif /* MODEST_PLATFORM_MAEMO */
769 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
771 ModestWindow *msg_win = NULL;
773 TnyFolder *folder = NULL;
774 gchar *account_name = NULL;
775 gchar *from_str = NULL;
776 /* GError *err = NULL; */
777 TnyAccount *account = NULL;
778 ModestWindowMgr *mgr;
779 gchar *signature = NULL, *blank_and_signature = NULL;
781 /* if there are no accounts yet, just show the wizard */
782 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
783 if (!modest_ui_actions_run_account_setup_wizard (win))
787 account_name = g_strdup (modest_window_get_active_account (win));
789 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
791 g_printerr ("modest: no account found\n");
795 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
797 TNY_ACCOUNT_TYPE_STORE);
799 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
803 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
805 g_printerr ("modest: failed get from string for '%s'\n", account_name);
809 gboolean use_signature = FALSE;
810 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr (), account_name, &use_signature);
813 blank_and_signature = g_strconcat ("\n", signature, NULL);
815 blank_and_signature = g_strdup ("");
820 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
822 g_printerr ("modest: failed to create new msg\n");
826 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
828 g_printerr ("modest: failed to find Drafts folder\n");
833 /* Create and register edit window */
834 /* This is destroyed by TODO. */
835 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
836 mgr = modest_runtime_get_window_mgr ();
837 modest_window_mgr_register_window (mgr, msg_win);
840 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
842 gtk_widget_show_all (GTK_WIDGET (msg_win));
845 g_free (account_name);
847 g_free (blank_and_signature);
849 g_object_unref (msg_win);
851 g_object_unref (G_OBJECT(account));
853 g_object_unref (G_OBJECT(msg));
855 g_object_unref (G_OBJECT(folder));
859 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
863 ModestMailOperationStatus status;
865 /* If there is no message or the operation was not successful */
866 status = modest_mail_operation_get_status (mail_op);
867 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
869 /* Remove the header from the preregistered uids */
870 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
880 open_msg_cb (ModestMailOperation *mail_op, TnyHeader *header, TnyMsg *msg, gpointer user_data)
882 ModestWindowMgr *mgr = NULL;
883 ModestWindow *parent_win = NULL;
884 ModestWindow *win = NULL;
885 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
886 gchar *account = NULL;
889 /* Do nothing if there was any problem with the mail
890 operation. The error will be shown by the error_handler of
891 the mail operation */
892 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
895 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
896 folder = tny_header_get_folder (header);
898 /* Mark header as read */
899 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
901 /* Gets folder type (OUTBOX headers will be opened in edit window */
902 if (modest_tny_folder_is_local_folder (folder)) {
903 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
908 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
910 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
912 /* If the header is in the drafts folder then open the editor,
913 else the message view window */
914 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
915 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
916 const gchar *from_header = NULL;
918 from_header = tny_header_get_from (header);
920 /* we cannot edit without a valid account... */
921 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
922 if (!modest_ui_actions_run_account_setup_wizard(parent_win))
927 GSList *accounts = modest_account_mgr_account_names (mgr, TRUE);
929 for (node = accounts; node != NULL; node = g_slist_next (node)) {
930 gchar *from = modest_account_mgr_get_from_string (mgr, node->data);
932 if (from && (strcmp (from_header, from) == 0)) {
934 account = g_strdup (node->data);
940 g_slist_foreach (accounts, (GFunc) g_free, NULL);
941 g_slist_free (accounts);
944 win = modest_msg_edit_window_new (msg, account, TRUE);
948 modest_platform_information_banner (NULL, NULL, _("mail_ib_opening_draft_message"));
951 gchar *uid = modest_tny_folder_get_header_unique_id (header);
953 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
954 GtkWidget *header_view;
955 GtkTreeSelection *sel;
956 GList *sel_list = NULL;
959 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
960 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
962 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
963 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
965 if (sel_list != NULL) {
966 GtkTreeRowReference *row_reference;
968 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
969 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
970 g_list_free (sel_list);
972 win = modest_msg_view_window_new_with_header_model (
973 msg, account, (const gchar*) uid,
974 model, row_reference);
975 gtk_tree_row_reference_free (row_reference);
977 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
980 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
985 /* Register and show new window */
987 mgr = modest_runtime_get_window_mgr ();
988 modest_window_mgr_register_window (mgr, win);
989 g_object_unref (win);
990 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
991 gtk_widget_show_all (GTK_WIDGET(win));
994 /* Update toolbar dimming state */
995 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
996 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1002 g_object_unref (parent_win);
1003 g_object_unref (folder);
1008 open_msg_error_handler (ModestMailOperation *mail_op,
1011 /* Show the message error */
1012 GObject *win = modest_mail_operation_get_source (mail_op);
1014 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1015 (gchar *) user_data);
1017 g_object_unref (win);
1021 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
1024 const GError *error;
1025 GObject *win = modest_mail_operation_get_source (mail_op);
1027 error = modest_mail_operation_get_error (mail_op);
1029 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
1031 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1034 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1035 _("mail_ni_ui_folder_get_msg_folder_error"));
1039 g_object_unref (win);
1043 * Returns the account a list of headers belongs to. It returns a
1044 * *new* reference so don't forget to unref it
1047 get_account_from_header_list (TnyList *headers)
1049 TnyAccount *account = NULL;
1051 if (tny_list_get_length (headers) > 0) {
1052 TnyIterator *iter = tny_list_create_iterator (headers);
1053 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1054 TnyFolder *folder = tny_header_get_folder (header);
1055 account = tny_folder_get_account (folder);
1056 g_object_unref (folder);
1057 g_object_unref (header);
1058 g_object_unref (iter);
1064 * This function is used by both modest_ui_actions_on_open and
1065 * modest_ui_actions_on_header_activated. This way we always do the
1066 * same when trying to open messages.
1069 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
1071 ModestWindowMgr *mgr = NULL;
1072 TnyIterator *iter = NULL, *iter_not_opened = NULL;
1073 ModestMailOperation *mail_op = NULL;
1074 TnyList *not_opened_headers = NULL;
1075 TnyHeaderFlags flags = 0;
1076 TnyAccount *account;
1078 g_return_if_fail (headers != NULL);
1080 /* Check that only one message is selected for opening */
1081 if (tny_list_get_length (headers) != 1) {
1082 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1083 _("mcen_ib_select_one_message"));
1087 mgr = modest_runtime_get_window_mgr ();
1088 iter = tny_list_create_iterator (headers);
1090 /* Get the account */
1091 account = get_account_from_header_list (headers);
1093 /* Look if we already have a message view for each header. If
1094 true, then remove the header from the list of headers to
1096 not_opened_headers = tny_simple_list_new ();
1097 while (!tny_iterator_is_done (iter)) {
1099 ModestWindow *window = NULL;
1100 TnyHeader *header = NULL;
1101 gboolean found = FALSE;
1103 header = TNY_HEADER (tny_iterator_get_current (iter));
1105 flags = tny_header_get_flags (header);
1108 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1110 /* Do not open again the message and present the
1111 window to the user */
1114 gtk_window_present (GTK_WINDOW (window));
1116 /* the header has been registered already, we don't do
1117 * anything but wait for the window to come up*/
1118 g_debug ("header %p already registered, waiting for window", header);
1120 tny_list_append (not_opened_headers, G_OBJECT (header));
1124 g_object_unref (header);
1126 tny_iterator_next (iter);
1128 g_object_unref (iter);
1131 /* Open each message */
1132 if (tny_list_get_length (not_opened_headers) == 0)
1135 /* If some messages would have to be downloaded, ask the user to
1136 * make a connection. It's generally easier to do this here (in the mainloop)
1137 * than later in a thread:
1139 if (tny_list_get_length (not_opened_headers) > 0) {
1141 gboolean found = FALSE;
1143 iter = tny_list_create_iterator (not_opened_headers);
1144 while (!tny_iterator_is_done (iter) && !found) {
1145 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1146 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1149 tny_iterator_next (iter);
1151 g_object_unref (header);
1153 g_object_unref (iter);
1155 /* Ask the user if there are any uncached messages */
1156 if (found && !connect_to_get_msg (win,
1157 header_list_count_uncached_msgs (not_opened_headers),
1162 /* Register the headers before actually creating the windows: */
1163 iter_not_opened = tny_list_create_iterator (not_opened_headers);
1164 while (!tny_iterator_is_done (iter_not_opened)) {
1165 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1167 modest_window_mgr_register_header (mgr, header, NULL);
1168 g_object_unref (header);
1170 tny_iterator_next (iter_not_opened);
1172 g_object_unref (iter_not_opened);
1173 iter_not_opened = NULL;
1175 /* Create the mail operation */
1176 if (tny_list_get_length (not_opened_headers) > 1) {
1177 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
1178 modest_ui_actions_get_msgs_full_error_handler,
1180 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1182 modest_mail_operation_get_msgs_full (mail_op,
1188 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1189 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1190 const gchar *proto_name;
1192 ModestTransportStoreProtocol proto;
1194 /* Get the error message depending on the protocol */
1195 proto_name = tny_account_get_proto (account);
1196 if (proto_name != NULL) {
1197 proto = modest_protocol_info_get_transport_store_protocol (proto_name);
1199 proto = MODEST_PROTOCOL_STORE_MAILDIR;
1202 if (proto == MODEST_PROTOCOL_STORE_POP) {
1203 error_msg = g_strdup (_("emev_ni_ui_pop3_msg_recv_error"));
1204 } else if (proto == MODEST_PROTOCOL_STORE_IMAP) {
1205 error_msg = g_strdup_printf (_("emev_ni_ui_imap_message_not_available_in_server"),
1206 tny_header_get_subject (header));
1208 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1211 /* Create and call the mail operation */
1212 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
1213 open_msg_error_handler,
1216 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1218 modest_mail_operation_get_msg (mail_op, header, open_msg_cb, NULL);
1220 g_object_unref (header);
1221 g_object_unref (iter);
1223 g_object_unref (mail_op);
1228 g_object_unref (account);
1229 if (not_opened_headers)
1230 g_object_unref (not_opened_headers);
1234 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1239 headers = get_selected_headers (win);
1244 _modest_ui_actions_open (headers, win);
1246 g_object_unref(headers);
1251 free_reply_forward_helper (gpointer data)
1253 ReplyForwardHelper *helper;
1255 helper = (ReplyForwardHelper *) data;
1256 g_free (helper->account_name);
1257 g_slice_free (ReplyForwardHelper, helper);
1261 reply_forward_cb (ModestMailOperation *mail_op, TnyHeader *header, TnyMsg *msg,
1265 ReplyForwardHelper *rf_helper;
1266 ModestWindow *msg_win = NULL;
1267 ModestEditType edit_type;
1269 TnyAccount *account = NULL;
1270 ModestWindowMgr *mgr = NULL;
1271 gchar *signature = NULL;
1272 gboolean use_signature;
1274 /* If there was any error. The mail operation could be NULL,
1275 this means that we already have the message downloaded and
1276 that we didn't do a mail operation to retrieve it */
1277 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1280 g_return_if_fail (user_data != NULL);
1281 rf_helper = (ReplyForwardHelper *) user_data;
1283 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1284 rf_helper->account_name);
1285 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr(),
1286 rf_helper->account_name,
1289 /* Create reply mail */
1290 switch (rf_helper->action) {
1293 modest_tny_msg_create_reply_msg (msg, header, from, signature,
1294 rf_helper->reply_forward_type,
1295 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1297 case ACTION_REPLY_TO_ALL:
1299 modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1300 MODEST_TNY_MSG_REPLY_MODE_ALL);
1301 edit_type = MODEST_EDIT_TYPE_REPLY;
1303 case ACTION_FORWARD:
1305 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1306 edit_type = MODEST_EDIT_TYPE_FORWARD;
1309 g_return_if_reached ();
1316 g_printerr ("modest: failed to create message\n");
1320 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1321 rf_helper->account_name,
1322 TNY_ACCOUNT_TYPE_STORE);
1324 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1328 /* Create and register the windows */
1329 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1330 mgr = modest_runtime_get_window_mgr ();
1331 modest_window_mgr_register_window (mgr, msg_win);
1333 if (rf_helper->parent_window != NULL) {
1334 gdouble parent_zoom;
1336 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1337 modest_window_set_zoom (msg_win, parent_zoom);
1340 /* Show edit window */
1341 gtk_widget_show_all (GTK_WIDGET (msg_win));
1345 g_object_unref (msg_win);
1347 g_object_unref (G_OBJECT (new_msg));
1349 g_object_unref (G_OBJECT (account));
1350 /* g_object_unref (msg); */
1351 free_reply_forward_helper (rf_helper);
1354 /* Checks a list of headers. If any of them are not currently
1355 * downloaded (CACHED) then returns TRUE else returns FALSE.
1358 header_list_count_uncached_msgs (TnyList *header_list)
1361 gint uncached_messages = 0;
1363 iter = tny_list_create_iterator (header_list);
1364 while (!tny_iterator_is_done (iter)) {
1367 header = TNY_HEADER (tny_iterator_get_current (iter));
1369 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1370 uncached_messages ++;
1371 g_object_unref (header);
1374 tny_iterator_next (iter);
1376 g_object_unref (iter);
1378 return uncached_messages;
1381 /* Returns FALSE if the user does not want to download the
1382 * messages. Returns TRUE if the user allowed the download.
1385 connect_to_get_msg (ModestWindow *win,
1386 gint num_of_uncached_msgs,
1387 TnyAccount *account)
1389 GtkResponseType response;
1391 /* Allways download if we are online. */
1392 if (tny_device_is_online (modest_runtime_get_device ()))
1395 /* If offline, then ask for user permission to download the messages */
1396 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1397 ngettext("mcen_nc_get_msg",
1399 num_of_uncached_msgs));
1401 if (response == GTK_RESPONSE_CANCEL)
1404 return modest_platform_connect_and_wait(GTK_WINDOW (win), account);
1408 * Common code for the reply and forward actions
1411 reply_forward (ReplyForwardAction action, ModestWindow *win)
1413 ModestMailOperation *mail_op = NULL;
1414 TnyList *header_list = NULL;
1415 ReplyForwardHelper *rf_helper = NULL;
1416 guint reply_forward_type;
1417 gboolean continue_download = TRUE;
1418 gboolean do_retrieve = TRUE;
1420 g_return_if_fail (MODEST_IS_WINDOW(win));
1422 /* we need an account when editing */
1423 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1424 if (!modest_ui_actions_run_account_setup_wizard (win))
1428 header_list = get_selected_headers (win);
1432 reply_forward_type =
1433 modest_conf_get_int (modest_runtime_get_conf (),
1434 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1437 /* check if we need to download msg before asking about it */
1438 do_retrieve = (action == ACTION_FORWARD) ||
1439 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1442 gint num_of_unc_msgs;
1444 /* check that the messages have been previously downloaded */
1445 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
1446 /* If there are any uncached message ask the user
1447 * whether he/she wants to download them. */
1448 if (num_of_unc_msgs) {
1449 TnyAccount *account = get_account_from_header_list (header_list);
1450 continue_download = connect_to_get_msg (win, num_of_unc_msgs, account);
1451 g_object_unref (account);
1455 if (!continue_download) {
1456 g_object_unref (header_list);
1460 /* We assume that we can only select messages of the
1461 same folder and that we reply all of them from the
1462 same account. In fact the interface currently only
1463 allows single selection */
1466 rf_helper = g_slice_new0 (ReplyForwardHelper);
1467 rf_helper->reply_forward_type = reply_forward_type;
1468 rf_helper->action = action;
1469 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1471 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1472 rf_helper->parent_window = GTK_WIDGET (win);
1473 if (!rf_helper->account_name)
1474 rf_helper->account_name =
1475 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1477 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1480 /* Get header and message. Do not free them here, the
1481 reply_forward_cb must do it */
1482 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1483 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1484 if (!msg || !header) {
1486 g_object_unref (msg);
1487 g_printerr ("modest: no message found\n");
1490 reply_forward_cb (NULL, header, msg, rf_helper);
1493 g_object_unref (header);
1498 /* Only reply/forward to one message */
1499 iter = tny_list_create_iterator (header_list);
1500 header = TNY_HEADER (tny_iterator_get_current (iter));
1501 g_object_unref (iter);
1504 /* Retrieve messages */
1507 modest_mail_operation_new_with_error_handling (G_OBJECT(win),
1508 modest_ui_actions_get_msgs_full_error_handler,
1510 modest_mail_operation_queue_add (
1511 modest_runtime_get_mail_operation_queue (), mail_op);
1513 modest_mail_operation_get_msg (mail_op,
1518 g_object_unref(mail_op);
1520 /* we put a ref here to prevent double unref as the reply
1521 * forward callback unrefs the header at its end */
1522 reply_forward_cb (NULL, header, NULL, rf_helper);
1526 g_object_unref (header);
1532 g_object_unref (header_list);
1536 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1538 g_return_if_fail (MODEST_IS_WINDOW(win));
1540 reply_forward (ACTION_REPLY, win);
1544 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1546 g_return_if_fail (MODEST_IS_WINDOW(win));
1548 reply_forward (ACTION_FORWARD, win);
1552 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1554 g_return_if_fail (MODEST_IS_WINDOW(win));
1556 reply_forward (ACTION_REPLY_TO_ALL, win);
1560 modest_ui_actions_on_next (GtkAction *action,
1561 ModestWindow *window)
1563 if (MODEST_IS_MAIN_WINDOW (window)) {
1564 GtkWidget *header_view;
1566 header_view = modest_main_window_get_child_widget (
1567 MODEST_MAIN_WINDOW(window),
1568 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1572 modest_header_view_select_next (
1573 MODEST_HEADER_VIEW(header_view));
1574 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1575 modest_msg_view_window_select_next_message (
1576 MODEST_MSG_VIEW_WINDOW (window));
1578 g_return_if_reached ();
1583 modest_ui_actions_on_prev (GtkAction *action,
1584 ModestWindow *window)
1586 g_return_if_fail (MODEST_IS_WINDOW(window));
1588 if (MODEST_IS_MAIN_WINDOW (window)) {
1589 GtkWidget *header_view;
1590 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1591 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1595 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1596 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1597 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1599 g_return_if_reached ();
1604 modest_ui_actions_on_sort (GtkAction *action,
1605 ModestWindow *window)
1607 g_return_if_fail (MODEST_IS_WINDOW(window));
1609 if (MODEST_IS_MAIN_WINDOW (window)) {
1610 GtkWidget *header_view;
1611 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1612 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1614 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1619 /* Show sorting dialog */
1620 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1625 new_messages_arrived (ModestMailOperation *self,
1626 TnyList *new_headers,
1629 ModestMainWindow *win = NULL;
1630 GtkWidget *folder_view = NULL;
1631 TnyFolderStore *folder = NULL;
1632 gboolean folder_empty = FALSE;
1634 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
1635 win = MODEST_MAIN_WINDOW (user_data);
1637 /* Don't do anything if there are not new headers, this could
1638 happen if there was any problem with the mail operation */
1642 /* Set contents style of headers view */
1643 if (modest_main_window_get_contents_style (win) == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1644 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1645 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1646 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1649 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1652 modest_main_window_set_contents_style (win,
1653 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1656 /* Notify new messages have been downloaded */
1657 if ((new_headers != NULL) && (tny_list_get_length (new_headers) > 0))
1658 modest_platform_on_new_headers_received (new_headers);
1662 * This function performs the send & receive required actions. The
1663 * window is used to create the mail operation. Typically it should
1664 * always be the main window, but we pass it as argument in order to
1668 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1670 gchar *acc_name = NULL;
1671 ModestMailOperation *mail_op;
1672 TnyAccount *store_account = NULL;
1674 /* If no account name was provided then get the current account, and if
1675 there is no current account then pick the default one: */
1676 if (!account_name) {
1677 acc_name = g_strdup (modest_window_get_active_account(win));
1679 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1681 g_printerr ("modest: cannot get default account\n");
1685 acc_name = g_strdup (account_name);
1689 /* Ensure that we have a connection available */
1691 modest_tny_account_store_get_server_account (modest_runtime_get_account_store (),
1693 TNY_ACCOUNT_TYPE_STORE);
1694 if (!modest_platform_connect_and_wait (NULL, TNY_ACCOUNT (store_account))) {
1695 g_object_unref (store_account);
1698 g_object_unref (store_account);
1700 /* Set send/receive operation in progress */
1701 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1703 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
1704 modest_ui_actions_send_receive_error_handler,
1707 g_signal_connect (G_OBJECT(mail_op), "operation-finished",
1708 G_CALLBACK (on_send_receive_finished),
1711 /* Send & receive. */
1712 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1713 /* Receive and then send. The operation is tagged initially as
1714 a receive operation because the account update performs a
1715 receive and then a send. The operation changes its type
1716 internally, so the progress objects will receive the proper
1717 progress information */
1718 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1719 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, win);
1720 g_object_unref (G_OBJECT (mail_op));
1728 modest_ui_actions_do_cancel_send (const gchar *account_name,
1731 TnyTransportAccount *transport_account;
1732 TnySendQueue *send_queue = NULL;
1733 GError *error = NULL;
1735 /* Get transport account */
1737 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1738 (modest_runtime_get_account_store(),
1740 TNY_ACCOUNT_TYPE_TRANSPORT));
1741 if (!transport_account) {
1742 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1747 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1748 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1749 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1750 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1751 "modest: could not find send queue for account\n");
1753 /* Keeep messages in outbox folder */
1754 tny_send_queue_cancel (send_queue, FALSE, &error);
1758 if (transport_account != NULL)
1759 g_object_unref (G_OBJECT (transport_account));
1763 modest_ui_actions_cancel_send_all (ModestWindow *win)
1765 GSList *account_names, *iter;
1767 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1770 iter = account_names;
1772 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1773 iter = g_slist_next (iter);
1776 modest_account_mgr_free_account_names (account_names);
1777 account_names = NULL;
1781 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1784 /* Check if accounts exist */
1785 gboolean accounts_exist =
1786 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1788 /* If not, allow the user to create an account before trying to send/receive. */
1789 if (!accounts_exist)
1790 modest_ui_actions_on_accounts (NULL, win);
1792 /* Cancel all sending operaitons */
1793 modest_ui_actions_cancel_send_all (win);
1797 * Refreshes all accounts. This function will be used by automatic
1801 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1803 GSList *account_names, *iter;
1805 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1808 iter = account_names;
1810 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1811 iter = g_slist_next (iter);
1814 modest_account_mgr_free_account_names (account_names);
1815 account_names = NULL;
1819 modest_do_refresh_current_folder(ModestWindow *win)
1821 /* Refresh currently selected folder. Note that if we only
1822 want to retreive the headers, then the refresh only will
1823 invoke a poke_status over all folders, i.e., only the
1824 total/unread count will be updated */
1825 if (MODEST_IS_MAIN_WINDOW (win)) {
1826 GtkWidget *header_view, *folder_view;
1827 TnyFolderStore *folder_store;
1829 /* Get folder and header view */
1831 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1832 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1836 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1838 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1840 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1841 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1843 /* We do not need to set the contents style
1844 because it hasn't changed. We also do not
1845 need to save the widget status. Just force
1847 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1848 TNY_FOLDER (folder_store),
1849 folder_refreshed_cb,
1850 MODEST_MAIN_WINDOW (win));
1854 g_object_unref (folder_store);
1860 * Handler of the click on Send&Receive button in the main toolbar
1863 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1865 /* Check if accounts exist */
1866 gboolean accounts_exist =
1867 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1869 /* If not, allow the user to create an account before trying to send/receive. */
1870 if (!accounts_exist)
1871 modest_ui_actions_on_accounts (NULL, win);
1873 modest_do_refresh_current_folder (win);
1875 /* Refresh the active account */
1876 modest_ui_actions_do_send_receive (NULL, win);
1881 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1884 GtkWidget *header_view;
1886 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1888 header_view = modest_main_window_get_child_widget (main_window,
1889 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1893 conf = modest_runtime_get_conf ();
1895 /* what is saved/restored is depending on the style; thus; we save with
1896 * old style, then update the style, and restore for this new style
1898 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1900 if (modest_header_view_get_style
1901 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1902 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1903 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1905 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1906 MODEST_HEADER_VIEW_STYLE_DETAILS);
1908 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1909 MODEST_CONF_HEADER_VIEW_KEY);
1914 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1916 ModestMainWindow *main_window)
1918 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1919 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1921 /* in the case the folder is empty, show the empty folder message and focus
1923 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1924 if (modest_header_view_is_empty (header_view)) {
1925 TnyFolder *folder = modest_header_view_get_folder (header_view);
1926 GtkWidget *folder_view =
1927 modest_main_window_get_child_widget (main_window,
1928 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1930 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1931 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1935 /* If no header has been selected then exit */
1940 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1941 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1943 /* Update toolbar dimming state */
1944 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1948 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1950 ModestMainWindow *main_window)
1954 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1959 if (modest_header_view_count_selected_headers (header_view) > 1) {
1960 hildon_banner_show_information (NULL, NULL, _("mcen_ib_select_one_message"));
1965 /* headers = tny_simple_list_new (); */
1966 /* tny_list_prepend (headers, G_OBJECT (header)); */
1967 headers = modest_header_view_get_selected_headers (header_view);
1969 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1971 g_object_unref (headers);
1975 set_active_account_from_tny_account (TnyAccount *account,
1976 ModestWindow *window)
1978 const gchar *server_acc_name = tny_account_get_id (account);
1980 /* We need the TnyAccount provided by the
1981 account store because that is the one that
1982 knows the name of the Modest account */
1983 TnyAccount *modest_server_account = modest_server_account =
1984 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1985 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1987 if (!modest_server_account) {
1988 g_warning ("%s: could not get tny account\n", __FUNCTION__);
1992 /* Update active account, but only if it's not a pseudo-account */
1993 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
1994 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
1995 const gchar *modest_acc_name =
1996 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1997 if (modest_acc_name)
1998 modest_window_set_active_account (window, modest_acc_name);
2001 g_object_unref (modest_server_account);
2006 folder_refreshed_cb (ModestMailOperation *mail_op,
2010 ModestMainWindow *win = NULL;
2011 GtkWidget *header_view;
2012 gboolean folder_empty = FALSE;
2013 gboolean all_marked_as_deleted = FALSE;
2015 g_return_if_fail (TNY_IS_FOLDER (folder));
2017 win = MODEST_MAIN_WINDOW (user_data);
2019 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2022 TnyFolder *current_folder;
2024 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
2025 if (current_folder != NULL && folder != current_folder) {
2026 g_object_unref (current_folder);
2029 g_object_unref (current_folder);
2032 /* Check if folder is empty and set headers view contents style */
2033 folder_empty = (tny_folder_get_all_count (folder) == 0);
2034 all_marked_as_deleted = modest_header_view_is_empty (MODEST_HEADER_VIEW(header_view));
2035 if (folder_empty || all_marked_as_deleted)
2036 modest_main_window_set_contents_style (win,
2037 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2041 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2042 TnyFolderStore *folder_store,
2044 ModestMainWindow *main_window)
2047 GtkWidget *header_view;
2049 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2051 header_view = modest_main_window_get_child_widget(main_window,
2052 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2056 conf = modest_runtime_get_conf ();
2058 if (TNY_IS_ACCOUNT (folder_store)) {
2060 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2062 /* Show account details */
2063 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2066 if (TNY_IS_FOLDER (folder_store) && selected) {
2068 /* Update the active account */
2069 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2071 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2072 g_object_unref (account);
2076 /* Set the header style by default, it could
2077 be changed later by the refresh callback to
2079 modest_main_window_set_contents_style (main_window,
2080 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2082 /* Set folder on header view. This function
2083 will call tny_folder_refresh_async so we
2084 pass a callback that will be called when
2085 finished. We use that callback to set the
2086 empty view if there are no messages */
2087 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2088 TNY_FOLDER (folder_store),
2089 folder_refreshed_cb,
2092 /* Restore configuration. We need to do this
2093 *after* the set_folder because the widget
2094 memory asks the header view about its
2096 modest_widget_memory_restore (modest_runtime_get_conf (),
2097 G_OBJECT(header_view),
2098 MODEST_CONF_HEADER_VIEW_KEY);
2100 /* Update the active account */
2101 //modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
2102 /* Save only if we're seeing headers */
2103 if (modest_main_window_get_contents_style (main_window) ==
2104 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2105 modest_widget_memory_save (conf, G_OBJECT (header_view),
2106 MODEST_CONF_HEADER_VIEW_KEY);
2107 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2111 /* Update toolbar dimming state */
2112 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2116 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2123 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2125 online = tny_device_is_online (modest_runtime_get_device());
2128 /* already online -- the item is simply not there... */
2129 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2131 GTK_MESSAGE_WARNING,
2133 _("The %s you selected cannot be found"),
2135 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2136 gtk_dialog_run (GTK_DIALOG(dialog));
2138 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2141 _("mcen_bd_dialog_cancel"),
2142 GTK_RESPONSE_REJECT,
2143 _("mcen_bd_dialog_ok"),
2144 GTK_RESPONSE_ACCEPT,
2146 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2147 "Do you want to get online?"), item);
2148 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2149 gtk_label_new (txt), FALSE, FALSE, 0);
2150 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2153 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2154 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2155 /* TODO: Comment about why is this commented out: */
2156 /* modest_platform_connect_and_wait (); */
2159 gtk_widget_destroy (dialog);
2163 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2166 /* g_message ("%s %s", __FUNCTION__, link); */
2171 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2174 modest_platform_activate_uri (link);
2178 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2181 modest_platform_show_uri_popup (link);
2185 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2188 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2192 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2193 const gchar *address,
2196 /* g_message ("%s %s", __FUNCTION__, address); */
2200 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2201 TnyMsg *saved_draft,
2204 ModestMsgEditWindow *edit_window;
2206 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2208 /* If there was any error do nothing */
2209 if (modest_mail_operation_get_error (mail_op) != NULL)
2212 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2216 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2218 TnyTransportAccount *transport_account;
2219 ModestMailOperation *mail_operation;
2221 gchar *account_name, *from;
2222 ModestAccountMgr *account_mgr;
2223 gchar *info_text = NULL;
2225 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2227 data = modest_msg_edit_window_get_msg_data (edit_window);
2229 account_name = g_strdup (data->account_name);
2230 account_mgr = modest_runtime_get_account_mgr();
2232 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2234 account_name = modest_account_mgr_get_default_account (account_mgr);
2235 if (!account_name) {
2236 g_printerr ("modest: no account found\n");
2237 modest_msg_edit_window_free_msg_data (edit_window, data);
2241 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2242 account_name = g_strdup (data->account_name);
2246 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2247 (modest_runtime_get_account_store(),
2249 TNY_ACCOUNT_TYPE_TRANSPORT));
2250 if (!transport_account) {
2251 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2252 g_free (account_name);
2253 modest_msg_edit_window_free_msg_data (edit_window, data);
2256 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2258 /* Create the mail operation */
2259 mail_operation = modest_mail_operation_new (G_OBJECT(edit_window));
2260 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2262 modest_mail_operation_save_to_drafts (mail_operation,
2274 data->priority_flags,
2275 on_save_to_drafts_cb,
2279 g_free (account_name);
2280 g_object_unref (G_OBJECT (transport_account));
2281 g_object_unref (G_OBJECT (mail_operation));
2283 modest_msg_edit_window_free_msg_data (edit_window, data);
2285 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2286 modest_platform_information_banner (NULL, NULL, info_text);
2287 modest_msg_edit_window_reset_modified (edit_window);
2291 /* For instance, when clicking the Send toolbar button when editing a message: */
2293 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2295 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2297 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2300 /* FIXME: Code added just for testing. The final version will
2301 use the send queue provided by tinymail and some
2303 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2305 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2306 gchar *account_name = g_strdup (data->account_name);
2308 g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2311 account_name = modest_account_mgr_get_default_account (account_mgr);
2313 if (!account_name) {
2314 modest_msg_edit_window_free_msg_data (edit_window, data);
2315 /* Run account setup wizard */
2316 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window)))
2320 /* Get the currently-active transport account for this modest account: */
2321 TnyTransportAccount *transport_account =
2322 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2323 (modest_runtime_get_account_store(),
2325 if (!transport_account) {
2326 /* Run account setup wizard */
2327 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2331 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2333 /* Create the mail operation */
2334 ModestMailOperation *mail_operation = modest_mail_operation_new (G_OBJECT(edit_window));
2335 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2337 modest_mail_operation_send_new_mail (mail_operation,
2349 data->priority_flags);
2353 g_free (account_name);
2354 g_object_unref (G_OBJECT (transport_account));
2355 g_object_unref (G_OBJECT (mail_operation));
2357 modest_msg_edit_window_free_msg_data (edit_window, data);
2358 modest_msg_edit_window_set_sent (edit_window, TRUE);
2360 /* Save settings and close the window: */
2361 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2365 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2366 ModestMsgEditWindow *window)
2368 ModestMsgEditFormatState *format_state = NULL;
2370 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2371 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2373 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2376 format_state = modest_msg_edit_window_get_format_state (window);
2377 g_return_if_fail (format_state != NULL);
2379 format_state->bold = gtk_toggle_action_get_active (action);
2380 modest_msg_edit_window_set_format_state (window, format_state);
2381 g_free (format_state);
2386 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2387 ModestMsgEditWindow *window)
2389 ModestMsgEditFormatState *format_state = NULL;
2391 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2392 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2394 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2397 format_state = modest_msg_edit_window_get_format_state (window);
2398 g_return_if_fail (format_state != NULL);
2400 format_state->italics = gtk_toggle_action_get_active (action);
2401 modest_msg_edit_window_set_format_state (window, format_state);
2402 g_free (format_state);
2407 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2408 ModestMsgEditWindow *window)
2410 ModestMsgEditFormatState *format_state = NULL;
2412 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2413 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2415 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2418 format_state = modest_msg_edit_window_get_format_state (window);
2419 g_return_if_fail (format_state != NULL);
2421 format_state->bullet = gtk_toggle_action_get_active (action);
2422 modest_msg_edit_window_set_format_state (window, format_state);
2423 g_free (format_state);
2428 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2429 GtkRadioAction *selected,
2430 ModestMsgEditWindow *window)
2432 ModestMsgEditFormatState *format_state = NULL;
2433 GtkJustification value;
2435 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2437 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2440 value = gtk_radio_action_get_current_value (selected);
2442 format_state = modest_msg_edit_window_get_format_state (window);
2443 g_return_if_fail (format_state != NULL);
2445 format_state->justification = value;
2446 modest_msg_edit_window_set_format_state (window, format_state);
2447 g_free (format_state);
2451 modest_ui_actions_on_select_editor_color (GtkAction *action,
2452 ModestMsgEditWindow *window)
2454 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2455 g_return_if_fail (GTK_IS_ACTION (action));
2457 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2460 modest_msg_edit_window_select_color (window);
2464 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2465 ModestMsgEditWindow *window)
2467 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2468 g_return_if_fail (GTK_IS_ACTION (action));
2470 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2473 modest_msg_edit_window_select_background_color (window);
2477 modest_ui_actions_on_insert_image (GtkAction *action,
2478 ModestMsgEditWindow *window)
2480 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2481 g_return_if_fail (GTK_IS_ACTION (action));
2483 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2486 modest_msg_edit_window_insert_image (window);
2490 modest_ui_actions_on_attach_file (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_offer_attach_file (window);
2500 modest_ui_actions_on_remove_attachments (GtkAction *action,
2501 ModestMsgEditWindow *window)
2503 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2504 g_return_if_fail (GTK_IS_ACTION (action));
2506 modest_msg_edit_window_remove_attachments (window, NULL);
2510 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2513 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2514 const GError *error = modest_mail_operation_get_error (mail_op);
2517 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2518 _("mail_in_ui_folder_create_error"));
2523 modest_ui_actions_create_folder(GtkWidget *parent_window,
2524 GtkWidget *folder_view)
2526 TnyFolderStore *parent_folder;
2528 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2530 if (parent_folder) {
2531 gboolean finished = FALSE;
2533 gchar *folder_name = NULL, *suggested_name = NULL;
2534 const gchar *proto_str = NULL;
2535 TnyAccount *account;
2537 if (TNY_IS_ACCOUNT (parent_folder))
2538 account = g_object_ref (parent_folder);
2540 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2541 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2543 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2544 MODEST_PROTOCOL_STORE_POP) {
2546 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2548 g_object_unref (account);
2550 /* Run the new folder dialog */
2552 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2557 g_free (suggested_name);
2558 suggested_name = NULL;
2560 if (result == GTK_RESPONSE_REJECT) {
2563 ModestMailOperation *mail_op;
2564 TnyFolder *new_folder = NULL;
2566 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
2567 modest_ui_actions_new_folder_error_handler,
2568 parent_window, NULL);
2570 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2572 new_folder = modest_mail_operation_create_folder (mail_op,
2574 (const gchar *) folder_name);
2576 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2579 g_object_unref (new_folder);
2582 g_object_unref (mail_op);
2585 suggested_name = folder_name;
2589 g_object_unref (parent_folder);
2594 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2596 GtkWidget *folder_view;
2598 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2600 folder_view = modest_main_window_get_child_widget (main_window,
2601 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2605 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2609 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2612 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2613 const GError *error = NULL;
2614 const gchar *message = NULL;
2616 /* Get error message */
2617 error = modest_mail_operation_get_error (mail_op);
2619 g_return_if_reached ();
2621 switch (error->code) {
2622 case MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS:
2623 message = _CS("ckdg_ib_folder_already_exists");
2626 g_return_if_reached ();
2629 modest_platform_information_banner (GTK_WIDGET (window), NULL, message);
2633 modest_ui_actions_on_rename_folder (GtkAction *action,
2634 ModestMainWindow *main_window)
2636 TnyFolderStore *folder;
2637 GtkWidget *folder_view;
2638 GtkWidget *header_view;
2640 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2642 folder_view = modest_main_window_get_child_widget (main_window,
2643 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2647 header_view = modest_main_window_get_child_widget (main_window,
2648 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2653 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2658 if (TNY_IS_FOLDER (folder)) {
2661 const gchar *current_name;
2662 TnyFolderStore *parent;
2663 gboolean do_rename = TRUE;
2665 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2666 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
2667 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
2668 parent, current_name,
2670 g_object_unref (parent);
2672 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
2674 } else if (modest_platform_is_network_folderstore(folder) &&
2675 !tny_device_is_online (modest_runtime_get_device())) {
2676 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2677 do_rename = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2678 g_object_unref(account);
2682 ModestMailOperation *mail_op;
2683 GtkTreeSelection *sel = NULL;
2686 modest_mail_operation_new_with_error_handling (G_OBJECT(main_window),
2687 modest_ui_actions_rename_folder_error_handler,
2690 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2693 /* Clear the headers view */
2694 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2695 gtk_tree_selection_unselect_all (sel);
2697 /* Select *after* the changes */
2698 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2699 TNY_FOLDER(folder), TRUE);
2701 /* Actually rename the folder */
2702 modest_mail_operation_rename_folder (mail_op,
2703 TNY_FOLDER (folder),
2704 (const gchar *) folder_name);
2706 g_object_unref (mail_op);
2707 g_free (folder_name);
2710 g_object_unref (folder);
2714 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2717 GObject *win = modest_mail_operation_get_source (mail_op);
2719 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2720 _("mail_in_ui_folder_delete_error"));
2721 g_object_unref (win);
2725 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2727 TnyFolderStore *folder;
2728 GtkWidget *folder_view;
2731 gboolean do_delete = TRUE;
2733 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (main_window), FALSE);
2735 folder_view = modest_main_window_get_child_widget (main_window,
2736 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2740 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2742 /* Show an error if it's an account */
2743 if (!TNY_IS_FOLDER (folder)) {
2744 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2745 _("mail_in_ui_folder_delete_error"));
2746 g_object_unref (G_OBJECT (folder));
2751 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2752 tny_folder_get_name (TNY_FOLDER (folder)));
2753 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2754 (const gchar *) message);
2757 if (response != GTK_RESPONSE_OK) {
2759 } else if (modest_platform_is_network_folderstore(folder) &&
2760 !tny_device_is_online (modest_runtime_get_device())) {
2761 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2762 do_delete = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2763 g_object_unref(account);
2767 ModestMailOperation *mail_op;
2768 GtkTreeSelection *sel;
2770 /* Unselect the folder before deleting it to free the headers */
2771 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2772 gtk_tree_selection_unselect_all (sel);
2774 /* Create the mail operation */
2776 modest_mail_operation_new_with_error_handling (G_OBJECT(main_window),
2777 modest_ui_actions_delete_folder_error_handler,
2780 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2782 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2783 g_object_unref (G_OBJECT (mail_op));
2786 g_object_unref (G_OBJECT (folder));
2792 modest_ui_actions_on_delete_folder (GtkAction *action,
2793 ModestMainWindow *main_window)
2795 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2797 if (delete_folder (main_window, FALSE)) {
2798 GtkWidget *folder_view;
2800 folder_view = modest_main_window_get_child_widget (main_window,
2801 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2802 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2807 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2809 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2811 delete_folder (main_window, TRUE);
2816 show_error (GtkWidget *parent_widget, const gchar* text)
2818 hildon_banner_show_information(parent_widget, NULL, text);
2821 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2823 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2830 gtk_dialog_run (dialog);
2831 gtk_widget_destroy (GTK_WIDGET (dialog));
2836 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2837 const gchar* server_account_name,
2842 ModestMainWindow *main_window)
2844 g_return_if_fail(server_account_name);
2845 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2847 /* Initalize output parameters: */
2854 #ifdef MODEST_PLATFORM_MAEMO
2855 /* Maemo uses a different (awkward) button order,
2856 * It should probably just use gtk_alternative_dialog_button_order ().
2858 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2861 _("mcen_bd_dialog_ok"),
2862 GTK_RESPONSE_ACCEPT,
2863 _("mcen_bd_dialog_cancel"),
2864 GTK_RESPONSE_REJECT,
2867 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2871 GTK_RESPONSE_REJECT,
2873 GTK_RESPONSE_ACCEPT,
2875 #endif /* MODEST_PLATFORM_MAEMO */
2877 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2879 gchar *server_name = modest_account_mgr_get_server_account_hostname (
2880 modest_runtime_get_account_mgr(), server_account_name);
2881 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2882 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2887 /* This causes a warning because the logical ID has no %s in it,
2888 * though the translation does, but there is not much we can do about that: */
2889 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2890 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2893 g_free (server_name);
2897 gchar *initial_username = modest_account_mgr_get_server_account_username (
2898 modest_runtime_get_account_mgr(), server_account_name);
2900 GtkWidget *entry_username = gtk_entry_new ();
2901 if (initial_username)
2902 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2903 /* Dim this if a connection has ever succeeded with this username,
2904 * as per the UI spec: */
2905 const gboolean username_known =
2906 modest_account_mgr_get_server_account_username_has_succeeded(
2907 modest_runtime_get_account_mgr(), server_account_name);
2908 gtk_widget_set_sensitive (entry_username, !username_known);
2910 #ifdef MODEST_PLATFORM_MAEMO
2911 /* Auto-capitalization is the default, so let's turn it off: */
2912 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2914 /* Create a size group to be used by all captions.
2915 * Note that HildonCaption does not create a default size group if we do not specify one.
2916 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2917 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2919 GtkWidget *caption = hildon_caption_new (sizegroup,
2920 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2921 gtk_widget_show (entry_username);
2922 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2923 FALSE, FALSE, MODEST_MARGIN_HALF);
2924 gtk_widget_show (caption);
2926 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2928 #endif /* MODEST_PLATFORM_MAEMO */
2931 GtkWidget *entry_password = gtk_entry_new ();
2932 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2933 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2935 #ifdef MODEST_PLATFORM_MAEMO
2936 /* Auto-capitalization is the default, so let's turn it off: */
2937 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2938 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2940 caption = hildon_caption_new (sizegroup,
2941 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2942 gtk_widget_show (entry_password);
2943 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2944 FALSE, FALSE, MODEST_MARGIN_HALF);
2945 gtk_widget_show (caption);
2946 g_object_unref (sizegroup);
2948 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2950 #endif /* MODEST_PLATFORM_MAEMO */
2952 if (initial_username != NULL)
2953 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
2955 /* This is not in the Maemo UI spec:
2956 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2957 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2961 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2963 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2965 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2967 modest_account_mgr_set_server_account_username (
2968 modest_runtime_get_account_mgr(), server_account_name,
2971 const gboolean username_was_changed =
2972 (strcmp (*username, initial_username) != 0);
2973 if (username_was_changed) {
2974 g_warning ("%s: tinymail does not yet support changing the "
2975 "username in the get_password() callback.\n", __FUNCTION__);
2980 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2982 /* We do not save the password in the configuration,
2983 * because this function is only called for passwords that should
2984 * not be remembered:
2985 modest_server_account_set_password (
2986 modest_runtime_get_account_mgr(), server_account_name,
2995 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
3007 /* This is not in the Maemo UI spec:
3008 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3014 gtk_widget_destroy (dialog);
3016 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3020 modest_ui_actions_on_cut (GtkAction *action,
3021 ModestWindow *window)
3023 GtkWidget *focused_widget;
3024 GtkClipboard *clipboard;
3026 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3027 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3028 if (GTK_IS_EDITABLE (focused_widget)) {
3029 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3030 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3031 gtk_clipboard_store (clipboard);
3032 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3033 GtkTextBuffer *buffer;
3035 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3036 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3037 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3038 gtk_clipboard_store (clipboard);
3039 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3040 TnyList *header_list = modest_header_view_get_selected_headers (
3041 MODEST_HEADER_VIEW (focused_widget));
3042 gboolean continue_download = FALSE;
3043 gint num_of_unc_msgs;
3045 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3047 if (num_of_unc_msgs) {
3048 TnyAccount *account = get_account_from_header_list (header_list);
3049 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3050 g_object_unref (account);
3053 if (num_of_unc_msgs == 0 || continue_download) {
3054 /* modest_platform_information_banner (
3055 NULL, NULL, _CS("mcen_ib_getting_items"));*/
3056 modest_header_view_cut_selection (
3057 MODEST_HEADER_VIEW (focused_widget));
3060 g_object_unref (header_list);
3061 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3062 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3067 modest_ui_actions_on_copy (GtkAction *action,
3068 ModestWindow *window)
3070 GtkClipboard *clipboard;
3071 GtkWidget *focused_widget;
3072 gboolean copied = TRUE;
3074 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3075 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3077 if (GTK_IS_LABEL (focused_widget)) {
3078 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
3079 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3080 gtk_clipboard_store (clipboard);
3081 } else if (GTK_IS_EDITABLE (focused_widget)) {
3082 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3083 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3084 gtk_clipboard_store (clipboard);
3085 } else if (GTK_IS_HTML (focused_widget)) {
3086 gtk_html_copy (GTK_HTML (focused_widget));
3087 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3088 gtk_clipboard_store (clipboard);
3089 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3090 GtkTextBuffer *buffer;
3091 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3092 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3093 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3094 gtk_clipboard_store (clipboard);
3095 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3096 TnyList *header_list = modest_header_view_get_selected_headers (
3097 MODEST_HEADER_VIEW (focused_widget));
3098 gboolean continue_download = FALSE;
3099 gint num_of_unc_msgs;
3101 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3103 if (num_of_unc_msgs) {
3104 TnyAccount *account = get_account_from_header_list (header_list);
3105 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3106 g_object_unref (account);
3109 if (num_of_unc_msgs == 0 || continue_download) {
3110 modest_platform_information_banner (
3111 NULL, NULL, _CS("mcen_ib_getting_items"));
3112 modest_header_view_copy_selection (
3113 MODEST_HEADER_VIEW (focused_widget));
3117 g_object_unref (header_list);
3119 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3120 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3123 /* Show information banner if there was a copy to clipboard */
3125 modest_platform_information_banner (
3126 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3130 modest_ui_actions_on_undo (GtkAction *action,
3131 ModestWindow *window)
3133 ModestEmailClipboard *clipboard = NULL;
3135 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3136 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3137 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3138 /* Clear clipboard source */
3139 clipboard = modest_runtime_get_email_clipboard ();
3140 modest_email_clipboard_clear (clipboard);
3143 g_return_if_reached ();
3148 modest_ui_actions_on_redo (GtkAction *action,
3149 ModestWindow *window)
3151 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3152 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3155 g_return_if_reached ();
3161 destroy_information_note (ModestMailOperation *mail_op, gpointer user_data)
3163 /* destroy information note */
3164 gtk_widget_destroy (GTK_WIDGET(user_data));
3169 paste_as_attachment_free (gpointer data)
3171 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3173 gtk_widget_destroy (helper->banner);
3174 g_object_unref (helper->banner);
3179 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3184 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3185 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3190 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3195 modest_ui_actions_on_paste (GtkAction *action,
3196 ModestWindow *window)
3198 GtkWidget *focused_widget = NULL;
3199 GtkWidget *inf_note = NULL;
3200 ModestMailOperation *mail_op = NULL;
3202 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3203 if (GTK_IS_EDITABLE (focused_widget)) {
3204 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3205 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3206 ModestEmailClipboard *e_clipboard = NULL;
3207 e_clipboard = modest_runtime_get_email_clipboard ();
3208 if (modest_email_clipboard_cleared (e_clipboard)) {
3209 GtkTextBuffer *buffer;
3210 GtkClipboard *clipboard;
3212 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3213 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3214 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3215 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3216 ModestMailOperation *mail_op;
3217 TnyFolder *src_folder;
3220 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3221 helper->window = MODEST_MSG_EDIT_WINDOW (window);
3222 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3223 _CS("ckct_nw_pasting"));
3224 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
3225 mail_op = modest_mail_operation_new (G_OBJECT (window));
3226 if (helper->banner != NULL) {
3227 g_object_ref (G_OBJECT (helper->banner));
3228 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
3229 gtk_widget_show (GTK_WIDGET (helper->banner));
3233 modest_mail_operation_get_msgs_full (mail_op,
3235 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
3237 paste_as_attachment_free);
3240 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3241 ModestEmailClipboard *clipboard = NULL;
3242 TnyFolder *src_folder = NULL;
3243 TnyFolderStore *folder_store = NULL;
3244 TnyList *data = NULL;
3245 gboolean delete = FALSE;
3247 /* Check clipboard source */
3248 clipboard = modest_runtime_get_email_clipboard ();
3249 if (modest_email_clipboard_cleared (clipboard))
3252 /* Get elements to paste */
3253 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
3255 /* Create a new mail operation */
3256 mail_op = modest_mail_operation_new (G_OBJECT(window));
3258 /* Get destination folder */
3259 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
3261 /* transfer messages */
3265 /* Ask for user confirmation */
3267 modest_ui_actions_msgs_move_to_confirmation (window,
3268 TNY_FOLDER (folder_store),
3272 if (response == GTK_RESPONSE_OK) {
3273 /* Launch notification */
3274 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3275 _CS("ckct_nw_pasting"));
3276 if (inf_note != NULL) {
3277 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3278 gtk_widget_show (GTK_WIDGET(inf_note));
3281 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3282 modest_mail_operation_xfer_msgs (mail_op,
3284 TNY_FOLDER (folder_store),
3286 destroy_information_note,
3289 g_object_unref (mail_op);
3292 } else if (src_folder != NULL) {
3293 /* Launch notification */
3294 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3295 _CS("ckct_nw_pasting"));
3296 if (inf_note != NULL) {
3297 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3298 gtk_widget_show (GTK_WIDGET(inf_note));
3301 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3302 modest_mail_operation_xfer_folder (mail_op,
3306 destroy_information_note,
3312 g_object_unref (data);
3313 if (src_folder != NULL)
3314 g_object_unref (src_folder);
3315 if (folder_store != NULL)
3316 g_object_unref (folder_store);
3322 modest_ui_actions_on_select_all (GtkAction *action,
3323 ModestWindow *window)
3325 GtkWidget *focused_widget;
3327 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3328 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3329 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3330 } else if (GTK_IS_LABEL (focused_widget)) {
3331 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3332 } else if (GTK_IS_EDITABLE (focused_widget)) {
3333 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3334 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3335 GtkTextBuffer *buffer;
3336 GtkTextIter start, end;
3338 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3339 gtk_text_buffer_get_start_iter (buffer, &start);
3340 gtk_text_buffer_get_end_iter (buffer, &end);
3341 gtk_text_buffer_select_range (buffer, &start, &end);
3342 } else if (GTK_IS_HTML (focused_widget)) {
3343 gtk_html_select_all (GTK_HTML (focused_widget));
3344 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3345 GtkWidget *header_view = focused_widget;
3346 GtkTreeSelection *selection = NULL;
3348 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
3349 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3350 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3353 /* Disable window dimming management */
3354 modest_window_disable_dimming (MODEST_WINDOW(window));
3356 /* Select all messages */
3357 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3358 gtk_tree_selection_select_all (selection);
3360 /* Set focuse on header view */
3361 gtk_widget_grab_focus (header_view);
3364 /* Enable window dimming management */
3365 modest_window_enable_dimming (MODEST_WINDOW(window));
3366 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3372 modest_ui_actions_on_mark_as_read (GtkAction *action,
3373 ModestWindow *window)
3375 g_return_if_fail (MODEST_IS_WINDOW(window));
3377 /* Mark each header as read */
3378 do_headers_action (window, headers_action_mark_as_read, NULL);
3382 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3383 ModestWindow *window)
3385 g_return_if_fail (MODEST_IS_WINDOW(window));
3387 /* Mark each header as read */
3388 do_headers_action (window, headers_action_mark_as_unread, NULL);
3392 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3393 GtkRadioAction *selected,
3394 ModestWindow *window)
3398 value = gtk_radio_action_get_current_value (selected);
3399 if (MODEST_IS_WINDOW (window)) {
3400 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3405 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3406 GtkRadioAction *selected,
3407 ModestWindow *window)
3409 TnyHeaderFlags flags;
3410 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3412 flags = gtk_radio_action_get_current_value (selected);
3413 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3417 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3418 GtkRadioAction *selected,
3419 ModestWindow *window)
3423 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3425 file_format = gtk_radio_action_get_current_value (selected);
3426 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3431 modest_ui_actions_on_zoom_plus (GtkAction *action,
3432 ModestWindow *window)
3434 g_return_if_fail (MODEST_IS_WINDOW (window));
3436 modest_window_zoom_plus (MODEST_WINDOW (window));
3440 modest_ui_actions_on_zoom_minus (GtkAction *action,
3441 ModestWindow *window)
3443 g_return_if_fail (MODEST_IS_WINDOW (window));
3445 modest_window_zoom_minus (MODEST_WINDOW (window));
3449 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3450 ModestWindow *window)
3452 ModestWindowMgr *mgr;
3453 gboolean fullscreen, active;
3454 g_return_if_fail (MODEST_IS_WINDOW (window));
3456 mgr = modest_runtime_get_window_mgr ();
3458 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3459 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3461 if (active != fullscreen) {
3462 modest_window_mgr_set_fullscreen_mode (mgr, active);
3463 gtk_window_present (GTK_WINDOW (window));
3468 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3469 ModestWindow *window)
3471 ModestWindowMgr *mgr;
3472 gboolean fullscreen;
3474 g_return_if_fail (MODEST_IS_WINDOW (window));
3476 mgr = modest_runtime_get_window_mgr ();
3477 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3478 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3480 gtk_window_present (GTK_WINDOW (window));
3484 * Used by modest_ui_actions_on_details to call do_headers_action
3487 headers_action_show_details (TnyHeader *header,
3488 ModestWindow *window,
3495 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3498 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3499 gtk_widget_show_all (dialog);
3500 gtk_dialog_run (GTK_DIALOG (dialog));
3502 gtk_widget_destroy (dialog);
3506 * Show the folder details in a ModestDetailsDialog widget
3509 show_folder_details (TnyFolder *folder,
3515 dialog = modest_details_dialog_new_with_folder (window, folder);
3518 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3519 gtk_widget_show_all (dialog);
3520 gtk_dialog_run (GTK_DIALOG (dialog));
3522 gtk_widget_destroy (dialog);
3526 * Show the header details in a ModestDetailsDialog widget
3529 modest_ui_actions_on_details (GtkAction *action,
3532 TnyList * headers_list;
3536 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3539 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3542 g_object_unref (msg);
3544 headers_list = get_selected_headers (win);
3548 iter = tny_list_create_iterator (headers_list);
3550 header = TNY_HEADER (tny_iterator_get_current (iter));
3552 headers_action_show_details (header, win, NULL);
3553 g_object_unref (header);
3556 g_object_unref (iter);
3557 g_object_unref (headers_list);
3559 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3560 GtkWidget *folder_view, *header_view;
3562 /* Check which widget has the focus */
3563 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3564 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3565 if (gtk_widget_is_focus (folder_view)) {
3566 TnyFolderStore *folder_store
3567 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3568 if (!folder_store) {
3569 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3572 /* Show only when it's a folder */
3573 /* This function should not be called for account items,
3574 * because we dim the menu item for them. */
3575 if (TNY_IS_FOLDER (folder_store)) {
3576 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3579 g_object_unref (folder_store);
3582 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3583 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3584 /* Show details of each header */
3585 do_headers_action (win, headers_action_show_details, header_view);
3591 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3592 ModestMsgEditWindow *window)
3594 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3596 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3600 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3601 ModestMsgEditWindow *window)
3603 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3605 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3609 modest_ui_actions_toggle_folders_view (GtkAction *action,
3610 ModestMainWindow *main_window)
3612 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3614 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3615 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3617 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3621 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3622 ModestWindow *window)
3624 gboolean active, fullscreen = FALSE;
3625 ModestWindowMgr *mgr;
3627 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3629 /* Check if we want to toggle the toolbar vuew in fullscreen
3631 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3632 "ViewShowToolbarFullScreen")) {
3636 /* Toggle toolbar */
3637 mgr = modest_runtime_get_window_mgr ();
3638 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
3642 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3643 ModestMsgEditWindow *window)
3645 modest_msg_edit_window_select_font (window);
3649 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3650 const gchar *display_name,
3653 /* Do not change the application name if the widget has not
3654 the focus. This callback could be called even if the folder
3655 view has not the focus, because the handled signal could be
3656 emitted when the folder view is redrawn */
3657 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3659 gtk_window_set_title (window, display_name);
3661 gtk_window_set_title (window, " ");
3666 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3668 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3669 modest_msg_edit_window_select_contacts (window);
3673 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3675 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3676 modest_msg_edit_window_check_names (window, FALSE);
3680 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3682 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3683 GTK_WIDGET (user_data));
3687 * This function is used to track changes in the selection of the
3688 * folder view that is inside the "move to" dialog to enable/disable
3689 * the OK button because we do not want the user to select a disallowed
3690 * destination for a folder.
3691 * The user also not desired to be able to use NEW button on items where
3692 * folder creation is not possibel.
3695 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
3696 TnyFolderStore *folder_store,
3700 GtkWidget *dialog = NULL;
3701 GtkWidget *ok_button = NULL, *new_button = NULL;
3702 GList *children = NULL;
3703 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
3704 gboolean moving_folder = FALSE;
3705 gboolean is_local_account = TRUE;
3706 GtkWidget *folder_view = NULL;
3707 ModestTnyFolderRules rules;
3712 /* Get the OK button */
3713 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
3717 children = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
3718 ok_button = GTK_WIDGET (children->next->next->data);
3719 new_button = GTK_WIDGET (children->next->data);
3720 g_list_free (children);
3722 /* check if folder_store is an remote account */
3723 if (TNY_IS_ACCOUNT (folder_store)) {
3724 TnyAccount *local_account = NULL;
3725 ModestTnyAccountStore *account_store = NULL;
3727 account_store = modest_runtime_get_account_store ();
3728 local_account = modest_tny_account_store_get_local_folders_account (account_store);
3730 if ((gpointer) local_account != (gpointer) folder_store) {
3731 is_local_account = FALSE;
3732 /* New button should be dimmed on remote
3734 new_sensitive = FALSE;
3736 g_object_unref (local_account);
3739 /* Check the target folder rules */
3740 if (TNY_IS_FOLDER (folder_store)) {
3741 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
3742 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
3743 ok_sensitive = FALSE;
3744 new_sensitive = FALSE;
3749 /* Check if we're moving a folder */
3750 if (MODEST_IS_MAIN_WINDOW (user_data)) {
3751 /* Get the widgets */
3752 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
3753 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3754 if (gtk_widget_is_focus (folder_view))
3755 moving_folder = TRUE;
3758 if (moving_folder) {
3759 TnyFolderStore *moved_folder = NULL, *parent = NULL;
3761 /* Get the folder to move */
3762 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3764 /* Check that we're not moving to the same folder */
3765 if (TNY_IS_FOLDER (moved_folder)) {
3766 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
3767 if (parent == folder_store)
3768 ok_sensitive = FALSE;
3769 g_object_unref (parent);
3772 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
3773 /* Do not allow to move to an account unless it's the
3774 local folders account */
3775 if (!is_local_account)
3776 ok_sensitive = FALSE;
3779 if (ok_sensitive && (moved_folder == folder_store)) {
3780 /* Do not allow to move to itself */
3781 ok_sensitive = FALSE;
3783 g_object_unref (moved_folder);
3785 TnyHeader *header = NULL;
3786 TnyFolder *src_folder = NULL;
3788 /* Moving a message */
3789 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
3790 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (user_data));
3791 src_folder = tny_header_get_folder (header);
3792 g_object_unref (header);
3795 TNY_FOLDER (modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view)));
3798 /* Do not allow to move the msg to the same folder */
3799 /* Do not allow to move the msg to an account */
3800 if ((gpointer) src_folder == (gpointer) folder_store ||
3801 TNY_IS_ACCOUNT (folder_store))
3802 ok_sensitive = FALSE;
3803 g_object_unref (src_folder);
3807 /* Set sensitivity of the OK button */
3808 gtk_widget_set_sensitive (ok_button, ok_sensitive);
3809 /* Set sensitivity of the NEW button */
3810 gtk_widget_set_sensitive (new_button, new_sensitive);
3814 create_move_to_dialog (GtkWindow *win,
3815 GtkWidget *folder_view,
3816 GtkWidget **tree_view)
3818 GtkWidget *dialog, *scroll;
3819 GtkWidget *new_button;
3821 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3823 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3826 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
3827 /* We do this manually so GTK+ does not associate a response ID for
3829 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
3830 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3831 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
3833 /* Create scrolled window */
3834 scroll = gtk_scrolled_window_new (NULL, NULL);
3835 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3836 GTK_POLICY_AUTOMATIC,
3837 GTK_POLICY_AUTOMATIC);
3839 /* Create folder view */
3840 *tree_view = modest_platform_create_folder_view (NULL);
3842 /* Track changes in the selection to
3843 * disable the OK button whenever "Move to" is not possible
3844 * disbale NEW button whenever New is not possible */
3845 g_signal_connect (*tree_view,
3846 "folder_selection_changed",
3847 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
3850 /* Listen to clicks on New button */
3851 g_signal_connect (G_OBJECT (new_button),
3853 G_CALLBACK(create_move_to_dialog_on_new_folder),
3856 /* It could happen that we're trying to move a message from a
3857 window (msg window for example) after the main window was
3858 closed, so we can not just get the model of the folder
3860 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
3861 const gchar *visible_id = NULL;
3863 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
3864 MODEST_FOLDER_VIEW(*tree_view));
3867 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
3869 /* Show the same account than the one that is shown in the main window */
3870 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
3873 const gchar *active_account_name = NULL;
3874 ModestAccountMgr *mgr = NULL;
3875 ModestAccountData *acc_data = NULL;
3877 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3878 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3880 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
3881 mgr = modest_runtime_get_account_mgr ();
3882 acc_data = modest_account_mgr_get_account_data (mgr, active_account_name);
3884 /* Set the new visible & active account */
3885 if (acc_data && acc_data->store_account) {
3886 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
3887 acc_data->store_account->account_name);
3888 modest_account_mgr_free_account_data (mgr, acc_data);
3892 /* Hide special folders */
3893 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3895 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3897 /* Add scroll to dialog */
3898 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3899 scroll, TRUE, TRUE, 0);
3901 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3902 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3908 * Returns TRUE if at least one of the headers of the list belongs to
3909 * a message that has been fully retrieved.
3911 #if 0 /* no longer in use. delete in 2007.10 */
3913 has_retrieved_msgs (TnyList *list)
3916 gboolean found = FALSE;
3918 iter = tny_list_create_iterator (list);
3919 while (!tny_iterator_is_done (iter) && !found) {
3921 TnyHeaderFlags flags = 0;
3923 header = TNY_HEADER (tny_iterator_get_current (iter));
3925 flags = tny_header_get_flags (header);
3926 if (flags & TNY_HEADER_FLAG_CACHED)
3927 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3930 g_object_unref (header);
3934 tny_iterator_next (iter);
3936 g_object_unref (iter);
3944 * Shows a confirmation dialog to the user when we're moving messages
3945 * from a remote server to the local storage. Returns the dialog
3946 * response. If it's other kind of movement then it always returns
3949 * This one is used by the next functions:
3950 * modest_ui_actions_on_paste - commented out
3951 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
3954 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
3955 TnyFolder *dest_folder,
3959 gint response = GTK_RESPONSE_OK;
3960 TnyAccount *account = NULL;
3961 TnyFolder *src_folder = NULL;
3962 TnyIterator *iter = NULL;
3963 TnyHeader *header = NULL;
3965 /* return with OK if the destination is a remote folder */
3966 if (modest_tny_folder_is_remote_folder (dest_folder))
3967 return GTK_RESPONSE_OK;
3969 /* Get source folder */
3970 iter = tny_list_create_iterator (headers);
3971 header = TNY_HEADER (tny_iterator_get_current (iter));
3973 src_folder = tny_header_get_folder (header);
3974 g_object_unref (header);
3976 g_object_unref (iter);
3978 /* if no src_folder, message may be an attahcment */
3979 if (src_folder == NULL)
3980 return GTK_RESPONSE_CANCEL;
3982 /* If the source is a local or MMC folder */
3983 if (!modest_tny_folder_is_remote_folder (src_folder)) {
3984 g_object_unref (src_folder);
3985 return GTK_RESPONSE_OK;
3988 /* Get the account */
3989 account = tny_folder_get_account (src_folder);
3991 /* now if offline we ask the user */
3992 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
3993 response = GTK_RESPONSE_OK;
3995 response = GTK_RESPONSE_CANCEL;
3998 g_object_unref (src_folder);
3999 g_object_unref (account);
4007 move_to_cb (ModestMailOperation *mail_op, gpointer user_data)
4009 MoveToHelper *helper = (MoveToHelper *) user_data;
4011 /* Note that the operation could have failed, in that case do
4013 if (modest_mail_operation_get_status (mail_op) ==
4014 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
4016 GObject *object = modest_mail_operation_get_source (mail_op);
4017 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4018 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4020 if (!modest_msg_view_window_select_next_message (self))
4021 if (!modest_msg_view_window_select_previous_message (self))
4022 /* No more messages to view, so close this window */
4023 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4024 } else if (MODEST_IS_MAIN_WINDOW (object) && helper->reference != NULL) {
4025 GtkWidget *header_view;
4027 GtkTreeSelection *sel;
4029 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4030 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4031 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
4032 path = gtk_tree_row_reference_get_path (helper->reference);
4033 gtk_tree_selection_select_path (sel, path);
4034 gtk_tree_path_free (path);
4036 g_object_unref (object);
4039 /* Close the "Pasting" information banner */
4040 gtk_widget_destroy (GTK_WIDGET(helper->banner));
4041 if (helper->reference != NULL)
4042 gtk_tree_row_reference_free (helper->reference);
4047 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
4050 ModestWindow *main_window = NULL;
4051 GtkWidget *folder_view = NULL;
4052 GObject *win = modest_mail_operation_get_source (mail_op);
4053 const GError *error = NULL;
4054 const gchar *message = NULL;
4056 /* Get error message */
4057 error = modest_mail_operation_get_error (mail_op);
4058 if (error != NULL && error->message != NULL) {
4059 message = error->message;
4061 message = _("mail_in_ui_folder_move_target_error");
4064 /* Disable next automatic folder selection */
4065 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ());
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 ()));
4458 /* Get the folder view widget if exists */
4460 folder_view = modest_main_window_get_child_widget (main_window,
4461 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4465 /* Create and run the dialog */
4466 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
4467 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
4468 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4469 result = gtk_dialog_run (GTK_DIALOG(dialog));
4470 g_object_ref (tree_view);
4471 gtk_widget_destroy (dialog);
4473 if (result != GTK_RESPONSE_ACCEPT)
4476 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
4477 /* Do window specific stuff */
4478 if (MODEST_IS_MAIN_WINDOW (win)) {
4479 modest_ui_actions_on_main_window_move_to (action,
4482 MODEST_MAIN_WINDOW (win));
4484 modest_ui_actions_on_msg_view_window_move_to (action,
4486 MODEST_MSG_VIEW_WINDOW (win));
4490 g_object_unref (dst_folder);
4494 * Calls #HeadersFunc for each header already selected in the main
4495 * window or the message currently being shown in the msg view window
4498 do_headers_action (ModestWindow *win,
4502 TnyList *headers_list = NULL;
4503 TnyIterator *iter = NULL;
4504 TnyHeader *header = NULL;
4505 TnyFolder *folder = NULL;
4508 headers_list = get_selected_headers (win);
4512 /* Get the folder */
4513 iter = tny_list_create_iterator (headers_list);
4514 header = TNY_HEADER (tny_iterator_get_current (iter));
4516 folder = tny_header_get_folder (header);
4517 g_object_unref (header);
4520 /* Call the function for each header */
4521 while (!tny_iterator_is_done (iter)) {
4522 header = TNY_HEADER (tny_iterator_get_current (iter));
4523 func (header, win, user_data);
4524 g_object_unref (header);
4525 tny_iterator_next (iter);
4528 /* Trick: do a poke status in order to speed up the signaling
4530 tny_folder_poke_status (folder);
4533 g_object_unref (folder);
4534 g_object_unref (iter);
4535 g_object_unref (headers_list);
4539 modest_ui_actions_view_attachment (GtkAction *action,
4540 ModestWindow *window)
4542 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4543 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4545 /* not supported window for this action */
4546 g_return_if_reached ();
4551 modest_ui_actions_save_attachments (GtkAction *action,
4552 ModestWindow *window)
4554 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4555 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4557 /* not supported window for this action */
4558 g_return_if_reached ();
4563 modest_ui_actions_remove_attachments (GtkAction *action,
4564 ModestWindow *window)
4566 if (MODEST_IS_MAIN_WINDOW (window)) {
4567 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4568 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4569 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4571 /* not supported window for this action */
4572 g_return_if_reached ();
4577 modest_ui_actions_on_settings (GtkAction *action,
4582 dialog = modest_platform_get_global_settings_dialog ();
4583 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4584 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4585 gtk_widget_show_all (dialog);
4587 gtk_dialog_run (GTK_DIALOG (dialog));
4589 gtk_widget_destroy (dialog);
4593 modest_ui_actions_on_help (GtkAction *action,
4596 const gchar *help_id = NULL;
4598 if (MODEST_IS_MAIN_WINDOW (win)) {
4599 GtkWidget *folder_view;
4600 TnyFolderStore *folder_store;
4602 /* Get selected folder */
4603 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4604 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4605 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4607 /* Switch help_id */
4608 if (TNY_IS_FOLDER (folder_store)) {
4609 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4610 case TNY_FOLDER_TYPE_NORMAL:
4611 help_id = "applications_email_managefolders";
4613 case TNY_FOLDER_TYPE_INBOX:
4614 help_id = "applications_email_inbox";
4616 case TNY_FOLDER_TYPE_OUTBOX:
4617 help_id = "applications_email_outbox";
4619 case TNY_FOLDER_TYPE_SENT:
4620 help_id = "applications_email_sent";
4622 case TNY_FOLDER_TYPE_DRAFTS:
4623 help_id = "applications_email_drafts";
4625 case TNY_FOLDER_TYPE_ARCHIVE:
4626 help_id = "applications_email_managefolders";
4629 help_id = "applications_email_managefolders";
4632 help_id = "applications_email_mainview";
4634 g_object_unref (folder_store);
4635 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4636 help_id = "applications_email_viewer";
4637 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4638 help_id = "applications_email_editor";
4640 modest_platform_show_help (GTK_WINDOW (win), help_id);
4644 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4645 ModestWindow *window)
4647 ModestMailOperation *mail_op;
4651 headers = get_selected_headers (window);
4655 /* Create mail operation */
4656 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (window),
4657 modest_ui_actions_get_msgs_full_error_handler,
4659 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4660 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4663 g_object_unref (headers);
4664 g_object_unref (mail_op);
4668 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4669 ModestWindow *window)
4671 g_return_if_fail (MODEST_IS_WINDOW (window));
4674 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4678 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4679 ModestWindow *window)
4681 g_return_if_fail (MODEST_IS_WINDOW (window));
4684 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4688 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4689 ModestWindow *window)
4691 g_return_if_fail (MODEST_IS_WINDOW (window));
4694 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4698 modest_ui_actions_on_format_menu_activated (GtkAction *action,
4699 ModestWindow *window)
4701 g_return_if_fail (MODEST_IS_WINDOW (window));
4704 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4708 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4709 ModestWindow *window)
4711 g_return_if_fail (MODEST_IS_WINDOW (window));
4714 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4718 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4719 ModestWindow *window)
4721 g_return_if_fail (MODEST_IS_WINDOW (window));
4724 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4728 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4729 ModestWindow *window)
4731 g_return_if_fail (MODEST_IS_WINDOW (window));
4734 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4738 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4739 ModestWindow *window)
4741 g_return_if_fail (MODEST_IS_WINDOW (window));
4744 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4748 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4749 ModestWindow *window)
4751 g_return_if_fail (MODEST_IS_WINDOW (window));
4754 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4758 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4760 g_return_if_fail (MODEST_IS_WINDOW (window));
4763 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4767 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4769 g_return_if_fail (MODEST_IS_WINDOW (window));
4771 modest_platform_show_search_messages (GTK_WINDOW (window));
4775 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4777 g_return_if_fail (MODEST_IS_WINDOW (win));
4778 modest_platform_show_addressbook (GTK_WINDOW (win));
4783 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4784 ModestWindow *window)
4786 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4788 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4792 on_send_receive_finished (ModestMailOperation *mail_op,
4795 /* Set send/receive operation finished */
4796 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW (user_data));
4801 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
4807 const gchar* server_name = NULL;
4808 TnyTransportAccount *server_account;
4809 gchar *message = NULL;
4811 /* Don't show anything if the user cancelled something */
4812 if (err->code == TNY_TRANSPORT_ACCOUNT_ERROR_SEND_USER_CANCEL)
4815 /* Get the server name: */
4817 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
4818 if (server_account) {
4819 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
4821 g_object_unref (server_account);
4822 server_account = NULL;
4825 g_return_if_fail (server_name);
4827 /* Show the appropriate message text for the GError: */
4828 switch (err->code) {
4829 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_HOST_LOOKUP_FAILED:
4830 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4832 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_SERVICE_UNAVAILABLE:
4833 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4835 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_AUTHENTICATION_NOT_SUPPORTED:
4836 message = g_strdup_printf (_("emev_ni_ui_smtp_authentication_fail_error"), server_name);
4838 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND:
4839 message = g_strdup (_("emev_ib_ui_smtp_send_error"));
4842 g_return_if_reached ();
4845 /* TODO if the username or the password where not defined we
4846 should show the Accounts Settings dialog or the Connection
4847 specific SMTP server window */
4849 modest_platform_run_information_dialog (NULL, message);
4854 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
4859 ModestMainWindow *main_window = NULL;
4860 ModestWindowMgr *mgr = NULL;
4861 GtkWidget *folder_view = NULL, *header_view = NULL;
4862 TnyFolderStore *selected_folder = NULL;
4863 TnyFolderType folder_type;
4865 mgr = modest_runtime_get_window_mgr ();
4866 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr));
4871 /* Check if selected folder is OUTBOX */
4872 folder_view = modest_main_window_get_child_widget (main_window,
4873 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4874 header_view = modest_main_window_get_child_widget (main_window,
4875 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4877 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4878 if (!TNY_IS_FOLDER (selected_folder))
4881 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
4882 #if GTK_CHECK_VERSION(2, 8, 0)
4883 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
4884 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
4885 GtkTreeViewColumn *tree_column;
4887 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
4888 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
4889 gtk_tree_view_column_queue_resize (tree_column);
4892 gtk_widget_queue_draw (header_view);
4897 if (selected_folder != NULL)
4898 g_object_unref (selected_folder);