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_progress_changed (ModestMailOperation *mail_op,
144 ModestMailOperationState *state,
147 static gint header_list_count_uncached_msgs (TnyList *header_list);
148 static gboolean connect_to_get_msg (
150 gint num_of_uncached_msgs);
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_run_account_setup_wizard (ModestWindow *win)
208 gboolean result = FALSE;
209 GtkDialog *wizard, *dialog;
211 /* Show the easy-setup wizard: */
212 dialog = modest_window_mgr_get_modal_dialog (modest_runtime_get_window_mgr());
213 if (dialog && MODEST_IS_EASYSETUP_WIZARD_DIALOG(dialog)) {
214 /* old wizard is active already;
216 gtk_window_present (GTK_WINDOW(dialog));
221 /* there is no such wizard yet */
223 wizard = GTK_DIALOG(modest_easysetup_wizard_dialog_new ());
225 g_printerr ("modest: failed to create easysetup wizard\n");
229 modest_window_mgr_set_modal_dialog
230 (modest_runtime_get_window_mgr(), GTK_DIALOG(wizard));
233 /* there is no such wizard yet */
234 wizard = GTK_DIALOG(modest_easysetup_wizard_dialog_new ());
235 modest_window_mgr_set_modal_dialog (modest_runtime_get_window_mgr(),
238 /* make it non-modal; if though we register it as a modal dialog above
239 * apparently, making it modal *at all* gives hangs -- FIXME: check this*/
240 gtk_window_set_modal (GTK_WINDOW(dialog), FALSE);
242 /* always present a main window in the background
243 * we do it here, so we cannot end up with to wizards (as this
244 * function might be called in modest_window_mgr_get_main_window as well */
246 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr());
248 /* make sure the mainwindow is visible */
249 gtk_widget_show_all (GTK_WIDGET(win));
250 gtk_window_present (GTK_WINDOW(win));
253 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
255 /* Don't make this a modal window, because secondary windows will then
256 * be unusable, freezing the UI: */
257 /* gtk_window_set_modal (GTK_WINDOW (wizard), TRUE); */
259 gint dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
260 if (dialog_response == GTK_RESPONSE_CANCEL)
263 /* Check whether an account was created: */
264 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
267 gtk_widget_destroy (GTK_WIDGET (wizard));
269 /* clear it from the window mgr */
270 modest_window_mgr_set_modal_dialog
271 (modest_runtime_get_window_mgr(), NULL);
278 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
281 const gchar *authors[] = {
282 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
285 about = gtk_about_dialog_new ();
286 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
287 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
288 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
289 _("Copyright (c) 2006, Nokia Corporation\n"
290 "All rights reserved."));
291 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
292 _("a modest e-mail client\n\n"
293 "design and implementation: Dirk-Jan C. Binnema\n"
294 "contributions from the fine people at KC and Ig\n"
295 "uses the tinymail email framework written by Philip van Hoof"));
296 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
297 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
298 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
299 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
301 gtk_dialog_run (GTK_DIALOG (about));
302 gtk_widget_destroy(about);
306 * Gets the list of currently selected messages. If the win is the
307 * main window, then it returns a newly allocated list of the headers
308 * selected in the header view. If win is the msg view window, then
309 * the value returned is a list with just a single header.
311 * The caller of this funcion must free the list.
314 get_selected_headers (ModestWindow *win)
316 if (MODEST_IS_MAIN_WINDOW(win)) {
317 GtkWidget *header_view;
319 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
320 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
321 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
323 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
324 /* for MsgViewWindows, we simply return a list with one element */
326 TnyList *list = NULL;
328 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
329 if (header != NULL) {
330 list = tny_simple_list_new ();
331 tny_list_prepend (list, G_OBJECT(header));
332 g_object_unref (G_OBJECT(header));
341 static GtkTreeRowReference *
342 get_next_after_selected_headers (ModestHeaderView *header_view)
344 GtkTreeSelection *sel;
345 GList *selected_rows, *node;
347 GtkTreeRowReference *result;
350 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
351 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
352 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
354 if (selected_rows == NULL)
357 node = g_list_last (selected_rows);
358 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
359 gtk_tree_path_next (path);
361 result = gtk_tree_row_reference_new (model, path);
363 gtk_tree_path_free (path);
364 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
365 g_list_free (selected_rows);
371 headers_action_mark_as_read (TnyHeader *header,
375 TnyHeaderFlags flags;
377 g_return_if_fail (TNY_IS_HEADER(header));
379 flags = tny_header_get_flags (header);
380 if (flags & TNY_HEADER_FLAG_SEEN) return;
381 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
385 headers_action_mark_as_unread (TnyHeader *header,
389 TnyHeaderFlags flags;
391 g_return_if_fail (TNY_IS_HEADER(header));
393 flags = tny_header_get_flags (header);
394 if (flags & TNY_HEADER_FLAG_SEEN) {
395 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
399 /** A convenience method, because deleting a message is
400 * otherwise complicated, and it's best to change it in one place
403 void modest_do_message_delete (TnyHeader *header, ModestWindow *win)
405 ModestMailOperation *mail_op = NULL;
406 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE,
407 win ? G_OBJECT(win) : NULL);
408 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
411 /* Always delete. TODO: Move to trash still not supported */
412 modest_mail_operation_remove_msg (mail_op, header, FALSE);
413 g_object_unref (G_OBJECT (mail_op));
416 /** A convenience method, because deleting a message is
417 * otherwise complicated, and it's best to change it in one place
420 void modest_do_messages_delete (TnyList *headers, ModestWindow *win)
422 ModestMailOperation *mail_op = NULL;
423 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE,
424 win ? G_OBJECT(win) : NULL);
425 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
428 /* Always delete. TODO: Move to trash still not supported */
429 modest_mail_operation_remove_msgs (mail_op, headers, FALSE);
430 g_object_unref (G_OBJECT (mail_op));
433 /** After deleing a message that is currently visible in a window,
434 * show the next message from the list, or close the window if there are no more messages.
437 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
439 /* Close msg view window or select next */
440 if (modest_msg_view_window_last_message_selected (win) &&
441 modest_msg_view_window_first_message_selected (win)) {
442 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
443 } else if (!modest_msg_view_window_select_next_message (win)) {
445 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
450 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
452 TnyList *header_list = NULL;
453 TnyIterator *iter = NULL;
454 TnyHeader *header = NULL;
455 gchar *message = NULL;
458 ModestWindowMgr *mgr;
459 GtkWidget *header_view = NULL;
461 g_return_if_fail (MODEST_IS_WINDOW(win));
463 /* Check first if the header view has the focus */
464 if (MODEST_IS_MAIN_WINDOW (win)) {
466 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
467 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
468 if (!gtk_widget_is_focus (header_view))
472 /* Get the headers, either from the header view (if win is the main window),
473 * or from the message view window: */
474 header_list = get_selected_headers (win);
475 if (!header_list) return;
477 /* Check if any of the headers are already opened, or in the process of being opened */
478 if (MODEST_IS_MAIN_WINDOW (win)) {
479 gint opened_headers = 0;
481 iter = tny_list_create_iterator (header_list);
482 mgr = modest_runtime_get_window_mgr ();
483 while (!tny_iterator_is_done (iter)) {
484 header = TNY_HEADER (tny_iterator_get_current (iter));
486 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
488 g_object_unref (header);
490 tny_iterator_next (iter);
492 g_object_unref (iter);
494 if (opened_headers > 0) {
497 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
500 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
503 g_object_unref (header_list);
509 if (tny_list_get_length(header_list) == 1) {
510 iter = tny_list_create_iterator (header_list);
511 header = TNY_HEADER (tny_iterator_get_current (iter));
513 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
514 g_object_unref (header);
517 g_object_unref (iter);
519 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
520 tny_list_get_length(header_list)), desc);
522 /* Confirmation dialog */
523 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
527 if (response == GTK_RESPONSE_OK) {
528 ModestWindow *main_window = NULL;
529 ModestWindowMgr *mgr = NULL;
530 GtkTreeModel *model = NULL;
531 GtkTreeSelection *sel = NULL;
532 GList *sel_list = NULL, *tmp = NULL;
533 GtkTreeRowReference *next_row_reference = NULL;
534 GtkTreeRowReference *prev_row_reference = NULL;
535 GtkTreePath *next_path = NULL;
536 GtkTreePath *prev_path = NULL;
539 /* Find last selected row */
540 if (MODEST_IS_MAIN_WINDOW (win)) {
541 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
542 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
543 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
544 for (tmp=sel_list; tmp; tmp=tmp->next) {
545 if (tmp->next == NULL) {
546 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
547 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
549 gtk_tree_path_prev (prev_path);
550 gtk_tree_path_next (next_path);
552 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
553 next_row_reference = gtk_tree_row_reference_new (model, next_path);
558 /* Disable window dimming management */
559 modest_window_disable_dimming (MODEST_WINDOW(win));
561 /* Remove each header. If it's a view window header_view == NULL */
562 modest_do_messages_delete (header_list, win);
564 /* Enable window dimming management */
566 gtk_tree_selection_unselect_all (sel);
568 modest_window_enable_dimming (MODEST_WINDOW(win));
570 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
571 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
573 /* Get main window */
574 mgr = modest_runtime_get_window_mgr ();
575 main_window = modest_window_mgr_get_main_window (mgr);
578 /* Move cursor to next row */
581 /* Select next or previous row */
582 if (gtk_tree_row_reference_valid (next_row_reference)) {
583 /* next_path = gtk_tree_row_reference_get_path (row_reference); */
584 gtk_tree_selection_select_path (sel, next_path);
586 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
587 gtk_tree_selection_select_path (sel, prev_path);
591 if (next_row_reference != NULL)
592 gtk_tree_row_reference_free (next_row_reference);
593 if (next_path != NULL)
594 gtk_tree_path_free (next_path);
595 if (prev_row_reference != NULL)
596 gtk_tree_row_reference_free (prev_row_reference);
597 if (prev_path != NULL)
598 gtk_tree_path_free (prev_path);
602 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, err->code, err->message);
606 /* Update toolbar dimming state */
607 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
610 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
611 g_list_free (sel_list);
617 g_object_unref (header_list);
623 /* delete either message or folder, based on where we are */
625 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
627 g_return_if_fail (MODEST_IS_WINDOW(win));
629 /* Check first if the header view has the focus */
630 if (MODEST_IS_MAIN_WINDOW (win)) {
632 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
633 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
634 if (gtk_widget_is_focus (w)) {
635 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
639 modest_ui_actions_on_delete_message (action, win);
645 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
647 ModestWindowMgr *mgr = NULL;
649 #ifdef MODEST_PLATFORM_MAEMO
650 modest_osso_save_state();
651 #endif /* MODEST_PLATFORM_MAEMO */
653 g_debug ("closing down, clearing %d item(s) from operation queue",
654 modest_mail_operation_queue_num_elements
655 (modest_runtime_get_mail_operation_queue()));
657 /* cancel all outstanding operations */
658 modest_mail_operation_queue_cancel_all
659 (modest_runtime_get_mail_operation_queue());
661 g_debug ("queue has been cleared");
664 /* Check if there are opened editing windows */
665 mgr = modest_runtime_get_window_mgr ();
666 modest_window_mgr_close_all_windows (mgr);
668 /* note: when modest-tny-account-store is finalized,
669 it will automatically set all network connections
672 /* gtk_main_quit (); */
676 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
680 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
682 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
683 /* gtk_widget_destroy (GTK_WIDGET (win)); */
684 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
685 /* gboolean ret_value; */
686 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
687 /* } else if (MODEST_IS_WINDOW (win)) { */
688 /* gtk_widget_destroy (GTK_WIDGET (win)); */
690 /* g_return_if_reached (); */
695 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
697 GtkClipboard *clipboard = NULL;
698 gchar *selection = NULL;
700 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
701 selection = gtk_clipboard_wait_for_text (clipboard);
703 /* Question: why is the clipboard being used here?
704 * It doesn't really make a lot of sense. */
708 modest_address_book_add_address (selection);
714 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
716 /* This is currently only implemented for Maemo */
717 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
718 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
719 modest_run_account_setup_wizard (win);
722 /* Show the list of accounts: */
723 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
724 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW (win));
726 /* The accounts dialog must be modal */
727 gtk_window_set_modal (GTK_WINDOW (account_win), TRUE);
728 modest_maemo_show_dialog_and_forget (GTK_WINDOW (win), account_win);
731 GtkWidget *dialog, *label;
733 /* Create the widgets */
735 dialog = gtk_dialog_new_with_buttons ("Message",
737 GTK_DIALOG_DESTROY_WITH_PARENT,
741 label = gtk_label_new ("Hello World!");
743 /* Ensure that the dialog box is destroyed when the user responds. */
745 g_signal_connect_swapped (dialog, "response",
746 G_CALLBACK (gtk_widget_destroy),
749 /* Add the label, and show everything we've added to the dialog. */
751 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
753 gtk_widget_show_all (dialog);
754 #endif /* MODEST_PLATFORM_MAEMO */
758 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
760 /* Save any changes. */
761 modest_connection_specific_smtp_window_save_server_accounts (
762 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window));
763 gtk_widget_destroy (GTK_WIDGET (window));
769 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
771 /* This is currently only implemented for Maemo,
772 * because it requires an API (libconic) to detect different connection
775 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
777 /* Create the window if necessary: */
778 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
779 modest_connection_specific_smtp_window_fill_with_connections (
780 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
781 modest_runtime_get_account_mgr());
783 /* Show the window: */
784 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
785 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
786 gtk_widget_show (specific_window);
788 /* Save changes when the window is hidden: */
789 g_signal_connect (specific_window, "hide",
790 G_CALLBACK (on_smtp_servers_window_hide), win);
791 #endif /* MODEST_PLATFORM_MAEMO */
795 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
797 ModestWindow *msg_win = NULL;
799 TnyFolder *folder = NULL;
800 gchar *account_name = NULL;
801 gchar *from_str = NULL;
802 /* GError *err = NULL; */
803 TnyAccount *account = NULL;
804 ModestWindowMgr *mgr;
805 gchar *signature = NULL, *blank_and_signature = NULL;
807 /* if there are no accounts yet, just show the wizard */
808 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
809 const gboolean created = modest_run_account_setup_wizard (win);
814 account_name = g_strdup (modest_window_get_active_account (win));
816 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
818 g_printerr ("modest: no account found\n");
822 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
824 TNY_ACCOUNT_TYPE_STORE);
826 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
830 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
832 g_printerr ("modest: failed get from string for '%s'\n", account_name);
836 gboolean use_signature = FALSE;
837 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr (), account_name, &use_signature);
840 blank_and_signature = g_strconcat ("\n", signature, NULL);
842 blank_and_signature = g_strdup ("");
847 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
849 g_printerr ("modest: failed to create new msg\n");
853 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
855 g_printerr ("modest: failed to find Drafts folder\n");
860 /* Create and register edit window */
861 /* This is destroyed by TODO. */
862 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
863 mgr = modest_runtime_get_window_mgr ();
864 modest_window_mgr_register_window (mgr, msg_win);
867 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
869 gtk_widget_show_all (GTK_WIDGET (msg_win));
872 g_free (account_name);
874 g_free (blank_and_signature);
876 g_object_unref (msg_win);
878 g_object_unref (G_OBJECT(account));
880 g_object_unref (G_OBJECT(msg));
882 g_object_unref (G_OBJECT(folder));
886 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
890 ModestMailOperationStatus status;
892 /* If there is no message or the operation was not successful */
893 status = modest_mail_operation_get_status (mail_op);
894 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
896 /* Remove the header from the preregistered uids */
897 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
907 open_msg_cb (ModestMailOperation *mail_op, TnyHeader *header, TnyMsg *msg, gpointer user_data)
909 ModestWindowMgr *mgr = NULL;
910 ModestWindow *parent_win = NULL;
911 ModestWindow *win = NULL;
912 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
913 gchar *account = NULL;
916 /* Do nothing if there was any problem with the mail
917 operation. The error will be shown by the error_handler of
918 the mail operation */
919 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
922 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
923 folder = tny_header_get_folder (header);
925 /* Mark header as read */
926 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
929 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
931 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
933 /* Gets folder type (OUTBOX headers will be opened in edit window */
934 if (modest_tny_folder_is_local_folder (folder))
935 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
937 /* If the header is in the drafts folder then open the editor,
938 else the message view window */
939 if ((folder_type == TNY_FOLDER_TYPE_DRAFTS) ||
940 (folder_type == TNY_FOLDER_TYPE_OUTBOX)) {
941 /* we cannot edit without a valid account... */
942 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
943 const gboolean created = modest_run_account_setup_wizard(parent_win);
947 win = modest_msg_edit_window_new (msg, account, TRUE);
951 modest_platform_information_banner (NULL, NULL, _("mail_ib_opening_draft_message"));
954 gchar *uid = modest_tny_folder_get_header_unique_id (header);
956 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
957 GtkWidget *header_view;
958 GtkTreeSelection *sel;
959 GList *sel_list = NULL;
962 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
963 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
965 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
966 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
968 if (sel_list != NULL) {
969 GtkTreeRowReference *row_reference;
971 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
972 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
973 g_list_free (sel_list);
975 win = modest_msg_view_window_new_with_header_model (
976 msg, account, (const gchar*) uid,
977 model, row_reference);
978 gtk_tree_row_reference_free (row_reference);
980 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
983 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
988 /* Register and show new window */
990 mgr = modest_runtime_get_window_mgr ();
991 modest_window_mgr_register_window (mgr, win);
992 g_object_unref (win);
993 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
994 gtk_widget_show_all (GTK_WIDGET(win));
997 /* Update toolbar dimming state */
998 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
999 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1005 g_object_unref (parent_win);
1006 g_object_unref (folder);
1010 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
1013 const GError *error;
1014 GObject *win = modest_mail_operation_get_source (mail_op);
1016 error = modest_mail_operation_get_error (mail_op);
1017 /* printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, error->code, error->message); */
1019 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
1021 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1024 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1025 _("mail_ni_ui_folder_get_msg_folder_error"));
1029 g_object_unref (win);
1033 * This function is used by both modest_ui_actions_on_open and
1034 * modest_ui_actions_on_header_activated. This way we always do the
1035 * same when trying to open messages.
1038 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
1040 ModestWindowMgr *mgr = NULL;
1041 TnyIterator *iter = NULL;
1042 ModestMailOperation *mail_op = NULL;
1043 TnyList *not_opened_headers = NULL;
1044 TnyHeaderFlags flags = 0;
1046 g_return_if_fail (headers != NULL);
1048 /* Check that only one message is selected for opening */
1049 if (tny_list_get_length (headers) != 1) {
1050 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1051 _("mcen_ib_select_one_message"));
1056 /* Look if we already have a message view for each header. If
1057 true, then remove the header from the list of headers to
1059 mgr = modest_runtime_get_window_mgr ();
1060 iter = tny_list_create_iterator (headers);
1061 not_opened_headers = tny_simple_list_new ();
1063 while (!tny_iterator_is_done (iter)) {
1065 ModestWindow *window = NULL;
1066 TnyHeader *header = NULL;
1067 gboolean found = FALSE;
1069 header = TNY_HEADER (tny_iterator_get_current (iter));
1071 flags = tny_header_get_flags (header);
1074 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1076 /* Do not open again the message and present the
1077 window to the user */
1080 gtk_window_present (GTK_WINDOW (window));
1082 /* the header has been registered already, we don't do
1083 * anything but wait for the window to come up*/
1084 g_debug ("header %p already registered, waiting for window", header);
1086 tny_list_append (not_opened_headers, G_OBJECT (header));
1090 g_object_unref (header);
1092 tny_iterator_next (iter);
1094 g_object_unref (iter);
1097 /* If some messages would have to be downloaded, ask the user to
1098 * make a connection. It's generally easier to do this here (in the mainloop)
1099 * than later in a thread:
1101 if (tny_list_get_length (not_opened_headers) > 0) {
1103 gboolean found = FALSE;
1105 iter = tny_list_create_iterator (not_opened_headers);
1106 while (!tny_iterator_is_done (iter) && !found) {
1107 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1108 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1111 tny_iterator_next (iter);
1113 g_object_unref (header);
1115 g_object_unref (iter);
1117 if (found && !modest_platform_connect_and_wait (GTK_WINDOW (win), NULL)) {
1118 g_object_unref (not_opened_headers);
1123 /* Register the headers before actually creating the windows: */
1124 TnyIterator *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);
1132 tny_iterator_next (iter_not_opened);
1134 g_object_unref (iter_not_opened);
1135 iter_not_opened = NULL;
1137 /* Open each message */
1138 if (tny_list_get_length (not_opened_headers) > 0) {
1139 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1141 modest_ui_actions_get_msgs_full_error_handler,
1143 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1144 if (tny_list_get_length (not_opened_headers) > 1) {
1145 modest_mail_operation_get_msgs_full (mail_op,
1151 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1152 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1153 modest_mail_operation_get_msg (mail_op, header, open_msg_cb, NULL);
1154 g_object_unref (header);
1155 g_object_unref (iter);
1157 g_object_unref (mail_op);
1161 if (not_opened_headers != NULL)
1162 g_object_unref (not_opened_headers);
1166 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1171 headers = get_selected_headers (win);
1176 _modest_ui_actions_open (headers, win);
1178 g_object_unref(headers);
1183 free_reply_forward_helper (gpointer data)
1185 ReplyForwardHelper *helper;
1187 helper = (ReplyForwardHelper *) data;
1188 g_free (helper->account_name);
1189 g_slice_free (ReplyForwardHelper, helper);
1193 reply_forward_cb (ModestMailOperation *mail_op, TnyHeader *header, TnyMsg *msg,
1197 ReplyForwardHelper *rf_helper;
1198 ModestWindow *msg_win = NULL;
1199 ModestEditType edit_type;
1201 TnyAccount *account = NULL;
1202 ModestWindowMgr *mgr = NULL;
1203 gchar *signature = NULL;
1204 gboolean use_signature;
1206 /* If there was any error. The mail operation could be NULL,
1207 this means that we already have the message downloaded and
1208 that we didn't do a mail operation to retrieve it */
1209 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1212 g_return_if_fail (user_data != NULL);
1213 rf_helper = (ReplyForwardHelper *) user_data;
1215 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1216 rf_helper->account_name);
1217 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr(),
1218 rf_helper->account_name,
1221 /* Create reply mail */
1222 switch (rf_helper->action) {
1225 modest_tny_msg_create_reply_msg (msg, header, from, signature,
1226 rf_helper->reply_forward_type,
1227 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1229 case ACTION_REPLY_TO_ALL:
1231 modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1232 MODEST_TNY_MSG_REPLY_MODE_ALL);
1233 edit_type = MODEST_EDIT_TYPE_REPLY;
1235 case ACTION_FORWARD:
1237 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1238 edit_type = MODEST_EDIT_TYPE_FORWARD;
1241 g_return_if_reached ();
1248 g_printerr ("modest: failed to create message\n");
1252 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1253 rf_helper->account_name,
1254 TNY_ACCOUNT_TYPE_STORE);
1256 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1260 /* Create and register the windows */
1261 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1262 mgr = modest_runtime_get_window_mgr ();
1263 modest_window_mgr_register_window (mgr, msg_win);
1265 if (rf_helper->parent_window != NULL) {
1266 gdouble parent_zoom;
1268 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1269 modest_window_set_zoom (msg_win, parent_zoom);
1272 /* Show edit window */
1273 gtk_widget_show_all (GTK_WIDGET (msg_win));
1277 g_object_unref (msg_win);
1279 g_object_unref (G_OBJECT (new_msg));
1281 g_object_unref (G_OBJECT (account));
1282 /* g_object_unref (msg); */
1283 free_reply_forward_helper (rf_helper);
1286 /* Checks a list of headers. If any of them are not currently
1287 * downloaded (CACHED) then returns TRUE else returns FALSE.
1290 header_list_count_uncached_msgs (TnyList *header_list)
1293 gint uncached_messages = 0;
1295 iter = tny_list_create_iterator (header_list);
1296 while (!tny_iterator_is_done (iter)) {
1299 header = TNY_HEADER (tny_iterator_get_current (iter));
1301 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1302 uncached_messages ++;
1303 g_object_unref (header);
1306 tny_iterator_next (iter);
1308 g_object_unref (iter);
1310 return uncached_messages;
1313 /* Returns FALSE if the user does not want to download the
1314 * messages. Returns TRUE if the user allowed the download.
1317 connect_to_get_msg (GtkWindow *win,
1318 gint num_of_uncached_msgs)
1320 /* Allways download if we are online. */
1321 if (tny_device_is_online (modest_runtime_get_device ()))
1324 /* If offline, then ask for user permission to download the messages */
1325 GtkResponseType response;
1326 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1327 ngettext("mcen_nc_get_msg",
1329 num_of_uncached_msgs));
1330 if (response == GTK_RESPONSE_CANCEL)
1333 return modest_platform_connect_and_wait(win, NULL);
1337 * Common code for the reply and forward actions
1340 reply_forward (ReplyForwardAction action, ModestWindow *win)
1342 ModestMailOperation *mail_op = NULL;
1343 TnyList *header_list = NULL;
1344 ReplyForwardHelper *rf_helper = NULL;
1345 guint reply_forward_type;
1346 gboolean continue_download = TRUE;
1347 gboolean do_retrieve = TRUE;
1349 g_return_if_fail (MODEST_IS_WINDOW(win));
1351 /* we need an account when editing */
1352 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1353 const gboolean created = modest_run_account_setup_wizard (win);
1358 header_list = get_selected_headers (win);
1362 reply_forward_type =
1363 modest_conf_get_int (modest_runtime_get_conf (),
1364 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1367 /* check if we need to download msg before asking about it */
1368 do_retrieve = (action == ACTION_FORWARD) ||
1369 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1372 gint num_of_unc_msgs;
1373 /* check that the messages have been previously downloaded */
1374 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
1375 /* If there are any uncached message ask the user
1376 * whether he/she wants to download them. */
1377 if (num_of_unc_msgs)
1378 continue_download = connect_to_get_msg (
1383 if (!continue_download) {
1384 g_object_unref (header_list);
1388 /* We assume that we can only select messages of the
1389 same folder and that we reply all of them from the
1390 same account. In fact the interface currently only
1391 allows single selection */
1394 rf_helper = g_slice_new0 (ReplyForwardHelper);
1395 rf_helper->reply_forward_type = reply_forward_type;
1396 rf_helper->action = action;
1397 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1399 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1400 rf_helper->parent_window = GTK_WIDGET (win);
1401 if (!rf_helper->account_name)
1402 rf_helper->account_name =
1403 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1405 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1408 /* Get header and message. Do not free them here, the
1409 reply_forward_cb must do it */
1410 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1411 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1412 if (!msg || !header) {
1414 g_object_unref (msg);
1415 g_printerr ("modest: no message found\n");
1418 reply_forward_cb (NULL, header, msg, rf_helper);
1421 g_object_unref (header);
1426 /* Only reply/forward to one message */
1427 iter = tny_list_create_iterator (header_list);
1428 header = TNY_HEADER (tny_iterator_get_current (iter));
1429 g_object_unref (iter);
1432 /* Retrieve messages */
1434 mail_op = modest_mail_operation_new_with_error_handling (
1435 MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1437 modest_ui_actions_get_msgs_full_error_handler,
1439 modest_mail_operation_queue_add (
1440 modest_runtime_get_mail_operation_queue (), mail_op);
1442 modest_mail_operation_get_msg (mail_op,
1447 g_object_unref(mail_op);
1449 /* we put a ref here to prevent double unref as the reply
1450 * forward callback unrefs the header at its end */
1451 reply_forward_cb (NULL, header, NULL, rf_helper);
1455 g_object_unref (header);
1461 g_object_unref (header_list);
1465 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1467 g_return_if_fail (MODEST_IS_WINDOW(win));
1469 reply_forward (ACTION_REPLY, win);
1473 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1475 g_return_if_fail (MODEST_IS_WINDOW(win));
1477 reply_forward (ACTION_FORWARD, win);
1481 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1483 g_return_if_fail (MODEST_IS_WINDOW(win));
1485 reply_forward (ACTION_REPLY_TO_ALL, win);
1489 modest_ui_actions_on_next (GtkAction *action,
1490 ModestWindow *window)
1492 if (MODEST_IS_MAIN_WINDOW (window)) {
1493 GtkWidget *header_view;
1495 header_view = modest_main_window_get_child_widget (
1496 MODEST_MAIN_WINDOW(window),
1497 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1501 modest_header_view_select_next (
1502 MODEST_HEADER_VIEW(header_view));
1503 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1504 modest_msg_view_window_select_next_message (
1505 MODEST_MSG_VIEW_WINDOW (window));
1507 g_return_if_reached ();
1512 modest_ui_actions_on_prev (GtkAction *action,
1513 ModestWindow *window)
1515 g_return_if_fail (MODEST_IS_WINDOW(window));
1517 if (MODEST_IS_MAIN_WINDOW (window)) {
1518 GtkWidget *header_view;
1519 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1520 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1524 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1525 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1526 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1528 g_return_if_reached ();
1533 modest_ui_actions_on_sort (GtkAction *action,
1534 ModestWindow *window)
1536 g_return_if_fail (MODEST_IS_WINDOW(window));
1538 if (MODEST_IS_MAIN_WINDOW (window)) {
1539 GtkWidget *header_view;
1540 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1541 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1543 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1548 /* Show sorting dialog */
1549 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1554 new_messages_arrived (ModestMailOperation *self,
1555 TnyList *new_headers,
1558 ModestMainWindow *win = NULL;
1559 GtkWidget *folder_view = NULL;
1560 TnyFolderStore *folder = NULL;
1561 gboolean folder_empty = FALSE;
1563 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
1564 win = MODEST_MAIN_WINDOW (user_data);
1566 /* Don't do anything if there are not new headers, this could
1567 happen if there was any problem with the mail operation */
1571 /* Set contents style of headers view */
1572 if (modest_main_window_get_contents_style (win) == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1573 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1574 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1575 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1578 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1581 modest_main_window_set_contents_style (win,
1582 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1585 /* Notify new messages have been downloaded */
1586 if ((new_headers != NULL) && (tny_list_get_length (new_headers) > 0)) {
1587 TnyIterator *iter = tny_list_create_iterator (new_headers);
1589 TnyHeader *header = NULL;
1591 header = TNY_HEADER (tny_iterator_get_current (iter));
1592 modest_platform_on_new_header_received (header);
1593 g_object_unref (header);
1595 tny_iterator_next (iter);
1596 } while (!tny_iterator_is_done (iter));
1597 g_object_unref (iter);
1602 * This function performs the send & receive required actions. The
1603 * window is used to create the mail operation. Typically it should
1604 * always be the main window, but we pass it as argument in order to
1608 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1610 gchar *acc_name = NULL;
1611 ModestMailOperation *mail_op;
1612 TnyAccount *store_account = NULL;
1614 /* If no account name was provided then get the current account, and if
1615 there is no current account then pick the default one: */
1616 if (!account_name) {
1617 acc_name = g_strdup (modest_window_get_active_account(win));
1619 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1621 g_printerr ("modest: cannot get default account\n");
1625 acc_name = g_strdup (account_name);
1629 /* Ensure that we have a connection available */
1631 modest_tny_account_store_get_server_account (modest_runtime_get_account_store (),
1633 TNY_ACCOUNT_TYPE_STORE);
1634 if (!modest_platform_connect_and_wait (NULL, TNY_ACCOUNT (store_account))) {
1635 g_object_unref (store_account);
1638 g_object_unref (store_account);
1640 /* Set send/receive operation in progress */
1641 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1643 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1645 modest_ui_actions_send_receive_error_handler,
1648 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1649 G_CALLBACK (_on_send_receive_progress_changed),
1652 /* Send & receive. */
1653 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1654 /* Receive and then send. The operation is tagged initially as
1655 a receive operation because the account update performs a
1656 receive and then a send. The operation changes its type
1657 internally, so the progress objects will receive the proper
1658 progress information */
1659 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1660 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, win);
1661 g_object_unref (G_OBJECT (mail_op));
1669 modest_ui_actions_do_cancel_send (const gchar *account_name,
1672 TnyTransportAccount *transport_account;
1673 TnySendQueue *send_queue = NULL;
1674 GError *error = NULL;
1676 /* Get transport account */
1678 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1679 (modest_runtime_get_account_store(),
1681 TNY_ACCOUNT_TYPE_TRANSPORT));
1682 if (!transport_account) {
1683 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1688 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1689 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1690 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1691 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1692 "modest: could not find send queue for account\n");
1694 /* Keeep messages in outbox folder */
1695 tny_send_queue_cancel (send_queue, FALSE, &error);
1699 if (transport_account != NULL)
1700 g_object_unref (G_OBJECT (transport_account));
1704 modest_ui_actions_cancel_send_all (ModestWindow *win)
1706 GSList *account_names, *iter;
1708 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1711 iter = account_names;
1713 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1714 iter = g_slist_next (iter);
1717 modest_account_mgr_free_account_names (account_names);
1718 account_names = NULL;
1722 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1725 /* Check if accounts exist */
1726 gboolean accounts_exist =
1727 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1729 /* If not, allow the user to create an account before trying to send/receive. */
1730 if (!accounts_exist)
1731 modest_ui_actions_on_accounts (NULL, win);
1733 /* Cancel all sending operaitons */
1734 modest_ui_actions_cancel_send_all (win);
1738 * Refreshes all accounts. This function will be used by automatic
1742 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1744 GSList *account_names, *iter;
1746 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1749 iter = account_names;
1751 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1752 iter = g_slist_next (iter);
1755 modest_account_mgr_free_account_names (account_names);
1756 account_names = NULL;
1760 modest_do_refresh_current_folder(ModestWindow *win)
1762 /* Refresh currently selected folder. Note that if we only
1763 want to retreive the headers, then the refresh only will
1764 invoke a poke_status over all folders, i.e., only the
1765 total/unread count will be updated */
1766 if (MODEST_IS_MAIN_WINDOW (win)) {
1767 GtkWidget *header_view, *folder_view;
1768 TnyFolderStore *folder_store;
1770 /* Get folder and header view */
1772 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1773 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1777 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1779 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1781 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1782 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1784 /* We do not need to set the contents style
1785 because it hasn't changed. We also do not
1786 need to save the widget status. Just force
1788 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1789 TNY_FOLDER (folder_store),
1790 folder_refreshed_cb,
1791 MODEST_MAIN_WINDOW (win));
1795 g_object_unref (folder_store);
1801 * Handler of the click on Send&Receive button in the main toolbar
1804 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1806 /* Check if accounts exist */
1807 gboolean accounts_exist =
1808 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1810 /* If not, allow the user to create an account before trying to send/receive. */
1811 if (!accounts_exist)
1812 modest_ui_actions_on_accounts (NULL, win);
1814 modest_do_refresh_current_folder (win);
1816 /* Refresh the active account */
1817 modest_ui_actions_do_send_receive (NULL, win);
1822 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1825 GtkWidget *header_view;
1827 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1829 header_view = modest_main_window_get_child_widget (main_window,
1830 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1834 conf = modest_runtime_get_conf ();
1836 /* what is saved/restored is depending on the style; thus; we save with
1837 * old style, then update the style, and restore for this new style
1839 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1841 if (modest_header_view_get_style
1842 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1843 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1844 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1846 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1847 MODEST_HEADER_VIEW_STYLE_DETAILS);
1849 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1850 MODEST_CONF_HEADER_VIEW_KEY);
1855 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1857 ModestMainWindow *main_window)
1859 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1860 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1862 /* in the case the folder is empty, show the empty folder message and focus
1864 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1865 if (modest_header_view_is_empty (header_view)) {
1866 TnyFolder *folder = modest_header_view_get_folder (header_view);
1867 GtkWidget *folder_view =
1868 modest_main_window_get_child_widget (main_window,
1869 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1871 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1872 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1876 /* If no header has been selected then exit */
1881 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1882 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1884 /* Update toolbar dimming state */
1885 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1889 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1891 ModestMainWindow *main_window)
1895 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1900 if (modest_header_view_count_selected_headers (header_view) > 1) {
1901 hildon_banner_show_information (NULL, NULL, _("mcen_ib_select_one_message"));
1906 /* headers = tny_simple_list_new (); */
1907 /* tny_list_prepend (headers, G_OBJECT (header)); */
1908 headers = modest_header_view_get_selected_headers (header_view);
1910 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1912 g_object_unref (headers);
1916 set_active_account_from_tny_account (TnyAccount *account,
1917 ModestWindow *window)
1919 const gchar *server_acc_name = tny_account_get_id (account);
1921 /* We need the TnyAccount provided by the
1922 account store because that is the one that
1923 knows the name of the Modest account */
1924 TnyAccount *modest_server_account = modest_server_account =
1925 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1926 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1928 if (!modest_server_account) {
1929 g_warning ("%s: could not get tny account\n", __FUNCTION__);
1933 /* Update active account, but only if it's not a pseudo-account */
1934 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
1935 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
1936 const gchar *modest_acc_name =
1937 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1938 if (modest_acc_name)
1939 modest_window_set_active_account (window, modest_acc_name);
1942 g_object_unref (modest_server_account);
1947 folder_refreshed_cb (ModestMailOperation *mail_op,
1951 ModestMainWindow *win = NULL;
1952 GtkWidget *header_view;
1953 gboolean folder_empty = FALSE;
1954 gboolean all_marked_as_deleted = FALSE;
1956 g_return_if_fail (TNY_IS_FOLDER (folder));
1958 win = MODEST_MAIN_WINDOW (user_data);
1960 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1963 TnyFolder *current_folder;
1965 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1966 if (current_folder != NULL && folder != current_folder) {
1967 g_object_unref (current_folder);
1970 g_object_unref (current_folder);
1973 /* Check if folder is empty and set headers view contents style */
1974 folder_empty = (tny_folder_get_all_count (folder) == 0);
1975 all_marked_as_deleted = modest_header_view_is_empty (MODEST_HEADER_VIEW(header_view));
1976 if (folder_empty || all_marked_as_deleted)
1977 modest_main_window_set_contents_style (win,
1978 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1982 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1983 TnyFolderStore *folder_store,
1985 ModestMainWindow *main_window)
1988 GtkWidget *header_view;
1990 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1992 header_view = modest_main_window_get_child_widget(main_window,
1993 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1997 conf = modest_runtime_get_conf ();
1999 if (TNY_IS_ACCOUNT (folder_store)) {
2001 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2003 /* Show account details */
2004 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2007 if (TNY_IS_FOLDER (folder_store) && selected) {
2009 /* Update the active account */
2010 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2012 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2013 g_object_unref (account);
2017 /* Set the header style by default, it could
2018 be changed later by the refresh callback to
2020 modest_main_window_set_contents_style (main_window,
2021 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2023 /* Set folder on header view. This function
2024 will call tny_folder_refresh_async so we
2025 pass a callback that will be called when
2026 finished. We use that callback to set the
2027 empty view if there are no messages */
2028 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2029 TNY_FOLDER (folder_store),
2030 folder_refreshed_cb,
2033 /* Restore configuration. We need to do this
2034 *after* the set_folder because the widget
2035 memory asks the header view about its
2037 modest_widget_memory_restore (modest_runtime_get_conf (),
2038 G_OBJECT(header_view),
2039 MODEST_CONF_HEADER_VIEW_KEY);
2041 /* Update the active account */
2042 //modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
2043 /* Save only if we're seeing headers */
2044 if (modest_main_window_get_contents_style (main_window) ==
2045 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2046 modest_widget_memory_save (conf, G_OBJECT (header_view),
2047 MODEST_CONF_HEADER_VIEW_KEY);
2048 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2052 /* Update toolbar dimming state */
2053 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2057 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2064 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2066 online = tny_device_is_online (modest_runtime_get_device());
2069 /* already online -- the item is simply not there... */
2070 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2072 GTK_MESSAGE_WARNING,
2074 _("The %s you selected cannot be found"),
2076 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2077 gtk_dialog_run (GTK_DIALOG(dialog));
2079 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2082 _("mcen_bd_dialog_cancel"),
2083 GTK_RESPONSE_REJECT,
2084 _("mcen_bd_dialog_ok"),
2085 GTK_RESPONSE_ACCEPT,
2087 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2088 "Do you want to get online?"), item);
2089 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2090 gtk_label_new (txt), FALSE, FALSE, 0);
2091 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2094 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2095 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2096 /* TODO: Comment about why is this commented out: */
2097 /* modest_platform_connect_and_wait (); */
2100 gtk_widget_destroy (dialog);
2104 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2107 /* g_message ("%s %s", __FUNCTION__, link); */
2112 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2115 modest_platform_activate_uri (link);
2119 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2122 modest_platform_show_uri_popup (link);
2126 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2129 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2133 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2134 const gchar *address,
2137 /* g_message ("%s %s", __FUNCTION__, address); */
2141 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2143 TnyTransportAccount *transport_account;
2144 ModestMailOperation *mail_operation;
2146 gchar *account_name, *from;
2147 ModestAccountMgr *account_mgr;
2148 gchar *info_text = NULL;
2150 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2152 data = modest_msg_edit_window_get_msg_data (edit_window);
2154 account_mgr = modest_runtime_get_account_mgr();
2155 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2157 account_name = modest_account_mgr_get_default_account (account_mgr);
2158 if (!account_name) {
2159 g_printerr ("modest: no account found\n");
2160 modest_msg_edit_window_free_msg_data (edit_window, data);
2164 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2165 account_name = g_strdup (data->account_name);
2169 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2170 (modest_runtime_get_account_store(),
2172 TNY_ACCOUNT_TYPE_TRANSPORT));
2173 if (!transport_account) {
2174 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2175 g_free (account_name);
2176 modest_msg_edit_window_free_msg_data (edit_window, data);
2179 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2181 /* Create the mail operation */
2182 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
2183 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2185 modest_mail_operation_save_to_drafts (mail_operation,
2198 data->priority_flags);
2201 g_free (account_name);
2202 g_object_unref (G_OBJECT (transport_account));
2203 g_object_unref (G_OBJECT (mail_operation));
2205 modest_msg_edit_window_free_msg_data (edit_window, data);
2207 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2208 modest_platform_information_banner (NULL, NULL, info_text);
2209 modest_msg_edit_window_reset_modified (edit_window);
2213 /* For instance, when clicking the Send toolbar button when editing a message: */
2215 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2217 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2219 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2222 /* Offer the connection dialog, if necessary: */
2223 if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
2226 /* FIXME: Code added just for testing. The final version will
2227 use the send queue provided by tinymail and some
2229 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2230 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2232 account_name = modest_account_mgr_get_default_account (account_mgr);
2234 if (!account_name) {
2235 /* Run account setup wizard */
2236 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2241 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2243 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2244 account_name = g_strdup (data->account_name);
2247 /* Get the currently-active transport account for this modest account: */
2248 TnyTransportAccount *transport_account =
2249 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2250 (modest_runtime_get_account_store(),
2252 if (!transport_account) {
2253 /* Run account setup wizard */
2254 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2259 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2261 /* Create the mail operation */
2262 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
2263 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2265 modest_mail_operation_send_new_mail (mail_operation,
2277 data->priority_flags);
2281 g_free (account_name);
2282 g_object_unref (G_OBJECT (transport_account));
2283 g_object_unref (G_OBJECT (mail_operation));
2285 modest_msg_edit_window_free_msg_data (edit_window, data);
2286 modest_msg_edit_window_set_sent (edit_window, TRUE);
2288 /* Save settings and close the window: */
2289 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2293 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2294 ModestMsgEditWindow *window)
2296 ModestMsgEditFormatState *format_state = NULL;
2298 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2299 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2301 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2304 format_state = modest_msg_edit_window_get_format_state (window);
2305 g_return_if_fail (format_state != NULL);
2307 format_state->bold = gtk_toggle_action_get_active (action);
2308 modest_msg_edit_window_set_format_state (window, format_state);
2309 g_free (format_state);
2314 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2315 ModestMsgEditWindow *window)
2317 ModestMsgEditFormatState *format_state = NULL;
2319 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2320 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2322 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2325 format_state = modest_msg_edit_window_get_format_state (window);
2326 g_return_if_fail (format_state != NULL);
2328 format_state->italics = gtk_toggle_action_get_active (action);
2329 modest_msg_edit_window_set_format_state (window, format_state);
2330 g_free (format_state);
2335 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2336 ModestMsgEditWindow *window)
2338 ModestMsgEditFormatState *format_state = NULL;
2340 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2341 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2343 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2346 format_state = modest_msg_edit_window_get_format_state (window);
2347 g_return_if_fail (format_state != NULL);
2349 format_state->bullet = gtk_toggle_action_get_active (action);
2350 modest_msg_edit_window_set_format_state (window, format_state);
2351 g_free (format_state);
2356 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2357 GtkRadioAction *selected,
2358 ModestMsgEditWindow *window)
2360 ModestMsgEditFormatState *format_state = NULL;
2361 GtkJustification value;
2363 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2365 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2368 value = gtk_radio_action_get_current_value (selected);
2370 format_state = modest_msg_edit_window_get_format_state (window);
2371 g_return_if_fail (format_state != NULL);
2373 format_state->justification = value;
2374 modest_msg_edit_window_set_format_state (window, format_state);
2375 g_free (format_state);
2379 modest_ui_actions_on_select_editor_color (GtkAction *action,
2380 ModestMsgEditWindow *window)
2382 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2383 g_return_if_fail (GTK_IS_ACTION (action));
2385 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2388 modest_msg_edit_window_select_color (window);
2392 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2393 ModestMsgEditWindow *window)
2395 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2396 g_return_if_fail (GTK_IS_ACTION (action));
2398 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2401 modest_msg_edit_window_select_background_color (window);
2405 modest_ui_actions_on_insert_image (GtkAction *action,
2406 ModestMsgEditWindow *window)
2408 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2409 g_return_if_fail (GTK_IS_ACTION (action));
2411 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2414 modest_msg_edit_window_insert_image (window);
2418 modest_ui_actions_on_attach_file (GtkAction *action,
2419 ModestMsgEditWindow *window)
2421 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2422 g_return_if_fail (GTK_IS_ACTION (action));
2424 modest_msg_edit_window_offer_attach_file (window);
2428 modest_ui_actions_on_remove_attachments (GtkAction *action,
2429 ModestMsgEditWindow *window)
2431 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2432 g_return_if_fail (GTK_IS_ACTION (action));
2434 modest_msg_edit_window_remove_attachments (window, NULL);
2438 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2441 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2442 const GError *error = modest_mail_operation_get_error (mail_op);
2445 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2446 _("mail_in_ui_folder_create_error"));
2451 modest_ui_actions_create_folder(GtkWidget *parent_window,
2452 GtkWidget *folder_view)
2454 TnyFolderStore *parent_folder;
2456 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2458 if (parent_folder) {
2459 gboolean finished = FALSE;
2461 gchar *folder_name = NULL, *suggested_name = NULL;
2462 const gchar *proto_str = NULL;
2463 TnyAccount *account;
2465 if (TNY_IS_ACCOUNT (parent_folder))
2466 account = g_object_ref (parent_folder);
2468 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2469 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2471 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2472 MODEST_PROTOCOL_STORE_POP) {
2474 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2476 g_object_unref (account);
2478 /* Run the new folder dialog */
2480 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2485 g_free (suggested_name);
2486 suggested_name = NULL;
2488 if (result == GTK_RESPONSE_REJECT) {
2491 ModestMailOperation *mail_op;
2492 TnyFolder *new_folder = NULL;
2494 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2495 G_OBJECT(parent_window),
2496 modest_ui_actions_new_folder_error_handler,
2499 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2501 new_folder = modest_mail_operation_create_folder (mail_op,
2503 (const gchar *) folder_name);
2505 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2508 g_object_unref (new_folder);
2511 g_object_unref (mail_op);
2514 suggested_name = folder_name;
2518 g_object_unref (parent_folder);
2523 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2525 GtkWidget *folder_view;
2527 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2529 folder_view = modest_main_window_get_child_widget (main_window,
2530 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2534 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2538 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2541 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2542 const GError *error = NULL;
2543 const gchar *message = NULL;
2545 /* Get error message */
2546 error = modest_mail_operation_get_error (mail_op);
2548 g_return_if_reached ();
2550 switch (error->code) {
2551 case MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS:
2552 message = _CS("ckdg_ib_folder_already_exists");
2555 g_return_if_reached ();
2558 modest_platform_information_banner (GTK_WIDGET (window), NULL, message);
2562 modest_ui_actions_on_rename_folder (GtkAction *action,
2563 ModestMainWindow *main_window)
2565 TnyFolderStore *folder;
2566 GtkWidget *folder_view;
2567 GtkWidget *header_view;
2569 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2571 folder_view = modest_main_window_get_child_widget (main_window,
2572 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2576 header_view = modest_main_window_get_child_widget (main_window,
2577 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2582 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2587 if (TNY_IS_FOLDER (folder)) {
2590 const gchar *current_name;
2591 TnyFolderStore *parent;
2592 gboolean do_rename = TRUE;
2594 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2595 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
2596 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
2597 parent, current_name,
2599 g_object_unref (parent);
2601 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
2603 } else if (modest_platform_is_network_folderstore(folder) &&
2604 !tny_device_is_online (modest_runtime_get_device())) {
2605 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2606 do_rename = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2607 g_object_unref(account);
2611 ModestMailOperation *mail_op;
2612 GtkTreeSelection *sel = NULL;
2615 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2616 G_OBJECT(main_window),
2617 modest_ui_actions_rename_folder_error_handler,
2620 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2623 /* Clear the headers view */
2624 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2625 gtk_tree_selection_unselect_all (sel);
2627 /* Select *after* the changes */
2628 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2629 TNY_FOLDER(folder), TRUE);
2631 /* Actually rename the folder */
2632 modest_mail_operation_rename_folder (mail_op,
2633 TNY_FOLDER (folder),
2634 (const gchar *) folder_name);
2636 g_object_unref (mail_op);
2637 g_free (folder_name);
2640 g_object_unref (folder);
2644 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2647 GObject *win = modest_mail_operation_get_source (mail_op);
2649 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2650 _("mail_in_ui_folder_delete_error"));
2651 g_object_unref (win);
2655 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2657 TnyFolderStore *folder;
2658 GtkWidget *folder_view;
2661 gboolean do_delete = TRUE;
2663 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (main_window), FALSE);
2665 folder_view = modest_main_window_get_child_widget (main_window,
2666 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2670 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2672 /* Show an error if it's an account */
2673 if (!TNY_IS_FOLDER (folder)) {
2674 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2675 _("mail_in_ui_folder_delete_error"));
2676 g_object_unref (G_OBJECT (folder));
2681 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2682 tny_folder_get_name (TNY_FOLDER (folder)));
2683 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2684 (const gchar *) message);
2687 if (response != GTK_RESPONSE_OK) {
2689 } else if (modest_platform_is_network_folderstore(folder) &&
2690 !tny_device_is_online (modest_runtime_get_device())) {
2691 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2692 do_delete = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2693 g_object_unref(account);
2697 ModestMailOperation *mail_op;
2698 GtkTreeSelection *sel;
2700 /* Unselect the folder before deleting it to free the headers */
2701 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2702 gtk_tree_selection_unselect_all (sel);
2704 /* Create the mail operation */
2706 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2707 G_OBJECT(main_window),
2708 modest_ui_actions_delete_folder_error_handler,
2711 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2713 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2714 g_object_unref (G_OBJECT (mail_op));
2717 g_object_unref (G_OBJECT (folder));
2723 modest_ui_actions_on_delete_folder (GtkAction *action,
2724 ModestMainWindow *main_window)
2726 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2728 if (delete_folder (main_window, FALSE)) {
2729 GtkWidget *folder_view;
2731 folder_view = modest_main_window_get_child_widget (main_window,
2732 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2733 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2738 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2740 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2742 delete_folder (main_window, TRUE);
2747 show_error (GtkWidget *parent_widget, const gchar* text)
2749 hildon_banner_show_information(parent_widget, NULL, text);
2752 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2754 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2761 gtk_dialog_run (dialog);
2762 gtk_widget_destroy (GTK_WIDGET (dialog));
2767 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2768 const gchar* server_account_name,
2773 ModestMainWindow *main_window)
2775 g_return_if_fail(server_account_name);
2776 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2778 /* Initalize output parameters: */
2785 #ifdef MODEST_PLATFORM_MAEMO
2786 /* Maemo uses a different (awkward) button order,
2787 * It should probably just use gtk_alternative_dialog_button_order ().
2789 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2792 _("mcen_bd_dialog_ok"),
2793 GTK_RESPONSE_ACCEPT,
2794 _("mcen_bd_dialog_cancel"),
2795 GTK_RESPONSE_REJECT,
2798 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2802 GTK_RESPONSE_REJECT,
2804 GTK_RESPONSE_ACCEPT,
2806 #endif /* MODEST_PLATFORM_MAEMO */
2808 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2810 gchar *server_name = modest_account_mgr_get_server_account_hostname (
2811 modest_runtime_get_account_mgr(), server_account_name);
2812 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2813 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2818 /* This causes a warning because the logical ID has no %s in it,
2819 * though the translation does, but there is not much we can do about that: */
2820 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2821 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2824 g_free (server_name);
2828 gchar *initial_username = modest_account_mgr_get_server_account_username (
2829 modest_runtime_get_account_mgr(), server_account_name);
2831 GtkWidget *entry_username = gtk_entry_new ();
2832 if (initial_username)
2833 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2834 /* Dim this if a connection has ever succeeded with this username,
2835 * as per the UI spec: */
2836 const gboolean username_known =
2837 modest_account_mgr_get_server_account_username_has_succeeded(
2838 modest_runtime_get_account_mgr(), server_account_name);
2839 gtk_widget_set_sensitive (entry_username, !username_known);
2841 #ifdef MODEST_PLATFORM_MAEMO
2842 /* Auto-capitalization is the default, so let's turn it off: */
2843 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2845 /* Create a size group to be used by all captions.
2846 * Note that HildonCaption does not create a default size group if we do not specify one.
2847 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2848 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2850 GtkWidget *caption = hildon_caption_new (sizegroup,
2851 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2852 gtk_widget_show (entry_username);
2853 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2854 FALSE, FALSE, MODEST_MARGIN_HALF);
2855 gtk_widget_show (caption);
2857 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2859 #endif /* MODEST_PLATFORM_MAEMO */
2862 GtkWidget *entry_password = gtk_entry_new ();
2863 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2864 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2866 #ifdef MODEST_PLATFORM_MAEMO
2867 /* Auto-capitalization is the default, so let's turn it off: */
2868 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2869 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2871 caption = hildon_caption_new (sizegroup,
2872 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2873 gtk_widget_show (entry_password);
2874 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2875 FALSE, FALSE, MODEST_MARGIN_HALF);
2876 gtk_widget_show (caption);
2877 g_object_unref (sizegroup);
2879 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2881 #endif /* MODEST_PLATFORM_MAEMO */
2883 if (initial_username != NULL)
2884 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
2886 /* This is not in the Maemo UI spec:
2887 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2888 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2892 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2894 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2896 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2898 modest_account_mgr_set_server_account_username (
2899 modest_runtime_get_account_mgr(), server_account_name,
2902 const gboolean username_was_changed =
2903 (strcmp (*username, initial_username) != 0);
2904 if (username_was_changed) {
2905 g_warning ("%s: tinymail does not yet support changing the "
2906 "username in the get_password() callback.\n", __FUNCTION__);
2911 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2913 /* We do not save the password in the configuration,
2914 * because this function is only called for passwords that should
2915 * not be remembered:
2916 modest_server_account_set_password (
2917 modest_runtime_get_account_mgr(), server_account_name,
2926 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2938 /* This is not in the Maemo UI spec:
2939 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2945 gtk_widget_destroy (dialog);
2947 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2951 modest_ui_actions_on_cut (GtkAction *action,
2952 ModestWindow *window)
2954 GtkWidget *focused_widget;
2955 GtkClipboard *clipboard;
2957 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2958 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2959 if (GTK_IS_EDITABLE (focused_widget)) {
2960 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2961 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2962 gtk_clipboard_store (clipboard);
2963 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2964 GtkTextBuffer *buffer;
2966 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2967 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2968 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2969 gtk_clipboard_store (clipboard);
2970 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2971 TnyList *header_list = modest_header_view_get_selected_headers (
2972 MODEST_HEADER_VIEW (focused_widget));
2973 gboolean continue_download = FALSE;
2974 gint num_of_unc_msgs;
2976 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
2978 if (num_of_unc_msgs)
2979 continue_download = connect_to_get_msg(
2980 GTK_WINDOW (window),
2983 if (num_of_unc_msgs == 0 || continue_download) {
2984 /* modest_platform_information_banner (
2985 NULL, NULL, _CS("mcen_ib_getting_items"));*/
2986 modest_header_view_cut_selection (
2987 MODEST_HEADER_VIEW (focused_widget));
2990 g_object_unref (header_list);
2991 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2992 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2997 modest_ui_actions_on_copy (GtkAction *action,
2998 ModestWindow *window)
3000 GtkClipboard *clipboard;
3001 GtkWidget *focused_widget;
3002 gboolean copied = TRUE;
3004 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3005 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3007 if (GTK_IS_LABEL (focused_widget)) {
3008 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
3009 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3010 gtk_clipboard_store (clipboard);
3011 } else if (GTK_IS_EDITABLE (focused_widget)) {
3012 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3013 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3014 gtk_clipboard_store (clipboard);
3015 } else if (GTK_IS_HTML (focused_widget)) {
3016 gtk_html_copy (GTK_HTML (focused_widget));
3017 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3018 gtk_clipboard_store (clipboard);
3019 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3020 GtkTextBuffer *buffer;
3021 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3022 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3023 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3024 gtk_clipboard_store (clipboard);
3025 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3026 TnyList *header_list = modest_header_view_get_selected_headers (
3027 MODEST_HEADER_VIEW (focused_widget));
3028 gboolean continue_download = FALSE;
3029 gint num_of_unc_msgs;
3031 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3033 if (num_of_unc_msgs)
3034 continue_download = connect_to_get_msg(
3035 GTK_WINDOW (window),
3038 if (num_of_unc_msgs == 0 || continue_download) {
3039 modest_platform_information_banner (
3040 NULL, NULL, _CS("mcen_ib_getting_items"));
3041 modest_header_view_copy_selection (
3042 MODEST_HEADER_VIEW (focused_widget));
3046 g_object_unref (header_list);
3048 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3049 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3052 /* Show information banner if there was a copy to clipboard */
3054 modest_platform_information_banner (
3055 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3059 modest_ui_actions_on_undo (GtkAction *action,
3060 ModestWindow *window)
3062 ModestEmailClipboard *clipboard = NULL;
3064 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3065 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3066 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3067 /* Clear clipboard source */
3068 clipboard = modest_runtime_get_email_clipboard ();
3069 modest_email_clipboard_clear (clipboard);
3072 g_return_if_reached ();
3077 modest_ui_actions_on_redo (GtkAction *action,
3078 ModestWindow *window)
3080 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3081 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3084 g_return_if_reached ();
3090 destroy_information_note (ModestMailOperation *mail_op, gpointer user_data)
3092 /* destroy information note */
3093 gtk_widget_destroy (GTK_WIDGET(user_data));
3098 paste_as_attachment_free (gpointer data)
3100 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3102 gtk_widget_destroy (helper->banner);
3103 g_object_unref (helper->banner);
3108 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3113 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3114 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3119 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3124 modest_ui_actions_on_paste (GtkAction *action,
3125 ModestWindow *window)
3127 GtkWidget *focused_widget = NULL;
3128 GtkWidget *inf_note = NULL;
3129 ModestMailOperation *mail_op = NULL;
3131 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3132 if (GTK_IS_EDITABLE (focused_widget)) {
3133 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3134 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3135 ModestEmailClipboard *e_clipboard = NULL;
3136 e_clipboard = modest_runtime_get_email_clipboard ();
3137 if (modest_email_clipboard_cleared (e_clipboard)) {
3138 GtkTextBuffer *buffer;
3139 GtkClipboard *clipboard;
3141 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3142 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3143 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3144 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3145 ModestMailOperation *mail_op;
3146 TnyFolder *src_folder;
3149 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3150 helper->window = MODEST_MSG_EDIT_WINDOW (window);
3151 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3152 _CS("ckct_nw_pasting"));
3153 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
3154 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3156 if (helper->banner != NULL) {
3157 g_object_ref (G_OBJECT (helper->banner));
3158 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
3159 gtk_widget_show (GTK_WIDGET (helper->banner));
3163 modest_mail_operation_get_msgs_full (mail_op,
3165 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
3167 paste_as_attachment_free);
3170 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3171 ModestEmailClipboard *clipboard = NULL;
3172 TnyFolder *src_folder = NULL;
3173 TnyFolderStore *folder_store = NULL;
3174 TnyList *data = NULL;
3175 gboolean delete = FALSE;
3177 /* Check clipboard source */
3178 clipboard = modest_runtime_get_email_clipboard ();
3179 if (modest_email_clipboard_cleared (clipboard))
3182 /* Get elements to paste */
3183 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
3185 /* Create a new mail operation */
3186 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
3188 /* Get destination folder */
3189 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
3191 /* transfer messages */
3195 /* Ask for user confirmation */
3197 modest_ui_actions_msgs_move_to_confirmation (GTK_WINDOW (window),
3198 TNY_FOLDER (folder_store),
3202 if (response == GTK_RESPONSE_OK) {
3203 /* Launch notification */
3204 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3205 _CS("ckct_nw_pasting"));
3206 if (inf_note != NULL) {
3207 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3208 gtk_widget_show (GTK_WIDGET(inf_note));
3211 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3212 modest_mail_operation_xfer_msgs (mail_op,
3214 TNY_FOLDER (folder_store),
3216 destroy_information_note,
3219 g_object_unref (mail_op);
3222 } else if (src_folder != NULL) {
3223 /* Launch notification */
3224 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3225 _CS("ckct_nw_pasting"));
3226 if (inf_note != NULL) {
3227 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3228 gtk_widget_show (GTK_WIDGET(inf_note));
3231 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3232 modest_mail_operation_xfer_folder (mail_op,
3236 destroy_information_note,
3242 g_object_unref (data);
3243 if (src_folder != NULL)
3244 g_object_unref (src_folder);
3245 if (folder_store != NULL)
3246 g_object_unref (folder_store);
3252 modest_ui_actions_on_select_all (GtkAction *action,
3253 ModestWindow *window)
3255 GtkWidget *focused_widget;
3257 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3258 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3259 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3260 } else if (GTK_IS_LABEL (focused_widget)) {
3261 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3262 } else if (GTK_IS_EDITABLE (focused_widget)) {
3263 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3264 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3265 GtkTextBuffer *buffer;
3266 GtkTextIter start, end;
3268 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3269 gtk_text_buffer_get_start_iter (buffer, &start);
3270 gtk_text_buffer_get_end_iter (buffer, &end);
3271 gtk_text_buffer_select_range (buffer, &start, &end);
3272 } else if (GTK_IS_HTML (focused_widget)) {
3273 gtk_html_select_all (GTK_HTML (focused_widget));
3274 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3275 GtkWidget *header_view = focused_widget;
3276 GtkTreeSelection *selection = NULL;
3278 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
3279 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3280 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3283 /* Disable window dimming management */
3284 modest_window_disable_dimming (MODEST_WINDOW(window));
3286 /* Select all messages */
3287 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3288 gtk_tree_selection_select_all (selection);
3290 /* Set focuse on header view */
3291 gtk_widget_grab_focus (header_view);
3294 /* Enable window dimming management */
3295 modest_window_enable_dimming (MODEST_WINDOW(window));
3296 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3302 modest_ui_actions_on_mark_as_read (GtkAction *action,
3303 ModestWindow *window)
3305 g_return_if_fail (MODEST_IS_WINDOW(window));
3307 /* Mark each header as read */
3308 do_headers_action (window, headers_action_mark_as_read, NULL);
3312 modest_ui_actions_on_mark_as_unread (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_unread, NULL);
3322 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3323 GtkRadioAction *selected,
3324 ModestWindow *window)
3328 value = gtk_radio_action_get_current_value (selected);
3329 if (MODEST_IS_WINDOW (window)) {
3330 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3335 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3336 GtkRadioAction *selected,
3337 ModestWindow *window)
3339 TnyHeaderFlags flags;
3340 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3342 flags = gtk_radio_action_get_current_value (selected);
3343 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3347 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3348 GtkRadioAction *selected,
3349 ModestWindow *window)
3353 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3355 file_format = gtk_radio_action_get_current_value (selected);
3356 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3361 modest_ui_actions_on_zoom_plus (GtkAction *action,
3362 ModestWindow *window)
3364 g_return_if_fail (MODEST_IS_WINDOW (window));
3366 modest_window_zoom_plus (MODEST_WINDOW (window));
3370 modest_ui_actions_on_zoom_minus (GtkAction *action,
3371 ModestWindow *window)
3373 g_return_if_fail (MODEST_IS_WINDOW (window));
3375 modest_window_zoom_minus (MODEST_WINDOW (window));
3379 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3380 ModestWindow *window)
3382 ModestWindowMgr *mgr;
3383 gboolean fullscreen, active;
3384 g_return_if_fail (MODEST_IS_WINDOW (window));
3386 mgr = modest_runtime_get_window_mgr ();
3388 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3389 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3391 if (active != fullscreen) {
3392 modest_window_mgr_set_fullscreen_mode (mgr, active);
3393 gtk_window_present (GTK_WINDOW (window));
3398 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3399 ModestWindow *window)
3401 ModestWindowMgr *mgr;
3402 gboolean fullscreen;
3404 g_return_if_fail (MODEST_IS_WINDOW (window));
3406 mgr = modest_runtime_get_window_mgr ();
3407 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3408 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3410 gtk_window_present (GTK_WINDOW (window));
3414 * Used by modest_ui_actions_on_details to call do_headers_action
3417 headers_action_show_details (TnyHeader *header,
3418 ModestWindow *window,
3425 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3428 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3429 gtk_widget_show_all (dialog);
3430 gtk_dialog_run (GTK_DIALOG (dialog));
3432 gtk_widget_destroy (dialog);
3436 * Show the folder details in a ModestDetailsDialog widget
3439 show_folder_details (TnyFolder *folder,
3445 dialog = modest_details_dialog_new_with_folder (window, folder);
3448 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3449 gtk_widget_show_all (dialog);
3450 gtk_dialog_run (GTK_DIALOG (dialog));
3452 gtk_widget_destroy (dialog);
3456 * Show the header details in a ModestDetailsDialog widget
3459 modest_ui_actions_on_details (GtkAction *action,
3462 TnyList * headers_list;
3466 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3469 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3472 g_object_unref (msg);
3474 headers_list = get_selected_headers (win);
3478 iter = tny_list_create_iterator (headers_list);
3480 header = TNY_HEADER (tny_iterator_get_current (iter));
3482 headers_action_show_details (header, win, NULL);
3483 g_object_unref (header);
3486 g_object_unref (iter);
3487 g_object_unref (headers_list);
3489 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3490 GtkWidget *folder_view, *header_view;
3492 /* Check which widget has the focus */
3493 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3494 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3495 if (gtk_widget_is_focus (folder_view)) {
3496 TnyFolderStore *folder_store
3497 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3498 if (!folder_store) {
3499 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3502 /* Show only when it's a folder */
3503 /* This function should not be called for account items,
3504 * because we dim the menu item for them. */
3505 if (TNY_IS_FOLDER (folder_store)) {
3506 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3509 g_object_unref (folder_store);
3512 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3513 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3514 /* Show details of each header */
3515 do_headers_action (win, headers_action_show_details, header_view);
3521 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3522 ModestMsgEditWindow *window)
3524 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3526 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3530 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3531 ModestMsgEditWindow *window)
3533 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3535 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3539 modest_ui_actions_toggle_folders_view (GtkAction *action,
3540 ModestMainWindow *main_window)
3542 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3544 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3545 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3547 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3551 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3552 ModestWindow *window)
3554 gboolean active, fullscreen = FALSE;
3555 ModestWindowMgr *mgr;
3557 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3559 /* Check if we want to toggle the toolbar vuew in fullscreen
3561 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3562 "ViewShowToolbarFullScreen")) {
3566 /* Toggle toolbar */
3567 mgr = modest_runtime_get_window_mgr ();
3568 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
3572 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3573 ModestMsgEditWindow *window)
3575 modest_msg_edit_window_select_font (window);
3579 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3580 const gchar *display_name,
3583 /* Do not change the application name if the widget has not
3584 the focus. This callback could be called even if the folder
3585 view has not the focus, because the handled signal could be
3586 emitted when the folder view is redrawn */
3587 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3589 gtk_window_set_title (window, display_name);
3591 gtk_window_set_title (window, " ");
3596 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3598 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3599 modest_msg_edit_window_select_contacts (window);
3603 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3605 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3606 modest_msg_edit_window_check_names (window, FALSE);
3610 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3612 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3613 GTK_WIDGET (user_data));
3617 * This function is used to track changes in the selection of the
3618 * folder view that is inside the "move to" dialog to enable/disable
3619 * the OK button because we do not want the user to select a disallowed
3620 * destination for a folder.
3621 * The user also not desired to be able to use NEW button on items where
3622 * folder creation is not possibel.
3625 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
3626 TnyFolderStore *folder_store,
3630 GtkWidget *dialog = NULL;
3631 GtkWidget *ok_button = NULL, *new_button = NULL;
3632 GList *children = NULL;
3633 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
3634 gboolean moving_folder = FALSE;
3635 gboolean is_local_account = TRUE;
3636 GtkWidget *folder_view = NULL;
3637 ModestTnyFolderRules rules;
3642 /* Get the OK button */
3643 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
3647 children = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
3648 ok_button = GTK_WIDGET (children->next->next->data);
3649 new_button = GTK_WIDGET (children->next->data);
3650 g_list_free (children);
3652 /* check if folder_store is an remote account */
3653 if (TNY_IS_ACCOUNT (folder_store)) {
3654 TnyAccount *local_account = NULL;
3655 ModestTnyAccountStore *account_store = NULL;
3657 account_store = modest_runtime_get_account_store ();
3658 local_account = modest_tny_account_store_get_local_folders_account (account_store);
3660 if ((gpointer) local_account != (gpointer) folder_store) {
3661 is_local_account = FALSE;
3662 /* New button should be dimmed on remote
3664 new_sensitive = FALSE;
3666 g_object_unref (local_account);
3669 /* Check the target folder rules */
3670 if (TNY_IS_FOLDER (folder_store)) {
3671 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
3672 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
3673 ok_sensitive = FALSE;
3674 new_sensitive = FALSE;
3679 /* Check if we're moving a folder */
3680 if (MODEST_IS_MAIN_WINDOW (user_data)) {
3681 /* Get the widgets */
3682 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
3683 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3684 if (gtk_widget_is_focus (folder_view))
3685 moving_folder = TRUE;
3688 if (moving_folder) {
3689 TnyFolderStore *moved_folder = NULL, *parent = NULL;
3691 /* Get the folder to move */
3692 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3694 /* Check that we're not moving to the same folder */
3695 if (TNY_IS_FOLDER (moved_folder)) {
3696 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
3697 if (parent == folder_store)
3698 ok_sensitive = FALSE;
3699 g_object_unref (parent);
3702 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
3703 /* Do not allow to move to an account unless it's the
3704 local folders account */
3705 if (!is_local_account)
3706 ok_sensitive = FALSE;
3709 if (ok_sensitive && (moved_folder == folder_store)) {
3710 /* Do not allow to move to itself */
3711 ok_sensitive = FALSE;
3713 g_object_unref (moved_folder);
3715 TnyHeader *header = NULL;
3716 TnyFolder *src_folder = NULL;
3718 /* Moving a message */
3719 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
3720 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (user_data));
3721 src_folder = tny_header_get_folder (header);
3722 g_object_unref (header);
3725 TNY_FOLDER (modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view)));
3728 /* Do not allow to move the msg to the same folder */
3729 /* Do not allow to move the msg to an account */
3730 if ((gpointer) src_folder == (gpointer) folder_store ||
3731 TNY_IS_ACCOUNT (folder_store))
3732 ok_sensitive = FALSE;
3733 g_object_unref (src_folder);
3737 /* Set sensitivity of the OK button */
3738 gtk_widget_set_sensitive (ok_button, ok_sensitive);
3739 /* Set sensitivity of the NEW button */
3740 gtk_widget_set_sensitive (new_button, new_sensitive);
3744 create_move_to_dialog (GtkWindow *win,
3745 GtkWidget *folder_view,
3746 GtkWidget **tree_view)
3748 GtkWidget *dialog, *scroll;
3749 GtkWidget *new_button;
3751 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3753 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3756 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
3757 /* We do this manually so GTK+ does not associate a response ID for
3759 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
3760 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3761 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
3763 /* Create scrolled window */
3764 scroll = gtk_scrolled_window_new (NULL, NULL);
3765 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3766 GTK_POLICY_AUTOMATIC,
3767 GTK_POLICY_AUTOMATIC);
3769 /* Create folder view */
3770 *tree_view = modest_platform_create_folder_view (NULL);
3772 /* Track changes in the selection to
3773 * disable the OK button whenever "Move to" is not possible
3774 * disbale NEW button whenever New is not possible */
3775 g_signal_connect (*tree_view,
3776 "folder_selection_changed",
3777 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
3780 /* Listen to clicks on New button */
3781 g_signal_connect (G_OBJECT (new_button),
3783 G_CALLBACK(create_move_to_dialog_on_new_folder),
3786 /* It could happen that we're trying to move a message from a
3787 window (msg window for example) after the main window was
3788 closed, so we can not just get the model of the folder
3790 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
3791 const gchar *visible_id = NULL;
3793 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
3794 MODEST_FOLDER_VIEW(*tree_view));
3797 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
3799 /* Show the same account than the one that is shown in the main window */
3800 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
3803 const gchar *active_account_name = NULL;
3804 ModestAccountMgr *mgr = NULL;
3805 ModestAccountData *acc_data = NULL;
3807 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3808 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3810 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
3811 mgr = modest_runtime_get_account_mgr ();
3812 acc_data = modest_account_mgr_get_account_data (mgr, active_account_name);
3814 /* Set the new visible & active account */
3815 if (acc_data && acc_data->store_account) {
3816 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
3817 acc_data->store_account->account_name);
3818 modest_account_mgr_free_account_data (mgr, acc_data);
3822 /* Hide special folders */
3823 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3825 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3827 /* Add scroll to dialog */
3828 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3829 scroll, TRUE, TRUE, 0);
3831 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3832 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3838 * Returns TRUE if at least one of the headers of the list belongs to
3839 * a message that has been fully retrieved.
3841 #if 0 /* no longer in use. delete in 2007.10 */
3843 has_retrieved_msgs (TnyList *list)
3846 gboolean found = FALSE;
3848 iter = tny_list_create_iterator (list);
3849 while (!tny_iterator_is_done (iter) && !found) {
3851 TnyHeaderFlags flags = 0;
3853 header = TNY_HEADER (tny_iterator_get_current (iter));
3855 flags = tny_header_get_flags (header);
3856 if (flags & TNY_HEADER_FLAG_CACHED)
3857 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3860 g_object_unref (header);
3864 tny_iterator_next (iter);
3866 g_object_unref (iter);
3874 * Shows a confirmation dialog to the user when we're moving messages
3875 * from a remote server to the local storage. Returns the dialog
3876 * response. If it's other kind of movement then it always returns
3879 * This one is used by the next functions:
3880 * modest_ui_actions_on_paste - commented out
3881 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
3884 modest_ui_actions_msgs_move_to_confirmation (GtkWindow *win,
3885 TnyFolder *dest_folder,
3889 gint response = GTK_RESPONSE_OK;
3891 /* return with OK if the destination is a remote folder */
3892 if (modest_tny_folder_is_remote_folder (dest_folder))
3893 return GTK_RESPONSE_OK;
3895 TnyFolder *src_folder = NULL;
3896 TnyIterator *iter = NULL;
3897 TnyHeader *header = NULL;
3899 /* Get source folder */
3900 iter = tny_list_create_iterator (headers);
3901 header = TNY_HEADER (tny_iterator_get_current (iter));
3903 src_folder = tny_header_get_folder (header);
3904 g_object_unref (header);
3906 g_object_unref (iter);
3908 /* if no src_folder, message may be an attahcment */
3909 if (src_folder == NULL)
3910 return GTK_RESPONSE_CANCEL;
3912 /* If the source is a local or MMC folder */
3913 if (!modest_tny_folder_is_remote_folder (src_folder)) {
3914 g_object_unref (src_folder);
3915 return GTK_RESPONSE_OK;
3917 g_object_unref (src_folder);
3919 /* now if offline we ask the user */
3920 if(connect_to_get_msg( GTK_WINDOW (win),
3921 tny_list_get_length (headers)))
3922 response = GTK_RESPONSE_OK;
3924 response = GTK_RESPONSE_CANCEL;
3932 move_to_cb (ModestMailOperation *mail_op, gpointer user_data)
3934 MoveToHelper *helper = (MoveToHelper *) user_data;
3936 /* Note that the operation could have failed, in that case do
3938 if (modest_mail_operation_get_status (mail_op) ==
3939 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
3941 GObject *object = modest_mail_operation_get_source (mail_op);
3942 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
3943 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
3945 if (!modest_msg_view_window_select_next_message (self))
3946 if (!modest_msg_view_window_select_previous_message (self))
3947 /* No more messages to view, so close this window */
3948 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3949 } else if (MODEST_IS_MAIN_WINDOW (object) && helper->reference != NULL) {
3950 GtkWidget *header_view;
3952 GtkTreeSelection *sel;
3954 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
3955 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3956 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
3957 path = gtk_tree_row_reference_get_path (helper->reference);
3958 gtk_tree_selection_select_path (sel, path);
3959 gtk_tree_path_free (path);
3961 g_object_unref (object);
3964 /* Close the "Pasting" information banner */
3965 gtk_widget_destroy (GTK_WIDGET(helper->banner));
3966 if (helper->reference != NULL)
3967 gtk_tree_row_reference_free (helper->reference);
3972 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3975 ModestWindow *main_window = NULL;
3976 GtkWidget *folder_view = NULL;
3977 GObject *win = modest_mail_operation_get_source (mail_op);
3978 const GError *error = NULL;
3979 const gchar *message = NULL;
3981 /* Get error message */
3982 error = modest_mail_operation_get_error (mail_op);
3983 if (error != NULL && error->message != NULL) {
3984 message = error->message;
3986 message = _("mail_in_ui_folder_move_target_error");
3989 /* Disable next automatic folder selection */
3990 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ());
3991 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
3992 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3993 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
3995 if (user_data && TNY_IS_FOLDER (user_data)) {
3996 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3997 TNY_FOLDER (user_data), FALSE);
4000 /* Show notification dialog */
4001 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
4002 g_object_unref (win);
4006 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
4009 GObject *win = modest_mail_operation_get_source (mail_op);
4010 const GError *error = modest_mail_operation_get_error (mail_op);
4012 g_return_if_fail (error != NULL);
4013 if (error->message != NULL)
4014 g_printerr ("modest: %s\n", error->message);
4016 g_printerr ("modest: unkonw error on send&receive operation");
4018 /* Show error message */
4019 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
4020 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
4021 /* _CS("sfil_ib_unable_to_receive")); */
4023 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
4024 /* _CS("sfil_ib_unable_to_send")); */
4025 g_object_unref (win);
4029 open_msg_for_purge_cb (ModestMailOperation *mail_op,
4036 gint pending_purges = 0;
4037 gboolean some_purged = FALSE;
4038 ModestWindow *win = MODEST_WINDOW (user_data);
4039 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
4041 /* If there was any error */
4042 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
4043 modest_window_mgr_unregister_header (mgr, header);
4047 /* Once the message has been retrieved for purging, we check if
4048 * it's all ok for purging */
4050 parts = tny_simple_list_new ();
4051 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
4052 iter = tny_list_create_iterator (parts);
4054 while (!tny_iterator_is_done (iter)) {
4056 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4057 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
4058 if (tny_mime_part_is_purged (part))
4065 g_object_unref (part);
4067 tny_iterator_next (iter);
4069 g_object_unref (iter);
4072 if (pending_purges>0) {
4074 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
4076 if (response == GTK_RESPONSE_OK) {
4077 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
4078 iter = tny_list_create_iterator (parts);
4079 while (!tny_iterator_is_done (iter)) {
4082 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4083 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
4084 tny_mime_part_set_purged (part);
4087 g_object_unref (part);
4089 tny_iterator_next (iter);
4092 tny_msg_rewrite_cache (msg);
4095 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
4097 g_object_unref (iter);
4099 modest_window_mgr_unregister_header (mgr, header);
4101 g_object_unref (parts);
4105 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
4106 ModestMainWindow *win)
4108 GtkWidget *header_view;
4109 TnyList *header_list;
4112 TnyHeaderFlags flags;
4113 ModestWindow *msg_view_window = NULL;
4116 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4118 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4119 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4121 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
4123 if (tny_list_get_length (header_list) == 1) {
4124 iter = tny_list_create_iterator (header_list);
4125 header = TNY_HEADER (tny_iterator_get_current (iter));
4126 g_object_unref (iter);
4131 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
4132 header, &msg_view_window);
4133 flags = tny_header_get_flags (header);
4134 if (!(flags & TNY_HEADER_FLAG_CACHED))
4137 if (msg_view_window != NULL)
4138 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
4140 /* do nothing; uid was registered before, so window is probably on it's way */
4141 g_warning ("debug: header %p has already been registered", header);
4144 ModestMailOperation *mail_op = NULL;
4145 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
4146 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4148 modest_ui_actions_get_msgs_full_error_handler,
4150 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4151 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
4153 g_object_unref (mail_op);
4156 g_object_unref (header);
4158 g_object_unref (header_list);
4162 * Utility function that transfer messages from both the main window
4163 * and the msg view window when using the "Move to" dialog
4166 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
4169 TnyList *headers = NULL;
4170 TnyAccount *dst_account = NULL;
4171 const gchar *proto_str = NULL;
4172 gboolean dst_is_pop = FALSE;
4174 if (!TNY_IS_FOLDER (dst_folder)) {
4175 modest_platform_information_banner (GTK_WIDGET (win),
4177 _CS("ckdg_ib_unable_to_move_to_current_location"));
4181 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
4182 proto_str = tny_account_get_proto (dst_account);
4184 /* tinymail will return NULL for local folders it seems */
4185 dst_is_pop = proto_str &&
4186 (modest_protocol_info_get_transport_store_protocol (proto_str) ==
4187 MODEST_PROTOCOL_STORE_POP);
4189 g_object_unref (dst_account);
4191 /* Get selected headers */
4192 headers = get_selected_headers (MODEST_WINDOW (win));
4195 modest_platform_information_banner (GTK_WIDGET (win),
4197 ngettext("mail_in_ui_folder_move_target_error",
4198 "mail_in_ui_folder_move_targets_error",
4199 tny_list_get_length (headers)));
4200 g_object_unref (headers);
4204 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4205 helper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4206 _CS("ckct_nw_pasting"));
4207 if (helper->banner != NULL) {
4208 gtk_window_set_modal (GTK_WINDOW(helper->banner), FALSE);
4209 gtk_widget_show (GTK_WIDGET(helper->banner));
4212 if (MODEST_IS_MAIN_WINDOW (win)) {
4213 GtkWidget *header_view =
4214 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
4215 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4216 helper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
4219 ModestMailOperation *mail_op =
4220 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4222 modest_ui_actions_move_folder_error_handler,
4224 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4227 modest_mail_operation_xfer_msgs (mail_op,
4229 TNY_FOLDER (dst_folder),
4234 g_object_unref (G_OBJECT (mail_op));
4235 g_object_unref (headers);
4239 * UI handler for the "Move to" action when invoked from the
4243 modest_ui_actions_on_main_window_move_to (GtkAction *action,
4244 GtkWidget *folder_view,
4245 TnyFolderStore *dst_folder,
4246 ModestMainWindow *win)
4248 ModestHeaderView *header_view = NULL;
4249 ModestMailOperation *mail_op = NULL;
4250 TnyFolderStore *src_folder;
4251 gboolean online = (tny_device_is_online (modest_runtime_get_device()));
4253 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4255 /* Get the source folder */
4256 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4258 /* Get header view */
4259 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
4261 /* Get folder or messages to transfer */
4262 if (gtk_widget_is_focus (folder_view)) {
4263 GtkTreeSelection *sel;
4264 gboolean do_xfer = TRUE;
4266 /* Allow only to transfer folders to the local root folder */
4267 if (TNY_IS_ACCOUNT (dst_folder) &&
4268 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder)) {
4270 } else if (!TNY_IS_FOLDER (src_folder)) {
4271 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
4273 } else if (!online && modest_platform_is_network_folderstore(src_folder)) {
4274 guint num_headers = tny_folder_get_all_count(TNY_FOLDER(src_folder));
4275 if (!connect_to_get_msg(GTK_WINDOW(win), num_headers)) {
4281 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4282 helper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4283 _CS("ckct_nw_pasting"));
4284 if (helper->banner != NULL) {
4285 gtk_window_set_modal (GTK_WINDOW(helper->banner), FALSE);
4286 gtk_widget_show (GTK_WIDGET(helper->banner));
4288 /* Clean folder on header view before moving it */
4289 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
4290 gtk_tree_selection_unselect_all (sel);
4293 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4295 modest_ui_actions_move_folder_error_handler,
4297 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4300 /* Select *after* the changes */
4301 /* TODO: this function hangs UI after transfer */
4302 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
4303 /* TNY_FOLDER (src_folder), TRUE); */
4305 modest_mail_operation_xfer_folder (mail_op,
4306 TNY_FOLDER (src_folder),
4311 /* Unref mail operation */
4312 g_object_unref (G_OBJECT (mail_op));
4314 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
4315 gboolean do_xfer = TRUE;
4316 /* Ask for confirmation if the source folder is remote and we're not connected */
4317 if (!online && modest_platform_is_network_folderstore(src_folder)) {
4318 TnyList *headers = modest_header_view_get_selected_headers(header_view);
4319 if (!msgs_already_deleted_from_server(headers, src_folder)) {
4320 guint num_headers = tny_list_get_length(headers);
4321 if (!connect_to_get_msg(GTK_WINDOW(win), num_headers)) {
4325 g_object_unref(headers);
4327 if (do_xfer) /* Transfer messages */
4328 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4332 g_object_unref (src_folder);
4337 * UI handler for the "Move to" action when invoked from the
4338 * ModestMsgViewWindow
4341 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
4342 TnyFolderStore *dst_folder,
4343 ModestMsgViewWindow *win)
4345 TnyHeader *header = NULL;
4346 TnyFolderStore *src_folder;
4348 /* Create header list */
4349 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
4350 src_folder = TNY_FOLDER_STORE(tny_header_get_folder(header));
4351 g_object_unref (header);
4353 /* Transfer the message if online or confirmed by the user */
4354 if (tny_device_is_online (modest_runtime_get_device()) || remote_folder_is_pop(src_folder) ||
4355 (modest_platform_is_network_folderstore(src_folder) && connect_to_get_msg(GTK_WINDOW(win), 1))) {
4356 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4359 g_object_unref (src_folder);
4363 modest_ui_actions_on_move_to (GtkAction *action,
4366 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
4368 TnyFolderStore *dst_folder = NULL;
4369 ModestMainWindow *main_window;
4371 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
4372 MODEST_IS_MSG_VIEW_WINDOW (win));
4374 /* Get the main window if exists */
4375 if (MODEST_IS_MAIN_WINDOW (win))
4376 main_window = MODEST_MAIN_WINDOW (win);
4379 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
4381 /* Get the folder view widget if exists */
4383 folder_view = modest_main_window_get_child_widget (main_window,
4384 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4388 /* Create and run the dialog */
4389 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
4390 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
4391 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4392 result = gtk_dialog_run (GTK_DIALOG(dialog));
4393 g_object_ref (tree_view);
4394 gtk_widget_destroy (dialog);
4396 if (result != GTK_RESPONSE_ACCEPT)
4399 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
4400 /* Do window specific stuff */
4401 if (MODEST_IS_MAIN_WINDOW (win)) {
4402 modest_ui_actions_on_main_window_move_to (action,
4405 MODEST_MAIN_WINDOW (win));
4407 modest_ui_actions_on_msg_view_window_move_to (action,
4409 MODEST_MSG_VIEW_WINDOW (win));
4413 g_object_unref (dst_folder);
4417 * Calls #HeadersFunc for each header already selected in the main
4418 * window or the message currently being shown in the msg view window
4421 do_headers_action (ModestWindow *win,
4425 TnyList *headers_list = NULL;
4426 TnyIterator *iter = NULL;
4427 TnyHeader *header = NULL;
4428 TnyFolder *folder = NULL;
4431 headers_list = get_selected_headers (win);
4435 /* Get the folder */
4436 iter = tny_list_create_iterator (headers_list);
4437 header = TNY_HEADER (tny_iterator_get_current (iter));
4439 folder = tny_header_get_folder (header);
4440 g_object_unref (header);
4443 /* Call the function for each header */
4444 while (!tny_iterator_is_done (iter)) {
4445 header = TNY_HEADER (tny_iterator_get_current (iter));
4446 func (header, win, user_data);
4447 g_object_unref (header);
4448 tny_iterator_next (iter);
4451 /* Trick: do a poke status in order to speed up the signaling
4453 tny_folder_poke_status (folder);
4456 g_object_unref (folder);
4457 g_object_unref (iter);
4458 g_object_unref (headers_list);
4462 modest_ui_actions_view_attachment (GtkAction *action,
4463 ModestWindow *window)
4465 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4466 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4468 /* not supported window for this action */
4469 g_return_if_reached ();
4474 modest_ui_actions_save_attachments (GtkAction *action,
4475 ModestWindow *window)
4477 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4478 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4480 /* not supported window for this action */
4481 g_return_if_reached ();
4486 modest_ui_actions_remove_attachments (GtkAction *action,
4487 ModestWindow *window)
4489 if (MODEST_IS_MAIN_WINDOW (window)) {
4490 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4491 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4492 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4494 /* not supported window for this action */
4495 g_return_if_reached ();
4500 modest_ui_actions_on_settings (GtkAction *action,
4505 dialog = modest_platform_get_global_settings_dialog ();
4506 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4507 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4508 gtk_widget_show_all (dialog);
4510 gtk_dialog_run (GTK_DIALOG (dialog));
4512 gtk_widget_destroy (dialog);
4516 modest_ui_actions_on_help (GtkAction *action,
4519 const gchar *help_id = NULL;
4521 if (MODEST_IS_MAIN_WINDOW (win)) {
4522 GtkWidget *folder_view;
4523 TnyFolderStore *folder_store;
4525 /* Get selected folder */
4526 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4527 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4528 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4530 /* Switch help_id */
4531 if (TNY_IS_FOLDER (folder_store)) {
4532 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4533 case TNY_FOLDER_TYPE_NORMAL:
4534 help_id = "applications_email_managefolders";
4536 case TNY_FOLDER_TYPE_INBOX:
4537 help_id = "applications_email_inbox";
4539 case TNY_FOLDER_TYPE_OUTBOX:
4540 help_id = "applications_email_outbox";
4542 case TNY_FOLDER_TYPE_SENT:
4543 help_id = "applications_email_sent";
4545 case TNY_FOLDER_TYPE_DRAFTS:
4546 help_id = "applications_email_drafts";
4548 case TNY_FOLDER_TYPE_ARCHIVE:
4549 help_id = "applications_email_managefolders";
4552 help_id = "applications_email_managefolders";
4555 help_id = "applications_email_mainview";
4557 g_object_unref (folder_store);
4558 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4559 help_id = "applications_email_viewer";
4560 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4561 help_id = "applications_email_editor";
4563 modest_platform_show_help (GTK_WINDOW (win), help_id);
4567 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4568 ModestWindow *window)
4570 ModestMailOperation *mail_op;
4574 headers = get_selected_headers (window);
4578 /* Create mail operation */
4579 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4581 modest_ui_actions_get_msgs_full_error_handler,
4583 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4584 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4587 g_object_unref (headers);
4588 g_object_unref (mail_op);
4592 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4593 ModestWindow *window)
4595 g_return_if_fail (MODEST_IS_WINDOW (window));
4598 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4602 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4603 ModestWindow *window)
4605 g_return_if_fail (MODEST_IS_WINDOW (window));
4608 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4612 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4613 ModestWindow *window)
4615 g_return_if_fail (MODEST_IS_WINDOW (window));
4618 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4622 modest_ui_actions_on_format_menu_activated (GtkAction *action,
4623 ModestWindow *window)
4625 g_return_if_fail (MODEST_IS_WINDOW (window));
4628 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4632 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4633 ModestWindow *window)
4635 g_return_if_fail (MODEST_IS_WINDOW (window));
4638 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4642 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4643 ModestWindow *window)
4645 g_return_if_fail (MODEST_IS_WINDOW (window));
4648 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4652 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4653 ModestWindow *window)
4655 g_return_if_fail (MODEST_IS_WINDOW (window));
4658 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4662 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4663 ModestWindow *window)
4665 g_return_if_fail (MODEST_IS_WINDOW (window));
4668 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4672 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4673 ModestWindow *window)
4675 g_return_if_fail (MODEST_IS_WINDOW (window));
4678 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4682 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4684 g_return_if_fail (MODEST_IS_WINDOW (window));
4687 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4691 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4693 g_return_if_fail (MODEST_IS_WINDOW (window));
4695 modest_platform_show_search_messages (GTK_WINDOW (window));
4699 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4701 g_return_if_fail (MODEST_IS_WINDOW (win));
4702 modest_platform_show_addressbook (GTK_WINDOW (win));
4707 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4708 ModestWindow *window)
4710 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4712 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4716 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
4717 ModestMailOperationState *state,
4720 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4722 /* Set send/receive operation finished */
4723 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4724 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));
4730 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
4736 const gchar* server_name = NULL;
4737 TnyTransportAccount *server_account;
4738 gchar *message = NULL;
4740 /* Don't show anything if the user cancelled something */
4741 if (err->code == TNY_TRANSPORT_ACCOUNT_ERROR_SEND_USER_CANCEL)
4744 /* Get the server name: */
4746 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
4747 if (server_account) {
4748 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
4750 g_object_unref (server_account);
4751 server_account = NULL;
4754 g_return_if_fail (server_name);
4756 /* Show the appropriate message text for the GError: */
4757 switch (err->code) {
4758 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_HOST_LOOKUP_FAILED:
4759 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4761 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_SERVICE_UNAVAILABLE:
4762 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4764 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_AUTHENTICATION_NOT_SUPPORTED:
4765 message = g_strdup_printf (_("emev_ni_ui_smtp_authentication_fail_error"), server_name);
4767 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND:
4768 message = g_strdup (_("emev_ib_ui_smtp_send_error"));
4771 g_return_if_reached ();
4774 /* TODO if the username or the password where not defined we
4775 should show the Accounts Settings dialog or the Connection
4776 specific SMTP server window */
4778 modest_platform_run_information_dialog (NULL, message);
4783 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
4788 ModestMainWindow *main_window = NULL;
4789 ModestWindowMgr *mgr = NULL;
4790 GtkWidget *folder_view = NULL, *header_view = NULL;
4791 TnyFolderStore *selected_folder = NULL;
4792 TnyFolderType folder_type;
4794 mgr = modest_runtime_get_window_mgr ();
4795 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr));
4800 /* Check if selected folder is OUTBOX */
4801 folder_view = modest_main_window_get_child_widget (main_window,
4802 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4803 header_view = modest_main_window_get_child_widget (main_window,
4804 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4806 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4807 if (!TNY_IS_FOLDER (selected_folder))
4810 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
4811 #if GTK_CHECK_VERSION(2, 8, 0)
4812 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
4813 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
4814 GtkTreeViewColumn *tree_column;
4816 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
4817 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
4818 gtk_tree_view_column_queue_resize (tree_column);
4821 gtk_widget_queue_draw (header_view);
4826 if (selected_folder != NULL)
4827 g_object_unref (selected_folder);