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,
2197 data->priority_flags);
2200 g_free (account_name);
2201 g_object_unref (G_OBJECT (transport_account));
2202 g_object_unref (G_OBJECT (mail_operation));
2204 modest_msg_edit_window_free_msg_data (edit_window, data);
2206 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2207 modest_platform_information_banner (NULL, NULL, info_text);
2208 modest_msg_edit_window_reset_modified (edit_window);
2212 /* For instance, when clicking the Send toolbar button when editing a message: */
2214 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2216 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2218 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2221 /* Offer the connection dialog, if necessary: */
2222 if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
2225 /* FIXME: Code added just for testing. The final version will
2226 use the send queue provided by tinymail and some
2228 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2229 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2231 account_name = modest_account_mgr_get_default_account (account_mgr);
2233 if (!account_name) {
2234 /* Run account setup wizard */
2235 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2240 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2242 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2243 account_name = g_strdup (data->account_name);
2246 /* Get the currently-active transport account for this modest account: */
2247 TnyTransportAccount *transport_account =
2248 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2249 (modest_runtime_get_account_store(),
2251 if (!transport_account) {
2252 /* Run account setup wizard */
2253 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2258 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2260 /* Create the mail operation */
2261 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
2262 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2264 modest_mail_operation_send_new_mail (mail_operation,
2275 data->priority_flags);
2279 g_free (account_name);
2280 g_object_unref (G_OBJECT (transport_account));
2281 g_object_unref (G_OBJECT (mail_operation));
2283 modest_msg_edit_window_free_msg_data (edit_window, data);
2284 modest_msg_edit_window_set_sent (edit_window, TRUE);
2286 /* Save settings and close the window: */
2287 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2291 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2292 ModestMsgEditWindow *window)
2294 ModestMsgEditFormatState *format_state = NULL;
2296 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2297 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2299 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2302 format_state = modest_msg_edit_window_get_format_state (window);
2303 g_return_if_fail (format_state != NULL);
2305 format_state->bold = gtk_toggle_action_get_active (action);
2306 modest_msg_edit_window_set_format_state (window, format_state);
2307 g_free (format_state);
2312 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2313 ModestMsgEditWindow *window)
2315 ModestMsgEditFormatState *format_state = NULL;
2317 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2318 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2320 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2323 format_state = modest_msg_edit_window_get_format_state (window);
2324 g_return_if_fail (format_state != NULL);
2326 format_state->italics = gtk_toggle_action_get_active (action);
2327 modest_msg_edit_window_set_format_state (window, format_state);
2328 g_free (format_state);
2333 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2334 ModestMsgEditWindow *window)
2336 ModestMsgEditFormatState *format_state = NULL;
2338 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2339 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2341 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2344 format_state = modest_msg_edit_window_get_format_state (window);
2345 g_return_if_fail (format_state != NULL);
2347 format_state->bullet = gtk_toggle_action_get_active (action);
2348 modest_msg_edit_window_set_format_state (window, format_state);
2349 g_free (format_state);
2354 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2355 GtkRadioAction *selected,
2356 ModestMsgEditWindow *window)
2358 ModestMsgEditFormatState *format_state = NULL;
2359 GtkJustification value;
2361 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2363 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2366 value = gtk_radio_action_get_current_value (selected);
2368 format_state = modest_msg_edit_window_get_format_state (window);
2369 g_return_if_fail (format_state != NULL);
2371 format_state->justification = value;
2372 modest_msg_edit_window_set_format_state (window, format_state);
2373 g_free (format_state);
2377 modest_ui_actions_on_select_editor_color (GtkAction *action,
2378 ModestMsgEditWindow *window)
2380 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2381 g_return_if_fail (GTK_IS_ACTION (action));
2383 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2386 modest_msg_edit_window_select_color (window);
2390 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2391 ModestMsgEditWindow *window)
2393 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2394 g_return_if_fail (GTK_IS_ACTION (action));
2396 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2399 modest_msg_edit_window_select_background_color (window);
2403 modest_ui_actions_on_insert_image (GtkAction *action,
2404 ModestMsgEditWindow *window)
2406 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2407 g_return_if_fail (GTK_IS_ACTION (action));
2409 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2412 modest_msg_edit_window_insert_image (window);
2416 modest_ui_actions_on_attach_file (GtkAction *action,
2417 ModestMsgEditWindow *window)
2419 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2420 g_return_if_fail (GTK_IS_ACTION (action));
2422 modest_msg_edit_window_offer_attach_file (window);
2426 modest_ui_actions_on_remove_attachments (GtkAction *action,
2427 ModestMsgEditWindow *window)
2429 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2430 g_return_if_fail (GTK_IS_ACTION (action));
2432 modest_msg_edit_window_remove_attachments (window, NULL);
2436 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2439 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2440 const GError *error = modest_mail_operation_get_error (mail_op);
2443 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2444 _("mail_in_ui_folder_create_error"));
2449 modest_ui_actions_create_folder(GtkWidget *parent_window,
2450 GtkWidget *folder_view)
2452 TnyFolderStore *parent_folder;
2454 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2456 if (parent_folder) {
2457 gboolean finished = FALSE;
2459 gchar *folder_name = NULL, *suggested_name = NULL;
2460 const gchar *proto_str = NULL;
2461 TnyAccount *account;
2463 if (TNY_IS_ACCOUNT (parent_folder))
2464 account = g_object_ref (parent_folder);
2466 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2467 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2469 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2470 MODEST_PROTOCOL_STORE_POP) {
2472 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2474 g_object_unref (account);
2476 /* Run the new folder dialog */
2478 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2483 g_free (suggested_name);
2484 suggested_name = NULL;
2486 if (result == GTK_RESPONSE_REJECT) {
2489 ModestMailOperation *mail_op;
2490 TnyFolder *new_folder = NULL;
2492 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2493 G_OBJECT(parent_window),
2494 modest_ui_actions_new_folder_error_handler,
2497 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2499 new_folder = modest_mail_operation_create_folder (mail_op,
2501 (const gchar *) folder_name);
2503 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2506 g_object_unref (new_folder);
2509 g_object_unref (mail_op);
2512 suggested_name = folder_name;
2516 g_object_unref (parent_folder);
2521 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2523 GtkWidget *folder_view;
2525 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2527 folder_view = modest_main_window_get_child_widget (main_window,
2528 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2532 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2536 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2539 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2540 const GError *error = NULL;
2541 const gchar *message = NULL;
2543 /* Get error message */
2544 error = modest_mail_operation_get_error (mail_op);
2546 g_return_if_reached ();
2548 switch (error->code) {
2549 case MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS:
2550 message = _CS("ckdg_ib_folder_already_exists");
2553 g_return_if_reached ();
2556 modest_platform_information_banner (GTK_WIDGET (window), NULL, message);
2560 modest_ui_actions_on_rename_folder (GtkAction *action,
2561 ModestMainWindow *main_window)
2563 TnyFolderStore *folder;
2564 GtkWidget *folder_view;
2565 GtkWidget *header_view;
2567 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2569 folder_view = modest_main_window_get_child_widget (main_window,
2570 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2574 header_view = modest_main_window_get_child_widget (main_window,
2575 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2580 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2585 if (TNY_IS_FOLDER (folder)) {
2588 const gchar *current_name;
2589 TnyFolderStore *parent;
2590 gboolean do_rename = TRUE;
2592 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2593 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
2594 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
2595 parent, current_name,
2597 g_object_unref (parent);
2599 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
2601 } else if (modest_platform_is_network_folderstore(folder) &&
2602 !tny_device_is_online (modest_runtime_get_device())) {
2603 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2604 do_rename = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2605 g_object_unref(account);
2609 ModestMailOperation *mail_op;
2610 GtkTreeSelection *sel = NULL;
2613 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2614 G_OBJECT(main_window),
2615 modest_ui_actions_rename_folder_error_handler,
2618 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2621 /* Clear the headers view */
2622 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2623 gtk_tree_selection_unselect_all (sel);
2625 /* Select *after* the changes */
2626 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2627 TNY_FOLDER(folder), TRUE);
2629 /* Actually rename the folder */
2630 modest_mail_operation_rename_folder (mail_op,
2631 TNY_FOLDER (folder),
2632 (const gchar *) folder_name);
2634 g_object_unref (mail_op);
2635 g_free (folder_name);
2638 g_object_unref (folder);
2642 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2645 GObject *win = modest_mail_operation_get_source (mail_op);
2647 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2648 _("mail_in_ui_folder_delete_error"));
2649 g_object_unref (win);
2653 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2655 TnyFolderStore *folder;
2656 GtkWidget *folder_view;
2659 gboolean do_delete = TRUE;
2661 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (main_window), FALSE);
2663 folder_view = modest_main_window_get_child_widget (main_window,
2664 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2668 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2670 /* Show an error if it's an account */
2671 if (!TNY_IS_FOLDER (folder)) {
2672 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2673 _("mail_in_ui_folder_delete_error"));
2674 g_object_unref (G_OBJECT (folder));
2679 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2680 tny_folder_get_name (TNY_FOLDER (folder)));
2681 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2682 (const gchar *) message);
2685 if (response != GTK_RESPONSE_OK) {
2687 } else if (modest_platform_is_network_folderstore(folder) &&
2688 !tny_device_is_online (modest_runtime_get_device())) {
2689 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2690 do_delete = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2691 g_object_unref(account);
2695 ModestMailOperation *mail_op;
2696 GtkTreeSelection *sel;
2698 /* Unselect the folder before deleting it to free the headers */
2699 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2700 gtk_tree_selection_unselect_all (sel);
2702 /* Create the mail operation */
2704 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2705 G_OBJECT(main_window),
2706 modest_ui_actions_delete_folder_error_handler,
2709 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2711 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2712 g_object_unref (G_OBJECT (mail_op));
2715 g_object_unref (G_OBJECT (folder));
2721 modest_ui_actions_on_delete_folder (GtkAction *action,
2722 ModestMainWindow *main_window)
2724 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2726 if (delete_folder (main_window, FALSE)) {
2727 GtkWidget *folder_view;
2729 folder_view = modest_main_window_get_child_widget (main_window,
2730 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2731 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2736 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2738 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2740 delete_folder (main_window, TRUE);
2745 show_error (GtkWidget *parent_widget, const gchar* text)
2747 hildon_banner_show_information(parent_widget, NULL, text);
2750 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2752 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2759 gtk_dialog_run (dialog);
2760 gtk_widget_destroy (GTK_WIDGET (dialog));
2765 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2766 const gchar* server_account_name,
2771 ModestMainWindow *main_window)
2773 g_return_if_fail(server_account_name);
2774 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2776 /* Initalize output parameters: */
2783 #ifdef MODEST_PLATFORM_MAEMO
2784 /* Maemo uses a different (awkward) button order,
2785 * It should probably just use gtk_alternative_dialog_button_order ().
2787 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2790 _("mcen_bd_dialog_ok"),
2791 GTK_RESPONSE_ACCEPT,
2792 _("mcen_bd_dialog_cancel"),
2793 GTK_RESPONSE_REJECT,
2796 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2800 GTK_RESPONSE_REJECT,
2802 GTK_RESPONSE_ACCEPT,
2804 #endif /* MODEST_PLATFORM_MAEMO */
2806 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2808 gchar *server_name = modest_account_mgr_get_server_account_hostname (
2809 modest_runtime_get_account_mgr(), server_account_name);
2810 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2811 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2816 /* This causes a warning because the logical ID has no %s in it,
2817 * though the translation does, but there is not much we can do about that: */
2818 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2819 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2822 g_free (server_name);
2826 gchar *initial_username = modest_account_mgr_get_server_account_username (
2827 modest_runtime_get_account_mgr(), server_account_name);
2829 GtkWidget *entry_username = gtk_entry_new ();
2830 if (initial_username)
2831 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2832 /* Dim this if a connection has ever succeeded with this username,
2833 * as per the UI spec: */
2834 const gboolean username_known =
2835 modest_account_mgr_get_server_account_username_has_succeeded(
2836 modest_runtime_get_account_mgr(), server_account_name);
2837 gtk_widget_set_sensitive (entry_username, !username_known);
2839 #ifdef MODEST_PLATFORM_MAEMO
2840 /* Auto-capitalization is the default, so let's turn it off: */
2841 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2843 /* Create a size group to be used by all captions.
2844 * Note that HildonCaption does not create a default size group if we do not specify one.
2845 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2846 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2848 GtkWidget *caption = hildon_caption_new (sizegroup,
2849 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2850 gtk_widget_show (entry_username);
2851 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2852 FALSE, FALSE, MODEST_MARGIN_HALF);
2853 gtk_widget_show (caption);
2855 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2857 #endif /* MODEST_PLATFORM_MAEMO */
2860 GtkWidget *entry_password = gtk_entry_new ();
2861 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2862 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2864 #ifdef MODEST_PLATFORM_MAEMO
2865 /* Auto-capitalization is the default, so let's turn it off: */
2866 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2867 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2869 caption = hildon_caption_new (sizegroup,
2870 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2871 gtk_widget_show (entry_password);
2872 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2873 FALSE, FALSE, MODEST_MARGIN_HALF);
2874 gtk_widget_show (caption);
2875 g_object_unref (sizegroup);
2877 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2879 #endif /* MODEST_PLATFORM_MAEMO */
2881 if (initial_username != NULL)
2882 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
2884 /* This is not in the Maemo UI spec:
2885 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2886 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2890 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2892 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2894 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2896 modest_account_mgr_set_server_account_username (
2897 modest_runtime_get_account_mgr(), server_account_name,
2900 const gboolean username_was_changed =
2901 (strcmp (*username, initial_username) != 0);
2902 if (username_was_changed) {
2903 g_warning ("%s: tinymail does not yet support changing the "
2904 "username in the get_password() callback.\n", __FUNCTION__);
2909 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2911 /* We do not save the password in the configuration,
2912 * because this function is only called for passwords that should
2913 * not be remembered:
2914 modest_server_account_set_password (
2915 modest_runtime_get_account_mgr(), server_account_name,
2924 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2936 /* This is not in the Maemo UI spec:
2937 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2943 gtk_widget_destroy (dialog);
2945 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2949 modest_ui_actions_on_cut (GtkAction *action,
2950 ModestWindow *window)
2952 GtkWidget *focused_widget;
2953 GtkClipboard *clipboard;
2955 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2956 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2957 if (GTK_IS_EDITABLE (focused_widget)) {
2958 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2959 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2960 gtk_clipboard_store (clipboard);
2961 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2962 GtkTextBuffer *buffer;
2964 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2965 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2966 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2967 gtk_clipboard_store (clipboard);
2968 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2969 TnyList *header_list = modest_header_view_get_selected_headers (
2970 MODEST_HEADER_VIEW (focused_widget));
2971 gboolean continue_download = FALSE;
2972 gint num_of_unc_msgs;
2974 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
2976 if (num_of_unc_msgs)
2977 continue_download = connect_to_get_msg(
2978 GTK_WINDOW (window),
2981 if (num_of_unc_msgs == 0 || continue_download) {
2982 /* modest_platform_information_banner (
2983 NULL, NULL, _CS("mcen_ib_getting_items"));*/
2984 modest_header_view_cut_selection (
2985 MODEST_HEADER_VIEW (focused_widget));
2988 g_object_unref (header_list);
2989 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2990 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2995 modest_ui_actions_on_copy (GtkAction *action,
2996 ModestWindow *window)
2998 GtkClipboard *clipboard;
2999 GtkWidget *focused_widget;
3000 gboolean copied = TRUE;
3002 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3003 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3005 if (GTK_IS_LABEL (focused_widget)) {
3006 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
3007 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3008 gtk_clipboard_store (clipboard);
3009 } else if (GTK_IS_EDITABLE (focused_widget)) {
3010 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3011 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3012 gtk_clipboard_store (clipboard);
3013 } else if (GTK_IS_HTML (focused_widget)) {
3014 gtk_html_copy (GTK_HTML (focused_widget));
3015 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3016 gtk_clipboard_store (clipboard);
3017 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3018 GtkTextBuffer *buffer;
3019 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3020 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3021 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3022 gtk_clipboard_store (clipboard);
3023 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3024 TnyList *header_list = modest_header_view_get_selected_headers (
3025 MODEST_HEADER_VIEW (focused_widget));
3026 gboolean continue_download = FALSE;
3027 gint num_of_unc_msgs;
3029 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3031 if (num_of_unc_msgs)
3032 continue_download = connect_to_get_msg(
3033 GTK_WINDOW (window),
3036 if (num_of_unc_msgs == 0 || continue_download) {
3037 modest_platform_information_banner (
3038 NULL, NULL, _CS("mcen_ib_getting_items"));
3039 modest_header_view_copy_selection (
3040 MODEST_HEADER_VIEW (focused_widget));
3044 g_object_unref (header_list);
3046 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3047 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3050 /* Show information banner if there was a copy to clipboard */
3052 modest_platform_information_banner (
3053 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3057 modest_ui_actions_on_undo (GtkAction *action,
3058 ModestWindow *window)
3060 ModestEmailClipboard *clipboard = NULL;
3062 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3063 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3064 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3065 /* Clear clipboard source */
3066 clipboard = modest_runtime_get_email_clipboard ();
3067 modest_email_clipboard_clear (clipboard);
3070 g_return_if_reached ();
3075 modest_ui_actions_on_redo (GtkAction *action,
3076 ModestWindow *window)
3078 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3079 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3082 g_return_if_reached ();
3088 destroy_information_note (ModestMailOperation *mail_op, gpointer user_data)
3090 /* destroy information note */
3091 gtk_widget_destroy (GTK_WIDGET(user_data));
3096 paste_as_attachment_free (gpointer data)
3098 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3100 gtk_widget_destroy (helper->banner);
3101 g_object_unref (helper->banner);
3106 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3111 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3112 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3117 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3122 modest_ui_actions_on_paste (GtkAction *action,
3123 ModestWindow *window)
3125 GtkWidget *focused_widget = NULL;
3126 GtkWidget *inf_note = NULL;
3127 ModestMailOperation *mail_op = NULL;
3129 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3130 if (GTK_IS_EDITABLE (focused_widget)) {
3131 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3132 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3133 ModestEmailClipboard *e_clipboard = NULL;
3134 e_clipboard = modest_runtime_get_email_clipboard ();
3135 if (modest_email_clipboard_cleared (e_clipboard)) {
3136 GtkTextBuffer *buffer;
3137 GtkClipboard *clipboard;
3139 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3140 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3141 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3142 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3143 ModestMailOperation *mail_op;
3144 TnyFolder *src_folder;
3147 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3148 helper->window = MODEST_MSG_EDIT_WINDOW (window);
3149 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3150 _CS("ckct_nw_pasting"));
3151 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
3152 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3154 if (helper->banner != NULL) {
3155 g_object_ref (G_OBJECT (helper->banner));
3156 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
3157 gtk_widget_show (GTK_WIDGET (helper->banner));
3161 modest_mail_operation_get_msgs_full (mail_op,
3163 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
3165 paste_as_attachment_free);
3168 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3169 ModestEmailClipboard *clipboard = NULL;
3170 TnyFolder *src_folder = NULL;
3171 TnyFolderStore *folder_store = NULL;
3172 TnyList *data = NULL;
3173 gboolean delete = FALSE;
3175 /* Check clipboard source */
3176 clipboard = modest_runtime_get_email_clipboard ();
3177 if (modest_email_clipboard_cleared (clipboard))
3180 /* Get elements to paste */
3181 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
3183 /* Create a new mail operation */
3184 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
3186 /* Get destination folder */
3187 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
3189 /* transfer messages */
3193 /* Ask for user confirmation */
3195 modest_ui_actions_msgs_move_to_confirmation (GTK_WINDOW (window),
3196 TNY_FOLDER (folder_store),
3200 if (response == GTK_RESPONSE_OK) {
3201 /* Launch notification */
3202 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3203 _CS("ckct_nw_pasting"));
3204 if (inf_note != NULL) {
3205 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3206 gtk_widget_show (GTK_WIDGET(inf_note));
3209 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3210 modest_mail_operation_xfer_msgs (mail_op,
3212 TNY_FOLDER (folder_store),
3214 destroy_information_note,
3217 g_object_unref (mail_op);
3220 } else if (src_folder != NULL) {
3221 /* Launch notification */
3222 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3223 _CS("ckct_nw_pasting"));
3224 if (inf_note != NULL) {
3225 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3226 gtk_widget_show (GTK_WIDGET(inf_note));
3229 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3230 modest_mail_operation_xfer_folder (mail_op,
3234 destroy_information_note,
3240 g_object_unref (data);
3241 if (src_folder != NULL)
3242 g_object_unref (src_folder);
3243 if (folder_store != NULL)
3244 g_object_unref (folder_store);
3250 modest_ui_actions_on_select_all (GtkAction *action,
3251 ModestWindow *window)
3253 GtkWidget *focused_widget;
3255 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3256 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3257 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3258 } else if (GTK_IS_LABEL (focused_widget)) {
3259 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3260 } else if (GTK_IS_EDITABLE (focused_widget)) {
3261 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3262 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3263 GtkTextBuffer *buffer;
3264 GtkTextIter start, end;
3266 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3267 gtk_text_buffer_get_start_iter (buffer, &start);
3268 gtk_text_buffer_get_end_iter (buffer, &end);
3269 gtk_text_buffer_select_range (buffer, &start, &end);
3270 } else if (GTK_IS_HTML (focused_widget)) {
3271 gtk_html_select_all (GTK_HTML (focused_widget));
3272 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3273 GtkWidget *header_view = focused_widget;
3274 GtkTreeSelection *selection = NULL;
3276 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
3277 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3278 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3281 /* Disable window dimming management */
3282 modest_window_disable_dimming (MODEST_WINDOW(window));
3284 /* Select all messages */
3285 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3286 gtk_tree_selection_select_all (selection);
3288 /* Set focuse on header view */
3289 gtk_widget_grab_focus (header_view);
3292 /* Enable window dimming management */
3293 modest_window_enable_dimming (MODEST_WINDOW(window));
3294 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3300 modest_ui_actions_on_mark_as_read (GtkAction *action,
3301 ModestWindow *window)
3303 g_return_if_fail (MODEST_IS_WINDOW(window));
3305 /* Mark each header as read */
3306 do_headers_action (window, headers_action_mark_as_read, NULL);
3310 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3311 ModestWindow *window)
3313 g_return_if_fail (MODEST_IS_WINDOW(window));
3315 /* Mark each header as read */
3316 do_headers_action (window, headers_action_mark_as_unread, NULL);
3320 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3321 GtkRadioAction *selected,
3322 ModestWindow *window)
3326 value = gtk_radio_action_get_current_value (selected);
3327 if (MODEST_IS_WINDOW (window)) {
3328 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3333 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3334 GtkRadioAction *selected,
3335 ModestWindow *window)
3337 TnyHeaderFlags flags;
3338 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3340 flags = gtk_radio_action_get_current_value (selected);
3341 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3345 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3346 GtkRadioAction *selected,
3347 ModestWindow *window)
3351 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3353 file_format = gtk_radio_action_get_current_value (selected);
3354 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3359 modest_ui_actions_on_zoom_plus (GtkAction *action,
3360 ModestWindow *window)
3362 g_return_if_fail (MODEST_IS_WINDOW (window));
3364 modest_window_zoom_plus (MODEST_WINDOW (window));
3368 modest_ui_actions_on_zoom_minus (GtkAction *action,
3369 ModestWindow *window)
3371 g_return_if_fail (MODEST_IS_WINDOW (window));
3373 modest_window_zoom_minus (MODEST_WINDOW (window));
3377 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3378 ModestWindow *window)
3380 ModestWindowMgr *mgr;
3381 gboolean fullscreen, active;
3382 g_return_if_fail (MODEST_IS_WINDOW (window));
3384 mgr = modest_runtime_get_window_mgr ();
3386 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3387 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3389 if (active != fullscreen) {
3390 modest_window_mgr_set_fullscreen_mode (mgr, active);
3391 gtk_window_present (GTK_WINDOW (window));
3396 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3397 ModestWindow *window)
3399 ModestWindowMgr *mgr;
3400 gboolean fullscreen;
3402 g_return_if_fail (MODEST_IS_WINDOW (window));
3404 mgr = modest_runtime_get_window_mgr ();
3405 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3406 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3408 gtk_window_present (GTK_WINDOW (window));
3412 * Used by modest_ui_actions_on_details to call do_headers_action
3415 headers_action_show_details (TnyHeader *header,
3416 ModestWindow *window,
3423 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3426 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3427 gtk_widget_show_all (dialog);
3428 gtk_dialog_run (GTK_DIALOG (dialog));
3430 gtk_widget_destroy (dialog);
3434 * Show the folder details in a ModestDetailsDialog widget
3437 show_folder_details (TnyFolder *folder,
3443 dialog = modest_details_dialog_new_with_folder (window, folder);
3446 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3447 gtk_widget_show_all (dialog);
3448 gtk_dialog_run (GTK_DIALOG (dialog));
3450 gtk_widget_destroy (dialog);
3454 * Show the header details in a ModestDetailsDialog widget
3457 modest_ui_actions_on_details (GtkAction *action,
3460 TnyList * headers_list;
3464 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3467 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3470 g_object_unref (msg);
3472 headers_list = get_selected_headers (win);
3476 iter = tny_list_create_iterator (headers_list);
3478 header = TNY_HEADER (tny_iterator_get_current (iter));
3480 headers_action_show_details (header, win, NULL);
3481 g_object_unref (header);
3484 g_object_unref (iter);
3485 g_object_unref (headers_list);
3487 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3488 GtkWidget *folder_view, *header_view;
3490 /* Check which widget has the focus */
3491 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3492 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3493 if (gtk_widget_is_focus (folder_view)) {
3494 TnyFolderStore *folder_store
3495 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3496 if (!folder_store) {
3497 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3500 /* Show only when it's a folder */
3501 /* This function should not be called for account items,
3502 * because we dim the menu item for them. */
3503 if (TNY_IS_FOLDER (folder_store)) {
3504 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3507 g_object_unref (folder_store);
3510 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3511 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3512 /* Show details of each header */
3513 do_headers_action (win, headers_action_show_details, header_view);
3519 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3520 ModestMsgEditWindow *window)
3522 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3524 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3528 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3529 ModestMsgEditWindow *window)
3531 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3533 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3537 modest_ui_actions_toggle_folders_view (GtkAction *action,
3538 ModestMainWindow *main_window)
3540 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3542 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3543 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3545 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3549 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3550 ModestWindow *window)
3552 gboolean active, fullscreen = FALSE;
3553 ModestWindowMgr *mgr;
3555 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3557 /* Check if we want to toggle the toolbar vuew in fullscreen
3559 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3560 "ViewShowToolbarFullScreen")) {
3564 /* Toggle toolbar */
3565 mgr = modest_runtime_get_window_mgr ();
3566 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
3570 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3571 ModestMsgEditWindow *window)
3573 modest_msg_edit_window_select_font (window);
3577 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3578 const gchar *display_name,
3581 /* Do not change the application name if the widget has not
3582 the focus. This callback could be called even if the folder
3583 view has not the focus, because the handled signal could be
3584 emitted when the folder view is redrawn */
3585 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3587 gtk_window_set_title (window, display_name);
3589 gtk_window_set_title (window, " ");
3594 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3596 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3597 modest_msg_edit_window_select_contacts (window);
3601 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3603 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3604 modest_msg_edit_window_check_names (window, FALSE);
3608 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3610 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3611 GTK_WIDGET (user_data));
3615 * This function is used to track changes in the selection of the
3616 * folder view that is inside the "move to" dialog to enable/disable
3617 * the OK button because we do not want the user to select a disallowed
3618 * destination for a folder.
3619 * The user also not desired to be able to use NEW button on items where
3620 * folder creation is not possibel.
3623 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
3624 TnyFolderStore *folder_store,
3628 GtkWidget *dialog = NULL;
3629 GtkWidget *ok_button = NULL, *new_button = NULL;
3630 GList *children = NULL;
3631 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
3632 gboolean moving_folder = FALSE;
3633 gboolean is_local_account = TRUE;
3634 GtkWidget *folder_view = NULL;
3635 ModestTnyFolderRules rules;
3640 /* Get the OK button */
3641 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
3645 children = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
3646 ok_button = GTK_WIDGET (children->next->next->data);
3647 new_button = GTK_WIDGET (children->next->data);
3648 g_list_free (children);
3650 /* check if folder_store is an remote account */
3651 if (TNY_IS_ACCOUNT (folder_store)) {
3652 TnyAccount *local_account = NULL;
3653 ModestTnyAccountStore *account_store = NULL;
3655 account_store = modest_runtime_get_account_store ();
3656 local_account = modest_tny_account_store_get_local_folders_account (account_store);
3658 if ((gpointer) local_account != (gpointer) folder_store) {
3659 is_local_account = FALSE;
3660 /* New button should be dimmed on remote
3662 new_sensitive = FALSE;
3664 g_object_unref (local_account);
3667 /* Check the target folder rules */
3668 if (TNY_IS_FOLDER (folder_store)) {
3669 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
3670 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
3671 ok_sensitive = FALSE;
3672 new_sensitive = FALSE;
3677 /* Check if we're moving a folder */
3678 if (MODEST_IS_MAIN_WINDOW (user_data)) {
3679 /* Get the widgets */
3680 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
3681 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3682 if (gtk_widget_is_focus (folder_view))
3683 moving_folder = TRUE;
3686 if (moving_folder) {
3687 TnyFolderStore *moved_folder = NULL, *parent = NULL;
3689 /* Get the folder to move */
3690 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3692 /* Check that we're not moving to the same folder */
3693 if (TNY_IS_FOLDER (moved_folder)) {
3694 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
3695 if (parent == folder_store)
3696 ok_sensitive = FALSE;
3697 g_object_unref (parent);
3700 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
3701 /* Do not allow to move to an account unless it's the
3702 local folders account */
3703 if (!is_local_account)
3704 ok_sensitive = FALSE;
3707 if (ok_sensitive && (moved_folder == folder_store)) {
3708 /* Do not allow to move to itself */
3709 ok_sensitive = FALSE;
3711 g_object_unref (moved_folder);
3713 TnyHeader *header = NULL;
3714 TnyFolder *src_folder = NULL;
3716 /* Moving a message */
3717 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
3718 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (user_data));
3719 src_folder = tny_header_get_folder (header);
3720 g_object_unref (header);
3723 TNY_FOLDER (modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view)));
3726 /* Do not allow to move the msg to the same folder */
3727 /* Do not allow to move the msg to an account */
3728 if ((gpointer) src_folder == (gpointer) folder_store ||
3729 TNY_IS_ACCOUNT (folder_store))
3730 ok_sensitive = FALSE;
3731 g_object_unref (src_folder);
3735 /* Set sensitivity of the OK button */
3736 gtk_widget_set_sensitive (ok_button, ok_sensitive);
3737 /* Set sensitivity of the NEW button */
3738 gtk_widget_set_sensitive (new_button, new_sensitive);
3742 create_move_to_dialog (GtkWindow *win,
3743 GtkWidget *folder_view,
3744 GtkWidget **tree_view)
3746 GtkWidget *dialog, *scroll;
3747 GtkWidget *new_button;
3749 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3751 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3754 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
3755 /* We do this manually so GTK+ does not associate a response ID for
3757 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
3758 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3759 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
3761 /* Create scrolled window */
3762 scroll = gtk_scrolled_window_new (NULL, NULL);
3763 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3764 GTK_POLICY_AUTOMATIC,
3765 GTK_POLICY_AUTOMATIC);
3767 /* Create folder view */
3768 *tree_view = modest_platform_create_folder_view (NULL);
3770 /* Track changes in the selection to
3771 * disable the OK button whenever "Move to" is not possible
3772 * disbale NEW button whenever New is not possible */
3773 g_signal_connect (*tree_view,
3774 "folder_selection_changed",
3775 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
3778 /* Listen to clicks on New button */
3779 g_signal_connect (G_OBJECT (new_button),
3781 G_CALLBACK(create_move_to_dialog_on_new_folder),
3784 /* It could happen that we're trying to move a message from a
3785 window (msg window for example) after the main window was
3786 closed, so we can not just get the model of the folder
3788 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
3789 const gchar *visible_id = NULL;
3791 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
3792 MODEST_FOLDER_VIEW(*tree_view));
3795 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
3797 /* Show the same account than the one that is shown in the main window */
3798 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
3801 const gchar *active_account_name = NULL;
3802 ModestAccountMgr *mgr = NULL;
3803 ModestAccountData *acc_data = NULL;
3805 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3806 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3808 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
3809 mgr = modest_runtime_get_account_mgr ();
3810 acc_data = modest_account_mgr_get_account_data (mgr, active_account_name);
3812 /* Set the new visible & active account */
3813 if (acc_data && acc_data->store_account) {
3814 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
3815 acc_data->store_account->account_name);
3816 modest_account_mgr_free_account_data (mgr, acc_data);
3820 /* Hide special folders */
3821 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3823 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3825 /* Add scroll to dialog */
3826 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3827 scroll, TRUE, TRUE, 0);
3829 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3830 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3836 * Returns TRUE if at least one of the headers of the list belongs to
3837 * a message that has been fully retrieved.
3839 #if 0 /* no longer in use. delete in 2007.10 */
3841 has_retrieved_msgs (TnyList *list)
3844 gboolean found = FALSE;
3846 iter = tny_list_create_iterator (list);
3847 while (!tny_iterator_is_done (iter) && !found) {
3849 TnyHeaderFlags flags = 0;
3851 header = TNY_HEADER (tny_iterator_get_current (iter));
3853 flags = tny_header_get_flags (header);
3854 if (flags & TNY_HEADER_FLAG_CACHED)
3855 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3858 g_object_unref (header);
3862 tny_iterator_next (iter);
3864 g_object_unref (iter);
3872 * Shows a confirmation dialog to the user when we're moving messages
3873 * from a remote server to the local storage. Returns the dialog
3874 * response. If it's other kind of movement then it always returns
3877 * This one is used by the next functions:
3878 * modest_ui_actions_on_paste - commented out
3879 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
3882 modest_ui_actions_msgs_move_to_confirmation (GtkWindow *win,
3883 TnyFolder *dest_folder,
3887 gint response = GTK_RESPONSE_OK;
3889 /* return with OK if the destination is a remote folder */
3890 if (modest_tny_folder_is_remote_folder (dest_folder))
3891 return GTK_RESPONSE_OK;
3893 TnyFolder *src_folder = NULL;
3894 TnyIterator *iter = NULL;
3895 TnyHeader *header = NULL;
3897 /* Get source folder */
3898 iter = tny_list_create_iterator (headers);
3899 header = TNY_HEADER (tny_iterator_get_current (iter));
3901 src_folder = tny_header_get_folder (header);
3902 g_object_unref (header);
3904 g_object_unref (iter);
3906 /* if no src_folder, message may be an attahcment */
3907 if (src_folder == NULL)
3908 return GTK_RESPONSE_CANCEL;
3910 /* If the source is a local or MMC folder */
3911 if (!modest_tny_folder_is_remote_folder (src_folder)) {
3912 g_object_unref (src_folder);
3913 return GTK_RESPONSE_OK;
3915 g_object_unref (src_folder);
3917 /* now if offline we ask the user */
3918 if(connect_to_get_msg( GTK_WINDOW (win),
3919 tny_list_get_length (headers)))
3920 response = GTK_RESPONSE_OK;
3922 response = GTK_RESPONSE_CANCEL;
3930 move_to_cb (ModestMailOperation *mail_op, gpointer user_data)
3932 MoveToHelper *helper = (MoveToHelper *) user_data;
3934 /* Note that the operation could have failed, in that case do
3936 if (modest_mail_operation_get_status (mail_op) ==
3937 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
3939 GObject *object = modest_mail_operation_get_source (mail_op);
3940 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
3941 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
3943 if (!modest_msg_view_window_select_next_message (self))
3944 if (!modest_msg_view_window_select_previous_message (self))
3945 /* No more messages to view, so close this window */
3946 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3947 } else if (MODEST_IS_MAIN_WINDOW (object) && helper->reference != NULL) {
3948 GtkWidget *header_view;
3950 GtkTreeSelection *sel;
3952 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
3953 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3954 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
3955 path = gtk_tree_row_reference_get_path (helper->reference);
3956 gtk_tree_selection_select_path (sel, path);
3957 gtk_tree_path_free (path);
3959 g_object_unref (object);
3962 /* Close the "Pasting" information banner */
3963 gtk_widget_destroy (GTK_WIDGET(helper->banner));
3964 if (helper->reference != NULL)
3965 gtk_tree_row_reference_free (helper->reference);
3970 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3973 ModestWindow *main_window = NULL;
3974 GtkWidget *folder_view = NULL;
3975 GObject *win = modest_mail_operation_get_source (mail_op);
3976 const GError *error = NULL;
3977 const gchar *message = NULL;
3979 /* Get error message */
3980 error = modest_mail_operation_get_error (mail_op);
3981 if (error != NULL && error->message != NULL) {
3982 message = error->message;
3984 message = _("mail_in_ui_folder_move_target_error");
3987 /* Disable next automatic folder selection */
3988 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ());
3989 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
3990 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3991 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
3993 if (user_data && TNY_IS_FOLDER (user_data)) {
3994 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3995 TNY_FOLDER (user_data), FALSE);
3998 /* Show notification dialog */
3999 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
4000 g_object_unref (win);
4004 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
4007 GObject *win = modest_mail_operation_get_source (mail_op);
4008 const GError *error = modest_mail_operation_get_error (mail_op);
4010 g_return_if_fail (error != NULL);
4011 if (error->message != NULL)
4012 g_printerr ("modest: %s\n", error->message);
4014 g_printerr ("modest: unkonw error on send&receive operation");
4016 /* Show error message */
4017 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
4018 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
4019 /* _CS("sfil_ib_unable_to_receive")); */
4021 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
4022 /* _CS("sfil_ib_unable_to_send")); */
4023 g_object_unref (win);
4027 open_msg_for_purge_cb (ModestMailOperation *mail_op,
4034 gint pending_purges = 0;
4035 gboolean some_purged = FALSE;
4036 ModestWindow *win = MODEST_WINDOW (user_data);
4037 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
4039 /* If there was any error */
4040 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
4041 modest_window_mgr_unregister_header (mgr, header);
4045 /* Once the message has been retrieved for purging, we check if
4046 * it's all ok for purging */
4048 parts = tny_simple_list_new ();
4049 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
4050 iter = tny_list_create_iterator (parts);
4052 while (!tny_iterator_is_done (iter)) {
4054 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4055 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
4056 if (tny_mime_part_is_purged (part))
4063 g_object_unref (part);
4065 tny_iterator_next (iter);
4067 g_object_unref (iter);
4070 if (pending_purges>0) {
4072 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
4074 if (response == GTK_RESPONSE_OK) {
4075 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
4076 iter = tny_list_create_iterator (parts);
4077 while (!tny_iterator_is_done (iter)) {
4080 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4081 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
4082 tny_mime_part_set_purged (part);
4085 g_object_unref (part);
4087 tny_iterator_next (iter);
4090 tny_msg_rewrite_cache (msg);
4093 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
4095 g_object_unref (iter);
4097 modest_window_mgr_unregister_header (mgr, header);
4099 g_object_unref (parts);
4103 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
4104 ModestMainWindow *win)
4106 GtkWidget *header_view;
4107 TnyList *header_list;
4110 TnyHeaderFlags flags;
4111 ModestWindow *msg_view_window = NULL;
4114 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4116 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4117 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4119 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
4121 if (tny_list_get_length (header_list) == 1) {
4122 iter = tny_list_create_iterator (header_list);
4123 header = TNY_HEADER (tny_iterator_get_current (iter));
4124 g_object_unref (iter);
4129 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
4130 header, &msg_view_window);
4131 flags = tny_header_get_flags (header);
4132 if (!(flags & TNY_HEADER_FLAG_CACHED))
4135 if (msg_view_window != NULL)
4136 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
4138 /* do nothing; uid was registered before, so window is probably on it's way */
4139 g_warning ("debug: header %p has already been registered", header);
4142 ModestMailOperation *mail_op = NULL;
4143 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
4144 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4146 modest_ui_actions_get_msgs_full_error_handler,
4148 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4149 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
4151 g_object_unref (mail_op);
4154 g_object_unref (header);
4156 g_object_unref (header_list);
4160 * Utility function that transfer messages from both the main window
4161 * and the msg view window when using the "Move to" dialog
4164 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
4167 TnyList *headers = NULL;
4168 TnyAccount *dst_account = NULL;
4169 const gchar *proto_str = NULL;
4170 gboolean dst_is_pop = FALSE;
4172 if (!TNY_IS_FOLDER (dst_folder)) {
4173 modest_platform_information_banner (GTK_WIDGET (win),
4175 _CS("ckdg_ib_unable_to_move_to_current_location"));
4179 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
4180 proto_str = tny_account_get_proto (dst_account);
4182 /* tinymail will return NULL for local folders it seems */
4183 dst_is_pop = proto_str &&
4184 (modest_protocol_info_get_transport_store_protocol (proto_str) ==
4185 MODEST_PROTOCOL_STORE_POP);
4187 g_object_unref (dst_account);
4189 /* Get selected headers */
4190 headers = get_selected_headers (MODEST_WINDOW (win));
4193 modest_platform_information_banner (GTK_WIDGET (win),
4195 ngettext("mail_in_ui_folder_move_target_error",
4196 "mail_in_ui_folder_move_targets_error",
4197 tny_list_get_length (headers)));
4198 g_object_unref (headers);
4202 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4203 helper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4204 _CS("ckct_nw_pasting"));
4205 if (helper->banner != NULL) {
4206 gtk_window_set_modal (GTK_WINDOW(helper->banner), FALSE);
4207 gtk_widget_show (GTK_WIDGET(helper->banner));
4210 if (MODEST_IS_MAIN_WINDOW (win)) {
4211 GtkWidget *header_view =
4212 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
4213 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4214 helper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
4217 ModestMailOperation *mail_op =
4218 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4220 modest_ui_actions_move_folder_error_handler,
4222 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4225 modest_mail_operation_xfer_msgs (mail_op,
4227 TNY_FOLDER (dst_folder),
4232 g_object_unref (G_OBJECT (mail_op));
4233 g_object_unref (headers);
4237 * UI handler for the "Move to" action when invoked from the
4241 modest_ui_actions_on_main_window_move_to (GtkAction *action,
4242 GtkWidget *folder_view,
4243 TnyFolderStore *dst_folder,
4244 ModestMainWindow *win)
4246 ModestHeaderView *header_view = NULL;
4247 ModestMailOperation *mail_op = NULL;
4248 TnyFolderStore *src_folder;
4249 gboolean online = (tny_device_is_online (modest_runtime_get_device()));
4251 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4253 /* Get the source folder */
4254 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4256 /* Get header view */
4257 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
4259 /* Get folder or messages to transfer */
4260 if (gtk_widget_is_focus (folder_view)) {
4261 GtkTreeSelection *sel;
4262 gboolean do_xfer = TRUE;
4264 /* Allow only to transfer folders to the local root folder */
4265 if (TNY_IS_ACCOUNT (dst_folder) &&
4266 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder)) {
4268 } else if (!TNY_IS_FOLDER (src_folder)) {
4269 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
4271 } else if (!online && modest_platform_is_network_folderstore(src_folder)) {
4272 guint num_headers = tny_folder_get_all_count(TNY_FOLDER(src_folder));
4273 if (!connect_to_get_msg(GTK_WINDOW(win), num_headers)) {
4279 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4280 helper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4281 _CS("ckct_nw_pasting"));
4282 if (helper->banner != NULL) {
4283 gtk_window_set_modal (GTK_WINDOW(helper->banner), FALSE);
4284 gtk_widget_show (GTK_WIDGET(helper->banner));
4286 /* Clean folder on header view before moving it */
4287 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
4288 gtk_tree_selection_unselect_all (sel);
4291 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4293 modest_ui_actions_move_folder_error_handler,
4295 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4298 /* Select *after* the changes */
4299 /* TODO: this function hangs UI after transfer */
4300 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
4301 /* TNY_FOLDER (src_folder), TRUE); */
4303 modest_mail_operation_xfer_folder (mail_op,
4304 TNY_FOLDER (src_folder),
4309 /* Unref mail operation */
4310 g_object_unref (G_OBJECT (mail_op));
4312 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
4313 gboolean do_xfer = TRUE;
4314 /* Ask for confirmation if the source folder is remote and we're not connected */
4315 if (!online && modest_platform_is_network_folderstore(src_folder)) {
4316 TnyList *headers = modest_header_view_get_selected_headers(header_view);
4317 if (!msgs_already_deleted_from_server(headers, src_folder)) {
4318 guint num_headers = tny_list_get_length(headers);
4319 if (!connect_to_get_msg(GTK_WINDOW(win), num_headers)) {
4323 g_object_unref(headers);
4325 if (do_xfer) /* Transfer messages */
4326 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4330 g_object_unref (src_folder);
4335 * UI handler for the "Move to" action when invoked from the
4336 * ModestMsgViewWindow
4339 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
4340 TnyFolderStore *dst_folder,
4341 ModestMsgViewWindow *win)
4343 TnyHeader *header = NULL;
4344 TnyFolderStore *src_folder;
4346 /* Create header list */
4347 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
4348 src_folder = TNY_FOLDER_STORE(tny_header_get_folder(header));
4349 g_object_unref (header);
4351 /* Transfer the message if online or confirmed by the user */
4352 if (tny_device_is_online (modest_runtime_get_device()) || remote_folder_is_pop(src_folder) ||
4353 (modest_platform_is_network_folderstore(src_folder) && connect_to_get_msg(GTK_WINDOW(win), 1))) {
4354 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4357 g_object_unref (src_folder);
4361 modest_ui_actions_on_move_to (GtkAction *action,
4364 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
4366 TnyFolderStore *dst_folder = NULL;
4367 ModestMainWindow *main_window;
4369 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
4370 MODEST_IS_MSG_VIEW_WINDOW (win));
4372 /* Get the main window if exists */
4373 if (MODEST_IS_MAIN_WINDOW (win))
4374 main_window = MODEST_MAIN_WINDOW (win);
4377 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
4379 /* Get the folder view widget if exists */
4381 folder_view = modest_main_window_get_child_widget (main_window,
4382 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4386 /* Create and run the dialog */
4387 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
4388 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
4389 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4390 result = gtk_dialog_run (GTK_DIALOG(dialog));
4391 g_object_ref (tree_view);
4392 gtk_widget_destroy (dialog);
4394 if (result != GTK_RESPONSE_ACCEPT)
4397 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
4398 /* Do window specific stuff */
4399 if (MODEST_IS_MAIN_WINDOW (win)) {
4400 modest_ui_actions_on_main_window_move_to (action,
4403 MODEST_MAIN_WINDOW (win));
4405 modest_ui_actions_on_msg_view_window_move_to (action,
4407 MODEST_MSG_VIEW_WINDOW (win));
4411 g_object_unref (dst_folder);
4415 * Calls #HeadersFunc for each header already selected in the main
4416 * window or the message currently being shown in the msg view window
4419 do_headers_action (ModestWindow *win,
4423 TnyList *headers_list = NULL;
4424 TnyIterator *iter = NULL;
4425 TnyHeader *header = NULL;
4426 TnyFolder *folder = NULL;
4429 headers_list = get_selected_headers (win);
4433 /* Get the folder */
4434 iter = tny_list_create_iterator (headers_list);
4435 header = TNY_HEADER (tny_iterator_get_current (iter));
4437 folder = tny_header_get_folder (header);
4438 g_object_unref (header);
4441 /* Call the function for each header */
4442 while (!tny_iterator_is_done (iter)) {
4443 header = TNY_HEADER (tny_iterator_get_current (iter));
4444 func (header, win, user_data);
4445 g_object_unref (header);
4446 tny_iterator_next (iter);
4449 /* Trick: do a poke status in order to speed up the signaling
4451 tny_folder_poke_status (folder);
4454 g_object_unref (folder);
4455 g_object_unref (iter);
4456 g_object_unref (headers_list);
4460 modest_ui_actions_view_attachment (GtkAction *action,
4461 ModestWindow *window)
4463 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4464 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4466 /* not supported window for this action */
4467 g_return_if_reached ();
4472 modest_ui_actions_save_attachments (GtkAction *action,
4473 ModestWindow *window)
4475 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4476 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4478 /* not supported window for this action */
4479 g_return_if_reached ();
4484 modest_ui_actions_remove_attachments (GtkAction *action,
4485 ModestWindow *window)
4487 if (MODEST_IS_MAIN_WINDOW (window)) {
4488 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4489 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4490 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4492 /* not supported window for this action */
4493 g_return_if_reached ();
4498 modest_ui_actions_on_settings (GtkAction *action,
4503 dialog = modest_platform_get_global_settings_dialog ();
4504 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4505 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4506 gtk_widget_show_all (dialog);
4508 gtk_dialog_run (GTK_DIALOG (dialog));
4510 gtk_widget_destroy (dialog);
4514 modest_ui_actions_on_help (GtkAction *action,
4517 const gchar *help_id = NULL;
4519 if (MODEST_IS_MAIN_WINDOW (win)) {
4520 GtkWidget *folder_view;
4521 TnyFolderStore *folder_store;
4523 /* Get selected folder */
4524 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4525 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4526 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4528 /* Switch help_id */
4529 if (TNY_IS_FOLDER (folder_store)) {
4530 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4531 case TNY_FOLDER_TYPE_NORMAL:
4532 help_id = "applications_email_managefolders";
4534 case TNY_FOLDER_TYPE_INBOX:
4535 help_id = "applications_email_inbox";
4537 case TNY_FOLDER_TYPE_OUTBOX:
4538 help_id = "applications_email_outbox";
4540 case TNY_FOLDER_TYPE_SENT:
4541 help_id = "applications_email_sent";
4543 case TNY_FOLDER_TYPE_DRAFTS:
4544 help_id = "applications_email_drafts";
4546 case TNY_FOLDER_TYPE_ARCHIVE:
4547 help_id = "applications_email_managefolders";
4550 help_id = "applications_email_managefolders";
4553 help_id = "applications_email_mainview";
4555 g_object_unref (folder_store);
4556 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4557 help_id = "applications_email_viewer";
4558 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4559 help_id = "applications_email_editor";
4561 modest_platform_show_help (GTK_WINDOW (win), help_id);
4565 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4566 ModestWindow *window)
4568 ModestMailOperation *mail_op;
4572 headers = get_selected_headers (window);
4576 /* Create mail operation */
4577 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4579 modest_ui_actions_get_msgs_full_error_handler,
4581 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4582 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4585 g_object_unref (headers);
4586 g_object_unref (mail_op);
4590 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4591 ModestWindow *window)
4593 g_return_if_fail (MODEST_IS_WINDOW (window));
4596 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4600 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4601 ModestWindow *window)
4603 g_return_if_fail (MODEST_IS_WINDOW (window));
4606 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4610 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4611 ModestWindow *window)
4613 g_return_if_fail (MODEST_IS_WINDOW (window));
4616 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4620 modest_ui_actions_on_format_menu_activated (GtkAction *action,
4621 ModestWindow *window)
4623 g_return_if_fail (MODEST_IS_WINDOW (window));
4626 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4630 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4631 ModestWindow *window)
4633 g_return_if_fail (MODEST_IS_WINDOW (window));
4636 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4640 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4641 ModestWindow *window)
4643 g_return_if_fail (MODEST_IS_WINDOW (window));
4646 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4650 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4651 ModestWindow *window)
4653 g_return_if_fail (MODEST_IS_WINDOW (window));
4656 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4660 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4661 ModestWindow *window)
4663 g_return_if_fail (MODEST_IS_WINDOW (window));
4666 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4670 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4671 ModestWindow *window)
4673 g_return_if_fail (MODEST_IS_WINDOW (window));
4676 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4680 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4682 g_return_if_fail (MODEST_IS_WINDOW (window));
4685 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4689 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4691 g_return_if_fail (MODEST_IS_WINDOW (window));
4693 modest_platform_show_search_messages (GTK_WINDOW (window));
4697 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4699 g_return_if_fail (MODEST_IS_WINDOW (win));
4700 modest_platform_show_addressbook (GTK_WINDOW (win));
4705 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4706 ModestWindow *window)
4708 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4710 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4714 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
4715 ModestMailOperationState *state,
4718 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4720 /* Set send/receive operation finished */
4721 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4722 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));
4728 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
4734 const gchar* server_name = NULL;
4735 TnyTransportAccount *server_account;
4736 gchar *message = NULL;
4738 /* Don't show anything if the user cancelled something */
4739 if (err->code == TNY_TRANSPORT_ACCOUNT_ERROR_SEND_USER_CANCEL)
4742 /* Get the server name: */
4744 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
4745 if (server_account) {
4746 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
4748 g_object_unref (server_account);
4749 server_account = NULL;
4752 g_return_if_fail (server_name);
4754 /* Show the appropriate message text for the GError: */
4755 switch (err->code) {
4756 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_HOST_LOOKUP_FAILED:
4757 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4759 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_SERVICE_UNAVAILABLE:
4760 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
4762 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND_AUTHENTICATION_NOT_SUPPORTED:
4763 message = g_strdup_printf (_("emev_ni_ui_smtp_authentication_fail_error"), server_name);
4765 case TNY_TRANSPORT_ACCOUNT_ERROR_SEND:
4766 message = g_strdup (_("emev_ib_ui_smtp_send_error"));
4769 g_return_if_reached ();
4772 /* TODO if the username or the password where not defined we
4773 should show the Accounts Settings dialog or the Connection
4774 specific SMTP server window */
4776 modest_platform_run_information_dialog (NULL, message);
4781 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
4786 ModestMainWindow *main_window = NULL;
4787 ModestWindowMgr *mgr = NULL;
4788 GtkWidget *folder_view = NULL, *header_view = NULL;
4789 TnyFolderStore *selected_folder = NULL;
4790 TnyFolderType folder_type;
4792 mgr = modest_runtime_get_window_mgr ();
4793 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr));
4798 /* Check if selected folder is OUTBOX */
4799 folder_view = modest_main_window_get_child_widget (main_window,
4800 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4801 header_view = modest_main_window_get_child_widget (main_window,
4802 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4804 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4805 if (!TNY_IS_FOLDER (selected_folder))
4808 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
4809 #if GTK_CHECK_VERSION(2, 8, 0)
4810 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
4811 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
4812 GtkTreeViewColumn *tree_column;
4814 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
4815 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
4816 gtk_tree_view_column_queue_resize (tree_column);
4819 gtk_widget_queue_draw (header_view);
4824 if (selected_folder != NULL)
4825 g_object_unref (selected_folder);