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 (folder_type == TNY_FOLDER_TYPE_OUTBOX)) {
914 /* we cannot edit without a valid account... */
915 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
916 if (!modest_ui_actions_run_account_setup_wizard(parent_win))
919 win = modest_msg_edit_window_new (msg, account, TRUE);
923 modest_platform_information_banner (NULL, NULL, _("mail_ib_opening_draft_message"));
926 gchar *uid = modest_tny_folder_get_header_unique_id (header);
928 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
929 GtkWidget *header_view;
930 GtkTreeSelection *sel;
931 GList *sel_list = NULL;
934 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
935 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
937 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
938 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
940 if (sel_list != NULL) {
941 GtkTreeRowReference *row_reference;
943 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
944 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
945 g_list_free (sel_list);
947 win = modest_msg_view_window_new_with_header_model (
948 msg, account, (const gchar*) uid,
949 model, row_reference);
950 gtk_tree_row_reference_free (row_reference);
952 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
955 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
960 /* Register and show new window */
962 mgr = modest_runtime_get_window_mgr ();
963 modest_window_mgr_register_window (mgr, win);
964 g_object_unref (win);
965 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
966 gtk_widget_show_all (GTK_WIDGET(win));
969 /* Update toolbar dimming state */
970 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
971 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
977 g_object_unref (parent_win);
978 g_object_unref (folder);
983 open_msg_error_handler (ModestMailOperation *mail_op,
986 /* Show the message error */
987 GObject *win = modest_mail_operation_get_source (mail_op);
989 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
990 (gchar *) user_data);
992 g_object_unref (win);
996 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
1000 GObject *win = modest_mail_operation_get_source (mail_op);
1002 error = modest_mail_operation_get_error (mail_op);
1004 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
1006 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1009 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1010 _("mail_ni_ui_folder_get_msg_folder_error"));
1014 g_object_unref (win);
1018 * Returns the account a list of headers belongs to. It returns a
1019 * *new* reference so don't forget to unref it
1022 get_account_from_header_list (TnyList *headers)
1024 TnyAccount *account = NULL;
1026 if (tny_list_get_length (headers) > 0) {
1027 TnyIterator *iter = tny_list_create_iterator (headers);
1028 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1029 TnyFolder *folder = tny_header_get_folder (header);
1030 account = tny_folder_get_account (folder);
1031 g_object_unref (folder);
1032 g_object_unref (header);
1033 g_object_unref (iter);
1039 * This function is used by both modest_ui_actions_on_open and
1040 * modest_ui_actions_on_header_activated. This way we always do the
1041 * same when trying to open messages.
1044 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
1046 ModestWindowMgr *mgr = NULL;
1047 TnyIterator *iter = NULL, *iter_not_opened = NULL;
1048 ModestMailOperation *mail_op = NULL;
1049 TnyList *not_opened_headers = NULL;
1050 TnyHeaderFlags flags = 0;
1051 TnyAccount *account;
1053 g_return_if_fail (headers != NULL);
1055 /* Check that only one message is selected for opening */
1056 if (tny_list_get_length (headers) != 1) {
1057 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1058 _("mcen_ib_select_one_message"));
1062 mgr = modest_runtime_get_window_mgr ();
1063 iter = tny_list_create_iterator (headers);
1065 /* Get the account */
1066 account = get_account_from_header_list (headers);
1068 /* Look if we already have a message view for each header. If
1069 true, then remove the header from the list of headers to
1071 not_opened_headers = tny_simple_list_new ();
1072 while (!tny_iterator_is_done (iter)) {
1074 ModestWindow *window = NULL;
1075 TnyHeader *header = NULL;
1076 gboolean found = FALSE;
1078 header = TNY_HEADER (tny_iterator_get_current (iter));
1080 flags = tny_header_get_flags (header);
1083 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1085 /* Do not open again the message and present the
1086 window to the user */
1089 gtk_window_present (GTK_WINDOW (window));
1091 /* the header has been registered already, we don't do
1092 * anything but wait for the window to come up*/
1093 g_debug ("header %p already registered, waiting for window", header);
1095 tny_list_append (not_opened_headers, G_OBJECT (header));
1099 g_object_unref (header);
1101 tny_iterator_next (iter);
1103 g_object_unref (iter);
1106 /* Open each message */
1107 if (tny_list_get_length (not_opened_headers) == 0)
1110 /* If some messages would have to be downloaded, ask the user to
1111 * make a connection. It's generally easier to do this here (in the mainloop)
1112 * than later in a thread:
1114 if (tny_list_get_length (not_opened_headers) > 0) {
1116 gboolean found = FALSE;
1118 iter = tny_list_create_iterator (not_opened_headers);
1119 while (!tny_iterator_is_done (iter) && !found) {
1120 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1121 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1124 tny_iterator_next (iter);
1126 g_object_unref (header);
1128 g_object_unref (iter);
1130 /* Ask the user if there are any uncached messages */
1131 if (found && !connect_to_get_msg (win,
1132 header_list_count_uncached_msgs (not_opened_headers),
1137 /* Register the headers before actually creating the windows: */
1138 iter_not_opened = tny_list_create_iterator (not_opened_headers);
1139 while (!tny_iterator_is_done (iter_not_opened)) {
1140 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1142 modest_window_mgr_register_header (mgr, header);
1143 g_object_unref (header);
1145 tny_iterator_next (iter_not_opened);
1147 g_object_unref (iter_not_opened);
1148 iter_not_opened = NULL;
1150 /* Create the mail operation */
1151 if (tny_list_get_length (not_opened_headers) > 1) {
1152 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
1153 modest_ui_actions_get_msgs_full_error_handler,
1155 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1157 modest_mail_operation_get_msgs_full (mail_op,
1163 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1164 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1165 const gchar *proto_name;
1167 ModestTransportStoreProtocol proto;
1169 /* Get the error message depending on the protocol */
1170 proto_name = tny_account_get_proto (account);
1171 if (proto_name != NULL) {
1172 proto = modest_protocol_info_get_transport_store_protocol (proto_name);
1174 proto = MODEST_PROTOCOL_STORE_MAILDIR;
1177 if (proto == MODEST_PROTOCOL_STORE_POP) {
1178 error_msg = g_strdup (_("emev_ni_ui_pop3_msg_recv_error"));
1179 } else if (proto == MODEST_PROTOCOL_STORE_IMAP) {
1180 error_msg = g_strdup_printf (_("emev_ni_ui_imap_message_not_available_in_server"),
1181 tny_header_get_subject (header));
1183 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1186 /* Create and call the mail operation */
1187 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
1188 open_msg_error_handler,
1191 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1193 modest_mail_operation_get_msg (mail_op, header, open_msg_cb, NULL);
1195 g_object_unref (header);
1196 g_object_unref (iter);
1198 g_object_unref (mail_op);
1203 g_object_unref (account);
1204 if (not_opened_headers)
1205 g_object_unref (not_opened_headers);
1209 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1214 headers = get_selected_headers (win);
1219 _modest_ui_actions_open (headers, win);
1221 g_object_unref(headers);
1226 free_reply_forward_helper (gpointer data)
1228 ReplyForwardHelper *helper;
1230 helper = (ReplyForwardHelper *) data;
1231 g_free (helper->account_name);
1232 g_slice_free (ReplyForwardHelper, helper);
1236 reply_forward_cb (ModestMailOperation *mail_op, TnyHeader *header, TnyMsg *msg,
1240 ReplyForwardHelper *rf_helper;
1241 ModestWindow *msg_win = NULL;
1242 ModestEditType edit_type;
1244 TnyAccount *account = NULL;
1245 ModestWindowMgr *mgr = NULL;
1246 gchar *signature = NULL;
1247 gboolean use_signature;
1249 /* If there was any error. The mail operation could be NULL,
1250 this means that we already have the message downloaded and
1251 that we didn't do a mail operation to retrieve it */
1252 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1255 g_return_if_fail (user_data != NULL);
1256 rf_helper = (ReplyForwardHelper *) user_data;
1258 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1259 rf_helper->account_name);
1260 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr(),
1261 rf_helper->account_name,
1264 /* Create reply mail */
1265 switch (rf_helper->action) {
1268 modest_tny_msg_create_reply_msg (msg, header, from, signature,
1269 rf_helper->reply_forward_type,
1270 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1272 case ACTION_REPLY_TO_ALL:
1274 modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1275 MODEST_TNY_MSG_REPLY_MODE_ALL);
1276 edit_type = MODEST_EDIT_TYPE_REPLY;
1278 case ACTION_FORWARD:
1280 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1281 edit_type = MODEST_EDIT_TYPE_FORWARD;
1284 g_return_if_reached ();
1291 g_printerr ("modest: failed to create message\n");
1295 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1296 rf_helper->account_name,
1297 TNY_ACCOUNT_TYPE_STORE);
1299 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1303 /* Create and register the windows */
1304 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1305 mgr = modest_runtime_get_window_mgr ();
1306 modest_window_mgr_register_window (mgr, msg_win);
1308 if (rf_helper->parent_window != NULL) {
1309 gdouble parent_zoom;
1311 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1312 modest_window_set_zoom (msg_win, parent_zoom);
1315 /* Show edit window */
1316 gtk_widget_show_all (GTK_WIDGET (msg_win));
1320 g_object_unref (msg_win);
1322 g_object_unref (G_OBJECT (new_msg));
1324 g_object_unref (G_OBJECT (account));
1325 /* g_object_unref (msg); */
1326 free_reply_forward_helper (rf_helper);
1329 /* Checks a list of headers. If any of them are not currently
1330 * downloaded (CACHED) then returns TRUE else returns FALSE.
1333 header_list_count_uncached_msgs (TnyList *header_list)
1336 gint uncached_messages = 0;
1338 iter = tny_list_create_iterator (header_list);
1339 while (!tny_iterator_is_done (iter)) {
1342 header = TNY_HEADER (tny_iterator_get_current (iter));
1344 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1345 uncached_messages ++;
1346 g_object_unref (header);
1349 tny_iterator_next (iter);
1351 g_object_unref (iter);
1353 return uncached_messages;
1356 /* Returns FALSE if the user does not want to download the
1357 * messages. Returns TRUE if the user allowed the download.
1360 connect_to_get_msg (ModestWindow *win,
1361 gint num_of_uncached_msgs,
1362 TnyAccount *account)
1364 GtkResponseType response;
1366 /* Allways download if we are online. */
1367 if (tny_device_is_online (modest_runtime_get_device ()))
1370 /* If offline, then ask for user permission to download the messages */
1371 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1372 ngettext("mcen_nc_get_msg",
1374 num_of_uncached_msgs));
1376 if (response == GTK_RESPONSE_CANCEL)
1379 return modest_platform_connect_and_wait(GTK_WINDOW (win), account);
1383 * Common code for the reply and forward actions
1386 reply_forward (ReplyForwardAction action, ModestWindow *win)
1388 ModestMailOperation *mail_op = NULL;
1389 TnyList *header_list = NULL;
1390 ReplyForwardHelper *rf_helper = NULL;
1391 guint reply_forward_type;
1392 gboolean continue_download = TRUE;
1393 gboolean do_retrieve = TRUE;
1395 g_return_if_fail (MODEST_IS_WINDOW(win));
1397 /* we need an account when editing */
1398 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1399 if (!modest_ui_actions_run_account_setup_wizard (win))
1403 header_list = get_selected_headers (win);
1407 reply_forward_type =
1408 modest_conf_get_int (modest_runtime_get_conf (),
1409 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1412 /* check if we need to download msg before asking about it */
1413 do_retrieve = (action == ACTION_FORWARD) ||
1414 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1417 gint num_of_unc_msgs;
1419 /* check that the messages have been previously downloaded */
1420 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
1421 /* If there are any uncached message ask the user
1422 * whether he/she wants to download them. */
1423 if (num_of_unc_msgs) {
1424 TnyAccount *account = get_account_from_header_list (header_list);
1425 continue_download = connect_to_get_msg (win, num_of_unc_msgs, account);
1426 g_object_unref (account);
1430 if (!continue_download) {
1431 g_object_unref (header_list);
1435 /* We assume that we can only select messages of the
1436 same folder and that we reply all of them from the
1437 same account. In fact the interface currently only
1438 allows single selection */
1441 rf_helper = g_slice_new0 (ReplyForwardHelper);
1442 rf_helper->reply_forward_type = reply_forward_type;
1443 rf_helper->action = action;
1444 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1446 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1447 rf_helper->parent_window = GTK_WIDGET (win);
1448 if (!rf_helper->account_name)
1449 rf_helper->account_name =
1450 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1452 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1455 /* Get header and message. Do not free them here, the
1456 reply_forward_cb must do it */
1457 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1458 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1459 if (!msg || !header) {
1461 g_object_unref (msg);
1462 g_printerr ("modest: no message found\n");
1465 reply_forward_cb (NULL, header, msg, rf_helper);
1468 g_object_unref (header);
1473 /* Only reply/forward to one message */
1474 iter = tny_list_create_iterator (header_list);
1475 header = TNY_HEADER (tny_iterator_get_current (iter));
1476 g_object_unref (iter);
1479 /* Retrieve messages */
1482 modest_mail_operation_new_with_error_handling (G_OBJECT(win),
1483 modest_ui_actions_get_msgs_full_error_handler,
1485 modest_mail_operation_queue_add (
1486 modest_runtime_get_mail_operation_queue (), mail_op);
1488 modest_mail_operation_get_msg (mail_op,
1493 g_object_unref(mail_op);
1495 /* we put a ref here to prevent double unref as the reply
1496 * forward callback unrefs the header at its end */
1497 reply_forward_cb (NULL, header, NULL, rf_helper);
1501 g_object_unref (header);
1507 g_object_unref (header_list);
1511 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1513 g_return_if_fail (MODEST_IS_WINDOW(win));
1515 reply_forward (ACTION_REPLY, win);
1519 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1521 g_return_if_fail (MODEST_IS_WINDOW(win));
1523 reply_forward (ACTION_FORWARD, win);
1527 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1529 g_return_if_fail (MODEST_IS_WINDOW(win));
1531 reply_forward (ACTION_REPLY_TO_ALL, win);
1535 modest_ui_actions_on_next (GtkAction *action,
1536 ModestWindow *window)
1538 if (MODEST_IS_MAIN_WINDOW (window)) {
1539 GtkWidget *header_view;
1541 header_view = modest_main_window_get_child_widget (
1542 MODEST_MAIN_WINDOW(window),
1543 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1547 modest_header_view_select_next (
1548 MODEST_HEADER_VIEW(header_view));
1549 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1550 modest_msg_view_window_select_next_message (
1551 MODEST_MSG_VIEW_WINDOW (window));
1553 g_return_if_reached ();
1558 modest_ui_actions_on_prev (GtkAction *action,
1559 ModestWindow *window)
1561 g_return_if_fail (MODEST_IS_WINDOW(window));
1563 if (MODEST_IS_MAIN_WINDOW (window)) {
1564 GtkWidget *header_view;
1565 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1566 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1570 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1571 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1572 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1574 g_return_if_reached ();
1579 modest_ui_actions_on_sort (GtkAction *action,
1580 ModestWindow *window)
1582 g_return_if_fail (MODEST_IS_WINDOW(window));
1584 if (MODEST_IS_MAIN_WINDOW (window)) {
1585 GtkWidget *header_view;
1586 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1587 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1589 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1594 /* Show sorting dialog */
1595 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1600 new_messages_arrived (ModestMailOperation *self,
1601 TnyList *new_headers,
1604 ModestMainWindow *win = NULL;
1605 GtkWidget *folder_view = NULL;
1606 TnyFolderStore *folder = NULL;
1607 gboolean folder_empty = FALSE;
1609 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
1610 win = MODEST_MAIN_WINDOW (user_data);
1612 /* Don't do anything if there are not new headers, this could
1613 happen if there was any problem with the mail operation */
1617 /* Set contents style of headers view */
1618 if (modest_main_window_get_contents_style (win) == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1619 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1620 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1621 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1624 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1627 modest_main_window_set_contents_style (win,
1628 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1631 /* Notify new messages have been downloaded */
1632 if ((new_headers != NULL) && (tny_list_get_length (new_headers) > 0))
1633 modest_platform_on_new_headers_received (new_headers);
1637 * This function performs the send & receive required actions. The
1638 * window is used to create the mail operation. Typically it should
1639 * always be the main window, but we pass it as argument in order to
1643 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1645 gchar *acc_name = NULL;
1646 ModestMailOperation *mail_op;
1647 TnyAccount *store_account = NULL;
1649 /* If no account name was provided then get the current account, and if
1650 there is no current account then pick the default one: */
1651 if (!account_name) {
1652 acc_name = g_strdup (modest_window_get_active_account(win));
1654 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1656 g_printerr ("modest: cannot get default account\n");
1660 acc_name = g_strdup (account_name);
1664 /* Ensure that we have a connection available */
1666 modest_tny_account_store_get_server_account (modest_runtime_get_account_store (),
1668 TNY_ACCOUNT_TYPE_STORE);
1669 if (!modest_platform_connect_and_wait (NULL, TNY_ACCOUNT (store_account))) {
1670 g_object_unref (store_account);
1673 g_object_unref (store_account);
1675 /* Set send/receive operation in progress */
1676 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1678 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
1679 modest_ui_actions_send_receive_error_handler,
1682 g_signal_connect (G_OBJECT(mail_op), "operation-finished",
1683 G_CALLBACK (on_send_receive_finished),
1686 /* Send & receive. */
1687 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1688 /* Receive and then send. The operation is tagged initially as
1689 a receive operation because the account update performs a
1690 receive and then a send. The operation changes its type
1691 internally, so the progress objects will receive the proper
1692 progress information */
1693 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1694 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, win);
1695 g_object_unref (G_OBJECT (mail_op));
1703 modest_ui_actions_do_cancel_send (const gchar *account_name,
1706 TnyTransportAccount *transport_account;
1707 TnySendQueue *send_queue = NULL;
1708 GError *error = NULL;
1710 /* Get transport account */
1712 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1713 (modest_runtime_get_account_store(),
1715 TNY_ACCOUNT_TYPE_TRANSPORT));
1716 if (!transport_account) {
1717 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1722 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1723 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1724 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1725 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1726 "modest: could not find send queue for account\n");
1728 /* Keeep messages in outbox folder */
1729 tny_send_queue_cancel (send_queue, FALSE, &error);
1733 if (transport_account != NULL)
1734 g_object_unref (G_OBJECT (transport_account));
1738 modest_ui_actions_cancel_send_all (ModestWindow *win)
1740 GSList *account_names, *iter;
1742 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1745 iter = account_names;
1747 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1748 iter = g_slist_next (iter);
1751 modest_account_mgr_free_account_names (account_names);
1752 account_names = NULL;
1756 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1759 /* Check if accounts exist */
1760 gboolean accounts_exist =
1761 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1763 /* If not, allow the user to create an account before trying to send/receive. */
1764 if (!accounts_exist)
1765 modest_ui_actions_on_accounts (NULL, win);
1767 /* Cancel all sending operaitons */
1768 modest_ui_actions_cancel_send_all (win);
1772 * Refreshes all accounts. This function will be used by automatic
1776 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1778 GSList *account_names, *iter;
1780 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1783 iter = account_names;
1785 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1786 iter = g_slist_next (iter);
1789 modest_account_mgr_free_account_names (account_names);
1790 account_names = NULL;
1794 modest_do_refresh_current_folder(ModestWindow *win)
1796 /* Refresh currently selected folder. Note that if we only
1797 want to retreive the headers, then the refresh only will
1798 invoke a poke_status over all folders, i.e., only the
1799 total/unread count will be updated */
1800 if (MODEST_IS_MAIN_WINDOW (win)) {
1801 GtkWidget *header_view, *folder_view;
1802 TnyFolderStore *folder_store;
1804 /* Get folder and header view */
1806 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1807 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1811 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1813 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1815 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1816 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1818 /* We do not need to set the contents style
1819 because it hasn't changed. We also do not
1820 need to save the widget status. Just force
1822 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1823 TNY_FOLDER (folder_store),
1824 folder_refreshed_cb,
1825 MODEST_MAIN_WINDOW (win));
1829 g_object_unref (folder_store);
1835 * Handler of the click on Send&Receive button in the main toolbar
1838 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1840 /* Check if accounts exist */
1841 gboolean accounts_exist =
1842 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1844 /* If not, allow the user to create an account before trying to send/receive. */
1845 if (!accounts_exist)
1846 modest_ui_actions_on_accounts (NULL, win);
1848 modest_do_refresh_current_folder (win);
1850 /* Refresh the active account */
1851 modest_ui_actions_do_send_receive (NULL, win);
1856 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1859 GtkWidget *header_view;
1861 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1863 header_view = modest_main_window_get_child_widget (main_window,
1864 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1868 conf = modest_runtime_get_conf ();
1870 /* what is saved/restored is depending on the style; thus; we save with
1871 * old style, then update the style, and restore for this new style
1873 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1875 if (modest_header_view_get_style
1876 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1877 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1878 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1880 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1881 MODEST_HEADER_VIEW_STYLE_DETAILS);
1883 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1884 MODEST_CONF_HEADER_VIEW_KEY);
1889 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1891 ModestMainWindow *main_window)
1893 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1894 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1896 /* in the case the folder is empty, show the empty folder message and focus
1898 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1899 if (modest_header_view_is_empty (header_view)) {
1900 TnyFolder *folder = modest_header_view_get_folder (header_view);
1901 GtkWidget *folder_view =
1902 modest_main_window_get_child_widget (main_window,
1903 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1905 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1906 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1910 /* If no header has been selected then exit */
1915 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1916 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1918 /* Update toolbar dimming state */
1919 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1923 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1925 ModestMainWindow *main_window)
1929 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1934 if (modest_header_view_count_selected_headers (header_view) > 1) {
1935 hildon_banner_show_information (NULL, NULL, _("mcen_ib_select_one_message"));
1940 /* headers = tny_simple_list_new (); */
1941 /* tny_list_prepend (headers, G_OBJECT (header)); */
1942 headers = modest_header_view_get_selected_headers (header_view);
1944 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1946 g_object_unref (headers);
1950 set_active_account_from_tny_account (TnyAccount *account,
1951 ModestWindow *window)
1953 const gchar *server_acc_name = tny_account_get_id (account);
1955 /* We need the TnyAccount provided by the
1956 account store because that is the one that
1957 knows the name of the Modest account */
1958 TnyAccount *modest_server_account = modest_server_account =
1959 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1960 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1962 if (!modest_server_account) {
1963 g_warning ("%s: could not get tny account\n", __FUNCTION__);
1967 /* Update active account, but only if it's not a pseudo-account */
1968 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
1969 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
1970 const gchar *modest_acc_name =
1971 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1972 if (modest_acc_name)
1973 modest_window_set_active_account (window, modest_acc_name);
1976 g_object_unref (modest_server_account);
1981 folder_refreshed_cb (ModestMailOperation *mail_op,
1985 ModestMainWindow *win = NULL;
1986 GtkWidget *header_view;
1987 gboolean folder_empty = FALSE;
1988 gboolean all_marked_as_deleted = FALSE;
1990 g_return_if_fail (TNY_IS_FOLDER (folder));
1992 win = MODEST_MAIN_WINDOW (user_data);
1994 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1997 TnyFolder *current_folder;
1999 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
2000 if (current_folder != NULL && folder != current_folder) {
2001 g_object_unref (current_folder);
2004 g_object_unref (current_folder);
2007 /* Check if folder is empty and set headers view contents style */
2008 folder_empty = (tny_folder_get_all_count (folder) == 0);
2009 all_marked_as_deleted = modest_header_view_is_empty (MODEST_HEADER_VIEW(header_view));
2010 if (folder_empty || all_marked_as_deleted)
2011 modest_main_window_set_contents_style (win,
2012 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2016 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2017 TnyFolderStore *folder_store,
2019 ModestMainWindow *main_window)
2022 GtkWidget *header_view;
2024 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2026 header_view = modest_main_window_get_child_widget(main_window,
2027 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2031 conf = modest_runtime_get_conf ();
2033 if (TNY_IS_ACCOUNT (folder_store)) {
2035 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2037 /* Show account details */
2038 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2041 if (TNY_IS_FOLDER (folder_store) && selected) {
2043 /* Update the active account */
2044 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2046 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2047 g_object_unref (account);
2051 /* Set the header style by default, it could
2052 be changed later by the refresh callback to
2054 modest_main_window_set_contents_style (main_window,
2055 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2057 /* Set folder on header view. This function
2058 will call tny_folder_refresh_async so we
2059 pass a callback that will be called when
2060 finished. We use that callback to set the
2061 empty view if there are no messages */
2062 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2063 TNY_FOLDER (folder_store),
2064 folder_refreshed_cb,
2067 /* Restore configuration. We need to do this
2068 *after* the set_folder because the widget
2069 memory asks the header view about its
2071 modest_widget_memory_restore (modest_runtime_get_conf (),
2072 G_OBJECT(header_view),
2073 MODEST_CONF_HEADER_VIEW_KEY);
2075 /* Update the active account */
2076 //modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
2077 /* Save only if we're seeing headers */
2078 if (modest_main_window_get_contents_style (main_window) ==
2079 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2080 modest_widget_memory_save (conf, G_OBJECT (header_view),
2081 MODEST_CONF_HEADER_VIEW_KEY);
2082 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2086 /* Update toolbar dimming state */
2087 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2091 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2098 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2100 online = tny_device_is_online (modest_runtime_get_device());
2103 /* already online -- the item is simply not there... */
2104 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2106 GTK_MESSAGE_WARNING,
2108 _("The %s you selected cannot be found"),
2110 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2111 gtk_dialog_run (GTK_DIALOG(dialog));
2113 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2116 _("mcen_bd_dialog_cancel"),
2117 GTK_RESPONSE_REJECT,
2118 _("mcen_bd_dialog_ok"),
2119 GTK_RESPONSE_ACCEPT,
2121 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2122 "Do you want to get online?"), item);
2123 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2124 gtk_label_new (txt), FALSE, FALSE, 0);
2125 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2128 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2129 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2130 /* TODO: Comment about why is this commented out: */
2131 /* modest_platform_connect_and_wait (); */
2134 gtk_widget_destroy (dialog);
2138 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2141 /* g_message ("%s %s", __FUNCTION__, link); */
2146 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2149 modest_platform_activate_uri (link);
2153 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2156 modest_platform_show_uri_popup (link);
2160 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2163 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2167 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2168 const gchar *address,
2171 /* g_message ("%s %s", __FUNCTION__, address); */
2175 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2176 TnyMsg *saved_draft,
2179 ModestMsgEditWindow *edit_window;
2181 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2183 /* If there was any error do nothing */
2184 if (modest_mail_operation_get_error (mail_op) != NULL)
2187 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2191 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2193 TnyTransportAccount *transport_account;
2194 ModestMailOperation *mail_operation;
2196 gchar *account_name, *from;
2197 ModestAccountMgr *account_mgr;
2198 gchar *info_text = NULL;
2200 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2202 data = modest_msg_edit_window_get_msg_data (edit_window);
2204 account_mgr = modest_runtime_get_account_mgr();
2205 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2207 account_name = modest_account_mgr_get_default_account (account_mgr);
2208 if (!account_name) {
2209 g_printerr ("modest: no account found\n");
2210 modest_msg_edit_window_free_msg_data (edit_window, data);
2214 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2215 account_name = g_strdup (data->account_name);
2219 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2220 (modest_runtime_get_account_store(),
2222 TNY_ACCOUNT_TYPE_TRANSPORT));
2223 if (!transport_account) {
2224 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2225 g_free (account_name);
2226 modest_msg_edit_window_free_msg_data (edit_window, data);
2229 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2231 /* Create the mail operation */
2232 mail_operation = modest_mail_operation_new (G_OBJECT(edit_window));
2233 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2235 modest_mail_operation_save_to_drafts (mail_operation,
2247 data->priority_flags,
2248 on_save_to_drafts_cb,
2252 g_free (account_name);
2253 g_object_unref (G_OBJECT (transport_account));
2254 g_object_unref (G_OBJECT (mail_operation));
2256 modest_msg_edit_window_free_msg_data (edit_window, data);
2258 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2259 modest_platform_information_banner (NULL, NULL, info_text);
2260 modest_msg_edit_window_reset_modified (edit_window);
2264 /* For instance, when clicking the Send toolbar button when editing a message: */
2266 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2268 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2270 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2273 /* FIXME: Code added just for testing. The final version will
2274 use the send queue provided by tinymail and some
2276 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2277 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2279 account_name = modest_account_mgr_get_default_account (account_mgr);
2281 if (!account_name) {
2282 /* Run account setup wizard */
2283 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window)))
2287 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2289 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2290 account_name = g_strdup (data->account_name);
2293 /* Get the currently-active transport account for this modest account: */
2294 TnyTransportAccount *transport_account =
2295 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2296 (modest_runtime_get_account_store(),
2298 if (!transport_account) {
2299 /* Run account setup wizard */
2300 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2304 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2306 /* Create the mail operation */
2307 ModestMailOperation *mail_operation = modest_mail_operation_new (G_OBJECT(edit_window));
2308 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2310 modest_mail_operation_send_new_mail (mail_operation,
2322 data->priority_flags);
2326 g_free (account_name);
2327 g_object_unref (G_OBJECT (transport_account));
2328 g_object_unref (G_OBJECT (mail_operation));
2330 modest_msg_edit_window_free_msg_data (edit_window, data);
2331 modest_msg_edit_window_set_sent (edit_window, TRUE);
2333 /* Save settings and close the window: */
2334 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2338 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2339 ModestMsgEditWindow *window)
2341 ModestMsgEditFormatState *format_state = NULL;
2343 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2344 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2346 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2349 format_state = modest_msg_edit_window_get_format_state (window);
2350 g_return_if_fail (format_state != NULL);
2352 format_state->bold = gtk_toggle_action_get_active (action);
2353 modest_msg_edit_window_set_format_state (window, format_state);
2354 g_free (format_state);
2359 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2360 ModestMsgEditWindow *window)
2362 ModestMsgEditFormatState *format_state = NULL;
2364 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2365 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2367 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2370 format_state = modest_msg_edit_window_get_format_state (window);
2371 g_return_if_fail (format_state != NULL);
2373 format_state->italics = gtk_toggle_action_get_active (action);
2374 modest_msg_edit_window_set_format_state (window, format_state);
2375 g_free (format_state);
2380 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2381 ModestMsgEditWindow *window)
2383 ModestMsgEditFormatState *format_state = NULL;
2385 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2386 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2388 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2391 format_state = modest_msg_edit_window_get_format_state (window);
2392 g_return_if_fail (format_state != NULL);
2394 format_state->bullet = gtk_toggle_action_get_active (action);
2395 modest_msg_edit_window_set_format_state (window, format_state);
2396 g_free (format_state);
2401 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2402 GtkRadioAction *selected,
2403 ModestMsgEditWindow *window)
2405 ModestMsgEditFormatState *format_state = NULL;
2406 GtkJustification value;
2408 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2410 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2413 value = gtk_radio_action_get_current_value (selected);
2415 format_state = modest_msg_edit_window_get_format_state (window);
2416 g_return_if_fail (format_state != NULL);
2418 format_state->justification = value;
2419 modest_msg_edit_window_set_format_state (window, format_state);
2420 g_free (format_state);
2424 modest_ui_actions_on_select_editor_color (GtkAction *action,
2425 ModestMsgEditWindow *window)
2427 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2428 g_return_if_fail (GTK_IS_ACTION (action));
2430 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2433 modest_msg_edit_window_select_color (window);
2437 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2438 ModestMsgEditWindow *window)
2440 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2441 g_return_if_fail (GTK_IS_ACTION (action));
2443 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2446 modest_msg_edit_window_select_background_color (window);
2450 modest_ui_actions_on_insert_image (GtkAction *action,
2451 ModestMsgEditWindow *window)
2453 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2454 g_return_if_fail (GTK_IS_ACTION (action));
2456 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2459 modest_msg_edit_window_insert_image (window);
2463 modest_ui_actions_on_attach_file (GtkAction *action,
2464 ModestMsgEditWindow *window)
2466 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2467 g_return_if_fail (GTK_IS_ACTION (action));
2469 modest_msg_edit_window_offer_attach_file (window);
2473 modest_ui_actions_on_remove_attachments (GtkAction *action,
2474 ModestMsgEditWindow *window)
2476 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2477 g_return_if_fail (GTK_IS_ACTION (action));
2479 modest_msg_edit_window_remove_attachments (window, NULL);
2483 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2486 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2487 const GError *error = modest_mail_operation_get_error (mail_op);
2490 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2491 _("mail_in_ui_folder_create_error"));
2496 modest_ui_actions_create_folder(GtkWidget *parent_window,
2497 GtkWidget *folder_view)
2499 TnyFolderStore *parent_folder;
2501 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2503 if (parent_folder) {
2504 gboolean finished = FALSE;
2506 gchar *folder_name = NULL, *suggested_name = NULL;
2507 const gchar *proto_str = NULL;
2508 TnyAccount *account;
2510 if (TNY_IS_ACCOUNT (parent_folder))
2511 account = g_object_ref (parent_folder);
2513 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2514 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2516 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2517 MODEST_PROTOCOL_STORE_POP) {
2519 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2521 g_object_unref (account);
2523 /* Run the new folder dialog */
2525 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2530 g_free (suggested_name);
2531 suggested_name = NULL;
2533 if (result == GTK_RESPONSE_REJECT) {
2536 ModestMailOperation *mail_op;
2537 TnyFolder *new_folder = NULL;
2539 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
2540 modest_ui_actions_new_folder_error_handler,
2541 parent_window, NULL);
2543 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2545 new_folder = modest_mail_operation_create_folder (mail_op,
2547 (const gchar *) folder_name);
2549 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2552 g_object_unref (new_folder);
2555 g_object_unref (mail_op);
2558 suggested_name = folder_name;
2562 g_object_unref (parent_folder);
2567 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2569 GtkWidget *folder_view;
2571 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2573 folder_view = modest_main_window_get_child_widget (main_window,
2574 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2578 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2582 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2585 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2586 const GError *error = NULL;
2587 const gchar *message = NULL;
2589 /* Get error message */
2590 error = modest_mail_operation_get_error (mail_op);
2592 g_return_if_reached ();
2594 switch (error->code) {
2595 case MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS:
2596 message = _CS("ckdg_ib_folder_already_exists");
2599 g_return_if_reached ();
2602 modest_platform_information_banner (GTK_WIDGET (window), NULL, message);
2606 modest_ui_actions_on_rename_folder (GtkAction *action,
2607 ModestMainWindow *main_window)
2609 TnyFolderStore *folder;
2610 GtkWidget *folder_view;
2611 GtkWidget *header_view;
2613 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2615 folder_view = modest_main_window_get_child_widget (main_window,
2616 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2620 header_view = modest_main_window_get_child_widget (main_window,
2621 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2626 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2631 if (TNY_IS_FOLDER (folder)) {
2634 const gchar *current_name;
2635 TnyFolderStore *parent;
2636 gboolean do_rename = TRUE;
2638 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2639 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
2640 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
2641 parent, current_name,
2643 g_object_unref (parent);
2645 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
2647 } else if (modest_platform_is_network_folderstore(folder) &&
2648 !tny_device_is_online (modest_runtime_get_device())) {
2649 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2650 do_rename = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2651 g_object_unref(account);
2655 ModestMailOperation *mail_op;
2656 GtkTreeSelection *sel = NULL;
2659 modest_mail_operation_new_with_error_handling (G_OBJECT(main_window),
2660 modest_ui_actions_rename_folder_error_handler,
2663 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2666 /* Clear the headers view */
2667 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2668 gtk_tree_selection_unselect_all (sel);
2670 /* Select *after* the changes */
2671 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2672 TNY_FOLDER(folder), TRUE);
2674 /* Actually rename the folder */
2675 modest_mail_operation_rename_folder (mail_op,
2676 TNY_FOLDER (folder),
2677 (const gchar *) folder_name);
2679 g_object_unref (mail_op);
2680 g_free (folder_name);
2683 g_object_unref (folder);
2687 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2690 GObject *win = modest_mail_operation_get_source (mail_op);
2692 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2693 _("mail_in_ui_folder_delete_error"));
2694 g_object_unref (win);
2698 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2700 TnyFolderStore *folder;
2701 GtkWidget *folder_view;
2704 gboolean do_delete = TRUE;
2706 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (main_window), FALSE);
2708 folder_view = modest_main_window_get_child_widget (main_window,
2709 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2713 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2715 /* Show an error if it's an account */
2716 if (!TNY_IS_FOLDER (folder)) {
2717 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2718 _("mail_in_ui_folder_delete_error"));
2719 g_object_unref (G_OBJECT (folder));
2724 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2725 tny_folder_get_name (TNY_FOLDER (folder)));
2726 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2727 (const gchar *) message);
2730 if (response != GTK_RESPONSE_OK) {
2732 } else if (modest_platform_is_network_folderstore(folder) &&
2733 !tny_device_is_online (modest_runtime_get_device())) {
2734 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2735 do_delete = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2736 g_object_unref(account);
2740 ModestMailOperation *mail_op;
2741 GtkTreeSelection *sel;
2743 /* Unselect the folder before deleting it to free the headers */
2744 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2745 gtk_tree_selection_unselect_all (sel);
2747 /* Create the mail operation */
2749 modest_mail_operation_new_with_error_handling (G_OBJECT(main_window),
2750 modest_ui_actions_delete_folder_error_handler,
2753 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2755 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2756 g_object_unref (G_OBJECT (mail_op));
2759 g_object_unref (G_OBJECT (folder));
2765 modest_ui_actions_on_delete_folder (GtkAction *action,
2766 ModestMainWindow *main_window)
2768 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2770 if (delete_folder (main_window, FALSE)) {
2771 GtkWidget *folder_view;
2773 folder_view = modest_main_window_get_child_widget (main_window,
2774 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2775 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2780 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2782 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2784 delete_folder (main_window, TRUE);
2789 show_error (GtkWidget *parent_widget, const gchar* text)
2791 hildon_banner_show_information(parent_widget, NULL, text);
2794 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2796 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2803 gtk_dialog_run (dialog);
2804 gtk_widget_destroy (GTK_WIDGET (dialog));
2809 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2810 const gchar* server_account_name,
2815 ModestMainWindow *main_window)
2817 g_return_if_fail(server_account_name);
2818 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2820 /* Initalize output parameters: */
2827 #ifdef MODEST_PLATFORM_MAEMO
2828 /* Maemo uses a different (awkward) button order,
2829 * It should probably just use gtk_alternative_dialog_button_order ().
2831 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2834 _("mcen_bd_dialog_ok"),
2835 GTK_RESPONSE_ACCEPT,
2836 _("mcen_bd_dialog_cancel"),
2837 GTK_RESPONSE_REJECT,
2840 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2844 GTK_RESPONSE_REJECT,
2846 GTK_RESPONSE_ACCEPT,
2848 #endif /* MODEST_PLATFORM_MAEMO */
2850 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2852 gchar *server_name = modest_account_mgr_get_server_account_hostname (
2853 modest_runtime_get_account_mgr(), server_account_name);
2854 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2855 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2860 /* This causes a warning because the logical ID has no %s in it,
2861 * though the translation does, but there is not much we can do about that: */
2862 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2863 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2866 g_free (server_name);
2870 gchar *initial_username = modest_account_mgr_get_server_account_username (
2871 modest_runtime_get_account_mgr(), server_account_name);
2873 GtkWidget *entry_username = gtk_entry_new ();
2874 if (initial_username)
2875 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2876 /* Dim this if a connection has ever succeeded with this username,
2877 * as per the UI spec: */
2878 const gboolean username_known =
2879 modest_account_mgr_get_server_account_username_has_succeeded(
2880 modest_runtime_get_account_mgr(), server_account_name);
2881 gtk_widget_set_sensitive (entry_username, !username_known);
2883 #ifdef MODEST_PLATFORM_MAEMO
2884 /* Auto-capitalization is the default, so let's turn it off: */
2885 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2887 /* Create a size group to be used by all captions.
2888 * Note that HildonCaption does not create a default size group if we do not specify one.
2889 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2890 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2892 GtkWidget *caption = hildon_caption_new (sizegroup,
2893 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2894 gtk_widget_show (entry_username);
2895 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2896 FALSE, FALSE, MODEST_MARGIN_HALF);
2897 gtk_widget_show (caption);
2899 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2901 #endif /* MODEST_PLATFORM_MAEMO */
2904 GtkWidget *entry_password = gtk_entry_new ();
2905 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2906 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2908 #ifdef MODEST_PLATFORM_MAEMO
2909 /* Auto-capitalization is the default, so let's turn it off: */
2910 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2911 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2913 caption = hildon_caption_new (sizegroup,
2914 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2915 gtk_widget_show (entry_password);
2916 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2917 FALSE, FALSE, MODEST_MARGIN_HALF);
2918 gtk_widget_show (caption);
2919 g_object_unref (sizegroup);
2921 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2923 #endif /* MODEST_PLATFORM_MAEMO */
2925 if (initial_username != NULL)
2926 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
2928 /* This is not in the Maemo UI spec:
2929 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2930 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2934 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2936 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2938 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2940 modest_account_mgr_set_server_account_username (
2941 modest_runtime_get_account_mgr(), server_account_name,
2944 const gboolean username_was_changed =
2945 (strcmp (*username, initial_username) != 0);
2946 if (username_was_changed) {
2947 g_warning ("%s: tinymail does not yet support changing the "
2948 "username in the get_password() callback.\n", __FUNCTION__);
2953 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2955 /* We do not save the password in the configuration,
2956 * because this function is only called for passwords that should
2957 * not be remembered:
2958 modest_server_account_set_password (
2959 modest_runtime_get_account_mgr(), server_account_name,
2968 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2980 /* This is not in the Maemo UI spec:
2981 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2987 gtk_widget_destroy (dialog);
2989 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2993 modest_ui_actions_on_cut (GtkAction *action,
2994 ModestWindow *window)
2996 GtkWidget *focused_widget;
2997 GtkClipboard *clipboard;
2999 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3000 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3001 if (GTK_IS_EDITABLE (focused_widget)) {
3002 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3003 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3004 gtk_clipboard_store (clipboard);
3005 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3006 GtkTextBuffer *buffer;
3008 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3009 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3010 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3011 gtk_clipboard_store (clipboard);
3012 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3013 TnyList *header_list = modest_header_view_get_selected_headers (
3014 MODEST_HEADER_VIEW (focused_widget));
3015 gboolean continue_download = FALSE;
3016 gint num_of_unc_msgs;
3018 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3020 if (num_of_unc_msgs) {
3021 TnyAccount *account = get_account_from_header_list (header_list);
3022 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3023 g_object_unref (account);
3026 if (num_of_unc_msgs == 0 || continue_download) {
3027 /* modest_platform_information_banner (
3028 NULL, NULL, _CS("mcen_ib_getting_items"));*/
3029 modest_header_view_cut_selection (
3030 MODEST_HEADER_VIEW (focused_widget));
3033 g_object_unref (header_list);
3034 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3035 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3040 modest_ui_actions_on_copy (GtkAction *action,
3041 ModestWindow *window)
3043 GtkClipboard *clipboard;
3044 GtkWidget *focused_widget;
3045 gboolean copied = TRUE;
3047 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3048 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3050 if (GTK_IS_LABEL (focused_widget)) {
3051 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
3052 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3053 gtk_clipboard_store (clipboard);
3054 } else if (GTK_IS_EDITABLE (focused_widget)) {
3055 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3056 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3057 gtk_clipboard_store (clipboard);
3058 } else if (GTK_IS_HTML (focused_widget)) {
3059 gtk_html_copy (GTK_HTML (focused_widget));
3060 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3061 gtk_clipboard_store (clipboard);
3062 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3063 GtkTextBuffer *buffer;
3064 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3065 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3066 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3067 gtk_clipboard_store (clipboard);
3068 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3069 TnyList *header_list = modest_header_view_get_selected_headers (
3070 MODEST_HEADER_VIEW (focused_widget));
3071 gboolean continue_download = FALSE;
3072 gint num_of_unc_msgs;
3074 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3076 if (num_of_unc_msgs) {
3077 TnyAccount *account = get_account_from_header_list (header_list);
3078 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3079 g_object_unref (account);
3082 if (num_of_unc_msgs == 0 || continue_download) {
3083 modest_platform_information_banner (
3084 NULL, NULL, _CS("mcen_ib_getting_items"));
3085 modest_header_view_copy_selection (
3086 MODEST_HEADER_VIEW (focused_widget));
3090 g_object_unref (header_list);
3092 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3093 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3096 /* Show information banner if there was a copy to clipboard */
3098 modest_platform_information_banner (
3099 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3103 modest_ui_actions_on_undo (GtkAction *action,
3104 ModestWindow *window)
3106 ModestEmailClipboard *clipboard = NULL;
3108 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3109 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3110 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3111 /* Clear clipboard source */
3112 clipboard = modest_runtime_get_email_clipboard ();
3113 modest_email_clipboard_clear (clipboard);
3116 g_return_if_reached ();
3121 modest_ui_actions_on_redo (GtkAction *action,
3122 ModestWindow *window)
3124 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3125 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3128 g_return_if_reached ();
3134 destroy_information_note (ModestMailOperation *mail_op, gpointer user_data)
3136 /* destroy information note */
3137 gtk_widget_destroy (GTK_WIDGET(user_data));
3142 paste_as_attachment_free (gpointer data)
3144 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3146 gtk_widget_destroy (helper->banner);
3147 g_object_unref (helper->banner);
3152 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3157 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3158 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3163 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3168 modest_ui_actions_on_paste (GtkAction *action,
3169 ModestWindow *window)
3171 GtkWidget *focused_widget = NULL;
3172 GtkWidget *inf_note = NULL;
3173 ModestMailOperation *mail_op = NULL;
3175 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3176 if (GTK_IS_EDITABLE (focused_widget)) {
3177 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3178 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3179 ModestEmailClipboard *e_clipboard = NULL;
3180 e_clipboard = modest_runtime_get_email_clipboard ();
3181 if (modest_email_clipboard_cleared (e_clipboard)) {
3182 GtkTextBuffer *buffer;
3183 GtkClipboard *clipboard;
3185 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3186 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3187 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3188 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3189 ModestMailOperation *mail_op;
3190 TnyFolder *src_folder;
3193 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3194 helper->window = MODEST_MSG_EDIT_WINDOW (window);
3195 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3196 _CS("ckct_nw_pasting"));
3197 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
3198 mail_op = modest_mail_operation_new (G_OBJECT (window));
3199 if (helper->banner != NULL) {
3200 g_object_ref (G_OBJECT (helper->banner));
3201 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
3202 gtk_widget_show (GTK_WIDGET (helper->banner));
3206 modest_mail_operation_get_msgs_full (mail_op,
3208 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
3210 paste_as_attachment_free);
3213 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3214 ModestEmailClipboard *clipboard = NULL;
3215 TnyFolder *src_folder = NULL;
3216 TnyFolderStore *folder_store = NULL;
3217 TnyList *data = NULL;
3218 gboolean delete = FALSE;
3220 /* Check clipboard source */
3221 clipboard = modest_runtime_get_email_clipboard ();
3222 if (modest_email_clipboard_cleared (clipboard))
3225 /* Get elements to paste */
3226 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
3228 /* Create a new mail operation */
3229 mail_op = modest_mail_operation_new (G_OBJECT(window));
3231 /* Get destination folder */
3232 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
3234 /* transfer messages */
3238 /* Ask for user confirmation */
3240 modest_ui_actions_msgs_move_to_confirmation (window,
3241 TNY_FOLDER (folder_store),
3245 if (response == GTK_RESPONSE_OK) {
3246 /* Launch notification */
3247 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3248 _CS("ckct_nw_pasting"));
3249 if (inf_note != NULL) {
3250 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3251 gtk_widget_show (GTK_WIDGET(inf_note));
3254 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3255 modest_mail_operation_xfer_msgs (mail_op,
3257 TNY_FOLDER (folder_store),
3259 destroy_information_note,
3262 g_object_unref (mail_op);
3265 } else if (src_folder != NULL) {
3266 /* Launch notification */
3267 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3268 _CS("ckct_nw_pasting"));
3269 if (inf_note != NULL) {
3270 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3271 gtk_widget_show (GTK_WIDGET(inf_note));
3274 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3275 modest_mail_operation_xfer_folder (mail_op,
3279 destroy_information_note,
3285 g_object_unref (data);
3286 if (src_folder != NULL)
3287 g_object_unref (src_folder);
3288 if (folder_store != NULL)
3289 g_object_unref (folder_store);
3295 modest_ui_actions_on_select_all (GtkAction *action,
3296 ModestWindow *window)
3298 GtkWidget *focused_widget;
3300 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3301 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3302 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3303 } else if (GTK_IS_LABEL (focused_widget)) {
3304 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3305 } else if (GTK_IS_EDITABLE (focused_widget)) {
3306 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3307 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3308 GtkTextBuffer *buffer;
3309 GtkTextIter start, end;
3311 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3312 gtk_text_buffer_get_start_iter (buffer, &start);
3313 gtk_text_buffer_get_end_iter (buffer, &end);
3314 gtk_text_buffer_select_range (buffer, &start, &end);
3315 } else if (GTK_IS_HTML (focused_widget)) {
3316 gtk_html_select_all (GTK_HTML (focused_widget));
3317 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3318 GtkWidget *header_view = focused_widget;
3319 GtkTreeSelection *selection = NULL;
3321 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
3322 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3323 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3326 /* Disable window dimming management */
3327 modest_window_disable_dimming (MODEST_WINDOW(window));
3329 /* Select all messages */
3330 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3331 gtk_tree_selection_select_all (selection);
3333 /* Set focuse on header view */
3334 gtk_widget_grab_focus (header_view);
3337 /* Enable window dimming management */
3338 modest_window_enable_dimming (MODEST_WINDOW(window));
3339 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3345 modest_ui_actions_on_mark_as_read (GtkAction *action,
3346 ModestWindow *window)
3348 g_return_if_fail (MODEST_IS_WINDOW(window));
3350 /* Mark each header as read */
3351 do_headers_action (window, headers_action_mark_as_read, NULL);
3355 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3356 ModestWindow *window)
3358 g_return_if_fail (MODEST_IS_WINDOW(window));
3360 /* Mark each header as read */
3361 do_headers_action (window, headers_action_mark_as_unread, NULL);
3365 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3366 GtkRadioAction *selected,
3367 ModestWindow *window)
3371 value = gtk_radio_action_get_current_value (selected);
3372 if (MODEST_IS_WINDOW (window)) {
3373 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3378 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3379 GtkRadioAction *selected,
3380 ModestWindow *window)
3382 TnyHeaderFlags flags;
3383 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3385 flags = gtk_radio_action_get_current_value (selected);
3386 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3390 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3391 GtkRadioAction *selected,
3392 ModestWindow *window)
3396 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3398 file_format = gtk_radio_action_get_current_value (selected);
3399 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3404 modest_ui_actions_on_zoom_plus (GtkAction *action,
3405 ModestWindow *window)
3407 g_return_if_fail (MODEST_IS_WINDOW (window));
3409 modest_window_zoom_plus (MODEST_WINDOW (window));
3413 modest_ui_actions_on_zoom_minus (GtkAction *action,
3414 ModestWindow *window)
3416 g_return_if_fail (MODEST_IS_WINDOW (window));
3418 modest_window_zoom_minus (MODEST_WINDOW (window));
3422 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3423 ModestWindow *window)
3425 ModestWindowMgr *mgr;
3426 gboolean fullscreen, active;
3427 g_return_if_fail (MODEST_IS_WINDOW (window));
3429 mgr = modest_runtime_get_window_mgr ();
3431 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3432 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3434 if (active != fullscreen) {
3435 modest_window_mgr_set_fullscreen_mode (mgr, active);
3436 gtk_window_present (GTK_WINDOW (window));
3441 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3442 ModestWindow *window)
3444 ModestWindowMgr *mgr;
3445 gboolean fullscreen;
3447 g_return_if_fail (MODEST_IS_WINDOW (window));
3449 mgr = modest_runtime_get_window_mgr ();
3450 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3451 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3453 gtk_window_present (GTK_WINDOW (window));
3457 * Used by modest_ui_actions_on_details to call do_headers_action
3460 headers_action_show_details (TnyHeader *header,
3461 ModestWindow *window,
3468 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3471 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3472 gtk_widget_show_all (dialog);
3473 gtk_dialog_run (GTK_DIALOG (dialog));
3475 gtk_widget_destroy (dialog);
3479 * Show the folder details in a ModestDetailsDialog widget
3482 show_folder_details (TnyFolder *folder,
3488 dialog = modest_details_dialog_new_with_folder (window, folder);
3491 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3492 gtk_widget_show_all (dialog);
3493 gtk_dialog_run (GTK_DIALOG (dialog));
3495 gtk_widget_destroy (dialog);
3499 * Show the header details in a ModestDetailsDialog widget
3502 modest_ui_actions_on_details (GtkAction *action,
3505 TnyList * headers_list;
3509 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3512 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3515 g_object_unref (msg);
3517 headers_list = get_selected_headers (win);
3521 iter = tny_list_create_iterator (headers_list);
3523 header = TNY_HEADER (tny_iterator_get_current (iter));
3525 headers_action_show_details (header, win, NULL);
3526 g_object_unref (header);
3529 g_object_unref (iter);
3530 g_object_unref (headers_list);
3532 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3533 GtkWidget *folder_view, *header_view;
3535 /* Check which widget has the focus */
3536 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3537 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3538 if (gtk_widget_is_focus (folder_view)) {
3539 TnyFolderStore *folder_store
3540 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3541 if (!folder_store) {
3542 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3545 /* Show only when it's a folder */
3546 /* This function should not be called for account items,
3547 * because we dim the menu item for them. */
3548 if (TNY_IS_FOLDER (folder_store)) {
3549 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3552 g_object_unref (folder_store);
3555 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3556 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3557 /* Show details of each header */
3558 do_headers_action (win, headers_action_show_details, header_view);
3564 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3565 ModestMsgEditWindow *window)
3567 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3569 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3573 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3574 ModestMsgEditWindow *window)
3576 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3578 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3582 modest_ui_actions_toggle_folders_view (GtkAction *action,
3583 ModestMainWindow *main_window)
3585 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3587 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3588 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3590 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3594 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3595 ModestWindow *window)
3597 gboolean active, fullscreen = FALSE;
3598 ModestWindowMgr *mgr;
3600 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3602 /* Check if we want to toggle the toolbar vuew in fullscreen
3604 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3605 "ViewShowToolbarFullScreen")) {
3609 /* Toggle toolbar */
3610 mgr = modest_runtime_get_window_mgr ();
3611 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
3615 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3616 ModestMsgEditWindow *window)
3618 modest_msg_edit_window_select_font (window);
3622 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3623 const gchar *display_name,
3626 /* Do not change the application name if the widget has not
3627 the focus. This callback could be called even if the folder
3628 view has not the focus, because the handled signal could be
3629 emitted when the folder view is redrawn */
3630 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3632 gtk_window_set_title (window, display_name);
3634 gtk_window_set_title (window, " ");
3639 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3641 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3642 modest_msg_edit_window_select_contacts (window);
3646 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3648 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3649 modest_msg_edit_window_check_names (window, FALSE);
3653 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3655 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3656 GTK_WIDGET (user_data));
3660 * This function is used to track changes in the selection of the
3661 * folder view that is inside the "move to" dialog to enable/disable
3662 * the OK button because we do not want the user to select a disallowed
3663 * destination for a folder.
3664 * The user also not desired to be able to use NEW button on items where
3665 * folder creation is not possibel.
3668 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
3669 TnyFolderStore *folder_store,
3673 GtkWidget *dialog = NULL;
3674 GtkWidget *ok_button = NULL, *new_button = NULL;
3675 GList *children = NULL;
3676 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
3677 gboolean moving_folder = FALSE;
3678 gboolean is_local_account = TRUE;
3679 GtkWidget *folder_view = NULL;
3680 ModestTnyFolderRules rules;
3685 /* Get the OK button */
3686 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
3690 children = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
3691 ok_button = GTK_WIDGET (children->next->next->data);
3692 new_button = GTK_WIDGET (children->next->data);
3693 g_list_free (children);
3695 /* check if folder_store is an remote account */
3696 if (TNY_IS_ACCOUNT (folder_store)) {
3697 TnyAccount *local_account = NULL;
3698 ModestTnyAccountStore *account_store = NULL;
3700 account_store = modest_runtime_get_account_store ();
3701 local_account = modest_tny_account_store_get_local_folders_account (account_store);
3703 if ((gpointer) local_account != (gpointer) folder_store) {
3704 is_local_account = FALSE;
3705 /* New button should be dimmed on remote
3707 new_sensitive = FALSE;
3709 g_object_unref (local_account);
3712 /* Check the target folder rules */
3713 if (TNY_IS_FOLDER (folder_store)) {
3714 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
3715 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
3716 ok_sensitive = FALSE;
3717 new_sensitive = FALSE;
3722 /* Check if we're moving a folder */
3723 if (MODEST_IS_MAIN_WINDOW (user_data)) {
3724 /* Get the widgets */
3725 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
3726 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3727 if (gtk_widget_is_focus (folder_view))
3728 moving_folder = TRUE;
3731 if (moving_folder) {
3732 TnyFolderStore *moved_folder = NULL, *parent = NULL;
3734 /* Get the folder to move */
3735 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3737 /* Check that we're not moving to the same folder */
3738 if (TNY_IS_FOLDER (moved_folder)) {
3739 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
3740 if (parent == folder_store)
3741 ok_sensitive = FALSE;
3742 g_object_unref (parent);
3745 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
3746 /* Do not allow to move to an account unless it's the
3747 local folders account */
3748 if (!is_local_account)
3749 ok_sensitive = FALSE;
3752 if (ok_sensitive && (moved_folder == folder_store)) {
3753 /* Do not allow to move to itself */
3754 ok_sensitive = FALSE;
3756 g_object_unref (moved_folder);
3758 TnyHeader *header = NULL;
3759 TnyFolder *src_folder = NULL;
3761 /* Moving a message */
3762 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
3763 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (user_data));
3764 src_folder = tny_header_get_folder (header);
3765 g_object_unref (header);
3768 TNY_FOLDER (modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view)));
3771 /* Do not allow to move the msg to the same folder */
3772 /* Do not allow to move the msg to an account */
3773 if ((gpointer) src_folder == (gpointer) folder_store ||
3774 TNY_IS_ACCOUNT (folder_store))
3775 ok_sensitive = FALSE;
3776 g_object_unref (src_folder);
3780 /* Set sensitivity of the OK button */
3781 gtk_widget_set_sensitive (ok_button, ok_sensitive);
3782 /* Set sensitivity of the NEW button */
3783 gtk_widget_set_sensitive (new_button, new_sensitive);
3787 create_move_to_dialog (GtkWindow *win,
3788 GtkWidget *folder_view,
3789 GtkWidget **tree_view)
3791 GtkWidget *dialog, *scroll;
3792 GtkWidget *new_button;
3794 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3796 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3799 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
3800 /* We do this manually so GTK+ does not associate a response ID for
3802 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
3803 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3804 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
3806 /* Create scrolled window */
3807 scroll = gtk_scrolled_window_new (NULL, NULL);
3808 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3809 GTK_POLICY_AUTOMATIC,
3810 GTK_POLICY_AUTOMATIC);
3812 /* Create folder view */
3813 *tree_view = modest_platform_create_folder_view (NULL);
3815 /* Track changes in the selection to
3816 * disable the OK button whenever "Move to" is not possible
3817 * disbale NEW button whenever New is not possible */
3818 g_signal_connect (*tree_view,
3819 "folder_selection_changed",
3820 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
3823 /* Listen to clicks on New button */
3824 g_signal_connect (G_OBJECT (new_button),
3826 G_CALLBACK(create_move_to_dialog_on_new_folder),
3829 /* It could happen that we're trying to move a message from a
3830 window (msg window for example) after the main window was
3831 closed, so we can not just get the model of the folder
3833 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
3834 const gchar *visible_id = NULL;
3836 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
3837 MODEST_FOLDER_VIEW(*tree_view));
3840 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
3842 /* Show the same account than the one that is shown in the main window */
3843 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
3846 const gchar *active_account_name = NULL;
3847 ModestAccountMgr *mgr = NULL;
3848 ModestAccountData *acc_data = NULL;
3850 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3851 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3853 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
3854 mgr = modest_runtime_get_account_mgr ();
3855 acc_data = modest_account_mgr_get_account_data (mgr, active_account_name);
3857 /* Set the new visible & active account */
3858 if (acc_data && acc_data->store_account) {
3859 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
3860 acc_data->store_account->account_name);
3861 modest_account_mgr_free_account_data (mgr, acc_data);
3865 /* Hide special folders */
3866 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3868 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3870 /* Add scroll to dialog */
3871 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3872 scroll, TRUE, TRUE, 0);
3874 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3875 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3881 * Returns TRUE if at least one of the headers of the list belongs to
3882 * a message that has been fully retrieved.
3884 #if 0 /* no longer in use. delete in 2007.10 */
3886 has_retrieved_msgs (TnyList *list)
3889 gboolean found = FALSE;
3891 iter = tny_list_create_iterator (list);
3892 while (!tny_iterator_is_done (iter) && !found) {
3894 TnyHeaderFlags flags = 0;
3896 header = TNY_HEADER (tny_iterator_get_current (iter));
3898 flags = tny_header_get_flags (header);
3899 if (flags & TNY_HEADER_FLAG_CACHED)
3900 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3903 g_object_unref (header);
3907 tny_iterator_next (iter);
3909 g_object_unref (iter);
3917 * Shows a confirmation dialog to the user when we're moving messages
3918 * from a remote server to the local storage. Returns the dialog
3919 * response. If it's other kind of movement then it always returns
3922 * This one is used by the next functions:
3923 * modest_ui_actions_on_paste - commented out
3924 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
3927 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
3928 TnyFolder *dest_folder,
3932 gint response = GTK_RESPONSE_OK;
3933 TnyAccount *account = NULL;
3934 TnyFolder *src_folder = NULL;
3935 TnyIterator *iter = NULL;
3936 TnyHeader *header = NULL;
3938 /* return with OK if the destination is a remote folder */
3939 if (modest_tny_folder_is_remote_folder (dest_folder))
3940 return GTK_RESPONSE_OK;
3942 /* Get source folder */
3943 iter = tny_list_create_iterator (headers);
3944 header = TNY_HEADER (tny_iterator_get_current (iter));
3946 src_folder = tny_header_get_folder (header);
3947 g_object_unref (header);
3949 g_object_unref (iter);
3951 /* if no src_folder, message may be an attahcment */
3952 if (src_folder == NULL)
3953 return GTK_RESPONSE_CANCEL;
3955 /* If the source is a local or MMC folder */
3956 if (!modest_tny_folder_is_remote_folder (src_folder)) {
3957 g_object_unref (src_folder);
3958 return GTK_RESPONSE_OK;
3961 /* Get the account */
3962 account = tny_folder_get_account (src_folder);
3964 /* now if offline we ask the user */
3965 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
3966 response = GTK_RESPONSE_OK;
3968 response = GTK_RESPONSE_CANCEL;
3971 g_object_unref (src_folder);
3972 g_object_unref (account);
3980 move_to_cb (ModestMailOperation *mail_op, gpointer user_data)
3982 MoveToHelper *helper = (MoveToHelper *) user_data;
3984 /* Note that the operation could have failed, in that case do
3986 if (modest_mail_operation_get_status (mail_op) ==
3987 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
3989 GObject *object = modest_mail_operation_get_source (mail_op);
3990 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
3991 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
3993 if (!modest_msg_view_window_select_next_message (self))
3994 if (!modest_msg_view_window_select_previous_message (self))
3995 /* No more messages to view, so close this window */
3996 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3997 } else if (MODEST_IS_MAIN_WINDOW (object) && helper->reference != NULL) {
3998 GtkWidget *header_view;
4000 GtkTreeSelection *sel;
4002 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4003 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4004 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
4005 path = gtk_tree_row_reference_get_path (helper->reference);
4006 gtk_tree_selection_select_path (sel, path);
4007 gtk_tree_path_free (path);
4009 g_object_unref (object);
4012 /* Close the "Pasting" information banner */
4013 gtk_widget_destroy (GTK_WIDGET(helper->banner));
4014 if (helper->reference != NULL)
4015 gtk_tree_row_reference_free (helper->reference);
4020 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
4023 ModestWindow *main_window = NULL;
4024 GtkWidget *folder_view = NULL;
4025 GObject *win = modest_mail_operation_get_source (mail_op);
4026 const GError *error = NULL;
4027 const gchar *message = NULL;
4029 /* Get error message */
4030 error = modest_mail_operation_get_error (mail_op);
4031 if (error != NULL && error->message != NULL) {
4032 message = error->message;
4034 message = _("mail_in_ui_folder_move_target_error");
4037 /* Disable next automatic folder selection */
4038 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ());
4039 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
4040 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4041 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
4043 if (user_data && TNY_IS_FOLDER (user_data)) {
4044 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
4045 TNY_FOLDER (user_data), FALSE);
4048 /* Show notification dialog */
4049 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
4050 g_object_unref (win);
4054 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
4057 GObject *win = modest_mail_operation_get_source (mail_op);
4058 const GError *error = modest_mail_operation_get_error (mail_op);
4060 g_return_if_fail (error != NULL);
4061 if (error->message != NULL)
4062 g_printerr ("modest: %s\n", error->message);
4064 g_printerr ("modest: unkonw error on send&receive operation");
4066 /* Show error message */
4067 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
4068 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
4069 /* _CS("sfil_ib_unable_to_receive")); */
4071 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
4072 /* _CS("sfil_ib_unable_to_send")); */
4073 g_object_unref (win);
4077 open_msg_for_purge_cb (ModestMailOperation *mail_op,
4084 gint pending_purges = 0;
4085 gboolean some_purged = FALSE;
4086 ModestWindow *win = MODEST_WINDOW (user_data);
4087 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
4089 /* If there was any error */
4090 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
4091 modest_window_mgr_unregister_header (mgr, header);
4095 /* Once the message has been retrieved for purging, we check if
4096 * it's all ok for purging */
4098 parts = tny_simple_list_new ();
4099 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
4100 iter = tny_list_create_iterator (parts);
4102 while (!tny_iterator_is_done (iter)) {
4104 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4105 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
4106 if (tny_mime_part_is_purged (part))
4113 g_object_unref (part);
4115 tny_iterator_next (iter);
4117 g_object_unref (iter);
4120 if (pending_purges>0) {
4122 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
4124 if (response == GTK_RESPONSE_OK) {
4125 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
4126 iter = tny_list_create_iterator (parts);
4127 while (!tny_iterator_is_done (iter)) {
4130 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4131 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
4132 tny_mime_part_set_purged (part);
4135 g_object_unref (part);
4137 tny_iterator_next (iter);
4140 tny_msg_rewrite_cache (msg);
4143 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
4145 g_object_unref (iter);
4147 modest_window_mgr_unregister_header (mgr, header);
4149 g_object_unref (parts);
4153 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
4154 ModestMainWindow *win)
4156 GtkWidget *header_view;
4157 TnyList *header_list;
4160 TnyHeaderFlags flags;
4161 ModestWindow *msg_view_window = NULL;
4164 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4166 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4167 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4169 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
4171 if (tny_list_get_length (header_list) == 1) {
4172 iter = tny_list_create_iterator (header_list);
4173 header = TNY_HEADER (tny_iterator_get_current (iter));
4174 g_object_unref (iter);
4179 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
4180 header, &msg_view_window);
4181 flags = tny_header_get_flags (header);
4182 if (!(flags & TNY_HEADER_FLAG_CACHED))
4185 if (msg_view_window != NULL)
4186 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
4188 /* do nothing; uid was registered before, so window is probably on it's way */
4189 g_warning ("debug: header %p has already been registered", header);
4192 ModestMailOperation *mail_op = NULL;
4193 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
4194 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
4195 modest_ui_actions_get_msgs_full_error_handler,
4197 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4198 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
4200 g_object_unref (mail_op);
4203 g_object_unref (header);
4205 g_object_unref (header_list);
4209 * Utility function that transfer messages from both the main window
4210 * and the msg view window when using the "Move to" dialog
4213 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
4216 TnyList *headers = NULL;
4217 TnyAccount *dst_account = NULL;
4218 const gchar *proto_str = NULL;
4219 gboolean dst_is_pop = FALSE;
4221 if (!TNY_IS_FOLDER (dst_folder)) {
4222 modest_platform_information_banner (GTK_WIDGET (win),
4224 _CS("ckdg_ib_unable_to_move_to_current_location"));
4228 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
4229 proto_str = tny_account_get_proto (dst_account);
4231 /* tinymail will return NULL for local folders it seems */
4232 dst_is_pop = proto_str &&
4233 (modest_protocol_info_get_transport_store_protocol (proto_str) ==
4234 MODEST_PROTOCOL_STORE_POP);
4236 g_object_unref (dst_account);
4238 /* Get selected headers */
4239 headers = get_selected_headers (MODEST_WINDOW (win));
4242 modest_platform_information_banner (GTK_WIDGET (win),
4244 ngettext("mail_in_ui_folder_move_target_error",
4245 "mail_in_ui_folder_move_targets_error",
4246 tny_list_get_length (headers)));
4247 g_object_unref (headers);
4251 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4252 helper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4253 _CS("ckct_nw_pasting"));
4254 if (helper->banner != NULL) {
4255 gtk_window_set_modal (GTK_WINDOW(helper->banner), FALSE);
4256 gtk_widget_show (GTK_WIDGET(helper->banner));
4259 if (MODEST_IS_MAIN_WINDOW (win)) {
4260 GtkWidget *header_view =
4261 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
4262 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4263 helper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
4266 ModestMailOperation *mail_op =
4267 modest_mail_operation_new_with_error_handling (G_OBJECT(win),
4268 modest_ui_actions_move_folder_error_handler,
4270 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4273 modest_mail_operation_xfer_msgs (mail_op,
4275 TNY_FOLDER (dst_folder),
4280 g_object_unref (G_OBJECT (mail_op));
4281 g_object_unref (headers);
4285 * UI handler for the "Move to" action when invoked from the
4289 modest_ui_actions_on_main_window_move_to (GtkAction *action,
4290 GtkWidget *folder_view,
4291 TnyFolderStore *dst_folder,
4292 ModestMainWindow *win)
4294 ModestHeaderView *header_view = NULL;
4295 ModestMailOperation *mail_op = NULL;
4296 TnyFolderStore *src_folder;
4297 gboolean online = (tny_device_is_online (modest_runtime_get_device()));
4299 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4301 /* Get the source folder */
4302 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4304 /* Get header view */
4305 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
4307 /* Get folder or messages to transfer */
4308 if (gtk_widget_is_focus (folder_view)) {
4309 GtkTreeSelection *sel;
4310 gboolean do_xfer = TRUE;
4312 /* Allow only to transfer folders to the local root folder */
4313 if (TNY_IS_ACCOUNT (dst_folder) &&
4314 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder)) {
4316 } else if (!TNY_IS_FOLDER (src_folder)) {
4317 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
4319 } else if (!online && modest_platform_is_network_folderstore(src_folder)) {
4320 guint num_headers = tny_folder_get_all_count(TNY_FOLDER (src_folder));
4321 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (src_folder));
4322 if (!connect_to_get_msg(MODEST_WINDOW (win), num_headers, account))
4324 g_object_unref (account);
4328 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4329 helper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4330 _CS("ckct_nw_pasting"));
4331 if (helper->banner != NULL) {
4332 gtk_window_set_modal (GTK_WINDOW(helper->banner), FALSE);
4333 gtk_widget_show (GTK_WIDGET(helper->banner));
4335 /* Clean folder on header view before moving it */
4336 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
4337 gtk_tree_selection_unselect_all (sel);
4340 modest_mail_operation_new_with_error_handling (G_OBJECT(win),
4341 modest_ui_actions_move_folder_error_handler,
4343 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4346 /* Select *after* the changes */
4347 /* TODO: this function hangs UI after transfer */
4348 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
4349 /* TNY_FOLDER (src_folder), TRUE); */
4351 modest_mail_operation_xfer_folder (mail_op,
4352 TNY_FOLDER (src_folder),
4357 /* Unref mail operation */
4358 g_object_unref (G_OBJECT (mail_op));
4360 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
4361 gboolean do_xfer = TRUE;
4362 /* Ask for confirmation if the source folder is remote and we're not connected */
4363 if (!online && modest_platform_is_network_folderstore(src_folder)) {
4364 TnyList *headers = modest_header_view_get_selected_headers(header_view);
4365 if (!msgs_already_deleted_from_server(headers, src_folder)) {
4366 guint num_headers = tny_list_get_length(headers);
4367 TnyAccount *account = get_account_from_header_list (headers);
4368 if (!connect_to_get_msg(MODEST_WINDOW (win), num_headers, account))
4370 g_object_unref (account);
4372 g_object_unref(headers);
4374 if (do_xfer) /* Transfer messages */
4375 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4379 g_object_unref (src_folder);
4384 * UI handler for the "Move to" action when invoked from the
4385 * ModestMsgViewWindow
4388 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
4389 TnyFolderStore *dst_folder,
4390 ModestMsgViewWindow *win)
4392 TnyHeader *header = NULL;
4393 TnyFolder *src_folder = NULL;
4394 TnyAccount *account = NULL;
4396 /* Create header list */
4397 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
4398 src_folder = TNY_FOLDER (tny_header_get_folder(header));
4399 g_object_unref (header);
4401 /* Transfer the message if online or confirmed by the user */
4402 account = tny_folder_get_account (src_folder);
4403 if (remote_folder_is_pop(TNY_FOLDER_STORE (src_folder)) ||
4404 (modest_platform_is_network_folderstore(TNY_FOLDER_STORE (src_folder)) &&
4405 connect_to_get_msg(MODEST_WINDOW (win), 1, account))) {
4406 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4408 g_object_unref (account);
4409 g_object_unref (src_folder);
4413 modest_ui_actions_on_move_to (GtkAction *action,
4416 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
4418 TnyFolderStore *dst_folder = NULL;
4419 ModestMainWindow *main_window;
4421 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
4422 MODEST_IS_MSG_VIEW_WINDOW (win));
4424 /* Get the main window if exists */
4425 if (MODEST_IS_MAIN_WINDOW (win))
4426 main_window = MODEST_MAIN_WINDOW (win);
4429 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
4431 /* Get the folder view widget if exists */
4433 folder_view = modest_main_window_get_child_widget (main_window,
4434 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4438 /* Create and run the dialog */
4439 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
4440 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
4441 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4442 result = gtk_dialog_run (GTK_DIALOG(dialog));
4443 g_object_ref (tree_view);
4444 gtk_widget_destroy (dialog);
4446 if (result != GTK_RESPONSE_ACCEPT)
4449 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
4450 /* Do window specific stuff */
4451 if (MODEST_IS_MAIN_WINDOW (win)) {
4452 modest_ui_actions_on_main_window_move_to (action,
4455 MODEST_MAIN_WINDOW (win));
4457 modest_ui_actions_on_msg_view_window_move_to (action,
4459 MODEST_MSG_VIEW_WINDOW (win));
4463 g_object_unref (dst_folder);
4467 * Calls #HeadersFunc for each header already selected in the main
4468 * window or the message currently being shown in the msg view window
4471 do_headers_action (ModestWindow *win,
4475 TnyList *headers_list = NULL;
4476 TnyIterator *iter = NULL;
4477 TnyHeader *header = NULL;
4478 TnyFolder *folder = NULL;
4481 headers_list = get_selected_headers (win);
4485 /* Get the folder */
4486 iter = tny_list_create_iterator (headers_list);
4487 header = TNY_HEADER (tny_iterator_get_current (iter));
4489 folder = tny_header_get_folder (header);
4490 g_object_unref (header);
4493 /* Call the function for each header */
4494 while (!tny_iterator_is_done (iter)) {
4495 header = TNY_HEADER (tny_iterator_get_current (iter));
4496 func (header, win, user_data);
4497 g_object_unref (header);
4498 tny_iterator_next (iter);
4501 /* Trick: do a poke status in order to speed up the signaling
4503 tny_folder_poke_status (folder);
4506 g_object_unref (folder);
4507 g_object_unref (iter);
4508 g_object_unref (headers_list);
4512 modest_ui_actions_view_attachment (GtkAction *action,
4513 ModestWindow *window)
4515 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4516 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4518 /* not supported window for this action */
4519 g_return_if_reached ();
4524 modest_ui_actions_save_attachments (GtkAction *action,
4525 ModestWindow *window)
4527 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4528 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4530 /* not supported window for this action */
4531 g_return_if_reached ();
4536 modest_ui_actions_remove_attachments (GtkAction *action,
4537 ModestWindow *window)
4539 if (MODEST_IS_MAIN_WINDOW (window)) {
4540 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4541 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4542 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4544 /* not supported window for this action */
4545 g_return_if_reached ();
4550 modest_ui_actions_on_settings (GtkAction *action,
4555 dialog = modest_platform_get_global_settings_dialog ();
4556 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4557 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4558 gtk_widget_show_all (dialog);
4560 gtk_dialog_run (GTK_DIALOG (dialog));
4562 gtk_widget_destroy (dialog);
4566 modest_ui_actions_on_help (GtkAction *action,
4569 const gchar *help_id = NULL;
4571 if (MODEST_IS_MAIN_WINDOW (win)) {
4572 GtkWidget *folder_view;
4573 TnyFolderStore *folder_store;
4575 /* Get selected folder */
4576 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4577 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4578 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4580 /* Switch help_id */
4581 if (TNY_IS_FOLDER (folder_store)) {
4582 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4583 case TNY_FOLDER_TYPE_NORMAL:
4584 help_id = "applications_email_managefolders";
4586 case TNY_FOLDER_TYPE_INBOX:
4587 help_id = "applications_email_inbox";
4589 case TNY_FOLDER_TYPE_OUTBOX:
4590 help_id = "applications_email_outbox";
4592 case TNY_FOLDER_TYPE_SENT:
4593 help_id = "applications_email_sent";
4595 case TNY_FOLDER_TYPE_DRAFTS:
4596 help_id = "applications_email_drafts";
4598 case TNY_FOLDER_TYPE_ARCHIVE:
4599 help_id = "applications_email_managefolders";
4602 help_id = "applications_email_managefolders";
4605 help_id = "applications_email_mainview";
4607 g_object_unref (folder_store);
4608 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4609 help_id = "applications_email_viewer";
4610 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4611 help_id = "applications_email_editor";
4613 modest_platform_show_help (GTK_WINDOW (win), help_id);
4617 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4618 ModestWindow *window)
4620 ModestMailOperation *mail_op;
4624 headers = get_selected_headers (window);
4628 /* Create mail operation */
4629 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (window),
4630 modest_ui_actions_get_msgs_full_error_handler,
4632 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4633 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4636 g_object_unref (headers);
4637 g_object_unref (mail_op);
4641 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4642 ModestWindow *window)
4644 g_return_if_fail (MODEST_IS_WINDOW (window));
4647 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4651 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4652 ModestWindow *window)
4654 g_return_if_fail (MODEST_IS_WINDOW (window));
4657 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4661 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4662 ModestWindow *window)
4664 g_return_if_fail (MODEST_IS_WINDOW (window));
4667 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4671 modest_ui_actions_on_format_menu_activated (GtkAction *action,
4672 ModestWindow *window)
4674 g_return_if_fail (MODEST_IS_WINDOW (window));
4677 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4681 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4682 ModestWindow *window)
4684 g_return_if_fail (MODEST_IS_WINDOW (window));
4687 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4691 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4692 ModestWindow *window)
4694 g_return_if_fail (MODEST_IS_WINDOW (window));
4697 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4701 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4702 ModestWindow *window)
4704 g_return_if_fail (MODEST_IS_WINDOW (window));
4707 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4711 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4712 ModestWindow *window)
4714 g_return_if_fail (MODEST_IS_WINDOW (window));
4717 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4721 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4722 ModestWindow *window)
4724 g_return_if_fail (MODEST_IS_WINDOW (window));
4727 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4731 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4733 g_return_if_fail (MODEST_IS_WINDOW (window));
4736 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4740 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4742 g_return_if_fail (MODEST_IS_WINDOW (window));
4744 modest_platform_show_search_messages (GTK_WINDOW (window));
4748 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4750 g_return_if_fail (MODEST_IS_WINDOW (win));
4751 modest_platform_show_addressbook (GTK_WINDOW (win));
4756 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4757 ModestWindow *window)
4759 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4761 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4765 on_send_receive_finished (ModestMailOperation *mail_op,
4768 /* Set send/receive operation finished */
4769 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW (user_data));
4774 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
4780 const gchar* server_name = NULL;
4781 TnyTransportAccount *server_account;
4782 gchar *message = NULL;
4784 /* Don't show anything if the user cancelled something */
4785 if (err->code == TNY_TRANSPORT_ACCOUNT_ERROR_SEND_USER_CANCEL)
4788 /* Get the server name: */
4790 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
4791 if (server_account) {
4792 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
4794 g_object_unref (server_account);
4795 server_account = NULL;
4798 g_return_if_fail (server_name);
4800 /* Show the appropriate message text for the GError: */
4801 switch (err->code) {
4802 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_HOST_LOOKUP_FAILED:
4803 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4805 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_SERVICE_UNAVAILABLE:
4806 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4808 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_AUTHENTICATION_NOT_SUPPORTED:
4809 message = g_strdup_printf (_("emev_ni_ui_smtp_authentication_fail_error"), server_name);
4811 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND:
4812 message = g_strdup (_("emev_ib_ui_smtp_send_error"));
4815 g_return_if_reached ();
4818 /* TODO if the username or the password where not defined we
4819 should show the Accounts Settings dialog or the Connection
4820 specific SMTP server window */
4822 modest_platform_run_information_dialog (NULL, message);
4827 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
4832 ModestMainWindow *main_window = NULL;
4833 ModestWindowMgr *mgr = NULL;
4834 GtkWidget *folder_view = NULL, *header_view = NULL;
4835 TnyFolderStore *selected_folder = NULL;
4836 TnyFolderType folder_type;
4838 mgr = modest_runtime_get_window_mgr ();
4839 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr));
4844 /* Check if selected folder is OUTBOX */
4845 folder_view = modest_main_window_get_child_widget (main_window,
4846 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4847 header_view = modest_main_window_get_child_widget (main_window,
4848 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4850 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4851 if (!TNY_IS_FOLDER (selected_folder))
4854 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
4855 #if GTK_CHECK_VERSION(2, 8, 0)
4856 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
4857 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
4858 GtkTreeViewColumn *tree_column;
4860 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
4861 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
4862 gtk_tree_view_column_queue_resize (tree_column);
4865 gtk_widget_queue_draw (header_view);
4870 if (selected_folder != NULL)
4871 g_object_unref (selected_folder);