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);
982 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
986 GObject *win = modest_mail_operation_get_source (mail_op);
988 error = modest_mail_operation_get_error (mail_op);
990 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
992 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
995 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
996 _("mail_ni_ui_folder_get_msg_folder_error"));
1000 g_object_unref (win);
1004 * Returns the account a list of headers belongs to. It returns a
1005 * *new* reference so don't forget to unref it
1008 get_account_from_header_list (TnyList *headers)
1010 TnyAccount *account = NULL;
1012 if (tny_list_get_length (headers) > 0) {
1013 TnyIterator *iter = tny_list_create_iterator (headers);
1014 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1015 TnyFolder *folder = tny_header_get_folder (header);
1016 account = tny_folder_get_account (folder);
1017 g_object_unref (folder);
1018 g_object_unref (header);
1019 g_object_unref (iter);
1025 * This function is used by both modest_ui_actions_on_open and
1026 * modest_ui_actions_on_header_activated. This way we always do the
1027 * same when trying to open messages.
1030 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
1032 ModestWindowMgr *mgr = NULL;
1033 TnyIterator *iter = NULL, *iter_not_opened = NULL;
1034 ModestMailOperation *mail_op = NULL;
1035 TnyList *not_opened_headers = NULL;
1036 TnyHeaderFlags flags = 0;
1037 TnyAccount *account;
1039 g_return_if_fail (headers != NULL);
1041 /* Check that only one message is selected for opening */
1042 if (tny_list_get_length (headers) != 1) {
1043 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1044 _("mcen_ib_select_one_message"));
1048 mgr = modest_runtime_get_window_mgr ();
1049 iter = tny_list_create_iterator (headers);
1051 /* Get the account */
1052 account = get_account_from_header_list (headers);
1054 /* Look if we already have a message view for each header. If
1055 true, then remove the header from the list of headers to
1057 not_opened_headers = tny_simple_list_new ();
1058 while (!tny_iterator_is_done (iter)) {
1060 ModestWindow *window = NULL;
1061 TnyHeader *header = NULL;
1062 gboolean found = FALSE;
1064 header = TNY_HEADER (tny_iterator_get_current (iter));
1066 flags = tny_header_get_flags (header);
1069 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1071 /* Do not open again the message and present the
1072 window to the user */
1075 gtk_window_present (GTK_WINDOW (window));
1077 /* the header has been registered already, we don't do
1078 * anything but wait for the window to come up*/
1079 g_debug ("header %p already registered, waiting for window", header);
1081 tny_list_append (not_opened_headers, G_OBJECT (header));
1085 g_object_unref (header);
1087 tny_iterator_next (iter);
1089 g_object_unref (iter);
1092 /* Open each message */
1093 if (tny_list_get_length (not_opened_headers) == 0)
1096 /* If some messages would have to be downloaded, ask the user to
1097 * make a connection. It's generally easier to do this here (in the mainloop)
1098 * than later in a thread:
1100 if (tny_list_get_length (not_opened_headers) > 0) {
1102 gboolean found = FALSE;
1104 iter = tny_list_create_iterator (not_opened_headers);
1105 while (!tny_iterator_is_done (iter) && !found) {
1106 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1107 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1110 tny_iterator_next (iter);
1112 g_object_unref (header);
1114 g_object_unref (iter);
1116 /* Ask the user if there are any uncached messages */
1117 if (found && !connect_to_get_msg (win,
1118 header_list_count_uncached_msgs (not_opened_headers),
1123 /* Register the headers before actually creating the windows: */
1124 iter_not_opened = tny_list_create_iterator (not_opened_headers);
1125 while (!tny_iterator_is_done (iter_not_opened)) {
1126 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1128 modest_window_mgr_register_header (mgr, header);
1129 g_object_unref (header);
1131 tny_iterator_next (iter_not_opened);
1133 g_object_unref (iter_not_opened);
1134 iter_not_opened = NULL;
1136 /* Create the mail operation */
1137 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
1138 modest_ui_actions_get_msgs_full_error_handler,
1140 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1141 if (tny_list_get_length (not_opened_headers) > 1) {
1142 modest_mail_operation_get_msgs_full (mail_op,
1148 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1149 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1150 modest_mail_operation_get_msg (mail_op, header, open_msg_cb, NULL);
1151 g_object_unref (header);
1152 g_object_unref (iter);
1154 g_object_unref (mail_op);
1159 g_object_unref (account);
1160 if (not_opened_headers)
1161 g_object_unref (not_opened_headers);
1165 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1170 headers = get_selected_headers (win);
1175 _modest_ui_actions_open (headers, win);
1177 g_object_unref(headers);
1182 free_reply_forward_helper (gpointer data)
1184 ReplyForwardHelper *helper;
1186 helper = (ReplyForwardHelper *) data;
1187 g_free (helper->account_name);
1188 g_slice_free (ReplyForwardHelper, helper);
1192 reply_forward_cb (ModestMailOperation *mail_op, TnyHeader *header, TnyMsg *msg,
1196 ReplyForwardHelper *rf_helper;
1197 ModestWindow *msg_win = NULL;
1198 ModestEditType edit_type;
1200 TnyAccount *account = NULL;
1201 ModestWindowMgr *mgr = NULL;
1202 gchar *signature = NULL;
1203 gboolean use_signature;
1205 /* If there was any error. The mail operation could be NULL,
1206 this means that we already have the message downloaded and
1207 that we didn't do a mail operation to retrieve it */
1208 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1211 g_return_if_fail (user_data != NULL);
1212 rf_helper = (ReplyForwardHelper *) user_data;
1214 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1215 rf_helper->account_name);
1216 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr(),
1217 rf_helper->account_name,
1220 /* Create reply mail */
1221 switch (rf_helper->action) {
1224 modest_tny_msg_create_reply_msg (msg, header, from, signature,
1225 rf_helper->reply_forward_type,
1226 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1228 case ACTION_REPLY_TO_ALL:
1230 modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1231 MODEST_TNY_MSG_REPLY_MODE_ALL);
1232 edit_type = MODEST_EDIT_TYPE_REPLY;
1234 case ACTION_FORWARD:
1236 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1237 edit_type = MODEST_EDIT_TYPE_FORWARD;
1240 g_return_if_reached ();
1247 g_printerr ("modest: failed to create message\n");
1251 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1252 rf_helper->account_name,
1253 TNY_ACCOUNT_TYPE_STORE);
1255 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1259 /* Create and register the windows */
1260 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1261 mgr = modest_runtime_get_window_mgr ();
1262 modest_window_mgr_register_window (mgr, msg_win);
1264 if (rf_helper->parent_window != NULL) {
1265 gdouble parent_zoom;
1267 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1268 modest_window_set_zoom (msg_win, parent_zoom);
1271 /* Show edit window */
1272 gtk_widget_show_all (GTK_WIDGET (msg_win));
1276 g_object_unref (msg_win);
1278 g_object_unref (G_OBJECT (new_msg));
1280 g_object_unref (G_OBJECT (account));
1281 /* g_object_unref (msg); */
1282 free_reply_forward_helper (rf_helper);
1285 /* Checks a list of headers. If any of them are not currently
1286 * downloaded (CACHED) then returns TRUE else returns FALSE.
1289 header_list_count_uncached_msgs (TnyList *header_list)
1292 gint uncached_messages = 0;
1294 iter = tny_list_create_iterator (header_list);
1295 while (!tny_iterator_is_done (iter)) {
1298 header = TNY_HEADER (tny_iterator_get_current (iter));
1300 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1301 uncached_messages ++;
1302 g_object_unref (header);
1305 tny_iterator_next (iter);
1307 g_object_unref (iter);
1309 return uncached_messages;
1312 /* Returns FALSE if the user does not want to download the
1313 * messages. Returns TRUE if the user allowed the download.
1316 connect_to_get_msg (ModestWindow *win,
1317 gint num_of_uncached_msgs,
1318 TnyAccount *account)
1320 GtkResponseType response;
1322 /* Allways download if we are online. */
1323 if (tny_device_is_online (modest_runtime_get_device ()))
1326 /* If offline, then ask for user permission to download the messages */
1327 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1328 ngettext("mcen_nc_get_msg",
1330 num_of_uncached_msgs));
1332 if (response == GTK_RESPONSE_CANCEL)
1335 return modest_platform_connect_and_wait(GTK_WINDOW (win), account);
1339 * Common code for the reply and forward actions
1342 reply_forward (ReplyForwardAction action, ModestWindow *win)
1344 ModestMailOperation *mail_op = NULL;
1345 TnyList *header_list = NULL;
1346 ReplyForwardHelper *rf_helper = NULL;
1347 guint reply_forward_type;
1348 gboolean continue_download = TRUE;
1349 gboolean do_retrieve = TRUE;
1351 g_return_if_fail (MODEST_IS_WINDOW(win));
1353 /* we need an account when editing */
1354 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1355 if (!modest_ui_actions_run_account_setup_wizard (win))
1359 header_list = get_selected_headers (win);
1363 reply_forward_type =
1364 modest_conf_get_int (modest_runtime_get_conf (),
1365 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1368 /* check if we need to download msg before asking about it */
1369 do_retrieve = (action == ACTION_FORWARD) ||
1370 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1373 gint num_of_unc_msgs;
1375 /* check that the messages have been previously downloaded */
1376 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
1377 /* If there are any uncached message ask the user
1378 * whether he/she wants to download them. */
1379 if (num_of_unc_msgs) {
1380 TnyAccount *account = get_account_from_header_list (header_list);
1381 continue_download = connect_to_get_msg (win, num_of_unc_msgs, account);
1382 g_object_unref (account);
1386 if (!continue_download) {
1387 g_object_unref (header_list);
1391 /* We assume that we can only select messages of the
1392 same folder and that we reply all of them from the
1393 same account. In fact the interface currently only
1394 allows single selection */
1397 rf_helper = g_slice_new0 (ReplyForwardHelper);
1398 rf_helper->reply_forward_type = reply_forward_type;
1399 rf_helper->action = action;
1400 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1402 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1403 rf_helper->parent_window = GTK_WIDGET (win);
1404 if (!rf_helper->account_name)
1405 rf_helper->account_name =
1406 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1408 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1411 /* Get header and message. Do not free them here, the
1412 reply_forward_cb must do it */
1413 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1414 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1415 if (!msg || !header) {
1417 g_object_unref (msg);
1418 g_printerr ("modest: no message found\n");
1421 reply_forward_cb (NULL, header, msg, rf_helper);
1424 g_object_unref (header);
1429 /* Only reply/forward to one message */
1430 iter = tny_list_create_iterator (header_list);
1431 header = TNY_HEADER (tny_iterator_get_current (iter));
1432 g_object_unref (iter);
1435 /* Retrieve messages */
1437 mail_op = modest_mail_operation_new_with_error_handling (
1439 modest_ui_actions_get_msgs_full_error_handler,
1441 modest_mail_operation_queue_add (
1442 modest_runtime_get_mail_operation_queue (), mail_op);
1444 modest_mail_operation_get_msg (mail_op,
1449 g_object_unref(mail_op);
1451 /* we put a ref here to prevent double unref as the reply
1452 * forward callback unrefs the header at its end */
1453 reply_forward_cb (NULL, header, NULL, rf_helper);
1457 g_object_unref (header);
1463 g_object_unref (header_list);
1467 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1469 g_return_if_fail (MODEST_IS_WINDOW(win));
1471 reply_forward (ACTION_REPLY, win);
1475 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1477 g_return_if_fail (MODEST_IS_WINDOW(win));
1479 reply_forward (ACTION_FORWARD, win);
1483 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1485 g_return_if_fail (MODEST_IS_WINDOW(win));
1487 reply_forward (ACTION_REPLY_TO_ALL, win);
1491 modest_ui_actions_on_next (GtkAction *action,
1492 ModestWindow *window)
1494 if (MODEST_IS_MAIN_WINDOW (window)) {
1495 GtkWidget *header_view;
1497 header_view = modest_main_window_get_child_widget (
1498 MODEST_MAIN_WINDOW(window),
1499 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1503 modest_header_view_select_next (
1504 MODEST_HEADER_VIEW(header_view));
1505 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1506 modest_msg_view_window_select_next_message (
1507 MODEST_MSG_VIEW_WINDOW (window));
1509 g_return_if_reached ();
1514 modest_ui_actions_on_prev (GtkAction *action,
1515 ModestWindow *window)
1517 g_return_if_fail (MODEST_IS_WINDOW(window));
1519 if (MODEST_IS_MAIN_WINDOW (window)) {
1520 GtkWidget *header_view;
1521 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1522 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1526 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1527 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1528 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1530 g_return_if_reached ();
1535 modest_ui_actions_on_sort (GtkAction *action,
1536 ModestWindow *window)
1538 g_return_if_fail (MODEST_IS_WINDOW(window));
1540 if (MODEST_IS_MAIN_WINDOW (window)) {
1541 GtkWidget *header_view;
1542 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1543 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1545 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1550 /* Show sorting dialog */
1551 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1556 new_messages_arrived (ModestMailOperation *self,
1557 TnyList *new_headers,
1560 ModestMainWindow *win = NULL;
1561 GtkWidget *folder_view = NULL;
1562 TnyFolderStore *folder = NULL;
1563 gboolean folder_empty = FALSE;
1565 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
1566 win = MODEST_MAIN_WINDOW (user_data);
1568 /* Don't do anything if there are not new headers, this could
1569 happen if there was any problem with the mail operation */
1573 /* Set contents style of headers view */
1574 if (modest_main_window_get_contents_style (win) == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1575 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1576 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1577 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1580 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1583 modest_main_window_set_contents_style (win,
1584 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1587 /* Notify new messages have been downloaded */
1588 if ((new_headers != NULL) && (tny_list_get_length (new_headers) > 0)) {
1589 TnyIterator *iter = tny_list_create_iterator (new_headers);
1591 TnyHeader *header = NULL;
1593 header = TNY_HEADER (tny_iterator_get_current (iter));
1594 modest_platform_on_new_header_received (header);
1595 g_object_unref (header);
1597 tny_iterator_next (iter);
1598 } while (!tny_iterator_is_done (iter));
1599 g_object_unref (iter);
1604 * This function performs the send & receive required actions. The
1605 * window is used to create the mail operation. Typically it should
1606 * always be the main window, but we pass it as argument in order to
1610 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1612 gchar *acc_name = NULL;
1613 ModestMailOperation *mail_op;
1614 TnyAccount *store_account = NULL;
1616 /* If no account name was provided then get the current account, and if
1617 there is no current account then pick the default one: */
1618 if (!account_name) {
1619 acc_name = g_strdup (modest_window_get_active_account(win));
1621 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1623 g_printerr ("modest: cannot get default account\n");
1627 acc_name = g_strdup (account_name);
1631 /* Ensure that we have a connection available */
1633 modest_tny_account_store_get_server_account (modest_runtime_get_account_store (),
1635 TNY_ACCOUNT_TYPE_STORE);
1636 if (!modest_platform_connect_and_wait (NULL, TNY_ACCOUNT (store_account))) {
1637 g_object_unref (store_account);
1640 g_object_unref (store_account);
1642 /* Set send/receive operation in progress */
1643 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1645 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
1646 modest_ui_actions_send_receive_error_handler,
1649 g_signal_connect (G_OBJECT(mail_op), "operation-finished",
1650 G_CALLBACK (on_send_receive_finished),
1653 /* Send & receive. */
1654 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1655 /* Receive and then send. The operation is tagged initially as
1656 a receive operation because the account update performs a
1657 receive and then a send. The operation changes its type
1658 internally, so the progress objects will receive the proper
1659 progress information */
1660 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1661 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, win);
1662 g_object_unref (G_OBJECT (mail_op));
1670 modest_ui_actions_do_cancel_send (const gchar *account_name,
1673 TnyTransportAccount *transport_account;
1674 TnySendQueue *send_queue = NULL;
1675 GError *error = NULL;
1677 /* Get transport account */
1679 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1680 (modest_runtime_get_account_store(),
1682 TNY_ACCOUNT_TYPE_TRANSPORT));
1683 if (!transport_account) {
1684 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1689 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1690 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1691 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1692 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1693 "modest: could not find send queue for account\n");
1695 /* Keeep messages in outbox folder */
1696 tny_send_queue_cancel (send_queue, FALSE, &error);
1700 if (transport_account != NULL)
1701 g_object_unref (G_OBJECT (transport_account));
1705 modest_ui_actions_cancel_send_all (ModestWindow *win)
1707 GSList *account_names, *iter;
1709 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1712 iter = account_names;
1714 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1715 iter = g_slist_next (iter);
1718 modest_account_mgr_free_account_names (account_names);
1719 account_names = NULL;
1723 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1726 /* Check if accounts exist */
1727 gboolean accounts_exist =
1728 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1730 /* If not, allow the user to create an account before trying to send/receive. */
1731 if (!accounts_exist)
1732 modest_ui_actions_on_accounts (NULL, win);
1734 /* Cancel all sending operaitons */
1735 modest_ui_actions_cancel_send_all (win);
1739 * Refreshes all accounts. This function will be used by automatic
1743 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1745 GSList *account_names, *iter;
1747 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1750 iter = account_names;
1752 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1753 iter = g_slist_next (iter);
1756 modest_account_mgr_free_account_names (account_names);
1757 account_names = NULL;
1761 modest_do_refresh_current_folder(ModestWindow *win)
1763 /* Refresh currently selected folder. Note that if we only
1764 want to retreive the headers, then the refresh only will
1765 invoke a poke_status over all folders, i.e., only the
1766 total/unread count will be updated */
1767 if (MODEST_IS_MAIN_WINDOW (win)) {
1768 GtkWidget *header_view, *folder_view;
1769 TnyFolderStore *folder_store;
1771 /* Get folder and header view */
1773 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1774 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1778 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1780 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1782 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1783 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1785 /* We do not need to set the contents style
1786 because it hasn't changed. We also do not
1787 need to save the widget status. Just force
1789 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1790 TNY_FOLDER (folder_store),
1791 folder_refreshed_cb,
1792 MODEST_MAIN_WINDOW (win));
1796 g_object_unref (folder_store);
1802 * Handler of the click on Send&Receive button in the main toolbar
1805 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1807 /* Check if accounts exist */
1808 gboolean accounts_exist =
1809 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1811 /* If not, allow the user to create an account before trying to send/receive. */
1812 if (!accounts_exist)
1813 modest_ui_actions_on_accounts (NULL, win);
1815 modest_do_refresh_current_folder (win);
1817 /* Refresh the active account */
1818 modest_ui_actions_do_send_receive (NULL, win);
1823 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1826 GtkWidget *header_view;
1828 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1830 header_view = modest_main_window_get_child_widget (main_window,
1831 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1835 conf = modest_runtime_get_conf ();
1837 /* what is saved/restored is depending on the style; thus; we save with
1838 * old style, then update the style, and restore for this new style
1840 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1842 if (modest_header_view_get_style
1843 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1844 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1845 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1847 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1848 MODEST_HEADER_VIEW_STYLE_DETAILS);
1850 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1851 MODEST_CONF_HEADER_VIEW_KEY);
1856 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1858 ModestMainWindow *main_window)
1860 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1861 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1863 /* in the case the folder is empty, show the empty folder message and focus
1865 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1866 if (modest_header_view_is_empty (header_view)) {
1867 TnyFolder *folder = modest_header_view_get_folder (header_view);
1868 GtkWidget *folder_view =
1869 modest_main_window_get_child_widget (main_window,
1870 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1872 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1873 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1877 /* If no header has been selected then exit */
1882 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1883 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1885 /* Update toolbar dimming state */
1886 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1890 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1892 ModestMainWindow *main_window)
1896 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1901 if (modest_header_view_count_selected_headers (header_view) > 1) {
1902 hildon_banner_show_information (NULL, NULL, _("mcen_ib_select_one_message"));
1907 /* headers = tny_simple_list_new (); */
1908 /* tny_list_prepend (headers, G_OBJECT (header)); */
1909 headers = modest_header_view_get_selected_headers (header_view);
1911 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1913 g_object_unref (headers);
1917 set_active_account_from_tny_account (TnyAccount *account,
1918 ModestWindow *window)
1920 const gchar *server_acc_name = tny_account_get_id (account);
1922 /* We need the TnyAccount provided by the
1923 account store because that is the one that
1924 knows the name of the Modest account */
1925 TnyAccount *modest_server_account = modest_server_account =
1926 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1927 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1929 if (!modest_server_account) {
1930 g_warning ("%s: could not get tny account\n", __FUNCTION__);
1934 /* Update active account, but only if it's not a pseudo-account */
1935 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
1936 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
1937 const gchar *modest_acc_name =
1938 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1939 if (modest_acc_name)
1940 modest_window_set_active_account (window, modest_acc_name);
1943 g_object_unref (modest_server_account);
1948 folder_refreshed_cb (ModestMailOperation *mail_op,
1952 ModestMainWindow *win = NULL;
1953 GtkWidget *header_view;
1954 gboolean folder_empty = FALSE;
1955 gboolean all_marked_as_deleted = FALSE;
1957 g_return_if_fail (TNY_IS_FOLDER (folder));
1959 win = MODEST_MAIN_WINDOW (user_data);
1961 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1964 TnyFolder *current_folder;
1966 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1967 if (current_folder != NULL && folder != current_folder) {
1968 g_object_unref (current_folder);
1971 g_object_unref (current_folder);
1974 /* Check if folder is empty and set headers view contents style */
1975 folder_empty = (tny_folder_get_all_count (folder) == 0);
1976 all_marked_as_deleted = modest_header_view_is_empty (MODEST_HEADER_VIEW(header_view));
1977 if (folder_empty || all_marked_as_deleted)
1978 modest_main_window_set_contents_style (win,
1979 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1983 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1984 TnyFolderStore *folder_store,
1986 ModestMainWindow *main_window)
1989 GtkWidget *header_view;
1991 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1993 header_view = modest_main_window_get_child_widget(main_window,
1994 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1998 conf = modest_runtime_get_conf ();
2000 if (TNY_IS_ACCOUNT (folder_store)) {
2002 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2004 /* Show account details */
2005 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2008 if (TNY_IS_FOLDER (folder_store) && selected) {
2010 /* Update the active account */
2011 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2013 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2014 g_object_unref (account);
2018 /* Set the header style by default, it could
2019 be changed later by the refresh callback to
2021 modest_main_window_set_contents_style (main_window,
2022 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2024 /* Set folder on header view. This function
2025 will call tny_folder_refresh_async so we
2026 pass a callback that will be called when
2027 finished. We use that callback to set the
2028 empty view if there are no messages */
2029 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2030 TNY_FOLDER (folder_store),
2031 folder_refreshed_cb,
2034 /* Restore configuration. We need to do this
2035 *after* the set_folder because the widget
2036 memory asks the header view about its
2038 modest_widget_memory_restore (modest_runtime_get_conf (),
2039 G_OBJECT(header_view),
2040 MODEST_CONF_HEADER_VIEW_KEY);
2042 /* Update the active account */
2043 //modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
2044 /* Save only if we're seeing headers */
2045 if (modest_main_window_get_contents_style (main_window) ==
2046 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2047 modest_widget_memory_save (conf, G_OBJECT (header_view),
2048 MODEST_CONF_HEADER_VIEW_KEY);
2049 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2053 /* Update toolbar dimming state */
2054 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2058 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2065 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2067 online = tny_device_is_online (modest_runtime_get_device());
2070 /* already online -- the item is simply not there... */
2071 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2073 GTK_MESSAGE_WARNING,
2075 _("The %s you selected cannot be found"),
2077 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2078 gtk_dialog_run (GTK_DIALOG(dialog));
2080 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2083 _("mcen_bd_dialog_cancel"),
2084 GTK_RESPONSE_REJECT,
2085 _("mcen_bd_dialog_ok"),
2086 GTK_RESPONSE_ACCEPT,
2088 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2089 "Do you want to get online?"), item);
2090 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2091 gtk_label_new (txt), FALSE, FALSE, 0);
2092 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2095 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2096 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2097 /* TODO: Comment about why is this commented out: */
2098 /* modest_platform_connect_and_wait (); */
2101 gtk_widget_destroy (dialog);
2105 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2108 /* g_message ("%s %s", __FUNCTION__, link); */
2113 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2116 modest_platform_activate_uri (link);
2120 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2123 modest_platform_show_uri_popup (link);
2127 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2130 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2134 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2135 const gchar *address,
2138 /* g_message ("%s %s", __FUNCTION__, address); */
2142 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2143 TnyMsg *saved_draft,
2146 ModestMsgEditWindow *edit_window;
2148 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2150 /* If there was any error do nothing */
2151 if (modest_mail_operation_get_error (mail_op) != NULL)
2154 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2158 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2160 TnyTransportAccount *transport_account;
2161 ModestMailOperation *mail_operation;
2163 gchar *account_name, *from;
2164 ModestAccountMgr *account_mgr;
2165 gchar *info_text = NULL;
2167 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2169 data = modest_msg_edit_window_get_msg_data (edit_window);
2171 account_mgr = modest_runtime_get_account_mgr();
2172 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2174 account_name = modest_account_mgr_get_default_account (account_mgr);
2175 if (!account_name) {
2176 g_printerr ("modest: no account found\n");
2177 modest_msg_edit_window_free_msg_data (edit_window, data);
2181 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2182 account_name = g_strdup (data->account_name);
2186 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2187 (modest_runtime_get_account_store(),
2189 TNY_ACCOUNT_TYPE_TRANSPORT));
2190 if (!transport_account) {
2191 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2192 g_free (account_name);
2193 modest_msg_edit_window_free_msg_data (edit_window, data);
2196 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2198 /* Create the mail operation */
2199 mail_operation = modest_mail_operation_new (G_OBJECT(edit_window));
2200 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2202 modest_mail_operation_save_to_drafts (mail_operation,
2214 data->priority_flags,
2215 on_save_to_drafts_cb,
2219 g_free (account_name);
2220 g_object_unref (G_OBJECT (transport_account));
2221 g_object_unref (G_OBJECT (mail_operation));
2223 modest_msg_edit_window_free_msg_data (edit_window, data);
2225 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2226 modest_platform_information_banner (NULL, NULL, info_text);
2227 modest_msg_edit_window_reset_modified (edit_window);
2231 /* For instance, when clicking the Send toolbar button when editing a message: */
2233 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2235 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2237 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2240 /* FIXME: Code added just for testing. The final version will
2241 use the send queue provided by tinymail and some
2243 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2244 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2246 account_name = modest_account_mgr_get_default_account (account_mgr);
2248 if (!account_name) {
2249 /* Run account setup wizard */
2250 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window)))
2254 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2256 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2257 account_name = g_strdup (data->account_name);
2260 /* Get the currently-active transport account for this modest account: */
2261 TnyTransportAccount *transport_account =
2262 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2263 (modest_runtime_get_account_store(),
2265 if (!transport_account) {
2266 /* Run account setup wizard */
2267 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2271 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2273 /* Create the mail operation */
2274 ModestMailOperation *mail_operation = modest_mail_operation_new (G_OBJECT(edit_window));
2275 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2277 modest_mail_operation_send_new_mail (mail_operation,
2289 data->priority_flags);
2293 g_free (account_name);
2294 g_object_unref (G_OBJECT (transport_account));
2295 g_object_unref (G_OBJECT (mail_operation));
2297 modest_msg_edit_window_free_msg_data (edit_window, data);
2298 modest_msg_edit_window_set_sent (edit_window, TRUE);
2300 /* Save settings and close the window: */
2301 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2305 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2306 ModestMsgEditWindow *window)
2308 ModestMsgEditFormatState *format_state = NULL;
2310 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2311 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2313 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2316 format_state = modest_msg_edit_window_get_format_state (window);
2317 g_return_if_fail (format_state != NULL);
2319 format_state->bold = gtk_toggle_action_get_active (action);
2320 modest_msg_edit_window_set_format_state (window, format_state);
2321 g_free (format_state);
2326 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2327 ModestMsgEditWindow *window)
2329 ModestMsgEditFormatState *format_state = NULL;
2331 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2332 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2334 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2337 format_state = modest_msg_edit_window_get_format_state (window);
2338 g_return_if_fail (format_state != NULL);
2340 format_state->italics = gtk_toggle_action_get_active (action);
2341 modest_msg_edit_window_set_format_state (window, format_state);
2342 g_free (format_state);
2347 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2348 ModestMsgEditWindow *window)
2350 ModestMsgEditFormatState *format_state = NULL;
2352 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2353 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2355 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2358 format_state = modest_msg_edit_window_get_format_state (window);
2359 g_return_if_fail (format_state != NULL);
2361 format_state->bullet = gtk_toggle_action_get_active (action);
2362 modest_msg_edit_window_set_format_state (window, format_state);
2363 g_free (format_state);
2368 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2369 GtkRadioAction *selected,
2370 ModestMsgEditWindow *window)
2372 ModestMsgEditFormatState *format_state = NULL;
2373 GtkJustification value;
2375 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2377 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2380 value = gtk_radio_action_get_current_value (selected);
2382 format_state = modest_msg_edit_window_get_format_state (window);
2383 g_return_if_fail (format_state != NULL);
2385 format_state->justification = value;
2386 modest_msg_edit_window_set_format_state (window, format_state);
2387 g_free (format_state);
2391 modest_ui_actions_on_select_editor_color (GtkAction *action,
2392 ModestMsgEditWindow *window)
2394 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2395 g_return_if_fail (GTK_IS_ACTION (action));
2397 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2400 modest_msg_edit_window_select_color (window);
2404 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2405 ModestMsgEditWindow *window)
2407 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2408 g_return_if_fail (GTK_IS_ACTION (action));
2410 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2413 modest_msg_edit_window_select_background_color (window);
2417 modest_ui_actions_on_insert_image (GtkAction *action,
2418 ModestMsgEditWindow *window)
2420 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2421 g_return_if_fail (GTK_IS_ACTION (action));
2423 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2426 modest_msg_edit_window_insert_image (window);
2430 modest_ui_actions_on_attach_file (GtkAction *action,
2431 ModestMsgEditWindow *window)
2433 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2434 g_return_if_fail (GTK_IS_ACTION (action));
2436 modest_msg_edit_window_offer_attach_file (window);
2440 modest_ui_actions_on_remove_attachments (GtkAction *action,
2441 ModestMsgEditWindow *window)
2443 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2444 g_return_if_fail (GTK_IS_ACTION (action));
2446 modest_msg_edit_window_remove_attachments (window, NULL);
2450 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2453 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2454 const GError *error = modest_mail_operation_get_error (mail_op);
2457 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2458 _("mail_in_ui_folder_create_error"));
2463 modest_ui_actions_create_folder(GtkWidget *parent_window,
2464 GtkWidget *folder_view)
2466 TnyFolderStore *parent_folder;
2468 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2470 if (parent_folder) {
2471 gboolean finished = FALSE;
2473 gchar *folder_name = NULL, *suggested_name = NULL;
2474 const gchar *proto_str = NULL;
2475 TnyAccount *account;
2477 if (TNY_IS_ACCOUNT (parent_folder))
2478 account = g_object_ref (parent_folder);
2480 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2481 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2483 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2484 MODEST_PROTOCOL_STORE_POP) {
2486 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2488 g_object_unref (account);
2490 /* Run the new folder dialog */
2492 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2497 g_free (suggested_name);
2498 suggested_name = NULL;
2500 if (result == GTK_RESPONSE_REJECT) {
2503 ModestMailOperation *mail_op;
2504 TnyFolder *new_folder = NULL;
2506 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
2507 modest_ui_actions_new_folder_error_handler,
2510 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2512 new_folder = modest_mail_operation_create_folder (mail_op,
2514 (const gchar *) folder_name);
2516 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2519 g_object_unref (new_folder);
2522 g_object_unref (mail_op);
2525 suggested_name = folder_name;
2529 g_object_unref (parent_folder);
2534 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2536 GtkWidget *folder_view;
2538 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2540 folder_view = modest_main_window_get_child_widget (main_window,
2541 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2545 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2549 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2552 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2553 const GError *error = NULL;
2554 const gchar *message = NULL;
2556 /* Get error message */
2557 error = modest_mail_operation_get_error (mail_op);
2559 g_return_if_reached ();
2561 switch (error->code) {
2562 case MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS:
2563 message = _CS("ckdg_ib_folder_already_exists");
2566 g_return_if_reached ();
2569 modest_platform_information_banner (GTK_WIDGET (window), NULL, message);
2573 modest_ui_actions_on_rename_folder (GtkAction *action,
2574 ModestMainWindow *main_window)
2576 TnyFolderStore *folder;
2577 GtkWidget *folder_view;
2578 GtkWidget *header_view;
2580 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2582 folder_view = modest_main_window_get_child_widget (main_window,
2583 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2587 header_view = modest_main_window_get_child_widget (main_window,
2588 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2593 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2598 if (TNY_IS_FOLDER (folder)) {
2601 const gchar *current_name;
2602 TnyFolderStore *parent;
2603 gboolean do_rename = TRUE;
2605 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2606 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
2607 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
2608 parent, current_name,
2610 g_object_unref (parent);
2612 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
2614 } else if (modest_platform_is_network_folderstore(folder) &&
2615 !tny_device_is_online (modest_runtime_get_device())) {
2616 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2617 do_rename = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2618 g_object_unref(account);
2622 ModestMailOperation *mail_op;
2623 GtkTreeSelection *sel = NULL;
2626 modest_mail_operation_new_with_error_handling (G_OBJECT(main_window),
2627 modest_ui_actions_rename_folder_error_handler,
2630 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2633 /* Clear the headers view */
2634 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2635 gtk_tree_selection_unselect_all (sel);
2637 /* Select *after* the changes */
2638 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2639 TNY_FOLDER(folder), TRUE);
2641 /* Actually rename the folder */
2642 modest_mail_operation_rename_folder (mail_op,
2643 TNY_FOLDER (folder),
2644 (const gchar *) folder_name);
2646 g_object_unref (mail_op);
2647 g_free (folder_name);
2650 g_object_unref (folder);
2654 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2657 GObject *win = modest_mail_operation_get_source (mail_op);
2659 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2660 _("mail_in_ui_folder_delete_error"));
2661 g_object_unref (win);
2665 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2667 TnyFolderStore *folder;
2668 GtkWidget *folder_view;
2671 gboolean do_delete = TRUE;
2673 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (main_window), FALSE);
2675 folder_view = modest_main_window_get_child_widget (main_window,
2676 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2680 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2682 /* Show an error if it's an account */
2683 if (!TNY_IS_FOLDER (folder)) {
2684 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2685 _("mail_in_ui_folder_delete_error"));
2686 g_object_unref (G_OBJECT (folder));
2691 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2692 tny_folder_get_name (TNY_FOLDER (folder)));
2693 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2694 (const gchar *) message);
2697 if (response != GTK_RESPONSE_OK) {
2699 } else if (modest_platform_is_network_folderstore(folder) &&
2700 !tny_device_is_online (modest_runtime_get_device())) {
2701 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2702 do_delete = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2703 g_object_unref(account);
2707 ModestMailOperation *mail_op;
2708 GtkTreeSelection *sel;
2710 /* Unselect the folder before deleting it to free the headers */
2711 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2712 gtk_tree_selection_unselect_all (sel);
2714 /* Create the mail operation */
2716 modest_mail_operation_new_with_error_handling (G_OBJECT(main_window),
2717 modest_ui_actions_delete_folder_error_handler,
2720 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2722 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2723 g_object_unref (G_OBJECT (mail_op));
2726 g_object_unref (G_OBJECT (folder));
2732 modest_ui_actions_on_delete_folder (GtkAction *action,
2733 ModestMainWindow *main_window)
2735 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2737 if (delete_folder (main_window, FALSE)) {
2738 GtkWidget *folder_view;
2740 folder_view = modest_main_window_get_child_widget (main_window,
2741 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2742 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2747 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2749 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2751 delete_folder (main_window, TRUE);
2756 show_error (GtkWidget *parent_widget, const gchar* text)
2758 hildon_banner_show_information(parent_widget, NULL, text);
2761 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2763 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2770 gtk_dialog_run (dialog);
2771 gtk_widget_destroy (GTK_WIDGET (dialog));
2776 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2777 const gchar* server_account_name,
2782 ModestMainWindow *main_window)
2784 g_return_if_fail(server_account_name);
2785 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2787 /* Initalize output parameters: */
2794 #ifdef MODEST_PLATFORM_MAEMO
2795 /* Maemo uses a different (awkward) button order,
2796 * It should probably just use gtk_alternative_dialog_button_order ().
2798 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2801 _("mcen_bd_dialog_ok"),
2802 GTK_RESPONSE_ACCEPT,
2803 _("mcen_bd_dialog_cancel"),
2804 GTK_RESPONSE_REJECT,
2807 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2811 GTK_RESPONSE_REJECT,
2813 GTK_RESPONSE_ACCEPT,
2815 #endif /* MODEST_PLATFORM_MAEMO */
2817 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2819 gchar *server_name = modest_account_mgr_get_server_account_hostname (
2820 modest_runtime_get_account_mgr(), server_account_name);
2821 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2822 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2827 /* This causes a warning because the logical ID has no %s in it,
2828 * though the translation does, but there is not much we can do about that: */
2829 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2830 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2833 g_free (server_name);
2837 gchar *initial_username = modest_account_mgr_get_server_account_username (
2838 modest_runtime_get_account_mgr(), server_account_name);
2840 GtkWidget *entry_username = gtk_entry_new ();
2841 if (initial_username)
2842 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2843 /* Dim this if a connection has ever succeeded with this username,
2844 * as per the UI spec: */
2845 const gboolean username_known =
2846 modest_account_mgr_get_server_account_username_has_succeeded(
2847 modest_runtime_get_account_mgr(), server_account_name);
2848 gtk_widget_set_sensitive (entry_username, !username_known);
2850 #ifdef MODEST_PLATFORM_MAEMO
2851 /* Auto-capitalization is the default, so let's turn it off: */
2852 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2854 /* Create a size group to be used by all captions.
2855 * Note that HildonCaption does not create a default size group if we do not specify one.
2856 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2857 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2859 GtkWidget *caption = hildon_caption_new (sizegroup,
2860 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2861 gtk_widget_show (entry_username);
2862 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2863 FALSE, FALSE, MODEST_MARGIN_HALF);
2864 gtk_widget_show (caption);
2866 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2868 #endif /* MODEST_PLATFORM_MAEMO */
2871 GtkWidget *entry_password = gtk_entry_new ();
2872 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2873 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2875 #ifdef MODEST_PLATFORM_MAEMO
2876 /* Auto-capitalization is the default, so let's turn it off: */
2877 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2878 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2880 caption = hildon_caption_new (sizegroup,
2881 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2882 gtk_widget_show (entry_password);
2883 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2884 FALSE, FALSE, MODEST_MARGIN_HALF);
2885 gtk_widget_show (caption);
2886 g_object_unref (sizegroup);
2888 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2890 #endif /* MODEST_PLATFORM_MAEMO */
2892 if (initial_username != NULL)
2893 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
2895 /* This is not in the Maemo UI spec:
2896 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2897 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2901 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2903 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2905 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2907 modest_account_mgr_set_server_account_username (
2908 modest_runtime_get_account_mgr(), server_account_name,
2911 const gboolean username_was_changed =
2912 (strcmp (*username, initial_username) != 0);
2913 if (username_was_changed) {
2914 g_warning ("%s: tinymail does not yet support changing the "
2915 "username in the get_password() callback.\n", __FUNCTION__);
2920 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2922 /* We do not save the password in the configuration,
2923 * because this function is only called for passwords that should
2924 * not be remembered:
2925 modest_server_account_set_password (
2926 modest_runtime_get_account_mgr(), server_account_name,
2935 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2947 /* This is not in the Maemo UI spec:
2948 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2954 gtk_widget_destroy (dialog);
2956 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2960 modest_ui_actions_on_cut (GtkAction *action,
2961 ModestWindow *window)
2963 GtkWidget *focused_widget;
2964 GtkClipboard *clipboard;
2966 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2967 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2968 if (GTK_IS_EDITABLE (focused_widget)) {
2969 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2970 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2971 gtk_clipboard_store (clipboard);
2972 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2973 GtkTextBuffer *buffer;
2975 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2976 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2977 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2978 gtk_clipboard_store (clipboard);
2979 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2980 TnyList *header_list = modest_header_view_get_selected_headers (
2981 MODEST_HEADER_VIEW (focused_widget));
2982 gboolean continue_download = FALSE;
2983 gint num_of_unc_msgs;
2985 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
2987 if (num_of_unc_msgs) {
2988 TnyAccount *account = get_account_from_header_list (header_list);
2989 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
2990 g_object_unref (account);
2993 if (num_of_unc_msgs == 0 || continue_download) {
2994 /* modest_platform_information_banner (
2995 NULL, NULL, _CS("mcen_ib_getting_items"));*/
2996 modest_header_view_cut_selection (
2997 MODEST_HEADER_VIEW (focused_widget));
3000 g_object_unref (header_list);
3001 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3002 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3007 modest_ui_actions_on_copy (GtkAction *action,
3008 ModestWindow *window)
3010 GtkClipboard *clipboard;
3011 GtkWidget *focused_widget;
3012 gboolean copied = TRUE;
3014 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3015 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3017 if (GTK_IS_LABEL (focused_widget)) {
3018 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
3019 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3020 gtk_clipboard_store (clipboard);
3021 } else if (GTK_IS_EDITABLE (focused_widget)) {
3022 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3023 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3024 gtk_clipboard_store (clipboard);
3025 } else if (GTK_IS_HTML (focused_widget)) {
3026 gtk_html_copy (GTK_HTML (focused_widget));
3027 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3028 gtk_clipboard_store (clipboard);
3029 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3030 GtkTextBuffer *buffer;
3031 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3032 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3033 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3034 gtk_clipboard_store (clipboard);
3035 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3036 TnyList *header_list = modest_header_view_get_selected_headers (
3037 MODEST_HEADER_VIEW (focused_widget));
3038 gboolean continue_download = FALSE;
3039 gint num_of_unc_msgs;
3041 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3043 if (num_of_unc_msgs) {
3044 TnyAccount *account = get_account_from_header_list (header_list);
3045 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3046 g_object_unref (account);
3049 if (num_of_unc_msgs == 0 || continue_download) {
3050 modest_platform_information_banner (
3051 NULL, NULL, _CS("mcen_ib_getting_items"));
3052 modest_header_view_copy_selection (
3053 MODEST_HEADER_VIEW (focused_widget));
3057 g_object_unref (header_list);
3059 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3060 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3063 /* Show information banner if there was a copy to clipboard */
3065 modest_platform_information_banner (
3066 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3070 modest_ui_actions_on_undo (GtkAction *action,
3071 ModestWindow *window)
3073 ModestEmailClipboard *clipboard = NULL;
3075 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3076 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3077 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3078 /* Clear clipboard source */
3079 clipboard = modest_runtime_get_email_clipboard ();
3080 modest_email_clipboard_clear (clipboard);
3083 g_return_if_reached ();
3088 modest_ui_actions_on_redo (GtkAction *action,
3089 ModestWindow *window)
3091 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3092 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3095 g_return_if_reached ();
3101 destroy_information_note (ModestMailOperation *mail_op, gpointer user_data)
3103 /* destroy information note */
3104 gtk_widget_destroy (GTK_WIDGET(user_data));
3109 paste_as_attachment_free (gpointer data)
3111 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3113 gtk_widget_destroy (helper->banner);
3114 g_object_unref (helper->banner);
3119 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3124 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3125 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3130 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3135 modest_ui_actions_on_paste (GtkAction *action,
3136 ModestWindow *window)
3138 GtkWidget *focused_widget = NULL;
3139 GtkWidget *inf_note = NULL;
3140 ModestMailOperation *mail_op = NULL;
3142 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3143 if (GTK_IS_EDITABLE (focused_widget)) {
3144 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3145 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3146 ModestEmailClipboard *e_clipboard = NULL;
3147 e_clipboard = modest_runtime_get_email_clipboard ();
3148 if (modest_email_clipboard_cleared (e_clipboard)) {
3149 GtkTextBuffer *buffer;
3150 GtkClipboard *clipboard;
3152 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3153 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3154 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3155 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3156 ModestMailOperation *mail_op;
3157 TnyFolder *src_folder;
3160 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3161 helper->window = MODEST_MSG_EDIT_WINDOW (window);
3162 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3163 _CS("ckct_nw_pasting"));
3164 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
3165 mail_op = modest_mail_operation_new (G_OBJECT (window));
3166 if (helper->banner != NULL) {
3167 g_object_ref (G_OBJECT (helper->banner));
3168 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
3169 gtk_widget_show (GTK_WIDGET (helper->banner));
3173 modest_mail_operation_get_msgs_full (mail_op,
3175 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
3177 paste_as_attachment_free);
3180 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3181 ModestEmailClipboard *clipboard = NULL;
3182 TnyFolder *src_folder = NULL;
3183 TnyFolderStore *folder_store = NULL;
3184 TnyList *data = NULL;
3185 gboolean delete = FALSE;
3187 /* Check clipboard source */
3188 clipboard = modest_runtime_get_email_clipboard ();
3189 if (modest_email_clipboard_cleared (clipboard))
3192 /* Get elements to paste */
3193 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
3195 /* Create a new mail operation */
3196 mail_op = modest_mail_operation_new (G_OBJECT(window));
3198 /* Get destination folder */
3199 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
3201 /* transfer messages */
3205 /* Ask for user confirmation */
3207 modest_ui_actions_msgs_move_to_confirmation (window,
3208 TNY_FOLDER (folder_store),
3212 if (response == GTK_RESPONSE_OK) {
3213 /* Launch notification */
3214 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3215 _CS("ckct_nw_pasting"));
3216 if (inf_note != NULL) {
3217 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3218 gtk_widget_show (GTK_WIDGET(inf_note));
3221 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3222 modest_mail_operation_xfer_msgs (mail_op,
3224 TNY_FOLDER (folder_store),
3226 destroy_information_note,
3229 g_object_unref (mail_op);
3232 } else if (src_folder != NULL) {
3233 /* Launch notification */
3234 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3235 _CS("ckct_nw_pasting"));
3236 if (inf_note != NULL) {
3237 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3238 gtk_widget_show (GTK_WIDGET(inf_note));
3241 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3242 modest_mail_operation_xfer_folder (mail_op,
3246 destroy_information_note,
3252 g_object_unref (data);
3253 if (src_folder != NULL)
3254 g_object_unref (src_folder);
3255 if (folder_store != NULL)
3256 g_object_unref (folder_store);
3262 modest_ui_actions_on_select_all (GtkAction *action,
3263 ModestWindow *window)
3265 GtkWidget *focused_widget;
3267 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3268 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3269 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3270 } else if (GTK_IS_LABEL (focused_widget)) {
3271 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3272 } else if (GTK_IS_EDITABLE (focused_widget)) {
3273 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3274 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3275 GtkTextBuffer *buffer;
3276 GtkTextIter start, end;
3278 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3279 gtk_text_buffer_get_start_iter (buffer, &start);
3280 gtk_text_buffer_get_end_iter (buffer, &end);
3281 gtk_text_buffer_select_range (buffer, &start, &end);
3282 } else if (GTK_IS_HTML (focused_widget)) {
3283 gtk_html_select_all (GTK_HTML (focused_widget));
3284 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3285 GtkWidget *header_view = focused_widget;
3286 GtkTreeSelection *selection = NULL;
3288 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
3289 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3290 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3293 /* Disable window dimming management */
3294 modest_window_disable_dimming (MODEST_WINDOW(window));
3296 /* Select all messages */
3297 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3298 gtk_tree_selection_select_all (selection);
3300 /* Set focuse on header view */
3301 gtk_widget_grab_focus (header_view);
3304 /* Enable window dimming management */
3305 modest_window_enable_dimming (MODEST_WINDOW(window));
3306 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3312 modest_ui_actions_on_mark_as_read (GtkAction *action,
3313 ModestWindow *window)
3315 g_return_if_fail (MODEST_IS_WINDOW(window));
3317 /* Mark each header as read */
3318 do_headers_action (window, headers_action_mark_as_read, NULL);
3322 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3323 ModestWindow *window)
3325 g_return_if_fail (MODEST_IS_WINDOW(window));
3327 /* Mark each header as read */
3328 do_headers_action (window, headers_action_mark_as_unread, NULL);
3332 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3333 GtkRadioAction *selected,
3334 ModestWindow *window)
3338 value = gtk_radio_action_get_current_value (selected);
3339 if (MODEST_IS_WINDOW (window)) {
3340 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3345 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3346 GtkRadioAction *selected,
3347 ModestWindow *window)
3349 TnyHeaderFlags flags;
3350 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3352 flags = gtk_radio_action_get_current_value (selected);
3353 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3357 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3358 GtkRadioAction *selected,
3359 ModestWindow *window)
3363 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3365 file_format = gtk_radio_action_get_current_value (selected);
3366 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3371 modest_ui_actions_on_zoom_plus (GtkAction *action,
3372 ModestWindow *window)
3374 g_return_if_fail (MODEST_IS_WINDOW (window));
3376 modest_window_zoom_plus (MODEST_WINDOW (window));
3380 modest_ui_actions_on_zoom_minus (GtkAction *action,
3381 ModestWindow *window)
3383 g_return_if_fail (MODEST_IS_WINDOW (window));
3385 modest_window_zoom_minus (MODEST_WINDOW (window));
3389 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3390 ModestWindow *window)
3392 ModestWindowMgr *mgr;
3393 gboolean fullscreen, active;
3394 g_return_if_fail (MODEST_IS_WINDOW (window));
3396 mgr = modest_runtime_get_window_mgr ();
3398 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3399 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3401 if (active != fullscreen) {
3402 modest_window_mgr_set_fullscreen_mode (mgr, active);
3403 gtk_window_present (GTK_WINDOW (window));
3408 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3409 ModestWindow *window)
3411 ModestWindowMgr *mgr;
3412 gboolean fullscreen;
3414 g_return_if_fail (MODEST_IS_WINDOW (window));
3416 mgr = modest_runtime_get_window_mgr ();
3417 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3418 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3420 gtk_window_present (GTK_WINDOW (window));
3424 * Used by modest_ui_actions_on_details to call do_headers_action
3427 headers_action_show_details (TnyHeader *header,
3428 ModestWindow *window,
3435 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3438 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3439 gtk_widget_show_all (dialog);
3440 gtk_dialog_run (GTK_DIALOG (dialog));
3442 gtk_widget_destroy (dialog);
3446 * Show the folder details in a ModestDetailsDialog widget
3449 show_folder_details (TnyFolder *folder,
3455 dialog = modest_details_dialog_new_with_folder (window, folder);
3458 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3459 gtk_widget_show_all (dialog);
3460 gtk_dialog_run (GTK_DIALOG (dialog));
3462 gtk_widget_destroy (dialog);
3466 * Show the header details in a ModestDetailsDialog widget
3469 modest_ui_actions_on_details (GtkAction *action,
3472 TnyList * headers_list;
3476 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3479 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3482 g_object_unref (msg);
3484 headers_list = get_selected_headers (win);
3488 iter = tny_list_create_iterator (headers_list);
3490 header = TNY_HEADER (tny_iterator_get_current (iter));
3492 headers_action_show_details (header, win, NULL);
3493 g_object_unref (header);
3496 g_object_unref (iter);
3497 g_object_unref (headers_list);
3499 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3500 GtkWidget *folder_view, *header_view;
3502 /* Check which widget has the focus */
3503 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3504 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3505 if (gtk_widget_is_focus (folder_view)) {
3506 TnyFolderStore *folder_store
3507 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3508 if (!folder_store) {
3509 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3512 /* Show only when it's a folder */
3513 /* This function should not be called for account items,
3514 * because we dim the menu item for them. */
3515 if (TNY_IS_FOLDER (folder_store)) {
3516 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3519 g_object_unref (folder_store);
3522 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3523 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3524 /* Show details of each header */
3525 do_headers_action (win, headers_action_show_details, header_view);
3531 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3532 ModestMsgEditWindow *window)
3534 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3536 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3540 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3541 ModestMsgEditWindow *window)
3543 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3545 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3549 modest_ui_actions_toggle_folders_view (GtkAction *action,
3550 ModestMainWindow *main_window)
3552 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3554 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3555 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3557 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3561 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3562 ModestWindow *window)
3564 gboolean active, fullscreen = FALSE;
3565 ModestWindowMgr *mgr;
3567 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3569 /* Check if we want to toggle the toolbar vuew in fullscreen
3571 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3572 "ViewShowToolbarFullScreen")) {
3576 /* Toggle toolbar */
3577 mgr = modest_runtime_get_window_mgr ();
3578 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
3582 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3583 ModestMsgEditWindow *window)
3585 modest_msg_edit_window_select_font (window);
3589 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3590 const gchar *display_name,
3593 /* Do not change the application name if the widget has not
3594 the focus. This callback could be called even if the folder
3595 view has not the focus, because the handled signal could be
3596 emitted when the folder view is redrawn */
3597 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3599 gtk_window_set_title (window, display_name);
3601 gtk_window_set_title (window, " ");
3606 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3608 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3609 modest_msg_edit_window_select_contacts (window);
3613 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3615 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3616 modest_msg_edit_window_check_names (window, FALSE);
3620 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3622 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3623 GTK_WIDGET (user_data));
3627 * This function is used to track changes in the selection of the
3628 * folder view that is inside the "move to" dialog to enable/disable
3629 * the OK button because we do not want the user to select a disallowed
3630 * destination for a folder.
3631 * The user also not desired to be able to use NEW button on items where
3632 * folder creation is not possibel.
3635 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
3636 TnyFolderStore *folder_store,
3640 GtkWidget *dialog = NULL;
3641 GtkWidget *ok_button = NULL, *new_button = NULL;
3642 GList *children = NULL;
3643 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
3644 gboolean moving_folder = FALSE;
3645 gboolean is_local_account = TRUE;
3646 GtkWidget *folder_view = NULL;
3647 ModestTnyFolderRules rules;
3652 /* Get the OK button */
3653 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
3657 children = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
3658 ok_button = GTK_WIDGET (children->next->next->data);
3659 new_button = GTK_WIDGET (children->next->data);
3660 g_list_free (children);
3662 /* check if folder_store is an remote account */
3663 if (TNY_IS_ACCOUNT (folder_store)) {
3664 TnyAccount *local_account = NULL;
3665 ModestTnyAccountStore *account_store = NULL;
3667 account_store = modest_runtime_get_account_store ();
3668 local_account = modest_tny_account_store_get_local_folders_account (account_store);
3670 if ((gpointer) local_account != (gpointer) folder_store) {
3671 is_local_account = FALSE;
3672 /* New button should be dimmed on remote
3674 new_sensitive = FALSE;
3676 g_object_unref (local_account);
3679 /* Check the target folder rules */
3680 if (TNY_IS_FOLDER (folder_store)) {
3681 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
3682 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
3683 ok_sensitive = FALSE;
3684 new_sensitive = FALSE;
3689 /* Check if we're moving a folder */
3690 if (MODEST_IS_MAIN_WINDOW (user_data)) {
3691 /* Get the widgets */
3692 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
3693 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3694 if (gtk_widget_is_focus (folder_view))
3695 moving_folder = TRUE;
3698 if (moving_folder) {
3699 TnyFolderStore *moved_folder = NULL, *parent = NULL;
3701 /* Get the folder to move */
3702 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3704 /* Check that we're not moving to the same folder */
3705 if (TNY_IS_FOLDER (moved_folder)) {
3706 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
3707 if (parent == folder_store)
3708 ok_sensitive = FALSE;
3709 g_object_unref (parent);
3712 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
3713 /* Do not allow to move to an account unless it's the
3714 local folders account */
3715 if (!is_local_account)
3716 ok_sensitive = FALSE;
3719 if (ok_sensitive && (moved_folder == folder_store)) {
3720 /* Do not allow to move to itself */
3721 ok_sensitive = FALSE;
3723 g_object_unref (moved_folder);
3725 TnyHeader *header = NULL;
3726 TnyFolder *src_folder = NULL;
3728 /* Moving a message */
3729 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
3730 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (user_data));
3731 src_folder = tny_header_get_folder (header);
3732 g_object_unref (header);
3735 TNY_FOLDER (modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view)));
3738 /* Do not allow to move the msg to the same folder */
3739 /* Do not allow to move the msg to an account */
3740 if ((gpointer) src_folder == (gpointer) folder_store ||
3741 TNY_IS_ACCOUNT (folder_store))
3742 ok_sensitive = FALSE;
3743 g_object_unref (src_folder);
3747 /* Set sensitivity of the OK button */
3748 gtk_widget_set_sensitive (ok_button, ok_sensitive);
3749 /* Set sensitivity of the NEW button */
3750 gtk_widget_set_sensitive (new_button, new_sensitive);
3754 create_move_to_dialog (GtkWindow *win,
3755 GtkWidget *folder_view,
3756 GtkWidget **tree_view)
3758 GtkWidget *dialog, *scroll;
3759 GtkWidget *new_button;
3761 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3763 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3766 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
3767 /* We do this manually so GTK+ does not associate a response ID for
3769 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
3770 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3771 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
3773 /* Create scrolled window */
3774 scroll = gtk_scrolled_window_new (NULL, NULL);
3775 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3776 GTK_POLICY_AUTOMATIC,
3777 GTK_POLICY_AUTOMATIC);
3779 /* Create folder view */
3780 *tree_view = modest_platform_create_folder_view (NULL);
3782 /* Track changes in the selection to
3783 * disable the OK button whenever "Move to" is not possible
3784 * disbale NEW button whenever New is not possible */
3785 g_signal_connect (*tree_view,
3786 "folder_selection_changed",
3787 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
3790 /* Listen to clicks on New button */
3791 g_signal_connect (G_OBJECT (new_button),
3793 G_CALLBACK(create_move_to_dialog_on_new_folder),
3796 /* It could happen that we're trying to move a message from a
3797 window (msg window for example) after the main window was
3798 closed, so we can not just get the model of the folder
3800 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
3801 const gchar *visible_id = NULL;
3803 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
3804 MODEST_FOLDER_VIEW(*tree_view));
3807 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
3809 /* Show the same account than the one that is shown in the main window */
3810 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
3813 const gchar *active_account_name = NULL;
3814 ModestAccountMgr *mgr = NULL;
3815 ModestAccountData *acc_data = NULL;
3817 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3818 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3820 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
3821 mgr = modest_runtime_get_account_mgr ();
3822 acc_data = modest_account_mgr_get_account_data (mgr, active_account_name);
3824 /* Set the new visible & active account */
3825 if (acc_data && acc_data->store_account) {
3826 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
3827 acc_data->store_account->account_name);
3828 modest_account_mgr_free_account_data (mgr, acc_data);
3832 /* Hide special folders */
3833 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3835 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3837 /* Add scroll to dialog */
3838 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3839 scroll, TRUE, TRUE, 0);
3841 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3842 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3848 * Returns TRUE if at least one of the headers of the list belongs to
3849 * a message that has been fully retrieved.
3851 #if 0 /* no longer in use. delete in 2007.10 */
3853 has_retrieved_msgs (TnyList *list)
3856 gboolean found = FALSE;
3858 iter = tny_list_create_iterator (list);
3859 while (!tny_iterator_is_done (iter) && !found) {
3861 TnyHeaderFlags flags = 0;
3863 header = TNY_HEADER (tny_iterator_get_current (iter));
3865 flags = tny_header_get_flags (header);
3866 if (flags & TNY_HEADER_FLAG_CACHED)
3867 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3870 g_object_unref (header);
3874 tny_iterator_next (iter);
3876 g_object_unref (iter);
3884 * Shows a confirmation dialog to the user when we're moving messages
3885 * from a remote server to the local storage. Returns the dialog
3886 * response. If it's other kind of movement then it always returns
3889 * This one is used by the next functions:
3890 * modest_ui_actions_on_paste - commented out
3891 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
3894 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
3895 TnyFolder *dest_folder,
3899 gint response = GTK_RESPONSE_OK;
3900 TnyAccount *account = NULL;
3901 TnyFolder *src_folder = NULL;
3902 TnyIterator *iter = NULL;
3903 TnyHeader *header = NULL;
3905 /* return with OK if the destination is a remote folder */
3906 if (modest_tny_folder_is_remote_folder (dest_folder))
3907 return GTK_RESPONSE_OK;
3909 /* Get source folder */
3910 iter = tny_list_create_iterator (headers);
3911 header = TNY_HEADER (tny_iterator_get_current (iter));
3913 src_folder = tny_header_get_folder (header);
3914 g_object_unref (header);
3916 g_object_unref (iter);
3918 /* if no src_folder, message may be an attahcment */
3919 if (src_folder == NULL)
3920 return GTK_RESPONSE_CANCEL;
3922 /* If the source is a local or MMC folder */
3923 if (!modest_tny_folder_is_remote_folder (src_folder)) {
3924 g_object_unref (src_folder);
3925 return GTK_RESPONSE_OK;
3928 /* Get the account */
3929 account = tny_folder_get_account (src_folder);
3931 /* now if offline we ask the user */
3932 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
3933 response = GTK_RESPONSE_OK;
3935 response = GTK_RESPONSE_CANCEL;
3938 g_object_unref (src_folder);
3939 g_object_unref (account);
3947 move_to_cb (ModestMailOperation *mail_op, gpointer user_data)
3949 MoveToHelper *helper = (MoveToHelper *) user_data;
3951 /* Note that the operation could have failed, in that case do
3953 if (modest_mail_operation_get_status (mail_op) ==
3954 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
3956 GObject *object = modest_mail_operation_get_source (mail_op);
3957 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
3958 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
3960 if (!modest_msg_view_window_select_next_message (self))
3961 if (!modest_msg_view_window_select_previous_message (self))
3962 /* No more messages to view, so close this window */
3963 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3964 } else if (MODEST_IS_MAIN_WINDOW (object) && helper->reference != NULL) {
3965 GtkWidget *header_view;
3967 GtkTreeSelection *sel;
3969 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
3970 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3971 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
3972 path = gtk_tree_row_reference_get_path (helper->reference);
3973 gtk_tree_selection_select_path (sel, path);
3974 gtk_tree_path_free (path);
3976 g_object_unref (object);
3979 /* Close the "Pasting" information banner */
3980 gtk_widget_destroy (GTK_WIDGET(helper->banner));
3981 if (helper->reference != NULL)
3982 gtk_tree_row_reference_free (helper->reference);
3987 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3990 ModestWindow *main_window = NULL;
3991 GtkWidget *folder_view = NULL;
3992 GObject *win = modest_mail_operation_get_source (mail_op);
3993 const GError *error = NULL;
3994 const gchar *message = NULL;
3996 /* Get error message */
3997 error = modest_mail_operation_get_error (mail_op);
3998 if (error != NULL && error->message != NULL) {
3999 message = error->message;
4001 message = _("mail_in_ui_folder_move_target_error");
4004 /* Disable next automatic folder selection */
4005 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ());
4006 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
4007 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4008 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
4010 if (user_data && TNY_IS_FOLDER (user_data)) {
4011 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
4012 TNY_FOLDER (user_data), FALSE);
4015 /* Show notification dialog */
4016 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
4017 g_object_unref (win);
4021 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
4024 GObject *win = modest_mail_operation_get_source (mail_op);
4025 const GError *error = modest_mail_operation_get_error (mail_op);
4027 g_return_if_fail (error != NULL);
4028 if (error->message != NULL)
4029 g_printerr ("modest: %s\n", error->message);
4031 g_printerr ("modest: unkonw error on send&receive operation");
4033 /* Show error message */
4034 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
4035 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
4036 /* _CS("sfil_ib_unable_to_receive")); */
4038 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
4039 /* _CS("sfil_ib_unable_to_send")); */
4040 g_object_unref (win);
4044 open_msg_for_purge_cb (ModestMailOperation *mail_op,
4051 gint pending_purges = 0;
4052 gboolean some_purged = FALSE;
4053 ModestWindow *win = MODEST_WINDOW (user_data);
4054 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
4056 /* If there was any error */
4057 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
4058 modest_window_mgr_unregister_header (mgr, header);
4062 /* Once the message has been retrieved for purging, we check if
4063 * it's all ok for purging */
4065 parts = tny_simple_list_new ();
4066 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
4067 iter = tny_list_create_iterator (parts);
4069 while (!tny_iterator_is_done (iter)) {
4071 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4072 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
4073 if (tny_mime_part_is_purged (part))
4080 g_object_unref (part);
4082 tny_iterator_next (iter);
4084 g_object_unref (iter);
4087 if (pending_purges>0) {
4089 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
4091 if (response == GTK_RESPONSE_OK) {
4092 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
4093 iter = tny_list_create_iterator (parts);
4094 while (!tny_iterator_is_done (iter)) {
4097 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4098 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
4099 tny_mime_part_set_purged (part);
4102 g_object_unref (part);
4104 tny_iterator_next (iter);
4107 tny_msg_rewrite_cache (msg);
4110 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
4112 g_object_unref (iter);
4114 modest_window_mgr_unregister_header (mgr, header);
4116 g_object_unref (parts);
4120 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
4121 ModestMainWindow *win)
4123 GtkWidget *header_view;
4124 TnyList *header_list;
4127 TnyHeaderFlags flags;
4128 ModestWindow *msg_view_window = NULL;
4131 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4133 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4134 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4136 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
4138 if (tny_list_get_length (header_list) == 1) {
4139 iter = tny_list_create_iterator (header_list);
4140 header = TNY_HEADER (tny_iterator_get_current (iter));
4141 g_object_unref (iter);
4146 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
4147 header, &msg_view_window);
4148 flags = tny_header_get_flags (header);
4149 if (!(flags & TNY_HEADER_FLAG_CACHED))
4152 if (msg_view_window != NULL)
4153 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
4155 /* do nothing; uid was registered before, so window is probably on it's way */
4156 g_warning ("debug: header %p has already been registered", header);
4159 ModestMailOperation *mail_op = NULL;
4160 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
4161 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
4162 modest_ui_actions_get_msgs_full_error_handler,
4164 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4165 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
4167 g_object_unref (mail_op);
4170 g_object_unref (header);
4172 g_object_unref (header_list);
4176 * Utility function that transfer messages from both the main window
4177 * and the msg view window when using the "Move to" dialog
4180 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
4183 TnyList *headers = NULL;
4184 TnyAccount *dst_account = NULL;
4185 const gchar *proto_str = NULL;
4186 gboolean dst_is_pop = FALSE;
4188 if (!TNY_IS_FOLDER (dst_folder)) {
4189 modest_platform_information_banner (GTK_WIDGET (win),
4191 _CS("ckdg_ib_unable_to_move_to_current_location"));
4195 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
4196 proto_str = tny_account_get_proto (dst_account);
4198 /* tinymail will return NULL for local folders it seems */
4199 dst_is_pop = proto_str &&
4200 (modest_protocol_info_get_transport_store_protocol (proto_str) ==
4201 MODEST_PROTOCOL_STORE_POP);
4203 g_object_unref (dst_account);
4205 /* Get selected headers */
4206 headers = get_selected_headers (MODEST_WINDOW (win));
4209 modest_platform_information_banner (GTK_WIDGET (win),
4211 ngettext("mail_in_ui_folder_move_target_error",
4212 "mail_in_ui_folder_move_targets_error",
4213 tny_list_get_length (headers)));
4214 g_object_unref (headers);
4218 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4219 helper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4220 _CS("ckct_nw_pasting"));
4221 if (helper->banner != NULL) {
4222 gtk_window_set_modal (GTK_WINDOW(helper->banner), FALSE);
4223 gtk_widget_show (GTK_WIDGET(helper->banner));
4226 if (MODEST_IS_MAIN_WINDOW (win)) {
4227 GtkWidget *header_view =
4228 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
4229 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4230 helper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
4233 ModestMailOperation *mail_op =
4234 modest_mail_operation_new_with_error_handling (G_OBJECT(win),
4235 modest_ui_actions_move_folder_error_handler,
4237 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4240 modest_mail_operation_xfer_msgs (mail_op,
4242 TNY_FOLDER (dst_folder),
4247 g_object_unref (G_OBJECT (mail_op));
4248 g_object_unref (headers);
4252 * UI handler for the "Move to" action when invoked from the
4256 modest_ui_actions_on_main_window_move_to (GtkAction *action,
4257 GtkWidget *folder_view,
4258 TnyFolderStore *dst_folder,
4259 ModestMainWindow *win)
4261 ModestHeaderView *header_view = NULL;
4262 ModestMailOperation *mail_op = NULL;
4263 TnyFolderStore *src_folder;
4264 gboolean online = (tny_device_is_online (modest_runtime_get_device()));
4266 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4268 /* Get the source folder */
4269 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4271 /* Get header view */
4272 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
4274 /* Get folder or messages to transfer */
4275 if (gtk_widget_is_focus (folder_view)) {
4276 GtkTreeSelection *sel;
4277 gboolean do_xfer = TRUE;
4279 /* Allow only to transfer folders to the local root folder */
4280 if (TNY_IS_ACCOUNT (dst_folder) &&
4281 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder)) {
4283 } else if (!TNY_IS_FOLDER (src_folder)) {
4284 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
4286 } else if (!online && modest_platform_is_network_folderstore(src_folder)) {
4287 guint num_headers = tny_folder_get_all_count(TNY_FOLDER (src_folder));
4288 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (src_folder));
4289 if (!connect_to_get_msg(MODEST_WINDOW (win), num_headers, account))
4291 g_object_unref (account);
4295 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4296 helper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4297 _CS("ckct_nw_pasting"));
4298 if (helper->banner != NULL) {
4299 gtk_window_set_modal (GTK_WINDOW(helper->banner), FALSE);
4300 gtk_widget_show (GTK_WIDGET(helper->banner));
4302 /* Clean folder on header view before moving it */
4303 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
4304 gtk_tree_selection_unselect_all (sel);
4307 modest_mail_operation_new_with_error_handling (G_OBJECT(win),
4308 modest_ui_actions_move_folder_error_handler,
4310 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4313 /* Select *after* the changes */
4314 /* TODO: this function hangs UI after transfer */
4315 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
4316 /* TNY_FOLDER (src_folder), TRUE); */
4318 modest_mail_operation_xfer_folder (mail_op,
4319 TNY_FOLDER (src_folder),
4324 /* Unref mail operation */
4325 g_object_unref (G_OBJECT (mail_op));
4327 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
4328 gboolean do_xfer = TRUE;
4329 /* Ask for confirmation if the source folder is remote and we're not connected */
4330 if (!online && modest_platform_is_network_folderstore(src_folder)) {
4331 TnyList *headers = modest_header_view_get_selected_headers(header_view);
4332 if (!msgs_already_deleted_from_server(headers, src_folder)) {
4333 guint num_headers = tny_list_get_length(headers);
4334 TnyAccount *account = get_account_from_header_list (headers);
4335 if (!connect_to_get_msg(MODEST_WINDOW (win), num_headers, account))
4337 g_object_unref (account);
4339 g_object_unref(headers);
4341 if (do_xfer) /* Transfer messages */
4342 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4346 g_object_unref (src_folder);
4351 * UI handler for the "Move to" action when invoked from the
4352 * ModestMsgViewWindow
4355 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
4356 TnyFolderStore *dst_folder,
4357 ModestMsgViewWindow *win)
4359 TnyHeader *header = NULL;
4360 TnyFolder *src_folder = NULL;
4361 TnyAccount *account = NULL;
4363 /* Create header list */
4364 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
4365 src_folder = TNY_FOLDER (tny_header_get_folder(header));
4366 g_object_unref (header);
4368 /* Transfer the message if online or confirmed by the user */
4369 account = tny_folder_get_account (src_folder);
4370 if (remote_folder_is_pop(TNY_FOLDER_STORE (src_folder)) ||
4371 (modest_platform_is_network_folderstore(TNY_FOLDER_STORE (src_folder)) &&
4372 connect_to_get_msg(MODEST_WINDOW (win), 1, account))) {
4373 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4375 g_object_unref (account);
4376 g_object_unref (src_folder);
4380 modest_ui_actions_on_move_to (GtkAction *action,
4383 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
4385 TnyFolderStore *dst_folder = NULL;
4386 ModestMainWindow *main_window;
4388 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
4389 MODEST_IS_MSG_VIEW_WINDOW (win));
4391 /* Get the main window if exists */
4392 if (MODEST_IS_MAIN_WINDOW (win))
4393 main_window = MODEST_MAIN_WINDOW (win);
4396 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
4398 /* Get the folder view widget if exists */
4400 folder_view = modest_main_window_get_child_widget (main_window,
4401 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4405 /* Create and run the dialog */
4406 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
4407 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
4408 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4409 result = gtk_dialog_run (GTK_DIALOG(dialog));
4410 g_object_ref (tree_view);
4411 gtk_widget_destroy (dialog);
4413 if (result != GTK_RESPONSE_ACCEPT)
4416 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
4417 /* Do window specific stuff */
4418 if (MODEST_IS_MAIN_WINDOW (win)) {
4419 modest_ui_actions_on_main_window_move_to (action,
4422 MODEST_MAIN_WINDOW (win));
4424 modest_ui_actions_on_msg_view_window_move_to (action,
4426 MODEST_MSG_VIEW_WINDOW (win));
4430 g_object_unref (dst_folder);
4434 * Calls #HeadersFunc for each header already selected in the main
4435 * window or the message currently being shown in the msg view window
4438 do_headers_action (ModestWindow *win,
4442 TnyList *headers_list = NULL;
4443 TnyIterator *iter = NULL;
4444 TnyHeader *header = NULL;
4445 TnyFolder *folder = NULL;
4448 headers_list = get_selected_headers (win);
4452 /* Get the folder */
4453 iter = tny_list_create_iterator (headers_list);
4454 header = TNY_HEADER (tny_iterator_get_current (iter));
4456 folder = tny_header_get_folder (header);
4457 g_object_unref (header);
4460 /* Call the function for each header */
4461 while (!tny_iterator_is_done (iter)) {
4462 header = TNY_HEADER (tny_iterator_get_current (iter));
4463 func (header, win, user_data);
4464 g_object_unref (header);
4465 tny_iterator_next (iter);
4468 /* Trick: do a poke status in order to speed up the signaling
4470 tny_folder_poke_status (folder);
4473 g_object_unref (folder);
4474 g_object_unref (iter);
4475 g_object_unref (headers_list);
4479 modest_ui_actions_view_attachment (GtkAction *action,
4480 ModestWindow *window)
4482 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4483 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4485 /* not supported window for this action */
4486 g_return_if_reached ();
4491 modest_ui_actions_save_attachments (GtkAction *action,
4492 ModestWindow *window)
4494 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4495 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4497 /* not supported window for this action */
4498 g_return_if_reached ();
4503 modest_ui_actions_remove_attachments (GtkAction *action,
4504 ModestWindow *window)
4506 if (MODEST_IS_MAIN_WINDOW (window)) {
4507 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4508 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4509 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4511 /* not supported window for this action */
4512 g_return_if_reached ();
4517 modest_ui_actions_on_settings (GtkAction *action,
4522 dialog = modest_platform_get_global_settings_dialog ();
4523 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4524 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4525 gtk_widget_show_all (dialog);
4527 gtk_dialog_run (GTK_DIALOG (dialog));
4529 gtk_widget_destroy (dialog);
4533 modest_ui_actions_on_help (GtkAction *action,
4536 const gchar *help_id = NULL;
4538 if (MODEST_IS_MAIN_WINDOW (win)) {
4539 GtkWidget *folder_view;
4540 TnyFolderStore *folder_store;
4542 /* Get selected folder */
4543 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4544 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4545 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4547 /* Switch help_id */
4548 if (TNY_IS_FOLDER (folder_store)) {
4549 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4550 case TNY_FOLDER_TYPE_NORMAL:
4551 help_id = "applications_email_managefolders";
4553 case TNY_FOLDER_TYPE_INBOX:
4554 help_id = "applications_email_inbox";
4556 case TNY_FOLDER_TYPE_OUTBOX:
4557 help_id = "applications_email_outbox";
4559 case TNY_FOLDER_TYPE_SENT:
4560 help_id = "applications_email_sent";
4562 case TNY_FOLDER_TYPE_DRAFTS:
4563 help_id = "applications_email_drafts";
4565 case TNY_FOLDER_TYPE_ARCHIVE:
4566 help_id = "applications_email_managefolders";
4569 help_id = "applications_email_managefolders";
4572 help_id = "applications_email_mainview";
4574 g_object_unref (folder_store);
4575 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4576 help_id = "applications_email_viewer";
4577 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4578 help_id = "applications_email_editor";
4580 modest_platform_show_help (GTK_WINDOW (win), help_id);
4584 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4585 ModestWindow *window)
4587 ModestMailOperation *mail_op;
4591 headers = get_selected_headers (window);
4595 /* Create mail operation */
4596 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (window),
4597 modest_ui_actions_get_msgs_full_error_handler,
4599 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4600 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4603 g_object_unref (headers);
4604 g_object_unref (mail_op);
4608 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4609 ModestWindow *window)
4611 g_return_if_fail (MODEST_IS_WINDOW (window));
4614 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4618 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4619 ModestWindow *window)
4621 g_return_if_fail (MODEST_IS_WINDOW (window));
4624 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4628 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4629 ModestWindow *window)
4631 g_return_if_fail (MODEST_IS_WINDOW (window));
4634 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4638 modest_ui_actions_on_format_menu_activated (GtkAction *action,
4639 ModestWindow *window)
4641 g_return_if_fail (MODEST_IS_WINDOW (window));
4644 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4648 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4649 ModestWindow *window)
4651 g_return_if_fail (MODEST_IS_WINDOW (window));
4654 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4658 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4659 ModestWindow *window)
4661 g_return_if_fail (MODEST_IS_WINDOW (window));
4664 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4668 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4669 ModestWindow *window)
4671 g_return_if_fail (MODEST_IS_WINDOW (window));
4674 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4678 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4679 ModestWindow *window)
4681 g_return_if_fail (MODEST_IS_WINDOW (window));
4684 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4688 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4689 ModestWindow *window)
4691 g_return_if_fail (MODEST_IS_WINDOW (window));
4694 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4698 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4700 g_return_if_fail (MODEST_IS_WINDOW (window));
4703 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4707 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4709 g_return_if_fail (MODEST_IS_WINDOW (window));
4711 modest_platform_show_search_messages (GTK_WINDOW (window));
4715 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4717 g_return_if_fail (MODEST_IS_WINDOW (win));
4718 modest_platform_show_addressbook (GTK_WINDOW (win));
4723 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4724 ModestWindow *window)
4726 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4728 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4732 on_send_receive_finished (ModestMailOperation *mail_op,
4735 /* Set send/receive operation finished */
4736 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW (user_data));
4741 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
4747 const gchar* server_name = NULL;
4748 TnyTransportAccount *server_account;
4749 gchar *message = NULL;
4751 /* Don't show anything if the user cancelled something */
4752 if (err->code == TNY_TRANSPORT_ACCOUNT_ERROR_SEND_USER_CANCEL)
4755 /* Get the server name: */
4757 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
4758 if (server_account) {
4759 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
4761 g_object_unref (server_account);
4762 server_account = NULL;
4765 g_return_if_fail (server_name);
4767 /* Show the appropriate message text for the GError: */
4768 switch (err->code) {
4769 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_HOST_LOOKUP_FAILED:
4770 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4772 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_SERVICE_UNAVAILABLE:
4773 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4775 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_AUTHENTICATION_NOT_SUPPORTED:
4776 message = g_strdup_printf (_("emev_ni_ui_smtp_authentication_fail_error"), server_name);
4778 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND:
4779 message = g_strdup (_("emev_ib_ui_smtp_send_error"));
4782 g_return_if_reached ();
4785 /* TODO if the username or the password where not defined we
4786 should show the Accounts Settings dialog or the Connection
4787 specific SMTP server window */
4789 modest_platform_run_information_dialog (NULL, message);
4794 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
4799 ModestMainWindow *main_window = NULL;
4800 ModestWindowMgr *mgr = NULL;
4801 GtkWidget *folder_view = NULL, *header_view = NULL;
4802 TnyFolderStore *selected_folder = NULL;
4803 TnyFolderType folder_type;
4805 mgr = modest_runtime_get_window_mgr ();
4806 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr));
4811 /* Check if selected folder is OUTBOX */
4812 folder_view = modest_main_window_get_child_widget (main_window,
4813 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4814 header_view = modest_main_window_get_child_widget (main_window,
4815 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4817 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4818 if (!TNY_IS_FOLDER (selected_folder))
4821 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
4822 #if GTK_CHECK_VERSION(2, 8, 0)
4823 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
4824 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
4825 GtkTreeViewColumn *tree_column;
4827 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
4828 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
4829 gtk_tree_view_column_queue_resize (tree_column);
4832 gtk_widget_queue_draw (header_view);
4837 if (selected_folder != NULL)
4838 g_object_unref (selected_folder);