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 _PasteAsAttachmentHelper {
107 ModestMsgEditWindow *window;
109 } PasteAsAttachmentHelper;
113 * The do_headers_action uses this kind of functions to perform some
114 * action to each member of a list of headers
116 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
118 static void do_headers_action (ModestWindow *win,
122 static void open_msg_cb (ModestMailOperation *mail_op,
127 static void reply_forward_cb (ModestMailOperation *mail_op,
132 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
134 static void folder_refreshed_cb (ModestMailOperation *mail_op,
138 static void _on_send_receive_progress_changed (ModestMailOperation *mail_op,
139 ModestMailOperationState *state,
143 download_uncached_messages (TnyList *header_list, GtkWindow *win,
148 msgs_move_to_confirmation (GtkWindow *win,
149 TnyFolder *dest_folder,
155 run_account_setup_wizard (ModestWindow *win)
157 ModestEasysetupWizardDialog *wizard;
159 g_return_if_fail (MODEST_IS_WINDOW(win));
161 wizard = modest_easysetup_wizard_dialog_new ();
162 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
164 /* Don't make this a modal window, because secondary windows will then
165 * be unusable, freezing the UI: */
166 /* gtk_window_set_modal (GTK_WINDOW (wizard), TRUE); */
168 gtk_dialog_run (GTK_DIALOG (wizard));
169 gtk_widget_destroy (GTK_WIDGET (wizard));
174 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
177 const gchar *authors[] = {
178 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
181 about = gtk_about_dialog_new ();
182 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
183 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
184 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
185 _("Copyright (c) 2006, Nokia Corporation\n"
186 "All rights reserved."));
187 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
188 _("a modest e-mail client\n\n"
189 "design and implementation: Dirk-Jan C. Binnema\n"
190 "contributions from the fine people at KC and Ig\n"
191 "uses the tinymail email framework written by Philip van Hoof"));
192 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
193 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
194 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
195 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
197 gtk_dialog_run (GTK_DIALOG (about));
198 gtk_widget_destroy(about);
202 * Gets the list of currently selected messages. If the win is the
203 * main window, then it returns a newly allocated list of the headers
204 * selected in the header view. If win is the msg view window, then
205 * the value returned is a list with just a single header.
207 * The caller of this funcion must free the list.
210 get_selected_headers (ModestWindow *win)
212 if (MODEST_IS_MAIN_WINDOW(win)) {
213 GtkWidget *header_view;
215 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
216 MODEST_WIDGET_TYPE_HEADER_VIEW);
217 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
219 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
220 /* for MsgViewWindows, we simply return a list with one element */
222 TnyList *list = NULL;
224 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
225 if (header != NULL) {
226 list = tny_simple_list_new ();
227 tny_list_prepend (list, G_OBJECT(header));
228 g_object_unref (G_OBJECT(header));
238 headers_action_mark_as_read (TnyHeader *header,
242 TnyHeaderFlags flags;
244 g_return_if_fail (TNY_IS_HEADER(header));
246 flags = tny_header_get_flags (header);
247 if (flags & TNY_HEADER_FLAG_SEEN) return;
248 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
252 headers_action_mark_as_unread (TnyHeader *header,
256 TnyHeaderFlags flags;
258 g_return_if_fail (TNY_IS_HEADER(header));
260 flags = tny_header_get_flags (header);
261 if (flags & TNY_HEADER_FLAG_SEEN) {
262 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
266 /** A convenience method, because deleting a message is
267 * otherwise complicated, and it's best to change it in one place
270 void modest_do_message_delete (TnyHeader *header, ModestWindow *win)
272 ModestMailOperation *mail_op = NULL;
273 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE,
274 win ? G_OBJECT(win) : NULL);
275 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
278 /* Always delete. TODO: Move to trash still not supported */
279 modest_mail_operation_remove_msg (mail_op, header, FALSE);
280 g_object_unref (G_OBJECT (mail_op));
284 headers_action_delete (TnyHeader *header,
288 modest_do_message_delete (header, win);
291 /** After deleing a message that is currently visible in a window,
292 * show the next message from the list, or close the window if there are no more messages.
294 void modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
296 /* Close msg view window or select next */
297 if (modest_msg_view_window_last_message_selected (win) &&
298 modest_msg_view_window_first_message_selected (win)) {
299 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
301 if (!modest_msg_view_window_select_next_message (win)) {
303 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
309 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
311 TnyList *header_list = NULL;
312 TnyIterator *iter = NULL;
313 TnyHeader *header = NULL;
314 gchar *message = NULL;
317 ModestWindowMgr *mgr;
318 GtkWidget *header_view = NULL;
320 g_return_if_fail (MODEST_IS_WINDOW(win));
322 /* Check first if the header view has the focus */
323 if (MODEST_IS_MAIN_WINDOW (win)) {
325 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
326 MODEST_WIDGET_TYPE_HEADER_VIEW);
327 if (!gtk_widget_is_focus (header_view))
331 /* Get the headers, either from the header view (if win is the main window),
332 * or from the message view window: */
333 header_list = get_selected_headers (win);
334 if (!header_list) return;
336 /* Check if any of the headers are already opened, or in the process of being opened */
337 if (MODEST_IS_MAIN_WINDOW (win)) {
339 iter = tny_list_create_iterator (header_list);
341 mgr = modest_runtime_get_window_mgr ();
342 while (!tny_iterator_is_done (iter) && !found) {
343 header = TNY_HEADER (tny_iterator_get_current (iter));
345 found = modest_window_mgr_find_registered_header (mgr, header, NULL);
346 g_object_unref (header);
349 tny_iterator_next (iter);
351 g_object_unref (iter);
356 num = g_strdup_printf ("%d", tny_list_get_length (header_list));
357 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
359 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
363 g_object_unref (header_list);
369 if (tny_list_get_length(header_list) == 1) {
370 iter = tny_list_create_iterator (header_list);
371 header = TNY_HEADER (tny_iterator_get_current (iter));
373 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
374 g_object_unref (header);
377 g_object_unref (iter);
379 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
380 tny_list_get_length(header_list)), desc);
382 /* Confirmation dialog */
383 printf("DEBUG: %s\n", __FUNCTION__);
384 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
388 if (response == GTK_RESPONSE_OK) {
389 ModestWindow *main_window = NULL;
390 ModestWindowMgr *mgr = NULL;
391 GtkTreeModel *model = NULL;
392 GtkTreeSelection *sel = NULL;
393 GList *sel_list = NULL, *tmp = NULL;
394 GtkTreeRowReference *row_reference = NULL;
395 GtkTreePath *next_path = NULL;
396 TnyFolder *folder = NULL;
399 /* Find last selected row */
400 if (MODEST_IS_MAIN_WINDOW (win)) {
401 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
402 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
403 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
404 for (tmp=sel_list; tmp; tmp=tmp->next) {
405 if (tmp->next == NULL) {
406 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
407 gtk_tree_path_next (next_path);
408 row_reference = gtk_tree_row_reference_new (model, next_path);
409 gtk_tree_path_free (next_path);
414 /* Remove each header. If it's a view window header_view == NULL */
415 do_headers_action (win, headers_action_delete, header_view);
417 /* refresh the header view (removing marked-as-deleted)*/
418 modest_header_view_refilter (MODEST_HEADER_VIEW(header_view));
420 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
421 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
423 /* Get main window */
424 mgr = modest_runtime_get_window_mgr ();
425 main_window = modest_window_mgr_get_main_window (mgr);
428 /* Move cursor to next row */
431 /* Select next row */
432 if (gtk_tree_row_reference_valid (row_reference)) {
433 next_path = gtk_tree_row_reference_get_path (row_reference);
434 gtk_tree_selection_select_path (sel, next_path);
435 gtk_tree_path_free (next_path);
437 if (row_reference != NULL)
438 gtk_tree_row_reference_free (row_reference);
441 /* Get folder from first header and sync it */
442 iter = tny_list_create_iterator (header_list);
443 header = TNY_HEADER (tny_iterator_get_current (iter));
444 folder = tny_header_get_folder (header);
445 if (TNY_IS_CAMEL_IMAP_FOLDER (folder))
446 /* tny_folder_sync_async(folder, FALSE, NULL, NULL, NULL); /\* FALSE --> don't expunge *\/ */
447 tny_folder_sync (folder, FALSE, &err); /* FALSE --> don't expunge */
448 /* else if (TNY_IS_CAMEL_POP_FOLDER (folder)) */
449 /* tny_folder_sync_async(folder, FALSE, NULL, NULL, NULL); /\* TRUE --> dont expunge *\/ */
450 /* tny_folder_sync (folder, TRUE, &err); /\* TRUE --> expunge *\/ */
453 /* tny_folder_sync_async(folder, TRUE, NULL, NULL, NULL); /\* TRUE --> expunge *\/ */
454 tny_folder_sync (folder, TRUE, &err); /* TRUE --> expunge */
457 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, err->code, err->message);
461 g_object_unref (header);
462 g_object_unref (iter);
463 g_object_unref (folder);
465 /* Update toolbar dimming state */
466 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
469 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
470 g_list_free (sel_list);
476 g_object_unref (header_list);
482 /* delete either message or folder, based on where we are */
484 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
486 g_return_if_fail (MODEST_IS_WINDOW(win));
488 /* Check first if the header view has the focus */
489 if (MODEST_IS_MAIN_WINDOW (win)) {
491 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
492 MODEST_WIDGET_TYPE_FOLDER_VIEW);
493 if (gtk_widget_is_focus (w)) {
494 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
498 modest_ui_actions_on_delete_message (action, win);
504 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
506 #ifdef MODEST_PLATFORM_MAEMO
507 modest_osso_save_state();
508 #endif /* MODEST_PLATFORM_MAEMO */
510 g_debug ("closing down, clearing %d item(s) from operation queue",
511 modest_mail_operation_queue_num_elements
512 (modest_runtime_get_mail_operation_queue()));
514 /* cancel all outstanding operations */
515 modest_mail_operation_queue_cancel_all
516 (modest_runtime_get_mail_operation_queue());
518 g_debug ("queue has been cleared");
520 /* note: when modest-tny-account-store is finalized,
521 it will automatically set all network connections
528 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
532 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
534 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
535 /* gtk_widget_destroy (GTK_WIDGET (win)); */
536 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
537 /* gboolean ret_value; */
538 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
539 /* } else if (MODEST_IS_WINDOW (win)) { */
540 /* gtk_widget_destroy (GTK_WIDGET (win)); */
542 /* g_return_if_reached (); */
547 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
549 GtkClipboard *clipboard = NULL;
550 gchar *selection = NULL;
552 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
553 selection = gtk_clipboard_wait_for_text (clipboard);
555 /* Question: why is the clipboard being used here?
556 * It doesn't really make a lot of sense. */
560 modest_address_book_add_address (selection);
566 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
568 /* This is currently only implemented for Maemo */
569 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
570 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
571 run_account_setup_wizard (win);
574 /* Show the list of accounts: */
575 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
576 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW (win));
578 /* Don't make this a modal window, because secondary windows will then
579 * be unusable, freezing the UI: */
580 /* gtk_window_set_modal (GTK_WINDOW (account_win), TRUE); */
581 modest_maemo_show_dialog_and_forget (GTK_WINDOW (win), account_win);
584 GtkWidget *dialog, *label;
586 /* Create the widgets */
588 dialog = gtk_dialog_new_with_buttons ("Message",
590 GTK_DIALOG_DESTROY_WITH_PARENT,
594 label = gtk_label_new ("Hello World!");
596 /* Ensure that the dialog box is destroyed when the user responds. */
598 g_signal_connect_swapped (dialog, "response",
599 G_CALLBACK (gtk_widget_destroy),
602 /* Add the label, and show everything we've added to the dialog. */
604 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
606 gtk_widget_show_all (dialog);
607 #endif /* MODEST_PLATFORM_MAEMO */
611 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
613 ModestWindow *main_window = MODEST_WINDOW (user_data);
615 /* Save any changes. */
616 modest_connection_specific_smtp_window_save_server_accounts (
617 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
618 modest_window_get_active_account (main_window));
619 gtk_widget_destroy (GTK_WIDGET (window));
625 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
627 /* This is currently only implemented for Maemo,
628 * because it requires an API (libconic) to detect different connection
631 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
633 /* Create the window if necessary: */
634 const gchar *active_account_name = modest_window_get_active_account (win);
636 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
637 * or show the default account?
638 * If we show the default account then the account name should be shown in
639 * the window when we show it. */
640 if (!active_account_name) {
641 g_warning ("%s: No account is active.", __FUNCTION__);
645 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
646 modest_connection_specific_smtp_window_fill_with_connections (
647 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
648 modest_runtime_get_account_mgr(),
649 active_account_name);
651 /* Show the window: */
652 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
653 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
654 gtk_widget_show (specific_window);
656 /* Save changes when the window is hidden: */
657 g_signal_connect (specific_window, "hide",
658 G_CALLBACK (on_smtp_servers_window_hide), win);
659 #endif /* MODEST_PLATFORM_MAEMO */
663 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
665 ModestWindow *msg_win = NULL;
667 TnyFolder *folder = NULL;
668 gchar *account_name = NULL;
669 gchar *from_str = NULL;
670 /* GError *err = NULL; */
671 TnyAccount *account = NULL;
672 ModestWindowMgr *mgr;
673 gchar *signature = NULL, *blank_and_signature = NULL;
675 /* if there are no accounts yet, just show the wizard */
676 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
677 run_account_setup_wizard (win);
681 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
683 account_name = g_strdup (modest_window_get_active_account (win));
685 g_printerr ("modest: no account found\n");
689 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
691 TNY_ACCOUNT_TYPE_STORE);
693 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
697 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
699 g_printerr ("modest: failed get from string for '%s'\n", account_name);
703 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
704 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
705 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
706 MODEST_ACCOUNT_SIGNATURE, FALSE);
707 blank_and_signature = g_strconcat ("\n", signature, NULL);
710 blank_and_signature = g_strdup ("");
713 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
715 g_printerr ("modest: failed to create new msg\n");
719 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
721 g_printerr ("modest: failed to find Drafts folder\n");
726 /* Create and register edit window */
727 /* This is destroyed by TOOD. */
728 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
729 mgr = modest_runtime_get_window_mgr ();
730 modest_window_mgr_register_window (mgr, msg_win);
733 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
735 gtk_widget_show_all (GTK_WIDGET (msg_win));
738 g_free (account_name);
740 g_free (blank_and_signature);
742 g_object_unref (msg_win);
744 g_object_unref (G_OBJECT(account));
746 g_object_unref (G_OBJECT(msg));
748 g_object_unref (G_OBJECT(folder));
752 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
756 ModestMailOperationStatus status;
758 /* If there is no message or the operation was not successful */
759 status = modest_mail_operation_get_status (mail_op);
760 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
762 /* Remove the header from the preregistered uids */
763 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
773 open_msg_cb (ModestMailOperation *mail_op,
778 ModestWindowMgr *mgr = NULL;
779 ModestWindow *parent_win = NULL;
780 ModestWindow *win = NULL;
781 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
782 gchar *account = NULL;
785 /* Do nothing if there was any problem with the mail
786 operation. The error will be shown by the error_handler of
787 the mail operation */
788 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
792 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
793 folder = tny_header_get_folder (header);
795 /* Mark header as read */
796 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
799 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
801 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
803 /* Gets folder type (OUTBOX headers will be opened in edit window */
804 if (modest_tny_folder_is_local_folder (folder))
805 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
807 /* If the header is in the drafts folder then open the editor,
808 else the message view window */
809 if ((folder_type == TNY_FOLDER_TYPE_DRAFTS) ||
810 (folder_type == TNY_FOLDER_TYPE_OUTBOX)) {
811 /* we cannot edit without a valid account... */
812 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
813 run_account_setup_wizard(parent_win);
816 win = modest_msg_edit_window_new (msg, account, TRUE);
819 gchar *uid = modest_tny_folder_get_header_unique_id (header);
821 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
822 GtkWidget *header_view;
823 GtkTreeSelection *sel;
824 GList *sel_list = NULL;
827 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
828 MODEST_WIDGET_TYPE_HEADER_VIEW);
830 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
831 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
833 if (sel_list != NULL) {
834 GtkTreeRowReference *row_reference;
836 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
837 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
838 g_list_free (sel_list);
840 win = modest_msg_view_window_new_with_header_model (msg,
845 gtk_tree_row_reference_free (row_reference);
847 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
850 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
855 /* Register and show new window */
857 mgr = modest_runtime_get_window_mgr ();
858 modest_window_mgr_register_window (mgr, win);
859 g_object_unref (win);
860 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
861 gtk_widget_show_all (GTK_WIDGET(win));
864 /* Update toolbar dimming state */
865 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
866 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
872 g_object_unref (parent_win);
873 g_object_unref (folder);
877 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
881 GObject *win = modest_mail_operation_get_source (mail_op);
883 error = modest_mail_operation_get_error (mail_op);
884 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, error->code, error->message);
886 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
888 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
891 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
892 _("mail_ni_ui_folder_get_msg_folder_error"));
896 g_object_unref (win);
900 * This function is used by both modest_ui_actions_on_open and
901 * modest_ui_actions_on_header_activated. This way we always do the
902 * same when trying to open messages.
905 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
907 ModestWindowMgr *mgr = NULL;
908 TnyIterator *iter = NULL;
909 ModestMailOperation *mail_op = NULL;
910 TnyList *not_opened_headers = NULL;
911 TnyHeaderFlags flags = 0;
913 /* Look if we already have a message view for each header. If
914 true, then remove the header from the list of headers to
916 mgr = modest_runtime_get_window_mgr ();
917 iter = tny_list_create_iterator (headers);
918 not_opened_headers = tny_simple_list_new ();
920 while (!tny_iterator_is_done (iter)) {
922 ModestWindow *window = NULL;
923 TnyHeader *header = NULL;
924 gboolean found = FALSE;
926 header = TNY_HEADER (tny_iterator_get_current (iter));
928 flags = tny_header_get_flags (header);
931 found = modest_window_mgr_find_registered_header (mgr, header, &window);
933 /* Do not open again the message and present the
934 window to the user */
937 gtk_window_present (GTK_WINDOW (window));
939 /* the header has been registered already, we don't do
940 * anything but wait for the window to come up*/
941 g_debug ("header %p already registered, waiting for window", header);
943 tny_list_append (not_opened_headers, G_OBJECT (header));
947 g_object_unref (header);
949 tny_iterator_next (iter);
951 g_object_unref (iter);
954 /* If some messages would have to be downloaded, ask the user to
955 * make a connection. It's generally easier to do this here (in the mainloop)
956 * than later in a thread:
958 if (tny_list_get_length (not_opened_headers) > 0) {
960 gboolean found = FALSE;
962 iter = tny_list_create_iterator (not_opened_headers);
963 while (!tny_iterator_is_done (iter) && !found) {
964 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
965 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
968 tny_iterator_next (iter);
970 g_object_unref (header);
972 g_object_unref (iter);
974 if (found && !modest_platform_connect_and_wait (GTK_WINDOW (win), NULL)) {
975 g_object_unref (not_opened_headers);
980 /* Register the headers before actually creating the windows: */
981 TnyIterator *iter_not_opened = tny_list_create_iterator (not_opened_headers);
982 while (!tny_iterator_is_done (iter_not_opened)) {
983 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
985 modest_window_mgr_register_header (mgr, header);
986 g_object_unref (header);
989 tny_iterator_next (iter_not_opened);
991 g_object_unref (iter_not_opened);
992 iter_not_opened = NULL;
994 /* Open each message */
995 if (tny_list_get_length (not_opened_headers) > 0) {
996 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
998 modest_ui_actions_get_msgs_full_error_handler,
1000 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1001 if (tny_list_get_length (not_opened_headers) > 1) {
1002 modest_mail_operation_get_msgs_full (mail_op,
1008 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1009 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1010 modest_mail_operation_get_msg (mail_op, header, open_msg_cb, NULL);
1011 g_object_unref (header);
1012 g_object_unref (iter);
1014 g_object_unref (mail_op);
1018 if (not_opened_headers != NULL)
1019 g_object_unref (not_opened_headers);
1023 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1028 headers = get_selected_headers (win);
1033 _modest_ui_actions_open (headers, win);
1035 g_object_unref(headers);
1040 free_reply_forward_helper (gpointer data)
1042 ReplyForwardHelper *helper;
1044 helper = (ReplyForwardHelper *) data;
1045 g_free (helper->account_name);
1046 g_slice_free (ReplyForwardHelper, helper);
1050 reply_forward_cb (ModestMailOperation *mail_op,
1056 ReplyForwardHelper *rf_helper;
1057 ModestWindow *msg_win = NULL;
1058 ModestEditType edit_type;
1060 TnyAccount *account = NULL;
1061 ModestWindowMgr *mgr = NULL;
1062 gchar *signature = NULL;
1064 /* If there was any error. The mail operation could be NULL,
1065 this means that we already have the message downloaded and
1066 that we didn't do a mail operation to retrieve it */
1067 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1070 g_return_if_fail (user_data != NULL);
1071 rf_helper = (ReplyForwardHelper *) user_data;
1073 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1074 rf_helper->account_name);
1075 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
1076 rf_helper->account_name,
1077 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
1078 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
1079 rf_helper->account_name,
1080 MODEST_ACCOUNT_SIGNATURE, FALSE);
1083 /* Create reply mail */
1084 switch (rf_helper->action) {
1087 modest_tny_msg_create_reply_msg (msg, header, from, signature,
1088 rf_helper->reply_forward_type,
1089 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1091 case ACTION_REPLY_TO_ALL:
1093 modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1094 MODEST_TNY_MSG_REPLY_MODE_ALL);
1095 edit_type = MODEST_EDIT_TYPE_REPLY;
1097 case ACTION_FORWARD:
1099 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1100 edit_type = MODEST_EDIT_TYPE_FORWARD;
1103 g_return_if_reached ();
1110 g_printerr ("modest: failed to create message\n");
1114 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1115 rf_helper->account_name,
1116 TNY_ACCOUNT_TYPE_STORE);
1118 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1122 /* Create and register the windows */
1123 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1124 mgr = modest_runtime_get_window_mgr ();
1125 modest_window_mgr_register_window (mgr, msg_win);
1127 if (rf_helper->parent_window != NULL) {
1128 gdouble parent_zoom;
1130 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1131 modest_window_set_zoom (msg_win, parent_zoom);
1134 /* Show edit window */
1135 gtk_widget_show_all (GTK_WIDGET (msg_win));
1139 g_object_unref (msg_win);
1141 g_object_unref (G_OBJECT (new_msg));
1143 g_object_unref (G_OBJECT (account));
1144 /* g_object_unref (msg); */
1145 free_reply_forward_helper (rf_helper);
1149 * Checks a list of headers. If any of them are not currently
1150 * downloaded (CACHED) then it asks the user for permission to
1153 * Returns FALSE if the user does not want to download the
1154 * messages. Returns TRUE if the user allowed the download or if all
1155 * of them are currently downloaded
1158 download_uncached_messages (TnyList *header_list,
1164 gint uncached_messages = 0;
1166 iter = tny_list_create_iterator (header_list);
1167 while (!tny_iterator_is_done (iter)) {
1170 header = TNY_HEADER (tny_iterator_get_current (iter));
1172 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1173 uncached_messages ++;
1174 g_object_unref (header);
1177 tny_iterator_next (iter);
1179 g_object_unref (iter);
1181 /* Ask for user permission to download the messages */
1183 if (uncached_messages > 0) {
1184 GtkResponseType response;
1186 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1187 _("emev_nc_include_original"));
1190 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1191 ngettext("mcen_nc_get_msg",
1193 uncached_messages));
1194 if (response == GTK_RESPONSE_CANCEL)
1197 /* If a download will be necessary, make sure that we have a connection: */
1198 retval = modest_platform_connect_and_wait(win, NULL);
1206 * Common code for the reply and forward actions
1209 reply_forward (ReplyForwardAction action, ModestWindow *win)
1211 ModestMailOperation *mail_op = NULL;
1212 TnyList *header_list = NULL;
1213 ReplyForwardHelper *rf_helper = NULL;
1214 guint reply_forward_type;
1215 gboolean continue_download = TRUE;
1216 gboolean do_retrieve = TRUE;
1218 g_return_if_fail (MODEST_IS_WINDOW(win));
1220 /* we need an account when editing */
1221 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1222 run_account_setup_wizard (win);
1226 header_list = get_selected_headers (win);
1230 reply_forward_type =
1231 modest_conf_get_int (modest_runtime_get_conf (),
1232 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1235 /* Check that the messages have been previously downloaded */
1236 do_retrieve = (action == ACTION_FORWARD) || (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1238 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win), TRUE);
1239 if (!continue_download) {
1240 g_object_unref (header_list);
1244 /* We assume that we can only select messages of the
1245 same folder and that we reply all of them from the
1246 same account. In fact the interface currently only
1247 allows single selection */
1250 rf_helper = g_slice_new0 (ReplyForwardHelper);
1251 rf_helper->reply_forward_type = reply_forward_type;
1252 rf_helper->action = action;
1253 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1255 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1256 rf_helper->parent_window = GTK_WIDGET (win);
1257 if (!rf_helper->account_name)
1258 rf_helper->account_name =
1259 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1261 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1264 /* Get header and message. Do not free them here, the
1265 reply_forward_cb must do it */
1266 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1267 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1268 if (!msg || !header) {
1270 g_object_unref (msg);
1271 g_printerr ("modest: no message found\n");
1274 reply_forward_cb (NULL, header, msg, rf_helper);
1277 g_object_unref (header);
1282 /* Only reply/forward to one message */
1283 iter = tny_list_create_iterator (header_list);
1284 header = TNY_HEADER (tny_iterator_get_current (iter));
1285 g_object_unref (iter);
1288 /* Retrieve messages */
1290 mail_op = modest_mail_operation_new_with_error_handling (
1291 MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1293 modest_ui_actions_get_msgs_full_error_handler,
1295 modest_mail_operation_queue_add (
1296 modest_runtime_get_mail_operation_queue (), mail_op);
1298 modest_mail_operation_get_msg (mail_op,
1303 g_object_unref(mail_op);
1305 /* we put a ref here to prevent double unref as the reply
1306 * forward callback unrefs the header at its end */
1307 reply_forward_cb (NULL, header, NULL, rf_helper);
1311 g_object_unref (header);
1317 g_object_unref (header_list);
1321 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1323 g_return_if_fail (MODEST_IS_WINDOW(win));
1325 reply_forward (ACTION_REPLY, win);
1329 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1331 g_return_if_fail (MODEST_IS_WINDOW(win));
1333 reply_forward (ACTION_FORWARD, win);
1337 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1339 g_return_if_fail (MODEST_IS_WINDOW(win));
1341 reply_forward (ACTION_REPLY_TO_ALL, win);
1345 modest_ui_actions_on_next (GtkAction *action,
1346 ModestWindow *window)
1348 if (MODEST_IS_MAIN_WINDOW (window)) {
1349 GtkWidget *header_view;
1351 header_view = modest_main_window_get_child_widget (
1352 MODEST_MAIN_WINDOW(window),
1353 MODEST_WIDGET_TYPE_HEADER_VIEW);
1357 modest_header_view_select_next (
1358 MODEST_HEADER_VIEW(header_view));
1359 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1360 modest_msg_view_window_select_next_message (
1361 MODEST_MSG_VIEW_WINDOW (window));
1363 g_return_if_reached ();
1368 modest_ui_actions_on_prev (GtkAction *action,
1369 ModestWindow *window)
1371 g_return_if_fail (MODEST_IS_WINDOW(window));
1373 if (MODEST_IS_MAIN_WINDOW (window)) {
1374 GtkWidget *header_view;
1375 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1376 MODEST_WIDGET_TYPE_HEADER_VIEW);
1380 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1381 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1382 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1384 g_return_if_reached ();
1389 modest_ui_actions_on_sort (GtkAction *action,
1390 ModestWindow *window)
1392 g_return_if_fail (MODEST_IS_WINDOW(window));
1394 if (MODEST_IS_MAIN_WINDOW (window)) {
1395 GtkWidget *header_view;
1396 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1397 MODEST_WIDGET_TYPE_HEADER_VIEW);
1399 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1404 /* Show sorting dialog */
1405 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1410 new_messages_arrived (ModestMailOperation *self,
1414 if (new_messages == 0)
1417 modest_platform_on_new_msg ();
1421 * This function performs the send & receive required actions. The
1422 * window is used to create the mail operation. Typically it should
1423 * always be the main window, but we pass it as argument in order to
1427 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1429 gchar *acc_name = NULL;
1430 ModestMailOperation *mail_op;
1432 /* If no account name was provided then get the current account, and if
1433 there is no current account then pick the default one: */
1434 if (!account_name) {
1435 acc_name = g_strdup (modest_window_get_active_account(win));
1437 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1439 g_printerr ("modest: cannot get default account\n");
1443 acc_name = g_strdup (account_name);
1446 /* Set send/receive operation in progress */
1447 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1449 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1451 modest_ui_actions_send_receive_error_handler,
1454 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1455 G_CALLBACK (_on_send_receive_progress_changed),
1458 /* Send & receive. */
1459 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1460 /* Receive and then send. The operation is tagged initially as
1461 a receive operation because the account update performs a
1462 receive and then a send. The operation changes its type
1463 internally, so the progress objects will receive the proper
1464 progress information */
1465 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1466 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, NULL);
1467 g_object_unref (G_OBJECT (mail_op));
1475 modest_ui_actions_do_cancel_send (const gchar *account_name,
1478 TnyTransportAccount *transport_account;
1479 TnySendQueue *send_queue = NULL;
1480 GError *error = NULL;
1482 /* Get transport account */
1484 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1485 (modest_runtime_get_account_store(),
1487 TNY_ACCOUNT_TYPE_TRANSPORT));
1488 if (!transport_account) {
1489 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1494 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1495 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1496 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1497 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1498 "modest: could not find send queue for account\n");
1500 /* Keeep messages in outbox folder */
1501 tny_send_queue_cancel (send_queue, FALSE, &error);
1505 if (transport_account != NULL)
1506 g_object_unref (G_OBJECT (transport_account));
1510 modest_ui_actions_cancel_send_all (ModestWindow *win)
1512 GSList *account_names, *iter;
1514 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1517 iter = account_names;
1519 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1520 iter = g_slist_next (iter);
1523 modest_account_mgr_free_account_names (account_names);
1524 account_names = NULL;
1528 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1531 /* Check if accounts exist */
1532 gboolean accounts_exist =
1533 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1535 /* If not, allow the user to create an account before trying to send/receive. */
1536 if (!accounts_exist)
1537 modest_ui_actions_on_accounts (NULL, win);
1539 /* Cancel all sending operaitons */
1540 modest_ui_actions_cancel_send_all (win);
1544 * Refreshes all accounts. This function will be used by automatic
1548 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1550 GSList *account_names, *iter;
1552 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1555 iter = account_names;
1557 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1558 iter = g_slist_next (iter);
1561 modest_account_mgr_free_account_names (account_names);
1562 account_names = NULL;
1566 modest_do_refresh_current_folder(ModestWindow *win)
1568 /* Refresh currently selected folder. Note that if we only
1569 want to retreive the headers, then the refresh only will
1570 invoke a poke_status over all folders, i.e., only the
1571 total/unread count will be updated */
1572 if (MODEST_IS_MAIN_WINDOW (win)) {
1573 GtkWidget *header_view, *folder_view;
1574 TnyFolderStore *folder_store;
1576 /* Get folder and header view */
1578 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1579 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1581 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1583 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1585 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1586 MODEST_WIDGET_TYPE_HEADER_VIEW);
1588 /* We do not need to set the contents style
1589 because it hasn't changed. We also do not
1590 need to save the widget status. Just force
1592 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1593 TNY_FOLDER (folder_store),
1594 folder_refreshed_cb,
1595 MODEST_MAIN_WINDOW (win));
1599 g_object_unref (folder_store);
1605 * Handler of the click on Send&Receive button in the main toolbar
1608 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1610 /* Check if accounts exist */
1611 gboolean accounts_exist =
1612 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1614 /* If not, allow the user to create an account before trying to send/receive. */
1615 if (!accounts_exist)
1616 modest_ui_actions_on_accounts (NULL, win);
1618 modest_do_refresh_current_folder (win);
1620 /* Refresh the active account */
1621 modest_ui_actions_do_send_receive (NULL, win);
1626 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1629 GtkWidget *header_view;
1631 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1633 header_view = modest_main_window_get_child_widget (main_window,
1634 MODEST_WIDGET_TYPE_HEADER_VIEW);
1638 conf = modest_runtime_get_conf ();
1640 /* what is saved/restored is depending on the style; thus; we save with
1641 * old style, then update the style, and restore for this new style
1643 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1645 if (modest_header_view_get_style
1646 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1647 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1648 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1650 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1651 MODEST_HEADER_VIEW_STYLE_DETAILS);
1653 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1654 MODEST_CONF_HEADER_VIEW_KEY);
1659 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1661 ModestMainWindow *main_window)
1663 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1664 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1666 /* in the case the folder is empty, show the empty folder message and focus
1668 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1669 if (modest_header_view_is_empty (header_view)) {
1670 TnyFolder *folder = modest_header_view_get_folder (header_view);
1671 GtkWidget *folder_view =
1672 modest_main_window_get_child_widget (main_window,
1673 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1675 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1676 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1680 /* If no header has been selected then exit */
1685 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1686 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1688 /* Update Main window title */
1689 if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
1690 const gchar *subject = tny_header_get_subject (header);
1691 if (subject && strlen(subject) > 0)
1692 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1694 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1697 /* Update toolbar dimming state */
1698 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1702 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1704 ModestMainWindow *main_window)
1708 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1713 headers = tny_simple_list_new ();
1714 tny_list_prepend (headers, G_OBJECT (header));
1716 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1718 g_object_unref (headers);
1722 set_active_account_from_tny_account (TnyAccount *account,
1723 ModestWindow *window)
1725 const gchar *server_acc_name = tny_account_get_id (account);
1727 /* We need the TnyAccount provided by the
1728 account store because that is the one that
1729 knows the name of the Modest account */
1730 TnyAccount *modest_server_account = modest_server_account =
1731 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1732 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1735 const gchar *modest_acc_name =
1736 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1737 modest_window_set_active_account (window, modest_acc_name);
1738 g_object_unref (modest_server_account);
1743 folder_refreshed_cb (ModestMailOperation *mail_op,
1747 ModestMainWindow *win = NULL;
1748 GtkWidget *header_view;
1749 TnyFolder *current_folder;
1751 g_return_if_fail (TNY_IS_FOLDER (folder));
1753 win = MODEST_MAIN_WINDOW (user_data);
1755 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1758 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1759 if (current_folder != NULL && folder != current_folder) {
1764 /* Check if folder is empty and set headers view contents style */
1765 if (tny_folder_get_all_count (folder) == 0) {
1766 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1767 modest_main_window_set_contents_style (win,
1768 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1770 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1775 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1776 TnyFolderStore *folder_store,
1778 ModestMainWindow *main_window)
1781 GtkWidget *header_view;
1783 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1785 header_view = modest_main_window_get_child_widget(main_window,
1786 MODEST_WIDGET_TYPE_HEADER_VIEW);
1790 conf = modest_runtime_get_conf ();
1792 if (TNY_IS_ACCOUNT (folder_store)) {
1794 /* Update active account */
1795 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1796 /* Show account details */
1797 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1800 if (TNY_IS_FOLDER (folder_store) && selected) {
1802 /* Update the active account */
1803 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1805 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1806 g_object_unref (account);
1810 /* Set the header style by default, it could
1811 be changed later by the refresh callback to
1813 modest_main_window_set_contents_style (main_window,
1814 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1816 /* Set folder on header view. This function
1817 will call tny_folder_refresh_async so we
1818 pass a callback that will be called when
1819 finished. We use that callback to set the
1820 empty view if there are no messages */
1821 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1822 TNY_FOLDER (folder_store),
1823 folder_refreshed_cb,
1826 /* Restore configuration. We need to do this
1827 *after* the set_folder because the widget
1828 memory asks the header view about its
1830 modest_widget_memory_restore (modest_runtime_get_conf (),
1831 G_OBJECT(header_view),
1832 MODEST_CONF_HEADER_VIEW_KEY);
1834 /* Update the active account */
1835 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1836 /* Save only if we're seeing headers */
1837 if (modest_main_window_get_contents_style (main_window) ==
1838 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1839 modest_widget_memory_save (conf, G_OBJECT (header_view),
1840 MODEST_CONF_HEADER_VIEW_KEY);
1841 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1845 /* Update toolbar dimming state */
1846 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1850 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1857 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1859 online = tny_device_is_online (modest_runtime_get_device());
1862 /* already online -- the item is simply not there... */
1863 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1865 GTK_MESSAGE_WARNING,
1867 _("The %s you selected cannot be found"),
1869 gtk_dialog_run (GTK_DIALOG(dialog));
1871 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1875 GTK_RESPONSE_REJECT,
1877 GTK_RESPONSE_ACCEPT,
1879 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1880 "Do you want to get online?"), item);
1881 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1882 gtk_label_new (txt), FALSE, FALSE, 0);
1883 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1886 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1887 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1888 /* TODO: Comment about why is this commented out: */
1889 /* modest_platform_connect_and_wait (); */
1892 gtk_widget_destroy (dialog);
1896 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1899 /* g_message ("%s %s", __FUNCTION__, link); */
1904 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1907 modest_platform_activate_uri (link);
1911 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1914 modest_platform_show_uri_popup (link);
1918 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1921 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1925 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1926 const gchar *address,
1929 /* g_message ("%s %s", __FUNCTION__, address); */
1933 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1935 TnyTransportAccount *transport_account;
1936 ModestMailOperation *mail_operation;
1938 gchar *account_name, *from;
1939 ModestAccountMgr *account_mgr;
1940 gchar *info_text = NULL;
1942 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1944 data = modest_msg_edit_window_get_msg_data (edit_window);
1946 account_mgr = modest_runtime_get_account_mgr();
1947 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1949 account_name = modest_account_mgr_get_default_account (account_mgr);
1950 if (!account_name) {
1951 g_printerr ("modest: no account found\n");
1952 modest_msg_edit_window_free_msg_data (edit_window, data);
1956 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1957 account_name = g_strdup (data->account_name);
1961 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1962 (modest_runtime_get_account_store(),
1964 TNY_ACCOUNT_TYPE_TRANSPORT));
1965 if (!transport_account) {
1966 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1967 g_free (account_name);
1968 modest_msg_edit_window_free_msg_data (edit_window, data);
1971 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1973 /* Create the mail operation */
1974 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1975 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1977 modest_mail_operation_save_to_drafts (mail_operation,
1989 data->priority_flags);
1992 g_free (account_name);
1993 g_object_unref (G_OBJECT (transport_account));
1994 g_object_unref (G_OBJECT (mail_operation));
1996 modest_msg_edit_window_free_msg_data (edit_window, data);
1998 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
1999 modest_platform_information_banner (NULL, NULL, info_text);
2003 /* For instance, when clicking the Send toolbar button when editing a message: */
2005 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2007 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2009 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2012 /* Offer the connection dialog, if necessary: */
2013 if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
2016 /* FIXME: Code added just for testing. The final version will
2017 use the send queue provided by tinymail and some
2019 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2020 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2022 account_name = modest_account_mgr_get_default_account (account_mgr);
2024 if (!account_name) {
2025 /* Run account setup wizard */
2026 run_account_setup_wizard(MODEST_WINDOW(edit_window));
2030 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2032 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2033 account_name = g_strdup (data->account_name);
2036 /* Get the currently-active transport account for this modest account: */
2037 TnyTransportAccount *transport_account =
2038 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2039 (modest_runtime_get_account_store(),
2041 if (!transport_account) {
2042 /* Run account setup wizard */
2043 run_account_setup_wizard(MODEST_WINDOW(edit_window));
2047 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2049 /* mail content checks and dialogs */
2050 if (data->subject == NULL || data->subject[0] == '\0') {
2051 GtkResponseType response;
2052 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
2053 _("mcen_nc_subject_is_empty_send"));
2054 if (response == GTK_RESPONSE_CANCEL) {
2055 g_free (account_name);
2060 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
2061 GtkResponseType response;
2062 gchar *note_message;
2063 gchar *note_subject = data->subject;
2064 if (note_subject == NULL || note_subject[0] == '\0')
2065 note_subject = _("mail_va_no_subject");
2066 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
2067 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
2069 g_free (note_message);
2070 if (response == GTK_RESPONSE_CANCEL) {
2071 g_free (account_name);
2076 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2078 /* Create the mail operation */
2079 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
2080 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2082 modest_mail_operation_send_new_mail (mail_operation,
2093 data->priority_flags);
2097 g_free (account_name);
2098 g_object_unref (G_OBJECT (transport_account));
2099 g_object_unref (G_OBJECT (mail_operation));
2101 modest_msg_edit_window_free_msg_data (edit_window, data);
2102 modest_msg_edit_window_set_sent (edit_window, TRUE);
2104 /* Save settings and close the window: */
2105 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2109 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2110 ModestMsgEditWindow *window)
2112 ModestMsgEditFormatState *format_state = NULL;
2114 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2115 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2117 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2120 format_state = modest_msg_edit_window_get_format_state (window);
2121 g_return_if_fail (format_state != NULL);
2123 format_state->bold = gtk_toggle_action_get_active (action);
2124 modest_msg_edit_window_set_format_state (window, format_state);
2125 g_free (format_state);
2130 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2131 ModestMsgEditWindow *window)
2133 ModestMsgEditFormatState *format_state = NULL;
2135 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2136 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2138 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2141 format_state = modest_msg_edit_window_get_format_state (window);
2142 g_return_if_fail (format_state != NULL);
2144 format_state->italics = gtk_toggle_action_get_active (action);
2145 modest_msg_edit_window_set_format_state (window, format_state);
2146 g_free (format_state);
2151 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2152 ModestMsgEditWindow *window)
2154 ModestMsgEditFormatState *format_state = NULL;
2156 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2157 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2159 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2162 format_state = modest_msg_edit_window_get_format_state (window);
2163 g_return_if_fail (format_state != NULL);
2165 format_state->bullet = gtk_toggle_action_get_active (action);
2166 modest_msg_edit_window_set_format_state (window, format_state);
2167 g_free (format_state);
2172 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2173 GtkRadioAction *selected,
2174 ModestMsgEditWindow *window)
2176 ModestMsgEditFormatState *format_state = NULL;
2177 GtkJustification value;
2179 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2181 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2184 value = gtk_radio_action_get_current_value (selected);
2186 format_state = modest_msg_edit_window_get_format_state (window);
2187 g_return_if_fail (format_state != NULL);
2189 format_state->justification = value;
2190 modest_msg_edit_window_set_format_state (window, format_state);
2191 g_free (format_state);
2195 modest_ui_actions_on_select_editor_color (GtkAction *action,
2196 ModestMsgEditWindow *window)
2198 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2199 g_return_if_fail (GTK_IS_ACTION (action));
2201 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2204 modest_msg_edit_window_select_color (window);
2208 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2209 ModestMsgEditWindow *window)
2211 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2212 g_return_if_fail (GTK_IS_ACTION (action));
2214 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2217 modest_msg_edit_window_select_background_color (window);
2221 modest_ui_actions_on_insert_image (GtkAction *action,
2222 ModestMsgEditWindow *window)
2224 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2225 g_return_if_fail (GTK_IS_ACTION (action));
2227 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2230 modest_msg_edit_window_insert_image (window);
2234 modest_ui_actions_on_attach_file (GtkAction *action,
2235 ModestMsgEditWindow *window)
2237 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2238 g_return_if_fail (GTK_IS_ACTION (action));
2240 modest_msg_edit_window_offer_attach_file (window);
2244 modest_ui_actions_on_remove_attachments (GtkAction *action,
2245 ModestMsgEditWindow *window)
2247 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2248 g_return_if_fail (GTK_IS_ACTION (action));
2250 modest_msg_edit_window_remove_attachments (window, NULL);
2254 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2257 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2258 const GError *error = modest_mail_operation_get_error (mail_op);
2262 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2263 modest_mail_operation_get_error (mail_op)->message);
2268 modest_ui_actions_create_folder(GtkWidget *parent_window,
2269 GtkWidget *folder_view)
2271 TnyFolderStore *parent_folder;
2273 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2275 if (parent_folder) {
2276 gboolean finished = FALSE;
2278 gchar *folder_name = NULL, *suggested_name = NULL;
2279 const gchar *proto_str = NULL;
2280 TnyAccount *account;
2282 if (TNY_IS_ACCOUNT (parent_folder))
2283 account = g_object_ref (parent_folder);
2285 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2286 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2288 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2289 MODEST_PROTOCOL_STORE_POP) {
2291 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2293 g_object_unref (account);
2295 /* Run the new folder dialog */
2297 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2302 g_free (suggested_name);
2303 suggested_name = NULL;
2305 if (result == GTK_RESPONSE_REJECT) {
2308 ModestMailOperation *mail_op;
2309 TnyFolder *new_folder = NULL;
2311 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2312 G_OBJECT(parent_window),
2313 modest_ui_actions_new_folder_error_handler,
2316 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2318 new_folder = modest_mail_operation_create_folder (mail_op,
2320 (const gchar *) folder_name);
2322 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2325 g_object_unref (new_folder);
2328 g_object_unref (mail_op);
2331 suggested_name = folder_name;
2335 g_object_unref (parent_folder);
2340 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2342 GtkWidget *folder_view;
2344 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2346 folder_view = modest_main_window_get_child_widget (main_window,
2347 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2351 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2355 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2358 GObject *win = modest_mail_operation_get_source (mail_op);
2359 const GError *error = NULL;
2360 const gchar *message = NULL;
2362 /* Get error message */
2363 error = modest_mail_operation_get_error (mail_op);
2364 if (error != NULL && error->message != NULL) {
2365 message = error->message;
2367 message = _("!!! FIXME: Unable to rename");
2370 /* Show notification dialog */
2371 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
2372 g_object_unref (win);
2376 modest_ui_actions_on_rename_folder (GtkAction *action,
2377 ModestMainWindow *main_window)
2379 TnyFolderStore *folder;
2380 GtkWidget *folder_view;
2381 GtkWidget *header_view;
2383 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2385 folder_view = modest_main_window_get_child_widget (main_window,
2386 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2390 header_view = modest_main_window_get_child_widget (main_window,
2391 MODEST_WIDGET_TYPE_HEADER_VIEW);
2396 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2400 /* Offer the connection dialog if necessary: */
2401 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2402 g_object_unref (G_OBJECT (folder));
2407 if (TNY_IS_FOLDER (folder)) {
2410 const gchar *current_name;
2412 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2413 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
2414 current_name, &folder_name);
2416 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
2417 ModestMailOperation *mail_op;
2420 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2421 G_OBJECT(main_window),
2422 modest_ui_actions_rename_folder_error_handler,
2426 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2429 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2431 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2432 TNY_FOLDER(folder), TRUE);
2435 modest_header_view_clear ((ModestHeaderView *) header_view);
2437 modest_mail_operation_rename_folder (mail_op,
2438 TNY_FOLDER (folder),
2439 (const gchar *) folder_name);
2441 g_object_unref (mail_op);
2442 g_free (folder_name);
2445 g_object_unref (folder);
2449 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2452 GObject *win = modest_mail_operation_get_source (mail_op);
2454 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2455 _("mail_in_ui_folder_delete_error"));
2456 g_object_unref (win);
2460 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2462 TnyFolderStore *folder;
2463 GtkWidget *folder_view;
2467 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
2469 folder_view = modest_main_window_get_child_widget (main_window,
2470 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2474 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2476 /* Show an error if it's an account */
2477 if (!TNY_IS_FOLDER (folder)) {
2478 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2479 _("mail_in_ui_folder_delete_error"));
2480 g_object_unref (G_OBJECT (folder));
2484 /* Offer the connection dialog if necessary: */
2485 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2486 g_object_unref (G_OBJECT (folder));
2491 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2492 tny_folder_get_name (TNY_FOLDER (folder)));
2493 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2494 (const gchar *) message);
2497 if (response == GTK_RESPONSE_OK) {
2498 ModestMailOperation *mail_op =
2499 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2500 G_OBJECT(main_window),
2501 modest_ui_actions_delete_folder_error_handler,
2504 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2506 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2507 g_object_unref (G_OBJECT (mail_op));
2510 g_object_unref (G_OBJECT (folder));
2514 modest_ui_actions_on_delete_folder (GtkAction *action,
2515 ModestMainWindow *main_window)
2517 GtkWidget *folder_view;
2518 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2520 delete_folder (main_window, FALSE);
2521 folder_view = modest_main_window_get_child_widget (main_window,
2522 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2525 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2529 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2531 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2533 delete_folder (main_window, TRUE);
2538 show_error (GtkWidget *parent_widget, const gchar* text)
2540 hildon_banner_show_information(parent_widget, NULL, text);
2543 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2545 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2552 gtk_dialog_run (dialog);
2553 gtk_widget_destroy (GTK_WIDGET (dialog));
2558 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2559 const gchar* server_account_name,
2564 ModestMainWindow *main_window)
2566 g_return_if_fail(server_account_name);
2567 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2569 /* Initalize output parameters: */
2576 #ifdef MODEST_PLATFORM_MAEMO
2577 /* Maemo uses a different (awkward) button order,
2578 * It should probably just use gtk_alternative_dialog_button_order ().
2580 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2584 GTK_RESPONSE_ACCEPT,
2586 GTK_RESPONSE_REJECT,
2589 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2593 GTK_RESPONSE_REJECT,
2595 GTK_RESPONSE_ACCEPT,
2597 #endif /* MODEST_PLATFORM_MAEMO */
2599 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2601 gchar *server_name = modest_server_account_get_hostname (
2602 modest_runtime_get_account_mgr(), server_account_name);
2603 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2604 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2609 /* This causes a warning because the logical ID has no %s in it,
2610 * though the translation does, but there is not much we can do about that: */
2611 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2612 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2615 g_free (server_name);
2619 gchar *initial_username = modest_server_account_get_username (
2620 modest_runtime_get_account_mgr(), server_account_name);
2622 GtkWidget *entry_username = gtk_entry_new ();
2623 if (initial_username)
2624 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2625 /* Dim this if a connection has ever succeeded with this username,
2626 * as per the UI spec: */
2627 const gboolean username_known =
2628 modest_server_account_get_username_has_succeeded(
2629 modest_runtime_get_account_mgr(), server_account_name);
2630 gtk_widget_set_sensitive (entry_username, !username_known);
2632 #ifdef MODEST_PLATFORM_MAEMO
2633 /* Auto-capitalization is the default, so let's turn it off: */
2634 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2636 /* Create a size group to be used by all captions.
2637 * Note that HildonCaption does not create a default size group if we do not specify one.
2638 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2639 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2641 GtkWidget *caption = hildon_caption_new (sizegroup,
2642 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2643 gtk_widget_show (entry_username);
2644 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2645 FALSE, FALSE, MODEST_MARGIN_HALF);
2646 gtk_widget_show (caption);
2648 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2650 #endif /* MODEST_PLATFORM_MAEMO */
2653 GtkWidget *entry_password = gtk_entry_new ();
2654 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2655 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2657 #ifdef MODEST_PLATFORM_MAEMO
2658 /* Auto-capitalization is the default, so let's turn it off: */
2659 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2660 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2662 caption = hildon_caption_new (sizegroup,
2663 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2664 gtk_widget_show (entry_password);
2665 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2666 FALSE, FALSE, MODEST_MARGIN_HALF);
2667 gtk_widget_show (caption);
2668 g_object_unref (sizegroup);
2670 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2672 #endif /* MODEST_PLATFORM_MAEMO */
2674 /* This is not in the Maemo UI spec:
2675 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2676 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2680 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2682 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2684 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2686 modest_server_account_set_username (
2687 modest_runtime_get_account_mgr(), server_account_name,
2690 const gboolean username_was_changed =
2691 (strcmp (*username, initial_username) != 0);
2692 if (username_was_changed) {
2693 g_warning ("%s: tinymail does not yet support changing the "
2694 "username in the get_password() callback.\n", __FUNCTION__);
2699 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2701 /* We do not save the password in the configuration,
2702 * because this function is only called for passwords that should
2703 * not be remembered:
2704 modest_server_account_set_password (
2705 modest_runtime_get_account_mgr(), server_account_name,
2714 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2726 /* This is not in the Maemo UI spec:
2727 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2733 gtk_widget_destroy (dialog);
2735 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2739 modest_ui_actions_on_cut (GtkAction *action,
2740 ModestWindow *window)
2742 GtkWidget *focused_widget;
2743 GtkClipboard *clipboard;
2745 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2746 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2747 if (GTK_IS_EDITABLE (focused_widget)) {
2748 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2749 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2750 gtk_clipboard_store (clipboard);
2751 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2752 GtkTextBuffer *buffer;
2754 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2755 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2756 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2757 gtk_clipboard_store (clipboard);
2758 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2759 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2760 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2761 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2766 modest_ui_actions_on_copy (GtkAction *action,
2767 ModestWindow *window)
2769 GtkClipboard *clipboard;
2770 GtkWidget *focused_widget;
2772 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2773 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2775 if (GTK_IS_LABEL (focused_widget)) {
2776 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2777 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2778 gtk_clipboard_store (clipboard);
2779 } else if (GTK_IS_EDITABLE (focused_widget)) {
2780 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2781 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2782 gtk_clipboard_store (clipboard);
2783 } else if (GTK_IS_HTML (focused_widget)) {
2784 gtk_html_copy (GTK_HTML (focused_widget));
2785 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2786 gtk_clipboard_store (clipboard);
2787 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2788 GtkTextBuffer *buffer;
2789 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2790 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2791 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2792 gtk_clipboard_store (clipboard);
2793 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2794 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2795 TnyIterator *iter = tny_list_create_iterator (header_list);
2796 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2798 gboolean ask = FALSE;
2800 TnyFolder *folder = tny_header_get_folder (header);
2801 TnyAccount *account = tny_folder_get_account (folder);
2802 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2803 /* If it's POP then ask */
2804 ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2805 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2806 g_object_unref (account);
2807 g_object_unref (folder);
2808 g_object_unref (header);
2811 g_object_unref (iter);
2813 /* Check that the messages have been previously downloaded */
2814 gboolean continue_download = TRUE;
2816 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window), FALSE);
2817 if (continue_download)
2818 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2819 g_object_unref (header_list);
2820 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2821 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2824 /* Show information banner */
2825 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2830 modest_ui_actions_on_undo (GtkAction *action,
2831 ModestWindow *window)
2833 ModestEmailClipboard *clipboard = NULL;
2835 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2836 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2837 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2838 /* Clear clipboard source */
2839 clipboard = modest_runtime_get_email_clipboard ();
2840 modest_email_clipboard_clear (clipboard);
2843 g_return_if_reached ();
2848 modest_ui_actions_on_redo (GtkAction *action,
2849 ModestWindow *window)
2851 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2852 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
2855 g_return_if_reached ();
2861 paste_msgs_cb (const GObject *object, gpointer user_data)
2863 g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2864 g_return_if_fail (GTK_IS_WIDGET (user_data));
2866 /* destroy information note */
2867 gtk_widget_destroy (GTK_WIDGET(user_data));
2871 paste_as_attachment_free (gpointer data)
2873 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
2875 gtk_widget_destroy (helper->banner);
2876 g_object_unref (helper->banner);
2881 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
2886 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
2887 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
2892 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
2897 modest_ui_actions_on_paste (GtkAction *action,
2898 ModestWindow *window)
2900 GtkWidget *focused_widget = NULL;
2901 GtkWidget *inf_note = NULL;
2902 ModestMailOperation *mail_op = NULL;
2904 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2905 if (GTK_IS_EDITABLE (focused_widget)) {
2906 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2907 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2908 ModestEmailClipboard *e_clipboard = NULL;
2909 e_clipboard = modest_runtime_get_email_clipboard ();
2910 if (modest_email_clipboard_cleared (e_clipboard)) {
2911 GtkTextBuffer *buffer;
2912 GtkClipboard *clipboard;
2914 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2915 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2916 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2917 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2918 ModestMailOperation *mail_op;
2919 TnyFolder *src_folder;
2922 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
2923 helper->window = MODEST_MSG_EDIT_WINDOW (window);
2924 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2925 _CS("ckct_nw_pasting"));
2926 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
2927 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2929 if (helper->banner != NULL) {
2930 g_object_ref (G_OBJECT (helper->banner));
2931 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
2932 gtk_widget_show (GTK_WIDGET (helper->banner));
2936 modest_mail_operation_get_msgs_full (mail_op,
2938 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
2940 paste_as_attachment_free);
2943 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2944 ModestEmailClipboard *clipboard = NULL;
2945 TnyFolder *src_folder = NULL;
2946 TnyFolderStore *folder_store = NULL;
2947 TnyList *data = NULL;
2948 gboolean delete = FALSE;
2950 /* Check clipboard source */
2951 clipboard = modest_runtime_get_email_clipboard ();
2952 if (modest_email_clipboard_cleared (clipboard))
2955 /* Get elements to paste */
2956 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2958 /* Create a new mail operation */
2959 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2961 /* Get destination folder */
2962 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2964 /* transfer messages */
2968 /* Ask for user confirmation */
2969 response = msgs_move_to_confirmation (GTK_WINDOW (window),
2970 TNY_FOLDER (folder_store),
2974 if (response == GTK_RESPONSE_OK) {
2975 /* Launch notification */
2976 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2977 _CS("ckct_nw_pasting"));
2978 if (inf_note != NULL) {
2979 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
2980 gtk_widget_show (GTK_WIDGET(inf_note));
2983 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2984 modest_mail_operation_xfer_msgs (mail_op,
2986 TNY_FOLDER (folder_store),
2991 g_object_unref (mail_op);
2994 } else if (src_folder != NULL) {
2995 /* Launch notification */
2996 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2997 _CS("ckct_nw_pasting"));
2998 if (inf_note != NULL) {
2999 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3000 gtk_widget_show (GTK_WIDGET(inf_note));
3003 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3004 modest_mail_operation_xfer_folder (mail_op,
3014 g_object_unref (data);
3015 if (src_folder != NULL)
3016 g_object_unref (src_folder);
3017 if (folder_store != NULL)
3018 g_object_unref (folder_store);
3024 modest_ui_actions_on_select_all (GtkAction *action,
3025 ModestWindow *window)
3027 GtkWidget *focused_widget;
3029 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3030 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3031 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3032 } else if (GTK_IS_LABEL (focused_widget)) {
3033 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3034 } else if (GTK_IS_EDITABLE (focused_widget)) {
3035 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3036 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3037 GtkTextBuffer *buffer;
3038 GtkTextIter start, end;
3040 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3041 gtk_text_buffer_get_start_iter (buffer, &start);
3042 gtk_text_buffer_get_end_iter (buffer, &end);
3043 gtk_text_buffer_select_range (buffer, &start, &end);
3044 } else if (GTK_IS_HTML (focused_widget)) {
3045 gtk_html_select_all (GTK_HTML (focused_widget));
3046 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3047 GtkWidget *header_view = focused_widget;
3048 GtkTreeSelection *selection = NULL;
3050 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
3051 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3052 MODEST_WIDGET_TYPE_HEADER_VIEW);
3054 /* Select all messages */
3055 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3056 gtk_tree_selection_select_all (selection);
3058 /* Set focuse on header view */
3059 gtk_widget_grab_focus (header_view);
3065 modest_ui_actions_on_mark_as_read (GtkAction *action,
3066 ModestWindow *window)
3068 g_return_if_fail (MODEST_IS_WINDOW(window));
3070 /* Mark each header as read */
3071 do_headers_action (window, headers_action_mark_as_read, NULL);
3075 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3076 ModestWindow *window)
3078 g_return_if_fail (MODEST_IS_WINDOW(window));
3080 /* Mark each header as read */
3081 do_headers_action (window, headers_action_mark_as_unread, NULL);
3085 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3086 GtkRadioAction *selected,
3087 ModestWindow *window)
3091 value = gtk_radio_action_get_current_value (selected);
3092 if (MODEST_IS_WINDOW (window)) {
3093 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3097 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3098 GtkRadioAction *selected,
3099 ModestWindow *window)
3101 TnyHeaderFlags flags;
3102 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3104 flags = gtk_radio_action_get_current_value (selected);
3105 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3108 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3109 GtkRadioAction *selected,
3110 ModestWindow *window)
3114 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3116 file_format = gtk_radio_action_get_current_value (selected);
3117 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3122 modest_ui_actions_on_zoom_plus (GtkAction *action,
3123 ModestWindow *window)
3125 g_return_if_fail (MODEST_IS_WINDOW (window));
3127 modest_window_zoom_plus (MODEST_WINDOW (window));
3131 modest_ui_actions_on_zoom_minus (GtkAction *action,
3132 ModestWindow *window)
3134 g_return_if_fail (MODEST_IS_WINDOW (window));
3136 modest_window_zoom_minus (MODEST_WINDOW (window));
3140 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3141 ModestWindow *window)
3143 ModestWindowMgr *mgr;
3144 gboolean fullscreen, active;
3145 g_return_if_fail (MODEST_IS_WINDOW (window));
3147 mgr = modest_runtime_get_window_mgr ();
3149 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3150 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3152 if (active != fullscreen) {
3153 modest_window_mgr_set_fullscreen_mode (mgr, active);
3154 gtk_window_present (GTK_WINDOW (window));
3159 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3160 ModestWindow *window)
3162 ModestWindowMgr *mgr;
3163 gboolean fullscreen;
3165 g_return_if_fail (MODEST_IS_WINDOW (window));
3167 mgr = modest_runtime_get_window_mgr ();
3168 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3169 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3171 gtk_window_present (GTK_WINDOW (window));
3175 * Used by modest_ui_actions_on_details to call do_headers_action
3178 headers_action_show_details (TnyHeader *header,
3179 ModestWindow *window,
3186 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3189 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3190 gtk_widget_show_all (dialog);
3191 gtk_dialog_run (GTK_DIALOG (dialog));
3193 gtk_widget_destroy (dialog);
3197 * Show the folder details in a ModestDetailsDialog widget
3200 show_folder_details (TnyFolder *folder,
3206 dialog = modest_details_dialog_new_with_folder (window, folder);
3209 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3210 gtk_widget_show_all (dialog);
3211 gtk_dialog_run (GTK_DIALOG (dialog));
3213 gtk_widget_destroy (dialog);
3217 * Show the header details in a ModestDetailsDialog widget
3220 modest_ui_actions_on_details (GtkAction *action,
3223 TnyList * headers_list;
3227 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3230 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3233 g_object_unref (msg);
3235 headers_list = get_selected_headers (win);
3239 iter = tny_list_create_iterator (headers_list);
3241 header = TNY_HEADER (tny_iterator_get_current (iter));
3243 headers_action_show_details (header, win, NULL);
3244 g_object_unref (header);
3247 g_object_unref (iter);
3248 g_object_unref (headers_list);
3250 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3251 GtkWidget *folder_view, *header_view;
3253 /* Check which widget has the focus */
3254 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3255 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3256 if (gtk_widget_is_focus (folder_view)) {
3257 TnyFolderStore *folder_store
3258 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3259 if (!folder_store) {
3260 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3263 /* Show only when it's a folder */
3264 /* This function should not be called for account items,
3265 * because we dim the menu item for them. */
3266 if (TNY_IS_FOLDER (folder_store)) {
3267 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3270 g_object_unref (folder_store);
3273 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3274 MODEST_WIDGET_TYPE_HEADER_VIEW);
3275 /* Show details of each header */
3276 do_headers_action (win, headers_action_show_details, header_view);
3282 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3283 ModestMsgEditWindow *window)
3285 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3287 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3291 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3292 ModestMsgEditWindow *window)
3294 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3296 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3300 modest_ui_actions_toggle_folders_view (GtkAction *action,
3301 ModestMainWindow *main_window)
3303 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3305 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3306 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3308 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3312 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3313 ModestWindow *window)
3315 gboolean active, fullscreen = FALSE;
3316 ModestWindowMgr *mgr;
3318 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3320 /* Check if we want to toggle the toolbar vuew in fullscreen
3322 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3323 "ViewShowToolbarFullScreen")) {
3327 /* Toggle toolbar */
3328 mgr = modest_runtime_get_window_mgr ();
3329 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
3333 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3334 ModestMsgEditWindow *window)
3336 modest_msg_edit_window_select_font (window);
3340 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3341 const gchar *display_name,
3344 /* Do not change the application name if the widget has not
3345 the focus. This callback could be called even if the folder
3346 view has not the focus, because the handled signal could be
3347 emitted when the folder view is redrawn */
3348 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3350 gtk_window_set_title (window, display_name);
3352 gtk_window_set_title (window, " ");
3357 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3359 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3360 modest_msg_edit_window_select_contacts (window);
3364 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3366 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3367 modest_msg_edit_window_check_names (window, FALSE);
3371 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3373 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3374 GTK_WIDGET (user_data));
3378 create_move_to_dialog (GtkWindow *win,
3379 GtkWidget *folder_view,
3380 GtkWidget **tree_view)
3382 GtkWidget *dialog, *scroll;
3383 GtkWidget *new_button;
3385 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3387 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3390 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
3391 /* We do this manually so GTK+ does not associate a response ID for
3393 new_button = gtk_button_new_from_stock (GTK_STOCK_NEW);
3394 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3395 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
3397 /* Create scrolled window */
3398 scroll = gtk_scrolled_window_new (NULL, NULL);
3399 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3400 GTK_POLICY_AUTOMATIC,
3401 GTK_POLICY_AUTOMATIC);
3403 /* Create folder view */
3404 *tree_view = modest_platform_create_folder_view (NULL);
3406 g_signal_connect (G_OBJECT (new_button), "clicked", G_CALLBACK(create_move_to_dialog_on_new_folder), *tree_view);
3408 /* It could happen that we're trying to move a message from a
3409 window (msg window for example) after the main window was
3410 closed, so we can not just get the model of the folder
3412 if (MODEST_IS_FOLDER_VIEW (folder_view))
3413 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
3414 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
3416 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3417 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3419 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3421 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3423 /* Add scroll to dialog */
3424 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3425 scroll, TRUE, TRUE, 0);
3427 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3428 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3434 * Returns TRUE if at least one of the headers of the list belongs to
3435 * a message that has been fully retrieved.
3438 has_retrieved_msgs (TnyList *list)
3441 gboolean found = FALSE;
3443 iter = tny_list_create_iterator (list);
3444 while (!tny_iterator_is_done (iter) && !found) {
3446 TnyHeaderFlags flags = 0;
3448 header = TNY_HEADER (tny_iterator_get_current (iter));
3450 flags = tny_header_get_flags (header);
3451 if (flags & TNY_HEADER_FLAG_CACHED)
3452 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3455 g_object_unref (header);
3459 tny_iterator_next (iter);
3461 g_object_unref (iter);
3467 * Shows a confirmation dialog to the user when we're moving messages
3468 * from a remote server to the local storage. Returns the dialog
3469 * response. If it's other kind of movement the it always returns
3473 msgs_move_to_confirmation (GtkWindow *win,
3474 TnyFolder *dest_folder,
3478 gint response = GTK_RESPONSE_OK;
3480 /* If the destination is a local folder (or MMC folder )*/
3481 if (!modest_tny_folder_is_remote_folder (dest_folder)) {
3482 /* if (modest_tny_folder_is_local_folder (dest_folder)) { */
3483 TnyFolder *src_folder = NULL;
3484 TnyIterator *iter = NULL;
3485 TnyHeader *header = NULL;
3487 /* Get source folder */
3488 iter = tny_list_create_iterator (headers);
3489 header = TNY_HEADER (tny_iterator_get_current (iter));
3491 src_folder = tny_header_get_folder (header);
3492 g_object_unref (header);
3495 g_object_unref (iter);
3497 /* if no src_folder, message may be an attahcment */
3498 if (src_folder == NULL)
3499 return GTK_RESPONSE_CANCEL;
3501 /* If the source is a remote folder */
3502 /* if (!modest_tny_folder_is_local_folder (src_folder)) { */
3503 if (modest_tny_folder_is_remote_folder (src_folder)) {
3504 const gchar *message = NULL;
3505 gboolean cached = has_retrieved_msgs (headers);
3507 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
3508 tny_list_get_length (headers));
3510 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
3511 tny_list_get_length (headers));
3513 if (cached && !delete)
3514 response = GTK_RESPONSE_OK;
3516 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
3517 (const gchar *) message);
3520 g_object_unref (src_folder);
3529 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
3531 ModestMsgViewWindow *self = NULL;
3533 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
3534 self = MODEST_MSG_VIEW_WINDOW (object);
3536 if (!modest_msg_view_window_select_next_message (self))
3537 if (!modest_msg_view_window_select_previous_message (self))
3538 /* No more messages to view, so close this window */
3539 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3543 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3546 GObject *win = modest_mail_operation_get_source (mail_op);
3547 const GError *error = NULL;
3548 const gchar *message = NULL;
3550 /* Get error message */
3551 error = modest_mail_operation_get_error (mail_op);
3552 if (error != NULL && error->message != NULL) {
3553 message = error->message;
3555 message = _("mail_in_ui_folder_move_target_error");
3558 /* Show notification dialog */
3559 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3560 g_object_unref (win);
3564 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3567 GObject *win = modest_mail_operation_get_source (mail_op);
3568 const GError *error = modest_mail_operation_get_error (mail_op);
3570 g_return_if_fail (error != NULL);
3571 if (error->message != NULL)
3572 g_printerr ("modest: %s\n", error->message);
3574 g_printerr ("modest: unkonw error on send&receive operation");
3576 /* Show error message */
3577 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3578 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3579 /* _CS("sfil_ib_unable_to_receive")); */
3581 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3582 /* _CS("sfil_ib_unable_to_send")); */
3583 g_object_unref (win);
3587 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3594 gint pending_purges = 0;
3595 gboolean some_purged = FALSE;
3596 ModestWindow *win = MODEST_WINDOW (user_data);
3597 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3599 /* If there was any error */
3600 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
3601 modest_window_mgr_unregister_header (mgr, header);
3605 /* Once the message has been retrieved for purging, we check if
3606 * it's all ok for purging */
3608 parts = tny_simple_list_new ();
3609 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3610 iter = tny_list_create_iterator (parts);
3612 while (!tny_iterator_is_done (iter)) {
3614 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3615 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
3616 if (tny_mime_part_is_purged (part))
3623 g_object_unref (part);
3625 tny_iterator_next (iter);
3628 if (pending_purges>0) {
3630 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3632 if (response == GTK_RESPONSE_OK) {
3633 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3634 tny_iterator_first (iter);
3635 while (!tny_iterator_is_done (iter)) {
3638 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3639 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
3640 tny_mime_part_set_purged (part);
3643 g_object_unref (part);
3645 tny_iterator_next (iter);
3648 tny_msg_rewrite_cache (msg);
3651 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3654 /* remove attachments */
3655 tny_iterator_first (iter);
3656 while (!tny_iterator_is_done (iter)) {
3659 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3661 /* One for the reference given by tny_iterator_get_current(): */
3662 g_object_unref (part);
3664 /* TODO: Is this meant to remove the attachment by doing another unref()?
3665 * Otherwise, this seems useless. */
3668 tny_iterator_next (iter);
3670 modest_window_mgr_unregister_header (mgr, header);
3672 g_object_unref (iter);
3673 g_object_unref (parts);
3677 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3678 ModestMainWindow *win)
3680 GtkWidget *header_view;
3681 TnyList *header_list;
3684 TnyHeaderFlags flags;
3685 ModestWindow *msg_view_window = NULL;
3688 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3690 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3691 MODEST_WIDGET_TYPE_HEADER_VIEW);
3693 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3695 if (tny_list_get_length (header_list) == 1) {
3696 iter = tny_list_create_iterator (header_list);
3697 header = TNY_HEADER (tny_iterator_get_current (iter));
3698 g_object_unref (iter);
3703 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3704 header, &msg_view_window);
3705 flags = tny_header_get_flags (header);
3706 if (!(flags & TNY_HEADER_FLAG_CACHED))
3709 if (msg_view_window != NULL)
3710 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3712 /* do nothing; uid was registered before, so window is probably on it's way */
3713 g_warning ("debug: header %p has already been registered", header);
3716 ModestMailOperation *mail_op = NULL;
3717 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3718 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3720 modest_ui_actions_get_msgs_full_error_handler,
3722 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3723 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3725 g_object_unref (mail_op);
3728 g_object_unref (header);
3730 g_object_unref (header_list);
3734 * Utility function that transfer messages from both the main window
3735 * and the msg view window when using the "Move to" dialog
3738 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
3741 TnyList *headers = NULL;
3743 TnyAccount *dst_account = NULL;
3744 const gchar *proto_str = NULL;
3745 gboolean dst_is_pop = FALSE;
3747 if (!TNY_IS_FOLDER (dst_folder)) {
3748 modest_platform_information_banner (GTK_WIDGET (win),
3750 _CS("ckdg_ib_unable_to_move_to_current_location"));
3754 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
3755 proto_str = tny_account_get_proto (dst_account);
3756 dst_is_pop = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
3757 MODEST_PROTOCOL_STORE_POP);
3758 g_object_unref (dst_account);
3760 /* Get selected headers */
3761 headers = get_selected_headers (MODEST_WINDOW (win));
3764 modest_platform_information_banner (GTK_WIDGET (win),
3766 ngettext("mail_in_ui_folder_move_target_error",
3767 "mail_in_ui_folder_move_targets_error",
3768 tny_list_get_length (headers)));
3769 g_object_unref (headers);
3773 /* Ask for user confirmation */
3774 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3775 TNY_FOLDER (dst_folder),
3779 /* Transfer messages */
3780 if (response == GTK_RESPONSE_OK) {
3781 ModestMailOperation *mail_op =
3782 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3784 modest_ui_actions_move_folder_error_handler,
3786 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3789 modest_mail_operation_xfer_msgs (mail_op,
3791 TNY_FOLDER (dst_folder),
3793 (MODEST_IS_MSG_VIEW_WINDOW (win)) ? transfer_msgs_from_viewer_cb : NULL,
3796 g_object_unref (G_OBJECT (mail_op));
3798 g_object_unref (headers);
3803 * UI handler for the "Move to" action when invoked from the
3807 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3808 GtkWidget *folder_view,
3809 TnyFolderStore *dst_folder,
3810 ModestMainWindow *win)
3812 GtkWidget *header_view = NULL;
3813 ModestMailOperation *mail_op = NULL;
3814 TnyFolderStore *src_folder;
3816 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3818 /* Get the source folder */
3819 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3821 /* Offer the connection dialog if necessary, if the source folder is in a networked account: */
3822 if (!modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3826 /* Get header view */
3828 modest_main_window_get_child_widget (win, MODEST_WIDGET_TYPE_HEADER_VIEW);
3830 /* Get folder or messages to transfer */
3831 if (gtk_widget_is_focus (folder_view)) {
3833 /* Allow only to transfer folders to the local root folder */
3834 if (TNY_IS_ACCOUNT (dst_folder) &&
3835 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder))
3838 /* Clean folder on header view before moving it */
3839 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3841 if (TNY_IS_FOLDER (src_folder)) {
3843 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3845 modest_ui_actions_move_folder_error_handler,
3847 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3850 modest_mail_operation_xfer_folder (mail_op,
3851 TNY_FOLDER (src_folder),
3854 /* Unref mail operation */
3855 g_object_unref (G_OBJECT (mail_op));
3857 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
3859 } else if (gtk_widget_is_focus (header_view)) {
3860 /* Transfer messages */
3861 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3866 g_object_unref (src_folder);
3871 * UI handler for the "Move to" action when invoked from the
3872 * ModestMsgViewWindow
3875 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3876 TnyFolderStore *dst_folder,
3877 ModestMsgViewWindow *win)
3879 TnyHeader *header = NULL;
3880 TnyFolder *src_folder;
3882 /* Create header list */
3883 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3884 src_folder = tny_header_get_folder(header);
3885 g_object_unref (header);
3887 /* Transfer the message */
3888 if (modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (src_folder)))
3889 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3891 g_object_unref (src_folder);
3895 modest_ui_actions_on_move_to (GtkAction *action,
3898 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3900 TnyFolderStore *dst_folder = NULL;
3901 ModestMainWindow *main_window;
3903 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3904 MODEST_IS_MSG_VIEW_WINDOW (win));
3906 /* Get the main window if exists */
3907 if (MODEST_IS_MAIN_WINDOW (win))
3908 main_window = MODEST_MAIN_WINDOW (win);
3911 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3913 /* Get the folder view widget if exists */
3915 folder_view = modest_main_window_get_child_widget (main_window,
3916 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3920 /* Create and run the dialog */
3921 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
3922 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3923 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3924 result = gtk_dialog_run (GTK_DIALOG(dialog));
3925 g_object_ref (tree_view);
3926 gtk_widget_destroy (dialog);
3928 if (result != GTK_RESPONSE_ACCEPT)
3931 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3932 /* Offer the connection dialog if necessary: */
3933 if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3936 /* Do window specific stuff */
3937 if (MODEST_IS_MAIN_WINDOW (win))
3938 modest_ui_actions_on_main_window_move_to (action,
3941 MODEST_MAIN_WINDOW (win));
3943 modest_ui_actions_on_msg_view_window_move_to (action,
3945 MODEST_MSG_VIEW_WINDOW (win));
3948 g_object_unref (dst_folder);
3952 * Calls #HeadersFunc for each header already selected in the main
3953 * window or the message currently being shown in the msg view window
3956 do_headers_action (ModestWindow *win,
3960 TnyList *headers_list = NULL;
3961 TnyIterator *iter = NULL;
3962 TnyHeader *header = NULL;
3963 TnyFolder *folder = NULL;
3966 headers_list = get_selected_headers (win);
3970 /* Get the folder */
3971 iter = tny_list_create_iterator (headers_list);
3972 header = TNY_HEADER (tny_iterator_get_current (iter));
3974 folder = tny_header_get_folder (header);
3975 g_object_unref (header);
3978 /* Call the function for each header */
3979 while (!tny_iterator_is_done (iter)) {
3980 header = TNY_HEADER (tny_iterator_get_current (iter));
3981 func (header, win, user_data);
3982 g_object_unref (header);
3983 tny_iterator_next (iter);
3986 /* Trick: do a poke status in order to speed up the signaling
3988 tny_folder_poke_status (folder);
3991 g_object_unref (folder);
3992 g_object_unref (iter);
3993 g_object_unref (headers_list);
3997 modest_ui_actions_view_attachment (GtkAction *action,
3998 ModestWindow *window)
4000 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4001 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4003 /* not supported window for this action */
4004 g_return_if_reached ();
4009 modest_ui_actions_save_attachments (GtkAction *action,
4010 ModestWindow *window)
4012 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4013 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4015 /* not supported window for this action */
4016 g_return_if_reached ();
4021 modest_ui_actions_remove_attachments (GtkAction *action,
4022 ModestWindow *window)
4024 if (MODEST_IS_MAIN_WINDOW (window)) {
4025 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4026 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4027 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4029 /* not supported window for this action */
4030 g_return_if_reached ();
4035 modest_ui_actions_on_settings (GtkAction *action,
4040 dialog = modest_platform_get_global_settings_dialog ();
4041 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4042 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4043 gtk_widget_show_all (dialog);
4045 gtk_dialog_run (GTK_DIALOG (dialog));
4047 gtk_widget_destroy (dialog);
4051 modest_ui_actions_on_help (GtkAction *action,
4054 const gchar *help_id = NULL;
4056 if (MODEST_IS_MAIN_WINDOW (win)) {
4057 const gchar *action_name;
4058 action_name = gtk_action_get_name (action);
4060 if (!strcmp (action_name, "FolderViewCSMHelp") ||
4061 !strcmp (action_name, "HeaderViewCSMHelp")) {
4062 GtkWidget *folder_view;
4063 TnyFolderStore *folder_store;
4064 /* Get selected folder */
4065 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4066 MODEST_WIDGET_TYPE_FOLDER_VIEW);
4067 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4069 /* Switch help_id */
4070 if (TNY_IS_FOLDER (folder_store)) {
4071 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4072 case TNY_FOLDER_TYPE_NORMAL:
4073 help_id = "applications_email_managefolders";
4075 case TNY_FOLDER_TYPE_INBOX:
4076 help_id = "applications_email_inbox";
4078 case TNY_FOLDER_TYPE_OUTBOX:
4079 help_id = "applications_email_outbox";
4081 case TNY_FOLDER_TYPE_SENT:
4082 help_id = "applications_email_sent";
4084 case TNY_FOLDER_TYPE_DRAFTS:
4085 help_id = "applications_email_drafts";
4087 case TNY_FOLDER_TYPE_ARCHIVE:
4088 help_id = "applications_email_managefolders";
4091 help_id = "applications_email_managefolders";
4094 help_id = "applications_email_mainview";
4096 g_object_unref (folder_store);
4098 help_id = "applications_email_mainview";
4100 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4101 help_id = "applications_email_viewer";
4102 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4103 help_id = "applications_email_editor";
4105 modest_platform_show_help (GTK_WINDOW (win), help_id);
4109 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4110 ModestWindow *window)
4112 ModestMailOperation *mail_op;
4116 headers = get_selected_headers (window);
4120 /* Create mail operation */
4121 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4123 modest_ui_actions_get_msgs_full_error_handler,
4125 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4126 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4129 g_object_unref (headers);
4130 g_object_unref (mail_op);
4134 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4135 ModestWindow *window)
4137 g_return_if_fail (MODEST_IS_WINDOW (window));
4140 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4144 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4145 ModestWindow *window)
4147 g_return_if_fail (MODEST_IS_WINDOW (window));
4150 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4154 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4155 ModestWindow *window)
4157 g_return_if_fail (MODEST_IS_WINDOW (window));
4160 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4164 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4165 ModestWindow *window)
4167 g_return_if_fail (MODEST_IS_WINDOW (window));
4170 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4174 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4175 ModestWindow *window)
4177 g_return_if_fail (MODEST_IS_WINDOW (window));
4180 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4184 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4185 ModestWindow *window)
4187 g_return_if_fail (MODEST_IS_WINDOW (window));
4190 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4194 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4195 ModestWindow *window)
4197 g_return_if_fail (MODEST_IS_WINDOW (window));
4200 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4204 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4205 ModestWindow *window)
4207 g_return_if_fail (MODEST_IS_WINDOW (window));
4210 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4214 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4216 g_return_if_fail (MODEST_IS_WINDOW (window));
4219 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4223 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4225 g_return_if_fail (MODEST_IS_WINDOW (window));
4227 modest_platform_show_search_messages (GTK_WINDOW (window));
4231 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4233 g_return_if_fail (MODEST_IS_WINDOW (win));
4234 modest_platform_show_addressbook (GTK_WINDOW (win));
4239 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4240 ModestWindow *window)
4242 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4244 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4248 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
4249 ModestMailOperationState *state,
4252 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4254 /* Set send/receive operation finished */
4255 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4256 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));