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);
902 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
904 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
906 /* Gets folder type (OUTBOX headers will be opened in edit window */
907 if (modest_tny_folder_is_local_folder (folder))
908 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
910 /* If the header is in the drafts folder then open the editor,
911 else the message view window */
912 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
913 /* we cannot edit without a valid account... */
914 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
915 if (!modest_ui_actions_run_account_setup_wizard(parent_win))
918 win = modest_msg_edit_window_new (msg, account, TRUE);
922 modest_platform_information_banner (NULL, NULL, _("mail_ib_opening_draft_message"));
925 gchar *uid = modest_tny_folder_get_header_unique_id (header);
927 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
928 GtkWidget *header_view;
929 GtkTreeSelection *sel;
930 GList *sel_list = NULL;
933 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
934 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
936 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
937 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
939 if (sel_list != NULL) {
940 GtkTreeRowReference *row_reference;
942 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
943 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
944 g_list_free (sel_list);
946 win = modest_msg_view_window_new_with_header_model (
947 msg, account, (const gchar*) uid,
948 model, row_reference);
949 gtk_tree_row_reference_free (row_reference);
951 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
954 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
959 /* Register and show new window */
961 mgr = modest_runtime_get_window_mgr ();
962 modest_window_mgr_register_window (mgr, win);
963 g_object_unref (win);
964 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
965 gtk_widget_show_all (GTK_WIDGET(win));
968 /* Update toolbar dimming state */
969 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
970 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
976 g_object_unref (parent_win);
977 g_object_unref (folder);
982 open_msg_error_handler (ModestMailOperation *mail_op,
985 /* Show the message error */
986 GObject *win = modest_mail_operation_get_source (mail_op);
988 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
989 (gchar *) user_data);
991 g_object_unref (win);
995 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
999 GObject *win = modest_mail_operation_get_source (mail_op);
1001 error = modest_mail_operation_get_error (mail_op);
1003 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
1005 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1008 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1009 _("mail_ni_ui_folder_get_msg_folder_error"));
1013 g_object_unref (win);
1017 * Returns the account a list of headers belongs to. It returns a
1018 * *new* reference so don't forget to unref it
1021 get_account_from_header_list (TnyList *headers)
1023 TnyAccount *account = NULL;
1025 if (tny_list_get_length (headers) > 0) {
1026 TnyIterator *iter = tny_list_create_iterator (headers);
1027 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1028 TnyFolder *folder = tny_header_get_folder (header);
1029 account = tny_folder_get_account (folder);
1030 g_object_unref (folder);
1031 g_object_unref (header);
1032 g_object_unref (iter);
1038 * This function is used by both modest_ui_actions_on_open and
1039 * modest_ui_actions_on_header_activated. This way we always do the
1040 * same when trying to open messages.
1043 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
1045 ModestWindowMgr *mgr = NULL;
1046 TnyIterator *iter = NULL, *iter_not_opened = NULL;
1047 ModestMailOperation *mail_op = NULL;
1048 TnyList *not_opened_headers = NULL;
1049 TnyHeaderFlags flags = 0;
1050 TnyAccount *account;
1052 g_return_if_fail (headers != NULL);
1054 /* Check that only one message is selected for opening */
1055 if (tny_list_get_length (headers) != 1) {
1056 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1057 _("mcen_ib_select_one_message"));
1061 mgr = modest_runtime_get_window_mgr ();
1062 iter = tny_list_create_iterator (headers);
1064 /* Get the account */
1065 account = get_account_from_header_list (headers);
1067 /* Look if we already have a message view for each header. If
1068 true, then remove the header from the list of headers to
1070 not_opened_headers = tny_simple_list_new ();
1071 while (!tny_iterator_is_done (iter)) {
1073 ModestWindow *window = NULL;
1074 TnyHeader *header = NULL;
1075 gboolean found = FALSE;
1077 header = TNY_HEADER (tny_iterator_get_current (iter));
1079 flags = tny_header_get_flags (header);
1082 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1084 /* Do not open again the message and present the
1085 window to the user */
1088 gtk_window_present (GTK_WINDOW (window));
1090 /* the header has been registered already, we don't do
1091 * anything but wait for the window to come up*/
1092 g_debug ("header %p already registered, waiting for window", header);
1094 tny_list_append (not_opened_headers, G_OBJECT (header));
1098 g_object_unref (header);
1100 tny_iterator_next (iter);
1102 g_object_unref (iter);
1105 /* Open each message */
1106 if (tny_list_get_length (not_opened_headers) == 0)
1109 /* If some messages would have to be downloaded, ask the user to
1110 * make a connection. It's generally easier to do this here (in the mainloop)
1111 * than later in a thread:
1113 if (tny_list_get_length (not_opened_headers) > 0) {
1115 gboolean found = FALSE;
1117 iter = tny_list_create_iterator (not_opened_headers);
1118 while (!tny_iterator_is_done (iter) && !found) {
1119 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1120 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1123 tny_iterator_next (iter);
1125 g_object_unref (header);
1127 g_object_unref (iter);
1129 /* Ask the user if there are any uncached messages */
1130 if (found && !connect_to_get_msg (win,
1131 header_list_count_uncached_msgs (not_opened_headers),
1136 /* Register the headers before actually creating the windows: */
1137 iter_not_opened = tny_list_create_iterator (not_opened_headers);
1138 while (!tny_iterator_is_done (iter_not_opened)) {
1139 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1141 modest_window_mgr_register_header (mgr, header);
1142 g_object_unref (header);
1144 tny_iterator_next (iter_not_opened);
1146 g_object_unref (iter_not_opened);
1147 iter_not_opened = NULL;
1149 /* Create the mail operation */
1150 if (tny_list_get_length (not_opened_headers) > 1) {
1151 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
1152 modest_ui_actions_get_msgs_full_error_handler,
1154 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1156 modest_mail_operation_get_msgs_full (mail_op,
1162 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1163 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1164 const gchar *proto_name;
1166 ModestTransportStoreProtocol proto;
1168 /* Get the error message depending on the protocol */
1169 proto_name = tny_account_get_proto (account);
1170 if (proto_name != NULL) {
1171 proto = modest_protocol_info_get_transport_store_protocol (proto_name);
1173 proto = MODEST_PROTOCOL_STORE_MAILDIR;
1176 if (proto == MODEST_PROTOCOL_STORE_POP) {
1177 error_msg = g_strdup (_("emev_ni_ui_pop3_msg_recv_error"));
1178 } else if (proto == MODEST_PROTOCOL_STORE_IMAP) {
1179 error_msg = g_strdup_printf (_("emev_ni_ui_imap_message_not_available_in_server"),
1180 tny_header_get_subject (header));
1182 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1185 /* Create and call the mail operation */
1186 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
1187 open_msg_error_handler,
1190 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1192 modest_mail_operation_get_msg (mail_op, header, open_msg_cb, NULL);
1194 g_object_unref (header);
1195 g_object_unref (iter);
1197 g_object_unref (mail_op);
1202 g_object_unref (account);
1203 if (not_opened_headers)
1204 g_object_unref (not_opened_headers);
1208 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1213 headers = get_selected_headers (win);
1218 _modest_ui_actions_open (headers, win);
1220 g_object_unref(headers);
1225 free_reply_forward_helper (gpointer data)
1227 ReplyForwardHelper *helper;
1229 helper = (ReplyForwardHelper *) data;
1230 g_free (helper->account_name);
1231 g_slice_free (ReplyForwardHelper, helper);
1235 reply_forward_cb (ModestMailOperation *mail_op, TnyHeader *header, TnyMsg *msg,
1239 ReplyForwardHelper *rf_helper;
1240 ModestWindow *msg_win = NULL;
1241 ModestEditType edit_type;
1243 TnyAccount *account = NULL;
1244 ModestWindowMgr *mgr = NULL;
1245 gchar *signature = NULL;
1246 gboolean use_signature;
1248 /* If there was any error. The mail operation could be NULL,
1249 this means that we already have the message downloaded and
1250 that we didn't do a mail operation to retrieve it */
1251 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1254 g_return_if_fail (user_data != NULL);
1255 rf_helper = (ReplyForwardHelper *) user_data;
1257 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1258 rf_helper->account_name);
1259 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr(),
1260 rf_helper->account_name,
1263 /* Create reply mail */
1264 switch (rf_helper->action) {
1267 modest_tny_msg_create_reply_msg (msg, header, from, signature,
1268 rf_helper->reply_forward_type,
1269 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1271 case ACTION_REPLY_TO_ALL:
1273 modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1274 MODEST_TNY_MSG_REPLY_MODE_ALL);
1275 edit_type = MODEST_EDIT_TYPE_REPLY;
1277 case ACTION_FORWARD:
1279 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1280 edit_type = MODEST_EDIT_TYPE_FORWARD;
1283 g_return_if_reached ();
1290 g_printerr ("modest: failed to create message\n");
1294 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1295 rf_helper->account_name,
1296 TNY_ACCOUNT_TYPE_STORE);
1298 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1302 /* Create and register the windows */
1303 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1304 mgr = modest_runtime_get_window_mgr ();
1305 modest_window_mgr_register_window (mgr, msg_win);
1307 if (rf_helper->parent_window != NULL) {
1308 gdouble parent_zoom;
1310 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1311 modest_window_set_zoom (msg_win, parent_zoom);
1314 /* Show edit window */
1315 gtk_widget_show_all (GTK_WIDGET (msg_win));
1319 g_object_unref (msg_win);
1321 g_object_unref (G_OBJECT (new_msg));
1323 g_object_unref (G_OBJECT (account));
1324 /* g_object_unref (msg); */
1325 free_reply_forward_helper (rf_helper);
1328 /* Checks a list of headers. If any of them are not currently
1329 * downloaded (CACHED) then returns TRUE else returns FALSE.
1332 header_list_count_uncached_msgs (TnyList *header_list)
1335 gint uncached_messages = 0;
1337 iter = tny_list_create_iterator (header_list);
1338 while (!tny_iterator_is_done (iter)) {
1341 header = TNY_HEADER (tny_iterator_get_current (iter));
1343 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1344 uncached_messages ++;
1345 g_object_unref (header);
1348 tny_iterator_next (iter);
1350 g_object_unref (iter);
1352 return uncached_messages;
1355 /* Returns FALSE if the user does not want to download the
1356 * messages. Returns TRUE if the user allowed the download.
1359 connect_to_get_msg (ModestWindow *win,
1360 gint num_of_uncached_msgs,
1361 TnyAccount *account)
1363 GtkResponseType response;
1365 /* Allways download if we are online. */
1366 if (tny_device_is_online (modest_runtime_get_device ()))
1369 /* If offline, then ask for user permission to download the messages */
1370 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1371 ngettext("mcen_nc_get_msg",
1373 num_of_uncached_msgs));
1375 if (response == GTK_RESPONSE_CANCEL)
1378 return modest_platform_connect_and_wait(GTK_WINDOW (win), account);
1382 * Common code for the reply and forward actions
1385 reply_forward (ReplyForwardAction action, ModestWindow *win)
1387 ModestMailOperation *mail_op = NULL;
1388 TnyList *header_list = NULL;
1389 ReplyForwardHelper *rf_helper = NULL;
1390 guint reply_forward_type;
1391 gboolean continue_download = TRUE;
1392 gboolean do_retrieve = TRUE;
1394 g_return_if_fail (MODEST_IS_WINDOW(win));
1396 /* we need an account when editing */
1397 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1398 if (!modest_ui_actions_run_account_setup_wizard (win))
1402 header_list = get_selected_headers (win);
1406 reply_forward_type =
1407 modest_conf_get_int (modest_runtime_get_conf (),
1408 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1411 /* check if we need to download msg before asking about it */
1412 do_retrieve = (action == ACTION_FORWARD) ||
1413 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1416 gint num_of_unc_msgs;
1418 /* check that the messages have been previously downloaded */
1419 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
1420 /* If there are any uncached message ask the user
1421 * whether he/she wants to download them. */
1422 if (num_of_unc_msgs) {
1423 TnyAccount *account = get_account_from_header_list (header_list);
1424 continue_download = connect_to_get_msg (win, num_of_unc_msgs, account);
1425 g_object_unref (account);
1429 if (!continue_download) {
1430 g_object_unref (header_list);
1434 /* We assume that we can only select messages of the
1435 same folder and that we reply all of them from the
1436 same account. In fact the interface currently only
1437 allows single selection */
1440 rf_helper = g_slice_new0 (ReplyForwardHelper);
1441 rf_helper->reply_forward_type = reply_forward_type;
1442 rf_helper->action = action;
1443 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1445 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1446 rf_helper->parent_window = GTK_WIDGET (win);
1447 if (!rf_helper->account_name)
1448 rf_helper->account_name =
1449 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1451 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1454 /* Get header and message. Do not free them here, the
1455 reply_forward_cb must do it */
1456 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1457 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1458 if (!msg || !header) {
1460 g_object_unref (msg);
1461 g_printerr ("modest: no message found\n");
1464 reply_forward_cb (NULL, header, msg, rf_helper);
1467 g_object_unref (header);
1472 /* Only reply/forward to one message */
1473 iter = tny_list_create_iterator (header_list);
1474 header = TNY_HEADER (tny_iterator_get_current (iter));
1475 g_object_unref (iter);
1478 /* Retrieve messages */
1481 modest_mail_operation_new_with_error_handling (G_OBJECT(win),
1482 modest_ui_actions_get_msgs_full_error_handler,
1484 modest_mail_operation_queue_add (
1485 modest_runtime_get_mail_operation_queue (), mail_op);
1487 modest_mail_operation_get_msg (mail_op,
1492 g_object_unref(mail_op);
1494 /* we put a ref here to prevent double unref as the reply
1495 * forward callback unrefs the header at its end */
1496 reply_forward_cb (NULL, header, NULL, rf_helper);
1500 g_object_unref (header);
1506 g_object_unref (header_list);
1510 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1512 g_return_if_fail (MODEST_IS_WINDOW(win));
1514 reply_forward (ACTION_REPLY, win);
1518 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1520 g_return_if_fail (MODEST_IS_WINDOW(win));
1522 reply_forward (ACTION_FORWARD, win);
1526 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1528 g_return_if_fail (MODEST_IS_WINDOW(win));
1530 reply_forward (ACTION_REPLY_TO_ALL, win);
1534 modest_ui_actions_on_next (GtkAction *action,
1535 ModestWindow *window)
1537 if (MODEST_IS_MAIN_WINDOW (window)) {
1538 GtkWidget *header_view;
1540 header_view = modest_main_window_get_child_widget (
1541 MODEST_MAIN_WINDOW(window),
1542 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1546 modest_header_view_select_next (
1547 MODEST_HEADER_VIEW(header_view));
1548 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1549 modest_msg_view_window_select_next_message (
1550 MODEST_MSG_VIEW_WINDOW (window));
1552 g_return_if_reached ();
1557 modest_ui_actions_on_prev (GtkAction *action,
1558 ModestWindow *window)
1560 g_return_if_fail (MODEST_IS_WINDOW(window));
1562 if (MODEST_IS_MAIN_WINDOW (window)) {
1563 GtkWidget *header_view;
1564 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1565 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1569 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1570 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1571 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1573 g_return_if_reached ();
1578 modest_ui_actions_on_sort (GtkAction *action,
1579 ModestWindow *window)
1581 g_return_if_fail (MODEST_IS_WINDOW(window));
1583 if (MODEST_IS_MAIN_WINDOW (window)) {
1584 GtkWidget *header_view;
1585 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1586 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1588 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1593 /* Show sorting dialog */
1594 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1599 new_messages_arrived (ModestMailOperation *self,
1600 TnyList *new_headers,
1603 ModestMainWindow *win = NULL;
1604 GtkWidget *folder_view = NULL;
1605 TnyFolderStore *folder = NULL;
1606 gboolean folder_empty = FALSE;
1608 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
1609 win = MODEST_MAIN_WINDOW (user_data);
1611 /* Don't do anything if there are not new headers, this could
1612 happen if there was any problem with the mail operation */
1616 /* Set contents style of headers view */
1617 if (modest_main_window_get_contents_style (win) == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1618 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1619 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1620 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1623 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1626 modest_main_window_set_contents_style (win,
1627 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1630 /* Notify new messages have been downloaded */
1631 if ((new_headers != NULL) && (tny_list_get_length (new_headers) > 0))
1632 modest_platform_on_new_headers_received (new_headers);
1636 * This function performs the send & receive required actions. The
1637 * window is used to create the mail operation. Typically it should
1638 * always be the main window, but we pass it as argument in order to
1642 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1644 gchar *acc_name = NULL;
1645 ModestMailOperation *mail_op;
1646 TnyAccount *store_account = NULL;
1648 /* If no account name was provided then get the current account, and if
1649 there is no current account then pick the default one: */
1650 if (!account_name) {
1651 acc_name = g_strdup (modest_window_get_active_account(win));
1653 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1655 g_printerr ("modest: cannot get default account\n");
1659 acc_name = g_strdup (account_name);
1663 /* Ensure that we have a connection available */
1665 modest_tny_account_store_get_server_account (modest_runtime_get_account_store (),
1667 TNY_ACCOUNT_TYPE_STORE);
1668 if (!modest_platform_connect_and_wait (NULL, TNY_ACCOUNT (store_account))) {
1669 g_object_unref (store_account);
1672 g_object_unref (store_account);
1674 /* Set send/receive operation in progress */
1675 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1677 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
1678 modest_ui_actions_send_receive_error_handler,
1681 g_signal_connect (G_OBJECT(mail_op), "operation-finished",
1682 G_CALLBACK (on_send_receive_finished),
1685 /* Send & receive. */
1686 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1687 /* Receive and then send. The operation is tagged initially as
1688 a receive operation because the account update performs a
1689 receive and then a send. The operation changes its type
1690 internally, so the progress objects will receive the proper
1691 progress information */
1692 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1693 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, win);
1694 g_object_unref (G_OBJECT (mail_op));
1702 modest_ui_actions_do_cancel_send (const gchar *account_name,
1705 TnyTransportAccount *transport_account;
1706 TnySendQueue *send_queue = NULL;
1707 GError *error = NULL;
1709 /* Get transport account */
1711 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1712 (modest_runtime_get_account_store(),
1714 TNY_ACCOUNT_TYPE_TRANSPORT));
1715 if (!transport_account) {
1716 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1721 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1722 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1723 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1724 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1725 "modest: could not find send queue for account\n");
1727 /* Keeep messages in outbox folder */
1728 tny_send_queue_cancel (send_queue, FALSE, &error);
1732 if (transport_account != NULL)
1733 g_object_unref (G_OBJECT (transport_account));
1737 modest_ui_actions_cancel_send_all (ModestWindow *win)
1739 GSList *account_names, *iter;
1741 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1744 iter = account_names;
1746 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1747 iter = g_slist_next (iter);
1750 modest_account_mgr_free_account_names (account_names);
1751 account_names = NULL;
1755 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1758 /* Check if accounts exist */
1759 gboolean accounts_exist =
1760 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1762 /* If not, allow the user to create an account before trying to send/receive. */
1763 if (!accounts_exist)
1764 modest_ui_actions_on_accounts (NULL, win);
1766 /* Cancel all sending operaitons */
1767 modest_ui_actions_cancel_send_all (win);
1771 * Refreshes all accounts. This function will be used by automatic
1775 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1777 GSList *account_names, *iter;
1779 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1782 iter = account_names;
1784 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1785 iter = g_slist_next (iter);
1788 modest_account_mgr_free_account_names (account_names);
1789 account_names = NULL;
1793 modest_do_refresh_current_folder(ModestWindow *win)
1795 /* Refresh currently selected folder. Note that if we only
1796 want to retreive the headers, then the refresh only will
1797 invoke a poke_status over all folders, i.e., only the
1798 total/unread count will be updated */
1799 if (MODEST_IS_MAIN_WINDOW (win)) {
1800 GtkWidget *header_view, *folder_view;
1801 TnyFolderStore *folder_store;
1803 /* Get folder and header view */
1805 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1806 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1810 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1812 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1814 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1815 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1817 /* We do not need to set the contents style
1818 because it hasn't changed. We also do not
1819 need to save the widget status. Just force
1821 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1822 TNY_FOLDER (folder_store),
1823 folder_refreshed_cb,
1824 MODEST_MAIN_WINDOW (win));
1828 g_object_unref (folder_store);
1834 * Handler of the click on Send&Receive button in the main toolbar
1837 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1839 /* Check if accounts exist */
1840 gboolean accounts_exist =
1841 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1843 /* If not, allow the user to create an account before trying to send/receive. */
1844 if (!accounts_exist)
1845 modest_ui_actions_on_accounts (NULL, win);
1847 modest_do_refresh_current_folder (win);
1849 /* Refresh the active account */
1850 modest_ui_actions_do_send_receive (NULL, win);
1855 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1858 GtkWidget *header_view;
1860 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1862 header_view = modest_main_window_get_child_widget (main_window,
1863 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1867 conf = modest_runtime_get_conf ();
1869 /* what is saved/restored is depending on the style; thus; we save with
1870 * old style, then update the style, and restore for this new style
1872 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1874 if (modest_header_view_get_style
1875 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1876 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1877 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1879 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1880 MODEST_HEADER_VIEW_STYLE_DETAILS);
1882 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1883 MODEST_CONF_HEADER_VIEW_KEY);
1888 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1890 ModestMainWindow *main_window)
1892 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1893 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1895 /* in the case the folder is empty, show the empty folder message and focus
1897 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1898 if (modest_header_view_is_empty (header_view)) {
1899 TnyFolder *folder = modest_header_view_get_folder (header_view);
1900 GtkWidget *folder_view =
1901 modest_main_window_get_child_widget (main_window,
1902 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1904 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1905 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1909 /* If no header has been selected then exit */
1914 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1915 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1917 /* Update toolbar dimming state */
1918 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1922 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1924 ModestMainWindow *main_window)
1928 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1933 if (modest_header_view_count_selected_headers (header_view) > 1) {
1934 hildon_banner_show_information (NULL, NULL, _("mcen_ib_select_one_message"));
1939 /* headers = tny_simple_list_new (); */
1940 /* tny_list_prepend (headers, G_OBJECT (header)); */
1941 headers = modest_header_view_get_selected_headers (header_view);
1943 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1945 g_object_unref (headers);
1949 set_active_account_from_tny_account (TnyAccount *account,
1950 ModestWindow *window)
1952 const gchar *server_acc_name = tny_account_get_id (account);
1954 /* We need the TnyAccount provided by the
1955 account store because that is the one that
1956 knows the name of the Modest account */
1957 TnyAccount *modest_server_account = modest_server_account =
1958 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1959 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1961 if (!modest_server_account) {
1962 g_warning ("%s: could not get tny account\n", __FUNCTION__);
1966 /* Update active account, but only if it's not a pseudo-account */
1967 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
1968 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
1969 const gchar *modest_acc_name =
1970 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1971 if (modest_acc_name)
1972 modest_window_set_active_account (window, modest_acc_name);
1975 g_object_unref (modest_server_account);
1980 folder_refreshed_cb (ModestMailOperation *mail_op,
1984 ModestMainWindow *win = NULL;
1985 GtkWidget *header_view;
1986 gboolean folder_empty = FALSE;
1987 gboolean all_marked_as_deleted = FALSE;
1989 g_return_if_fail (TNY_IS_FOLDER (folder));
1991 win = MODEST_MAIN_WINDOW (user_data);
1993 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1996 TnyFolder *current_folder;
1998 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1999 if (current_folder != NULL && folder != current_folder) {
2000 g_object_unref (current_folder);
2003 g_object_unref (current_folder);
2006 /* Check if folder is empty and set headers view contents style */
2007 folder_empty = (tny_folder_get_all_count (folder) == 0);
2008 all_marked_as_deleted = modest_header_view_is_empty (MODEST_HEADER_VIEW(header_view));
2009 if (folder_empty || all_marked_as_deleted)
2010 modest_main_window_set_contents_style (win,
2011 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2015 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2016 TnyFolderStore *folder_store,
2018 ModestMainWindow *main_window)
2021 GtkWidget *header_view;
2023 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2025 header_view = modest_main_window_get_child_widget(main_window,
2026 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2030 conf = modest_runtime_get_conf ();
2032 if (TNY_IS_ACCOUNT (folder_store)) {
2034 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2036 /* Show account details */
2037 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2040 if (TNY_IS_FOLDER (folder_store) && selected) {
2042 /* Update the active account */
2043 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2045 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2046 g_object_unref (account);
2050 /* Set the header style by default, it could
2051 be changed later by the refresh callback to
2053 modest_main_window_set_contents_style (main_window,
2054 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2056 /* Set folder on header view. This function
2057 will call tny_folder_refresh_async so we
2058 pass a callback that will be called when
2059 finished. We use that callback to set the
2060 empty view if there are no messages */
2061 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2062 TNY_FOLDER (folder_store),
2063 folder_refreshed_cb,
2066 /* Restore configuration. We need to do this
2067 *after* the set_folder because the widget
2068 memory asks the header view about its
2070 modest_widget_memory_restore (modest_runtime_get_conf (),
2071 G_OBJECT(header_view),
2072 MODEST_CONF_HEADER_VIEW_KEY);
2074 /* Update the active account */
2075 //modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
2076 /* Save only if we're seeing headers */
2077 if (modest_main_window_get_contents_style (main_window) ==
2078 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2079 modest_widget_memory_save (conf, G_OBJECT (header_view),
2080 MODEST_CONF_HEADER_VIEW_KEY);
2081 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2085 /* Update toolbar dimming state */
2086 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2090 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2097 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2099 online = tny_device_is_online (modest_runtime_get_device());
2102 /* already online -- the item is simply not there... */
2103 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2105 GTK_MESSAGE_WARNING,
2107 _("The %s you selected cannot be found"),
2109 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2110 gtk_dialog_run (GTK_DIALOG(dialog));
2112 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2115 _("mcen_bd_dialog_cancel"),
2116 GTK_RESPONSE_REJECT,
2117 _("mcen_bd_dialog_ok"),
2118 GTK_RESPONSE_ACCEPT,
2120 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2121 "Do you want to get online?"), item);
2122 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2123 gtk_label_new (txt), FALSE, FALSE, 0);
2124 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2127 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2128 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2129 /* TODO: Comment about why is this commented out: */
2130 /* modest_platform_connect_and_wait (); */
2133 gtk_widget_destroy (dialog);
2137 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2140 /* g_message ("%s %s", __FUNCTION__, link); */
2145 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2148 modest_platform_activate_uri (link);
2152 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2155 modest_platform_show_uri_popup (link);
2159 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2162 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2166 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2167 const gchar *address,
2170 /* g_message ("%s %s", __FUNCTION__, address); */
2174 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2175 TnyMsg *saved_draft,
2178 ModestMsgEditWindow *edit_window;
2180 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2182 /* If there was any error do nothing */
2183 if (modest_mail_operation_get_error (mail_op) != NULL)
2186 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2190 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2192 TnyTransportAccount *transport_account;
2193 ModestMailOperation *mail_operation;
2195 gchar *account_name, *from;
2196 ModestAccountMgr *account_mgr;
2197 gchar *info_text = NULL;
2199 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2201 data = modest_msg_edit_window_get_msg_data (edit_window);
2203 account_mgr = modest_runtime_get_account_mgr();
2204 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2206 account_name = modest_account_mgr_get_default_account (account_mgr);
2207 if (!account_name) {
2208 g_printerr ("modest: no account found\n");
2209 modest_msg_edit_window_free_msg_data (edit_window, data);
2213 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2214 account_name = g_strdup (data->account_name);
2218 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2219 (modest_runtime_get_account_store(),
2221 TNY_ACCOUNT_TYPE_TRANSPORT));
2222 if (!transport_account) {
2223 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2224 g_free (account_name);
2225 modest_msg_edit_window_free_msg_data (edit_window, data);
2228 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2230 /* Create the mail operation */
2231 mail_operation = modest_mail_operation_new (G_OBJECT(edit_window));
2232 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2234 modest_mail_operation_save_to_drafts (mail_operation,
2246 data->priority_flags,
2247 on_save_to_drafts_cb,
2251 g_free (account_name);
2252 g_object_unref (G_OBJECT (transport_account));
2253 g_object_unref (G_OBJECT (mail_operation));
2255 modest_msg_edit_window_free_msg_data (edit_window, data);
2257 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2258 modest_platform_information_banner (NULL, NULL, info_text);
2259 modest_msg_edit_window_reset_modified (edit_window);
2263 /* For instance, when clicking the Send toolbar button when editing a message: */
2265 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2267 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2269 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2272 /* FIXME: Code added just for testing. The final version will
2273 use the send queue provided by tinymail and some
2275 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2276 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2278 account_name = modest_account_mgr_get_default_account (account_mgr);
2280 if (!account_name) {
2281 /* Run account setup wizard */
2282 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window)))
2286 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2288 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2289 account_name = g_strdup (data->account_name);
2292 /* Get the currently-active transport account for this modest account: */
2293 TnyTransportAccount *transport_account =
2294 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2295 (modest_runtime_get_account_store(),
2297 if (!transport_account) {
2298 /* Run account setup wizard */
2299 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2303 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2305 /* Create the mail operation */
2306 ModestMailOperation *mail_operation = modest_mail_operation_new (G_OBJECT(edit_window));
2307 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2309 modest_mail_operation_send_new_mail (mail_operation,
2321 data->priority_flags);
2325 g_free (account_name);
2326 g_object_unref (G_OBJECT (transport_account));
2327 g_object_unref (G_OBJECT (mail_operation));
2329 modest_msg_edit_window_free_msg_data (edit_window, data);
2330 modest_msg_edit_window_set_sent (edit_window, TRUE);
2332 /* Save settings and close the window: */
2333 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2337 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2338 ModestMsgEditWindow *window)
2340 ModestMsgEditFormatState *format_state = NULL;
2342 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2343 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2345 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2348 format_state = modest_msg_edit_window_get_format_state (window);
2349 g_return_if_fail (format_state != NULL);
2351 format_state->bold = gtk_toggle_action_get_active (action);
2352 modest_msg_edit_window_set_format_state (window, format_state);
2353 g_free (format_state);
2358 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2359 ModestMsgEditWindow *window)
2361 ModestMsgEditFormatState *format_state = NULL;
2363 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2364 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2366 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2369 format_state = modest_msg_edit_window_get_format_state (window);
2370 g_return_if_fail (format_state != NULL);
2372 format_state->italics = gtk_toggle_action_get_active (action);
2373 modest_msg_edit_window_set_format_state (window, format_state);
2374 g_free (format_state);
2379 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2380 ModestMsgEditWindow *window)
2382 ModestMsgEditFormatState *format_state = NULL;
2384 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2385 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2387 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2390 format_state = modest_msg_edit_window_get_format_state (window);
2391 g_return_if_fail (format_state != NULL);
2393 format_state->bullet = gtk_toggle_action_get_active (action);
2394 modest_msg_edit_window_set_format_state (window, format_state);
2395 g_free (format_state);
2400 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2401 GtkRadioAction *selected,
2402 ModestMsgEditWindow *window)
2404 ModestMsgEditFormatState *format_state = NULL;
2405 GtkJustification value;
2407 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2409 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2412 value = gtk_radio_action_get_current_value (selected);
2414 format_state = modest_msg_edit_window_get_format_state (window);
2415 g_return_if_fail (format_state != NULL);
2417 format_state->justification = value;
2418 modest_msg_edit_window_set_format_state (window, format_state);
2419 g_free (format_state);
2423 modest_ui_actions_on_select_editor_color (GtkAction *action,
2424 ModestMsgEditWindow *window)
2426 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2427 g_return_if_fail (GTK_IS_ACTION (action));
2429 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2432 modest_msg_edit_window_select_color (window);
2436 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2437 ModestMsgEditWindow *window)
2439 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2440 g_return_if_fail (GTK_IS_ACTION (action));
2442 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2445 modest_msg_edit_window_select_background_color (window);
2449 modest_ui_actions_on_insert_image (GtkAction *action,
2450 ModestMsgEditWindow *window)
2452 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2453 g_return_if_fail (GTK_IS_ACTION (action));
2455 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2458 modest_msg_edit_window_insert_image (window);
2462 modest_ui_actions_on_attach_file (GtkAction *action,
2463 ModestMsgEditWindow *window)
2465 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2466 g_return_if_fail (GTK_IS_ACTION (action));
2468 modest_msg_edit_window_offer_attach_file (window);
2472 modest_ui_actions_on_remove_attachments (GtkAction *action,
2473 ModestMsgEditWindow *window)
2475 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2476 g_return_if_fail (GTK_IS_ACTION (action));
2478 modest_msg_edit_window_remove_attachments (window, NULL);
2482 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2485 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2486 const GError *error = modest_mail_operation_get_error (mail_op);
2489 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2490 _("mail_in_ui_folder_create_error"));
2495 modest_ui_actions_create_folder(GtkWidget *parent_window,
2496 GtkWidget *folder_view)
2498 TnyFolderStore *parent_folder;
2500 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2502 if (parent_folder) {
2503 gboolean finished = FALSE;
2505 gchar *folder_name = NULL, *suggested_name = NULL;
2506 const gchar *proto_str = NULL;
2507 TnyAccount *account;
2509 if (TNY_IS_ACCOUNT (parent_folder))
2510 account = g_object_ref (parent_folder);
2512 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2513 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2515 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2516 MODEST_PROTOCOL_STORE_POP) {
2518 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2520 g_object_unref (account);
2522 /* Run the new folder dialog */
2524 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2529 g_free (suggested_name);
2530 suggested_name = NULL;
2532 if (result == GTK_RESPONSE_REJECT) {
2535 ModestMailOperation *mail_op;
2536 TnyFolder *new_folder = NULL;
2538 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
2539 modest_ui_actions_new_folder_error_handler,
2540 parent_window, NULL);
2542 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2544 new_folder = modest_mail_operation_create_folder (mail_op,
2546 (const gchar *) folder_name);
2548 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2551 g_object_unref (new_folder);
2554 g_object_unref (mail_op);
2557 suggested_name = folder_name;
2561 g_object_unref (parent_folder);
2566 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2568 GtkWidget *folder_view;
2570 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2572 folder_view = modest_main_window_get_child_widget (main_window,
2573 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2577 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2581 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2584 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2585 const GError *error = NULL;
2586 const gchar *message = NULL;
2588 /* Get error message */
2589 error = modest_mail_operation_get_error (mail_op);
2591 g_return_if_reached ();
2593 switch (error->code) {
2594 case MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS:
2595 message = _CS("ckdg_ib_folder_already_exists");
2598 g_return_if_reached ();
2601 modest_platform_information_banner (GTK_WIDGET (window), NULL, message);
2605 modest_ui_actions_on_rename_folder (GtkAction *action,
2606 ModestMainWindow *main_window)
2608 TnyFolderStore *folder;
2609 GtkWidget *folder_view;
2610 GtkWidget *header_view;
2612 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2614 folder_view = modest_main_window_get_child_widget (main_window,
2615 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2619 header_view = modest_main_window_get_child_widget (main_window,
2620 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2625 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2630 if (TNY_IS_FOLDER (folder)) {
2633 const gchar *current_name;
2634 TnyFolderStore *parent;
2635 gboolean do_rename = TRUE;
2637 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2638 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
2639 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
2640 parent, current_name,
2642 g_object_unref (parent);
2644 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
2646 } else if (modest_platform_is_network_folderstore(folder) &&
2647 !tny_device_is_online (modest_runtime_get_device())) {
2648 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2649 do_rename = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2650 g_object_unref(account);
2654 ModestMailOperation *mail_op;
2655 GtkTreeSelection *sel = NULL;
2658 modest_mail_operation_new_with_error_handling (G_OBJECT(main_window),
2659 modest_ui_actions_rename_folder_error_handler,
2662 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2665 /* Clear the headers view */
2666 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2667 gtk_tree_selection_unselect_all (sel);
2669 /* Select *after* the changes */
2670 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2671 TNY_FOLDER(folder), TRUE);
2673 /* Actually rename the folder */
2674 modest_mail_operation_rename_folder (mail_op,
2675 TNY_FOLDER (folder),
2676 (const gchar *) folder_name);
2678 g_object_unref (mail_op);
2679 g_free (folder_name);
2682 g_object_unref (folder);
2686 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2689 GObject *win = modest_mail_operation_get_source (mail_op);
2691 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2692 _("mail_in_ui_folder_delete_error"));
2693 g_object_unref (win);
2697 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2699 TnyFolderStore *folder;
2700 GtkWidget *folder_view;
2703 gboolean do_delete = TRUE;
2705 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (main_window), FALSE);
2707 folder_view = modest_main_window_get_child_widget (main_window,
2708 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2712 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2714 /* Show an error if it's an account */
2715 if (!TNY_IS_FOLDER (folder)) {
2716 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2717 _("mail_in_ui_folder_delete_error"));
2718 g_object_unref (G_OBJECT (folder));
2723 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2724 tny_folder_get_name (TNY_FOLDER (folder)));
2725 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2726 (const gchar *) message);
2729 if (response != GTK_RESPONSE_OK) {
2731 } else if (modest_platform_is_network_folderstore(folder) &&
2732 !tny_device_is_online (modest_runtime_get_device())) {
2733 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2734 do_delete = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2735 g_object_unref(account);
2739 ModestMailOperation *mail_op;
2740 GtkTreeSelection *sel;
2742 /* Unselect the folder before deleting it to free the headers */
2743 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2744 gtk_tree_selection_unselect_all (sel);
2746 /* Create the mail operation */
2748 modest_mail_operation_new_with_error_handling (G_OBJECT(main_window),
2749 modest_ui_actions_delete_folder_error_handler,
2752 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2754 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2755 g_object_unref (G_OBJECT (mail_op));
2758 g_object_unref (G_OBJECT (folder));
2764 modest_ui_actions_on_delete_folder (GtkAction *action,
2765 ModestMainWindow *main_window)
2767 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2769 if (delete_folder (main_window, FALSE)) {
2770 GtkWidget *folder_view;
2772 folder_view = modest_main_window_get_child_widget (main_window,
2773 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2774 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2779 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2781 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2783 delete_folder (main_window, TRUE);
2788 show_error (GtkWidget *parent_widget, const gchar* text)
2790 hildon_banner_show_information(parent_widget, NULL, text);
2793 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2795 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2802 gtk_dialog_run (dialog);
2803 gtk_widget_destroy (GTK_WIDGET (dialog));
2808 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2809 const gchar* server_account_name,
2814 ModestMainWindow *main_window)
2816 g_return_if_fail(server_account_name);
2817 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2819 /* Initalize output parameters: */
2826 #ifdef MODEST_PLATFORM_MAEMO
2827 /* Maemo uses a different (awkward) button order,
2828 * It should probably just use gtk_alternative_dialog_button_order ().
2830 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2833 _("mcen_bd_dialog_ok"),
2834 GTK_RESPONSE_ACCEPT,
2835 _("mcen_bd_dialog_cancel"),
2836 GTK_RESPONSE_REJECT,
2839 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2843 GTK_RESPONSE_REJECT,
2845 GTK_RESPONSE_ACCEPT,
2847 #endif /* MODEST_PLATFORM_MAEMO */
2849 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2851 gchar *server_name = modest_account_mgr_get_server_account_hostname (
2852 modest_runtime_get_account_mgr(), server_account_name);
2853 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2854 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2859 /* This causes a warning because the logical ID has no %s in it,
2860 * though the translation does, but there is not much we can do about that: */
2861 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2862 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2865 g_free (server_name);
2869 gchar *initial_username = modest_account_mgr_get_server_account_username (
2870 modest_runtime_get_account_mgr(), server_account_name);
2872 GtkWidget *entry_username = gtk_entry_new ();
2873 if (initial_username)
2874 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2875 /* Dim this if a connection has ever succeeded with this username,
2876 * as per the UI spec: */
2877 const gboolean username_known =
2878 modest_account_mgr_get_server_account_username_has_succeeded(
2879 modest_runtime_get_account_mgr(), server_account_name);
2880 gtk_widget_set_sensitive (entry_username, !username_known);
2882 #ifdef MODEST_PLATFORM_MAEMO
2883 /* Auto-capitalization is the default, so let's turn it off: */
2884 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2886 /* Create a size group to be used by all captions.
2887 * Note that HildonCaption does not create a default size group if we do not specify one.
2888 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2889 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2891 GtkWidget *caption = hildon_caption_new (sizegroup,
2892 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2893 gtk_widget_show (entry_username);
2894 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2895 FALSE, FALSE, MODEST_MARGIN_HALF);
2896 gtk_widget_show (caption);
2898 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2900 #endif /* MODEST_PLATFORM_MAEMO */
2903 GtkWidget *entry_password = gtk_entry_new ();
2904 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2905 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2907 #ifdef MODEST_PLATFORM_MAEMO
2908 /* Auto-capitalization is the default, so let's turn it off: */
2909 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2910 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2912 caption = hildon_caption_new (sizegroup,
2913 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2914 gtk_widget_show (entry_password);
2915 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2916 FALSE, FALSE, MODEST_MARGIN_HALF);
2917 gtk_widget_show (caption);
2918 g_object_unref (sizegroup);
2920 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2922 #endif /* MODEST_PLATFORM_MAEMO */
2924 if (initial_username != NULL)
2925 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
2927 /* This is not in the Maemo UI spec:
2928 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2929 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2933 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2935 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2937 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2939 modest_account_mgr_set_server_account_username (
2940 modest_runtime_get_account_mgr(), server_account_name,
2943 const gboolean username_was_changed =
2944 (strcmp (*username, initial_username) != 0);
2945 if (username_was_changed) {
2946 g_warning ("%s: tinymail does not yet support changing the "
2947 "username in the get_password() callback.\n", __FUNCTION__);
2952 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2954 /* We do not save the password in the configuration,
2955 * because this function is only called for passwords that should
2956 * not be remembered:
2957 modest_server_account_set_password (
2958 modest_runtime_get_account_mgr(), server_account_name,
2967 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2979 /* This is not in the Maemo UI spec:
2980 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2986 gtk_widget_destroy (dialog);
2988 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2992 modest_ui_actions_on_cut (GtkAction *action,
2993 ModestWindow *window)
2995 GtkWidget *focused_widget;
2996 GtkClipboard *clipboard;
2998 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2999 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3000 if (GTK_IS_EDITABLE (focused_widget)) {
3001 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3002 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3003 gtk_clipboard_store (clipboard);
3004 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3005 GtkTextBuffer *buffer;
3007 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3008 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3009 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3010 gtk_clipboard_store (clipboard);
3011 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3012 TnyList *header_list = modest_header_view_get_selected_headers (
3013 MODEST_HEADER_VIEW (focused_widget));
3014 gboolean continue_download = FALSE;
3015 gint num_of_unc_msgs;
3017 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3019 if (num_of_unc_msgs) {
3020 TnyAccount *account = get_account_from_header_list (header_list);
3021 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3022 g_object_unref (account);
3025 if (num_of_unc_msgs == 0 || continue_download) {
3026 /* modest_platform_information_banner (
3027 NULL, NULL, _CS("mcen_ib_getting_items"));*/
3028 modest_header_view_cut_selection (
3029 MODEST_HEADER_VIEW (focused_widget));
3032 g_object_unref (header_list);
3033 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3034 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3039 modest_ui_actions_on_copy (GtkAction *action,
3040 ModestWindow *window)
3042 GtkClipboard *clipboard;
3043 GtkWidget *focused_widget;
3044 gboolean copied = TRUE;
3046 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3047 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3049 if (GTK_IS_LABEL (focused_widget)) {
3050 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
3051 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3052 gtk_clipboard_store (clipboard);
3053 } else if (GTK_IS_EDITABLE (focused_widget)) {
3054 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3055 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3056 gtk_clipboard_store (clipboard);
3057 } else if (GTK_IS_HTML (focused_widget)) {
3058 gtk_html_copy (GTK_HTML (focused_widget));
3059 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3060 gtk_clipboard_store (clipboard);
3061 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3062 GtkTextBuffer *buffer;
3063 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3064 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3065 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3066 gtk_clipboard_store (clipboard);
3067 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3068 TnyList *header_list = modest_header_view_get_selected_headers (
3069 MODEST_HEADER_VIEW (focused_widget));
3070 gboolean continue_download = FALSE;
3071 gint num_of_unc_msgs;
3073 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3075 if (num_of_unc_msgs) {
3076 TnyAccount *account = get_account_from_header_list (header_list);
3077 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3078 g_object_unref (account);
3081 if (num_of_unc_msgs == 0 || continue_download) {
3082 modest_platform_information_banner (
3083 NULL, NULL, _CS("mcen_ib_getting_items"));
3084 modest_header_view_copy_selection (
3085 MODEST_HEADER_VIEW (focused_widget));
3089 g_object_unref (header_list);
3091 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3092 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3095 /* Show information banner if there was a copy to clipboard */
3097 modest_platform_information_banner (
3098 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3102 modest_ui_actions_on_undo (GtkAction *action,
3103 ModestWindow *window)
3105 ModestEmailClipboard *clipboard = NULL;
3107 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3108 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3109 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3110 /* Clear clipboard source */
3111 clipboard = modest_runtime_get_email_clipboard ();
3112 modest_email_clipboard_clear (clipboard);
3115 g_return_if_reached ();
3120 modest_ui_actions_on_redo (GtkAction *action,
3121 ModestWindow *window)
3123 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3124 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3127 g_return_if_reached ();
3133 destroy_information_note (ModestMailOperation *mail_op, gpointer user_data)
3135 /* destroy information note */
3136 gtk_widget_destroy (GTK_WIDGET(user_data));
3141 paste_as_attachment_free (gpointer data)
3143 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3145 gtk_widget_destroy (helper->banner);
3146 g_object_unref (helper->banner);
3151 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3156 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3157 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3162 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3167 modest_ui_actions_on_paste (GtkAction *action,
3168 ModestWindow *window)
3170 GtkWidget *focused_widget = NULL;
3171 GtkWidget *inf_note = NULL;
3172 ModestMailOperation *mail_op = NULL;
3174 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3175 if (GTK_IS_EDITABLE (focused_widget)) {
3176 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3177 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3178 ModestEmailClipboard *e_clipboard = NULL;
3179 e_clipboard = modest_runtime_get_email_clipboard ();
3180 if (modest_email_clipboard_cleared (e_clipboard)) {
3181 GtkTextBuffer *buffer;
3182 GtkClipboard *clipboard;
3184 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3185 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3186 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3187 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3188 ModestMailOperation *mail_op;
3189 TnyFolder *src_folder;
3192 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3193 helper->window = MODEST_MSG_EDIT_WINDOW (window);
3194 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3195 _CS("ckct_nw_pasting"));
3196 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
3197 mail_op = modest_mail_operation_new (G_OBJECT (window));
3198 if (helper->banner != NULL) {
3199 g_object_ref (G_OBJECT (helper->banner));
3200 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
3201 gtk_widget_show (GTK_WIDGET (helper->banner));
3205 modest_mail_operation_get_msgs_full (mail_op,
3207 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
3209 paste_as_attachment_free);
3212 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3213 ModestEmailClipboard *clipboard = NULL;
3214 TnyFolder *src_folder = NULL;
3215 TnyFolderStore *folder_store = NULL;
3216 TnyList *data = NULL;
3217 gboolean delete = FALSE;
3219 /* Check clipboard source */
3220 clipboard = modest_runtime_get_email_clipboard ();
3221 if (modest_email_clipboard_cleared (clipboard))
3224 /* Get elements to paste */
3225 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
3227 /* Create a new mail operation */
3228 mail_op = modest_mail_operation_new (G_OBJECT(window));
3230 /* Get destination folder */
3231 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
3233 /* transfer messages */
3237 /* Ask for user confirmation */
3239 modest_ui_actions_msgs_move_to_confirmation (window,
3240 TNY_FOLDER (folder_store),
3244 if (response == GTK_RESPONSE_OK) {
3245 /* Launch notification */
3246 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3247 _CS("ckct_nw_pasting"));
3248 if (inf_note != NULL) {
3249 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3250 gtk_widget_show (GTK_WIDGET(inf_note));
3253 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3254 modest_mail_operation_xfer_msgs (mail_op,
3256 TNY_FOLDER (folder_store),
3258 destroy_information_note,
3261 g_object_unref (mail_op);
3264 } else if (src_folder != NULL) {
3265 /* Launch notification */
3266 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3267 _CS("ckct_nw_pasting"));
3268 if (inf_note != NULL) {
3269 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3270 gtk_widget_show (GTK_WIDGET(inf_note));
3273 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3274 modest_mail_operation_xfer_folder (mail_op,
3278 destroy_information_note,
3284 g_object_unref (data);
3285 if (src_folder != NULL)
3286 g_object_unref (src_folder);
3287 if (folder_store != NULL)
3288 g_object_unref (folder_store);
3294 modest_ui_actions_on_select_all (GtkAction *action,
3295 ModestWindow *window)
3297 GtkWidget *focused_widget;
3299 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3300 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3301 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3302 } else if (GTK_IS_LABEL (focused_widget)) {
3303 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3304 } else if (GTK_IS_EDITABLE (focused_widget)) {
3305 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3306 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3307 GtkTextBuffer *buffer;
3308 GtkTextIter start, end;
3310 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3311 gtk_text_buffer_get_start_iter (buffer, &start);
3312 gtk_text_buffer_get_end_iter (buffer, &end);
3313 gtk_text_buffer_select_range (buffer, &start, &end);
3314 } else if (GTK_IS_HTML (focused_widget)) {
3315 gtk_html_select_all (GTK_HTML (focused_widget));
3316 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3317 GtkWidget *header_view = focused_widget;
3318 GtkTreeSelection *selection = NULL;
3320 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
3321 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3322 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3325 /* Disable window dimming management */
3326 modest_window_disable_dimming (MODEST_WINDOW(window));
3328 /* Select all messages */
3329 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3330 gtk_tree_selection_select_all (selection);
3332 /* Set focuse on header view */
3333 gtk_widget_grab_focus (header_view);
3336 /* Enable window dimming management */
3337 modest_window_enable_dimming (MODEST_WINDOW(window));
3338 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3344 modest_ui_actions_on_mark_as_read (GtkAction *action,
3345 ModestWindow *window)
3347 g_return_if_fail (MODEST_IS_WINDOW(window));
3349 /* Mark each header as read */
3350 do_headers_action (window, headers_action_mark_as_read, NULL);
3354 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3355 ModestWindow *window)
3357 g_return_if_fail (MODEST_IS_WINDOW(window));
3359 /* Mark each header as read */
3360 do_headers_action (window, headers_action_mark_as_unread, NULL);
3364 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3365 GtkRadioAction *selected,
3366 ModestWindow *window)
3370 value = gtk_radio_action_get_current_value (selected);
3371 if (MODEST_IS_WINDOW (window)) {
3372 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3377 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3378 GtkRadioAction *selected,
3379 ModestWindow *window)
3381 TnyHeaderFlags flags;
3382 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3384 flags = gtk_radio_action_get_current_value (selected);
3385 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3389 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3390 GtkRadioAction *selected,
3391 ModestWindow *window)
3395 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3397 file_format = gtk_radio_action_get_current_value (selected);
3398 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3403 modest_ui_actions_on_zoom_plus (GtkAction *action,
3404 ModestWindow *window)
3406 g_return_if_fail (MODEST_IS_WINDOW (window));
3408 modest_window_zoom_plus (MODEST_WINDOW (window));
3412 modest_ui_actions_on_zoom_minus (GtkAction *action,
3413 ModestWindow *window)
3415 g_return_if_fail (MODEST_IS_WINDOW (window));
3417 modest_window_zoom_minus (MODEST_WINDOW (window));
3421 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3422 ModestWindow *window)
3424 ModestWindowMgr *mgr;
3425 gboolean fullscreen, active;
3426 g_return_if_fail (MODEST_IS_WINDOW (window));
3428 mgr = modest_runtime_get_window_mgr ();
3430 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3431 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3433 if (active != fullscreen) {
3434 modest_window_mgr_set_fullscreen_mode (mgr, active);
3435 gtk_window_present (GTK_WINDOW (window));
3440 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3441 ModestWindow *window)
3443 ModestWindowMgr *mgr;
3444 gboolean fullscreen;
3446 g_return_if_fail (MODEST_IS_WINDOW (window));
3448 mgr = modest_runtime_get_window_mgr ();
3449 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3450 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3452 gtk_window_present (GTK_WINDOW (window));
3456 * Used by modest_ui_actions_on_details to call do_headers_action
3459 headers_action_show_details (TnyHeader *header,
3460 ModestWindow *window,
3467 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3470 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3471 gtk_widget_show_all (dialog);
3472 gtk_dialog_run (GTK_DIALOG (dialog));
3474 gtk_widget_destroy (dialog);
3478 * Show the folder details in a ModestDetailsDialog widget
3481 show_folder_details (TnyFolder *folder,
3487 dialog = modest_details_dialog_new_with_folder (window, folder);
3490 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3491 gtk_widget_show_all (dialog);
3492 gtk_dialog_run (GTK_DIALOG (dialog));
3494 gtk_widget_destroy (dialog);
3498 * Show the header details in a ModestDetailsDialog widget
3501 modest_ui_actions_on_details (GtkAction *action,
3504 TnyList * headers_list;
3508 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3511 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3514 g_object_unref (msg);
3516 headers_list = get_selected_headers (win);
3520 iter = tny_list_create_iterator (headers_list);
3522 header = TNY_HEADER (tny_iterator_get_current (iter));
3524 headers_action_show_details (header, win, NULL);
3525 g_object_unref (header);
3528 g_object_unref (iter);
3529 g_object_unref (headers_list);
3531 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3532 GtkWidget *folder_view, *header_view;
3534 /* Check which widget has the focus */
3535 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3536 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3537 if (gtk_widget_is_focus (folder_view)) {
3538 TnyFolderStore *folder_store
3539 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3540 if (!folder_store) {
3541 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3544 /* Show only when it's a folder */
3545 /* This function should not be called for account items,
3546 * because we dim the menu item for them. */
3547 if (TNY_IS_FOLDER (folder_store)) {
3548 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3551 g_object_unref (folder_store);
3554 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3555 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3556 /* Show details of each header */
3557 do_headers_action (win, headers_action_show_details, header_view);
3563 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3564 ModestMsgEditWindow *window)
3566 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3568 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3572 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3573 ModestMsgEditWindow *window)
3575 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3577 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3581 modest_ui_actions_toggle_folders_view (GtkAction *action,
3582 ModestMainWindow *main_window)
3584 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3586 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3587 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3589 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3593 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3594 ModestWindow *window)
3596 gboolean active, fullscreen = FALSE;
3597 ModestWindowMgr *mgr;
3599 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3601 /* Check if we want to toggle the toolbar vuew in fullscreen
3603 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3604 "ViewShowToolbarFullScreen")) {
3608 /* Toggle toolbar */
3609 mgr = modest_runtime_get_window_mgr ();
3610 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
3614 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3615 ModestMsgEditWindow *window)
3617 modest_msg_edit_window_select_font (window);
3621 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3622 const gchar *display_name,
3625 /* Do not change the application name if the widget has not
3626 the focus. This callback could be called even if the folder
3627 view has not the focus, because the handled signal could be
3628 emitted when the folder view is redrawn */
3629 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3631 gtk_window_set_title (window, display_name);
3633 gtk_window_set_title (window, " ");
3638 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3640 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3641 modest_msg_edit_window_select_contacts (window);
3645 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3647 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3648 modest_msg_edit_window_check_names (window, FALSE);
3652 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3654 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3655 GTK_WIDGET (user_data));
3659 * This function is used to track changes in the selection of the
3660 * folder view that is inside the "move to" dialog to enable/disable
3661 * the OK button because we do not want the user to select a disallowed
3662 * destination for a folder.
3663 * The user also not desired to be able to use NEW button on items where
3664 * folder creation is not possibel.
3667 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
3668 TnyFolderStore *folder_store,
3672 GtkWidget *dialog = NULL;
3673 GtkWidget *ok_button = NULL, *new_button = NULL;
3674 GList *children = NULL;
3675 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
3676 gboolean moving_folder = FALSE;
3677 gboolean is_local_account = TRUE;
3678 GtkWidget *folder_view = NULL;
3679 ModestTnyFolderRules rules;
3684 /* Get the OK button */
3685 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
3689 children = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
3690 ok_button = GTK_WIDGET (children->next->next->data);
3691 new_button = GTK_WIDGET (children->next->data);
3692 g_list_free (children);
3694 /* check if folder_store is an remote account */
3695 if (TNY_IS_ACCOUNT (folder_store)) {
3696 TnyAccount *local_account = NULL;
3697 ModestTnyAccountStore *account_store = NULL;
3699 account_store = modest_runtime_get_account_store ();
3700 local_account = modest_tny_account_store_get_local_folders_account (account_store);
3702 if ((gpointer) local_account != (gpointer) folder_store) {
3703 is_local_account = FALSE;
3704 /* New button should be dimmed on remote
3706 new_sensitive = FALSE;
3708 g_object_unref (local_account);
3711 /* Check the target folder rules */
3712 if (TNY_IS_FOLDER (folder_store)) {
3713 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
3714 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
3715 ok_sensitive = FALSE;
3716 new_sensitive = FALSE;
3721 /* Check if we're moving a folder */
3722 if (MODEST_IS_MAIN_WINDOW (user_data)) {
3723 /* Get the widgets */
3724 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
3725 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3726 if (gtk_widget_is_focus (folder_view))
3727 moving_folder = TRUE;
3730 if (moving_folder) {
3731 TnyFolderStore *moved_folder = NULL, *parent = NULL;
3733 /* Get the folder to move */
3734 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3736 /* Check that we're not moving to the same folder */
3737 if (TNY_IS_FOLDER (moved_folder)) {
3738 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
3739 if (parent == folder_store)
3740 ok_sensitive = FALSE;
3741 g_object_unref (parent);
3744 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
3745 /* Do not allow to move to an account unless it's the
3746 local folders account */
3747 if (!is_local_account)
3748 ok_sensitive = FALSE;
3751 if (ok_sensitive && (moved_folder == folder_store)) {
3752 /* Do not allow to move to itself */
3753 ok_sensitive = FALSE;
3755 g_object_unref (moved_folder);
3757 TnyHeader *header = NULL;
3758 TnyFolder *src_folder = NULL;
3760 /* Moving a message */
3761 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
3762 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (user_data));
3763 src_folder = tny_header_get_folder (header);
3764 g_object_unref (header);
3767 TNY_FOLDER (modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view)));
3770 /* Do not allow to move the msg to the same folder */
3771 /* Do not allow to move the msg to an account */
3772 if ((gpointer) src_folder == (gpointer) folder_store ||
3773 TNY_IS_ACCOUNT (folder_store))
3774 ok_sensitive = FALSE;
3775 g_object_unref (src_folder);
3779 /* Set sensitivity of the OK button */
3780 gtk_widget_set_sensitive (ok_button, ok_sensitive);
3781 /* Set sensitivity of the NEW button */
3782 gtk_widget_set_sensitive (new_button, new_sensitive);
3786 create_move_to_dialog (GtkWindow *win,
3787 GtkWidget *folder_view,
3788 GtkWidget **tree_view)
3790 GtkWidget *dialog, *scroll;
3791 GtkWidget *new_button;
3793 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3795 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3798 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
3799 /* We do this manually so GTK+ does not associate a response ID for
3801 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
3802 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3803 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
3805 /* Create scrolled window */
3806 scroll = gtk_scrolled_window_new (NULL, NULL);
3807 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3808 GTK_POLICY_AUTOMATIC,
3809 GTK_POLICY_AUTOMATIC);
3811 /* Create folder view */
3812 *tree_view = modest_platform_create_folder_view (NULL);
3814 /* Track changes in the selection to
3815 * disable the OK button whenever "Move to" is not possible
3816 * disbale NEW button whenever New is not possible */
3817 g_signal_connect (*tree_view,
3818 "folder_selection_changed",
3819 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
3822 /* Listen to clicks on New button */
3823 g_signal_connect (G_OBJECT (new_button),
3825 G_CALLBACK(create_move_to_dialog_on_new_folder),
3828 /* It could happen that we're trying to move a message from a
3829 window (msg window for example) after the main window was
3830 closed, so we can not just get the model of the folder
3832 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
3833 const gchar *visible_id = NULL;
3835 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
3836 MODEST_FOLDER_VIEW(*tree_view));
3839 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
3841 /* Show the same account than the one that is shown in the main window */
3842 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
3845 const gchar *active_account_name = NULL;
3846 ModestAccountMgr *mgr = NULL;
3847 ModestAccountData *acc_data = NULL;
3849 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3850 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3852 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
3853 mgr = modest_runtime_get_account_mgr ();
3854 acc_data = modest_account_mgr_get_account_data (mgr, active_account_name);
3856 /* Set the new visible & active account */
3857 if (acc_data && acc_data->store_account) {
3858 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
3859 acc_data->store_account->account_name);
3860 modest_account_mgr_free_account_data (mgr, acc_data);
3864 /* Hide special folders */
3865 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3867 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3869 /* Add scroll to dialog */
3870 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3871 scroll, TRUE, TRUE, 0);
3873 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3874 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3880 * Returns TRUE if at least one of the headers of the list belongs to
3881 * a message that has been fully retrieved.
3883 #if 0 /* no longer in use. delete in 2007.10 */
3885 has_retrieved_msgs (TnyList *list)
3888 gboolean found = FALSE;
3890 iter = tny_list_create_iterator (list);
3891 while (!tny_iterator_is_done (iter) && !found) {
3893 TnyHeaderFlags flags = 0;
3895 header = TNY_HEADER (tny_iterator_get_current (iter));
3897 flags = tny_header_get_flags (header);
3898 if (flags & TNY_HEADER_FLAG_CACHED)
3899 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3902 g_object_unref (header);
3906 tny_iterator_next (iter);
3908 g_object_unref (iter);
3916 * Shows a confirmation dialog to the user when we're moving messages
3917 * from a remote server to the local storage. Returns the dialog
3918 * response. If it's other kind of movement then it always returns
3921 * This one is used by the next functions:
3922 * modest_ui_actions_on_paste - commented out
3923 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
3926 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
3927 TnyFolder *dest_folder,
3931 gint response = GTK_RESPONSE_OK;
3932 TnyAccount *account = NULL;
3933 TnyFolder *src_folder = NULL;
3934 TnyIterator *iter = NULL;
3935 TnyHeader *header = NULL;
3937 /* return with OK if the destination is a remote folder */
3938 if (modest_tny_folder_is_remote_folder (dest_folder))
3939 return GTK_RESPONSE_OK;
3941 /* Get source folder */
3942 iter = tny_list_create_iterator (headers);
3943 header = TNY_HEADER (tny_iterator_get_current (iter));
3945 src_folder = tny_header_get_folder (header);
3946 g_object_unref (header);
3948 g_object_unref (iter);
3950 /* if no src_folder, message may be an attahcment */
3951 if (src_folder == NULL)
3952 return GTK_RESPONSE_CANCEL;
3954 /* If the source is a local or MMC folder */
3955 if (!modest_tny_folder_is_remote_folder (src_folder)) {
3956 g_object_unref (src_folder);
3957 return GTK_RESPONSE_OK;
3960 /* Get the account */
3961 account = tny_folder_get_account (src_folder);
3963 /* now if offline we ask the user */
3964 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
3965 response = GTK_RESPONSE_OK;
3967 response = GTK_RESPONSE_CANCEL;
3970 g_object_unref (src_folder);
3971 g_object_unref (account);
3979 move_to_cb (ModestMailOperation *mail_op, gpointer user_data)
3981 MoveToHelper *helper = (MoveToHelper *) user_data;
3983 /* Note that the operation could have failed, in that case do
3985 if (modest_mail_operation_get_status (mail_op) ==
3986 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
3988 GObject *object = modest_mail_operation_get_source (mail_op);
3989 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
3990 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
3992 if (!modest_msg_view_window_select_next_message (self))
3993 if (!modest_msg_view_window_select_previous_message (self))
3994 /* No more messages to view, so close this window */
3995 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3996 } else if (MODEST_IS_MAIN_WINDOW (object) && helper->reference != NULL) {
3997 GtkWidget *header_view;
3999 GtkTreeSelection *sel;
4001 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4002 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4003 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
4004 path = gtk_tree_row_reference_get_path (helper->reference);
4005 gtk_tree_selection_select_path (sel, path);
4006 gtk_tree_path_free (path);
4008 g_object_unref (object);
4011 /* Close the "Pasting" information banner */
4012 gtk_widget_destroy (GTK_WIDGET(helper->banner));
4013 if (helper->reference != NULL)
4014 gtk_tree_row_reference_free (helper->reference);
4019 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
4022 ModestWindow *main_window = NULL;
4023 GtkWidget *folder_view = NULL;
4024 GObject *win = modest_mail_operation_get_source (mail_op);
4025 const GError *error = NULL;
4026 const gchar *message = NULL;
4028 /* Get error message */
4029 error = modest_mail_operation_get_error (mail_op);
4030 if (error != NULL && error->message != NULL) {
4031 message = error->message;
4033 message = _("mail_in_ui_folder_move_target_error");
4036 /* Disable next automatic folder selection */
4037 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ());
4038 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
4039 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4040 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
4042 if (user_data && TNY_IS_FOLDER (user_data)) {
4043 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
4044 TNY_FOLDER (user_data), FALSE);
4047 /* Show notification dialog */
4048 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
4049 g_object_unref (win);
4053 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
4056 GObject *win = modest_mail_operation_get_source (mail_op);
4057 const GError *error = modest_mail_operation_get_error (mail_op);
4059 g_return_if_fail (error != NULL);
4060 if (error->message != NULL)
4061 g_printerr ("modest: %s\n", error->message);
4063 g_printerr ("modest: unkonw error on send&receive operation");
4065 /* Show error message */
4066 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
4067 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
4068 /* _CS("sfil_ib_unable_to_receive")); */
4070 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
4071 /* _CS("sfil_ib_unable_to_send")); */
4072 g_object_unref (win);
4076 open_msg_for_purge_cb (ModestMailOperation *mail_op,
4083 gint pending_purges = 0;
4084 gboolean some_purged = FALSE;
4085 ModestWindow *win = MODEST_WINDOW (user_data);
4086 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
4088 /* If there was any error */
4089 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
4090 modest_window_mgr_unregister_header (mgr, header);
4094 /* Once the message has been retrieved for purging, we check if
4095 * it's all ok for purging */
4097 parts = tny_simple_list_new ();
4098 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
4099 iter = tny_list_create_iterator (parts);
4101 while (!tny_iterator_is_done (iter)) {
4103 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4104 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
4105 if (tny_mime_part_is_purged (part))
4112 g_object_unref (part);
4114 tny_iterator_next (iter);
4116 g_object_unref (iter);
4119 if (pending_purges>0) {
4121 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
4123 if (response == GTK_RESPONSE_OK) {
4124 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
4125 iter = tny_list_create_iterator (parts);
4126 while (!tny_iterator_is_done (iter)) {
4129 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4130 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
4131 tny_mime_part_set_purged (part);
4134 g_object_unref (part);
4136 tny_iterator_next (iter);
4139 tny_msg_rewrite_cache (msg);
4142 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
4144 g_object_unref (iter);
4146 modest_window_mgr_unregister_header (mgr, header);
4148 g_object_unref (parts);
4152 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
4153 ModestMainWindow *win)
4155 GtkWidget *header_view;
4156 TnyList *header_list;
4159 TnyHeaderFlags flags;
4160 ModestWindow *msg_view_window = NULL;
4163 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4165 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4166 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4168 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
4170 if (tny_list_get_length (header_list) == 1) {
4171 iter = tny_list_create_iterator (header_list);
4172 header = TNY_HEADER (tny_iterator_get_current (iter));
4173 g_object_unref (iter);
4178 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
4179 header, &msg_view_window);
4180 flags = tny_header_get_flags (header);
4181 if (!(flags & TNY_HEADER_FLAG_CACHED))
4184 if (msg_view_window != NULL)
4185 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
4187 /* do nothing; uid was registered before, so window is probably on it's way */
4188 g_warning ("debug: header %p has already been registered", header);
4191 ModestMailOperation *mail_op = NULL;
4192 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
4193 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
4194 modest_ui_actions_get_msgs_full_error_handler,
4196 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4197 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
4199 g_object_unref (mail_op);
4202 g_object_unref (header);
4204 g_object_unref (header_list);
4208 * Utility function that transfer messages from both the main window
4209 * and the msg view window when using the "Move to" dialog
4212 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
4215 TnyList *headers = NULL;
4216 TnyAccount *dst_account = NULL;
4217 const gchar *proto_str = NULL;
4218 gboolean dst_is_pop = FALSE;
4220 if (!TNY_IS_FOLDER (dst_folder)) {
4221 modest_platform_information_banner (GTK_WIDGET (win),
4223 _CS("ckdg_ib_unable_to_move_to_current_location"));
4227 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
4228 proto_str = tny_account_get_proto (dst_account);
4230 /* tinymail will return NULL for local folders it seems */
4231 dst_is_pop = proto_str &&
4232 (modest_protocol_info_get_transport_store_protocol (proto_str) ==
4233 MODEST_PROTOCOL_STORE_POP);
4235 g_object_unref (dst_account);
4237 /* Get selected headers */
4238 headers = get_selected_headers (MODEST_WINDOW (win));
4241 modest_platform_information_banner (GTK_WIDGET (win),
4243 ngettext("mail_in_ui_folder_move_target_error",
4244 "mail_in_ui_folder_move_targets_error",
4245 tny_list_get_length (headers)));
4246 g_object_unref (headers);
4250 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4251 helper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4252 _CS("ckct_nw_pasting"));
4253 if (helper->banner != NULL) {
4254 gtk_window_set_modal (GTK_WINDOW(helper->banner), FALSE);
4255 gtk_widget_show (GTK_WIDGET(helper->banner));
4258 if (MODEST_IS_MAIN_WINDOW (win)) {
4259 GtkWidget *header_view =
4260 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
4261 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4262 helper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
4265 ModestMailOperation *mail_op =
4266 modest_mail_operation_new_with_error_handling (G_OBJECT(win),
4267 modest_ui_actions_move_folder_error_handler,
4269 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4272 modest_mail_operation_xfer_msgs (mail_op,
4274 TNY_FOLDER (dst_folder),
4279 g_object_unref (G_OBJECT (mail_op));
4280 g_object_unref (headers);
4284 * UI handler for the "Move to" action when invoked from the
4288 modest_ui_actions_on_main_window_move_to (GtkAction *action,
4289 GtkWidget *folder_view,
4290 TnyFolderStore *dst_folder,
4291 ModestMainWindow *win)
4293 ModestHeaderView *header_view = NULL;
4294 ModestMailOperation *mail_op = NULL;
4295 TnyFolderStore *src_folder;
4296 gboolean online = (tny_device_is_online (modest_runtime_get_device()));
4298 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4300 /* Get the source folder */
4301 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4303 /* Get header view */
4304 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
4306 /* Get folder or messages to transfer */
4307 if (gtk_widget_is_focus (folder_view)) {
4308 GtkTreeSelection *sel;
4309 gboolean do_xfer = TRUE;
4311 /* Allow only to transfer folders to the local root folder */
4312 if (TNY_IS_ACCOUNT (dst_folder) &&
4313 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder)) {
4315 } else if (!TNY_IS_FOLDER (src_folder)) {
4316 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
4318 } else if (!online && modest_platform_is_network_folderstore(src_folder)) {
4319 guint num_headers = tny_folder_get_all_count(TNY_FOLDER (src_folder));
4320 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (src_folder));
4321 if (!connect_to_get_msg(MODEST_WINDOW (win), num_headers, account))
4323 g_object_unref (account);
4327 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4328 helper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4329 _CS("ckct_nw_pasting"));
4330 if (helper->banner != NULL) {
4331 gtk_window_set_modal (GTK_WINDOW(helper->banner), FALSE);
4332 gtk_widget_show (GTK_WIDGET(helper->banner));
4334 /* Clean folder on header view before moving it */
4335 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
4336 gtk_tree_selection_unselect_all (sel);
4339 modest_mail_operation_new_with_error_handling (G_OBJECT(win),
4340 modest_ui_actions_move_folder_error_handler,
4342 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4345 /* Select *after* the changes */
4346 /* TODO: this function hangs UI after transfer */
4347 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
4348 /* TNY_FOLDER (src_folder), TRUE); */
4350 modest_mail_operation_xfer_folder (mail_op,
4351 TNY_FOLDER (src_folder),
4356 /* Unref mail operation */
4357 g_object_unref (G_OBJECT (mail_op));
4359 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
4360 gboolean do_xfer = TRUE;
4361 /* Ask for confirmation if the source folder is remote and we're not connected */
4362 if (!online && modest_platform_is_network_folderstore(src_folder)) {
4363 TnyList *headers = modest_header_view_get_selected_headers(header_view);
4364 if (!msgs_already_deleted_from_server(headers, src_folder)) {
4365 guint num_headers = tny_list_get_length(headers);
4366 TnyAccount *account = get_account_from_header_list (headers);
4367 if (!connect_to_get_msg(MODEST_WINDOW (win), num_headers, account))
4369 g_object_unref (account);
4371 g_object_unref(headers);
4373 if (do_xfer) /* Transfer messages */
4374 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4378 g_object_unref (src_folder);
4383 * UI handler for the "Move to" action when invoked from the
4384 * ModestMsgViewWindow
4387 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
4388 TnyFolderStore *dst_folder,
4389 ModestMsgViewWindow *win)
4391 TnyHeader *header = NULL;
4392 TnyFolder *src_folder = NULL;
4393 TnyAccount *account = NULL;
4395 /* Create header list */
4396 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
4397 src_folder = TNY_FOLDER (tny_header_get_folder(header));
4398 g_object_unref (header);
4400 /* Transfer the message if online or confirmed by the user */
4401 account = tny_folder_get_account (src_folder);
4402 if (remote_folder_is_pop(TNY_FOLDER_STORE (src_folder)) ||
4403 (modest_platform_is_network_folderstore(TNY_FOLDER_STORE (src_folder)) &&
4404 connect_to_get_msg(MODEST_WINDOW (win), 1, account))) {
4405 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4407 g_object_unref (account);
4408 g_object_unref (src_folder);
4412 modest_ui_actions_on_move_to (GtkAction *action,
4415 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
4417 TnyFolderStore *dst_folder = NULL;
4418 ModestMainWindow *main_window;
4420 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
4421 MODEST_IS_MSG_VIEW_WINDOW (win));
4423 /* Get the main window if exists */
4424 if (MODEST_IS_MAIN_WINDOW (win))
4425 main_window = MODEST_MAIN_WINDOW (win);
4428 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
4430 /* Get the folder view widget if exists */
4432 folder_view = modest_main_window_get_child_widget (main_window,
4433 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4437 /* Create and run the dialog */
4438 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
4439 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
4440 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4441 result = gtk_dialog_run (GTK_DIALOG(dialog));
4442 g_object_ref (tree_view);
4443 gtk_widget_destroy (dialog);
4445 if (result != GTK_RESPONSE_ACCEPT)
4448 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
4449 /* Do window specific stuff */
4450 if (MODEST_IS_MAIN_WINDOW (win)) {
4451 modest_ui_actions_on_main_window_move_to (action,
4454 MODEST_MAIN_WINDOW (win));
4456 modest_ui_actions_on_msg_view_window_move_to (action,
4458 MODEST_MSG_VIEW_WINDOW (win));
4462 g_object_unref (dst_folder);
4466 * Calls #HeadersFunc for each header already selected in the main
4467 * window or the message currently being shown in the msg view window
4470 do_headers_action (ModestWindow *win,
4474 TnyList *headers_list = NULL;
4475 TnyIterator *iter = NULL;
4476 TnyHeader *header = NULL;
4477 TnyFolder *folder = NULL;
4480 headers_list = get_selected_headers (win);
4484 /* Get the folder */
4485 iter = tny_list_create_iterator (headers_list);
4486 header = TNY_HEADER (tny_iterator_get_current (iter));
4488 folder = tny_header_get_folder (header);
4489 g_object_unref (header);
4492 /* Call the function for each header */
4493 while (!tny_iterator_is_done (iter)) {
4494 header = TNY_HEADER (tny_iterator_get_current (iter));
4495 func (header, win, user_data);
4496 g_object_unref (header);
4497 tny_iterator_next (iter);
4500 /* Trick: do a poke status in order to speed up the signaling
4502 tny_folder_poke_status (folder);
4505 g_object_unref (folder);
4506 g_object_unref (iter);
4507 g_object_unref (headers_list);
4511 modest_ui_actions_view_attachment (GtkAction *action,
4512 ModestWindow *window)
4514 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4515 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4517 /* not supported window for this action */
4518 g_return_if_reached ();
4523 modest_ui_actions_save_attachments (GtkAction *action,
4524 ModestWindow *window)
4526 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4527 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4529 /* not supported window for this action */
4530 g_return_if_reached ();
4535 modest_ui_actions_remove_attachments (GtkAction *action,
4536 ModestWindow *window)
4538 if (MODEST_IS_MAIN_WINDOW (window)) {
4539 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4540 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4541 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4543 /* not supported window for this action */
4544 g_return_if_reached ();
4549 modest_ui_actions_on_settings (GtkAction *action,
4554 dialog = modest_platform_get_global_settings_dialog ();
4555 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4556 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4557 gtk_widget_show_all (dialog);
4559 gtk_dialog_run (GTK_DIALOG (dialog));
4561 gtk_widget_destroy (dialog);
4565 modest_ui_actions_on_help (GtkAction *action,
4568 const gchar *help_id = NULL;
4570 if (MODEST_IS_MAIN_WINDOW (win)) {
4571 GtkWidget *folder_view;
4572 TnyFolderStore *folder_store;
4574 /* Get selected folder */
4575 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4576 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4577 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4579 /* Switch help_id */
4580 if (TNY_IS_FOLDER (folder_store)) {
4581 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4582 case TNY_FOLDER_TYPE_NORMAL:
4583 help_id = "applications_email_managefolders";
4585 case TNY_FOLDER_TYPE_INBOX:
4586 help_id = "applications_email_inbox";
4588 case TNY_FOLDER_TYPE_OUTBOX:
4589 help_id = "applications_email_outbox";
4591 case TNY_FOLDER_TYPE_SENT:
4592 help_id = "applications_email_sent";
4594 case TNY_FOLDER_TYPE_DRAFTS:
4595 help_id = "applications_email_drafts";
4597 case TNY_FOLDER_TYPE_ARCHIVE:
4598 help_id = "applications_email_managefolders";
4601 help_id = "applications_email_managefolders";
4604 help_id = "applications_email_mainview";
4606 g_object_unref (folder_store);
4607 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4608 help_id = "applications_email_viewer";
4609 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4610 help_id = "applications_email_editor";
4612 modest_platform_show_help (GTK_WINDOW (win), help_id);
4616 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4617 ModestWindow *window)
4619 ModestMailOperation *mail_op;
4623 headers = get_selected_headers (window);
4627 /* Create mail operation */
4628 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (window),
4629 modest_ui_actions_get_msgs_full_error_handler,
4631 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4632 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4635 g_object_unref (headers);
4636 g_object_unref (mail_op);
4640 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4641 ModestWindow *window)
4643 g_return_if_fail (MODEST_IS_WINDOW (window));
4646 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4650 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4651 ModestWindow *window)
4653 g_return_if_fail (MODEST_IS_WINDOW (window));
4656 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4660 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4661 ModestWindow *window)
4663 g_return_if_fail (MODEST_IS_WINDOW (window));
4666 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4670 modest_ui_actions_on_format_menu_activated (GtkAction *action,
4671 ModestWindow *window)
4673 g_return_if_fail (MODEST_IS_WINDOW (window));
4676 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4680 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4681 ModestWindow *window)
4683 g_return_if_fail (MODEST_IS_WINDOW (window));
4686 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4690 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4691 ModestWindow *window)
4693 g_return_if_fail (MODEST_IS_WINDOW (window));
4696 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4700 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4701 ModestWindow *window)
4703 g_return_if_fail (MODEST_IS_WINDOW (window));
4706 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4710 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4711 ModestWindow *window)
4713 g_return_if_fail (MODEST_IS_WINDOW (window));
4716 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4720 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4721 ModestWindow *window)
4723 g_return_if_fail (MODEST_IS_WINDOW (window));
4726 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4730 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4732 g_return_if_fail (MODEST_IS_WINDOW (window));
4735 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4739 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4741 g_return_if_fail (MODEST_IS_WINDOW (window));
4743 modest_platform_show_search_messages (GTK_WINDOW (window));
4747 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4749 g_return_if_fail (MODEST_IS_WINDOW (win));
4750 modest_platform_show_addressbook (GTK_WINDOW (win));
4755 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4756 ModestWindow *window)
4758 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4760 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4764 on_send_receive_finished (ModestMailOperation *mail_op,
4767 /* Set send/receive operation finished */
4768 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW (user_data));
4773 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
4779 const gchar* server_name = NULL;
4780 TnyTransportAccount *server_account;
4781 gchar *message = NULL;
4783 /* Don't show anything if the user cancelled something */
4784 if (err->code == TNY_TRANSPORT_ACCOUNT_ERROR_SEND_USER_CANCEL)
4787 /* Get the server name: */
4789 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
4790 if (server_account) {
4791 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
4793 g_object_unref (server_account);
4794 server_account = NULL;
4797 g_return_if_fail (server_name);
4799 /* Show the appropriate message text for the GError: */
4800 switch (err->code) {
4801 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_HOST_LOOKUP_FAILED:
4802 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4804 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_SERVICE_UNAVAILABLE:
4805 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4807 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_AUTHENTICATION_NOT_SUPPORTED:
4808 message = g_strdup_printf (_("emev_ni_ui_smtp_authentication_fail_error"), server_name);
4810 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND:
4811 message = g_strdup (_("emev_ib_ui_smtp_send_error"));
4814 g_return_if_reached ();
4817 /* TODO if the username or the password where not defined we
4818 should show the Accounts Settings dialog or the Connection
4819 specific SMTP server window */
4821 modest_platform_run_information_dialog (NULL, message);
4826 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
4831 ModestMainWindow *main_window = NULL;
4832 ModestWindowMgr *mgr = NULL;
4833 GtkWidget *folder_view = NULL, *header_view = NULL;
4834 TnyFolderStore *selected_folder = NULL;
4835 TnyFolderType folder_type;
4837 mgr = modest_runtime_get_window_mgr ();
4838 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr));
4843 /* Check if selected folder is OUTBOX */
4844 folder_view = modest_main_window_get_child_widget (main_window,
4845 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4846 header_view = modest_main_window_get_child_widget (main_window,
4847 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4849 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4850 if (!TNY_IS_FOLDER (selected_folder))
4853 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
4854 #if GTK_CHECK_VERSION(2, 8, 0)
4855 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
4856 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
4857 GtkTreeViewColumn *tree_column;
4859 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
4860 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
4861 gtk_tree_view_column_queue_resize (tree_column);
4864 gtk_widget_queue_draw (header_view);
4869 if (selected_folder != NULL)
4870 g_object_unref (selected_folder);