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,
154 /* Show the account creation wizard dialog.
155 * returns: TRUE if an account was created. FALSE if the user cancelled.
158 modest_run_account_setup_wizard (ModestWindow *win)
160 gboolean result = FALSE;
161 ModestEasysetupWizardDialog *wizard;
164 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ());
166 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
168 wizard = modest_easysetup_wizard_dialog_new ();
169 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
171 /* Don't make this a modal window, because secondary windows will then
172 * be unusable, freezing the UI: */
173 /* gtk_window_set_modal (GTK_WINDOW (wizard), TRUE); */
175 gint dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
176 if (dialog_response == GTK_RESPONSE_CANCEL)
179 /* Check whether an account was created: */
180 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
183 gtk_widget_destroy (GTK_WIDGET (wizard));
190 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
193 const gchar *authors[] = {
194 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
197 about = gtk_about_dialog_new ();
198 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
199 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
200 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
201 _("Copyright (c) 2006, Nokia Corporation\n"
202 "All rights reserved."));
203 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
204 _("a modest e-mail client\n\n"
205 "design and implementation: Dirk-Jan C. Binnema\n"
206 "contributions from the fine people at KC and Ig\n"
207 "uses the tinymail email framework written by Philip van Hoof"));
208 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
209 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
210 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
211 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
213 gtk_dialog_run (GTK_DIALOG (about));
214 gtk_widget_destroy(about);
218 * Gets the list of currently selected messages. If the win is the
219 * main window, then it returns a newly allocated list of the headers
220 * selected in the header view. If win is the msg view window, then
221 * the value returned is a list with just a single header.
223 * The caller of this funcion must free the list.
226 get_selected_headers (ModestWindow *win)
228 if (MODEST_IS_MAIN_WINDOW(win)) {
229 GtkWidget *header_view;
231 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
232 MODEST_WIDGET_TYPE_HEADER_VIEW);
233 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
235 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
236 /* for MsgViewWindows, we simply return a list with one element */
238 TnyList *list = NULL;
240 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
241 if (header != NULL) {
242 list = tny_simple_list_new ();
243 tny_list_prepend (list, G_OBJECT(header));
244 g_object_unref (G_OBJECT(header));
254 headers_action_mark_as_read (TnyHeader *header,
258 TnyHeaderFlags flags;
260 g_return_if_fail (TNY_IS_HEADER(header));
262 flags = tny_header_get_flags (header);
263 if (flags & TNY_HEADER_FLAG_SEEN) return;
264 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
268 headers_action_mark_as_unread (TnyHeader *header,
272 TnyHeaderFlags flags;
274 g_return_if_fail (TNY_IS_HEADER(header));
276 flags = tny_header_get_flags (header);
277 if (flags & TNY_HEADER_FLAG_SEEN) {
278 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
282 /** A convenience method, because deleting a message is
283 * otherwise complicated, and it's best to change it in one place
286 void modest_do_message_delete (TnyHeader *header, ModestWindow *win)
288 ModestMailOperation *mail_op = NULL;
289 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE,
290 win ? G_OBJECT(win) : NULL);
291 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
294 /* Always delete. TODO: Move to trash still not supported */
295 modest_mail_operation_remove_msg (mail_op, header, FALSE);
296 g_object_unref (G_OBJECT (mail_op));
300 headers_action_delete (TnyHeader *header,
304 modest_do_message_delete (header, win);
307 /** After deleing a message that is currently visible in a window,
308 * show the next message from the list, or close the window if there are no more messages.
310 void modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
312 /* Close msg view window or select next */
313 if (modest_msg_view_window_last_message_selected (win) &&
314 modest_msg_view_window_first_message_selected (win)) {
315 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
317 if (!modest_msg_view_window_select_next_message (win)) {
319 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
325 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
327 TnyList *header_list = NULL;
328 TnyIterator *iter = NULL;
329 TnyHeader *header = NULL;
330 gchar *message = NULL;
333 ModestWindowMgr *mgr;
334 GtkWidget *header_view = NULL;
336 g_return_if_fail (MODEST_IS_WINDOW(win));
338 /* Check first if the header view has the focus */
339 if (MODEST_IS_MAIN_WINDOW (win)) {
341 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
342 MODEST_WIDGET_TYPE_HEADER_VIEW);
343 if (!gtk_widget_is_focus (header_view))
347 /* Get the headers, either from the header view (if win is the main window),
348 * or from the message view window: */
349 header_list = get_selected_headers (win);
350 if (!header_list) return;
352 /* Check if any of the headers are already opened, or in the process of being opened */
353 if (MODEST_IS_MAIN_WINDOW (win)) {
355 iter = tny_list_create_iterator (header_list);
357 mgr = modest_runtime_get_window_mgr ();
358 while (!tny_iterator_is_done (iter) && !found) {
359 header = TNY_HEADER (tny_iterator_get_current (iter));
361 found = modest_window_mgr_find_registered_header (mgr, header, NULL);
362 g_object_unref (header);
365 tny_iterator_next (iter);
367 g_object_unref (iter);
372 num = g_strdup_printf ("%d", tny_list_get_length (header_list));
373 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
375 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
379 g_object_unref (header_list);
385 if (tny_list_get_length(header_list) == 1) {
386 iter = tny_list_create_iterator (header_list);
387 header = TNY_HEADER (tny_iterator_get_current (iter));
389 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
390 g_object_unref (header);
393 g_object_unref (iter);
395 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
396 tny_list_get_length(header_list)), desc);
398 /* Confirmation dialog */
399 printf("DEBUG: %s\n", __FUNCTION__);
400 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
404 if (response == GTK_RESPONSE_OK) {
405 ModestWindow *main_window = NULL;
406 ModestWindowMgr *mgr = NULL;
407 GtkTreeModel *model = NULL;
408 GtkTreeSelection *sel = NULL;
409 GList *sel_list = NULL, *tmp = NULL;
410 GtkTreeRowReference *row_reference = NULL;
411 GtkTreePath *next_path = NULL;
412 TnyFolder *folder = NULL;
415 /* Find last selected row */
416 if (MODEST_IS_MAIN_WINDOW (win)) {
417 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
418 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
419 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
420 for (tmp=sel_list; tmp; tmp=tmp->next) {
421 if (tmp->next == NULL) {
422 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
423 gtk_tree_path_next (next_path);
424 row_reference = gtk_tree_row_reference_new (model, next_path);
425 gtk_tree_path_free (next_path);
430 /* Remove each header. If it's a view window header_view == NULL */
431 do_headers_action (win, headers_action_delete, header_view);
433 /* refresh the header view (removing marked-as-deleted)*/
434 modest_header_view_refilter (MODEST_HEADER_VIEW(header_view));
436 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
437 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
439 /* Get main window */
440 mgr = modest_runtime_get_window_mgr ();
441 main_window = modest_window_mgr_get_main_window (mgr);
444 /* Move cursor to next row */
447 /* Select next row */
448 if (gtk_tree_row_reference_valid (row_reference)) {
449 next_path = gtk_tree_row_reference_get_path (row_reference);
450 gtk_tree_selection_select_path (sel, next_path);
451 gtk_tree_path_free (next_path);
453 if (row_reference != NULL)
454 gtk_tree_row_reference_free (row_reference);
457 /* Get folder from first header and sync it */
458 iter = tny_list_create_iterator (header_list);
459 header = TNY_HEADER (tny_iterator_get_current (iter));
460 folder = tny_header_get_folder (header);
461 if (TNY_IS_CAMEL_IMAP_FOLDER (folder))
462 /* tny_folder_sync_async(folder, FALSE, NULL, NULL, NULL); /\* FALSE --> don't expunge *\/ */
463 tny_folder_sync (folder, FALSE, &err); /* FALSE --> don't expunge */
464 else if (TNY_IS_CAMEL_POP_FOLDER (folder))
465 /* tny_folder_sync_async(folder, FALSE, NULL, NULL, NULL); /\* TRUE --> dont expunge *\/ */
466 tny_folder_sync (folder, TRUE, &err); /* TRUE --> expunge */
469 /* tny_folder_sync_async(folder, TRUE, NULL, NULL, NULL); /\* TRUE --> expunge *\/ */
470 tny_folder_sync (folder, TRUE, &err); /* TRUE --> expunge */
473 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, err->code, err->message);
477 g_object_unref (header);
478 g_object_unref (iter);
479 g_object_unref (folder);
481 /* Update toolbar dimming state */
482 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
485 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
486 g_list_free (sel_list);
492 g_object_unref (header_list);
498 /* delete either message or folder, based on where we are */
500 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
502 g_return_if_fail (MODEST_IS_WINDOW(win));
504 /* Check first if the header view has the focus */
505 if (MODEST_IS_MAIN_WINDOW (win)) {
507 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
508 MODEST_WIDGET_TYPE_FOLDER_VIEW);
509 if (gtk_widget_is_focus (w)) {
510 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
514 modest_ui_actions_on_delete_message (action, win);
520 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
522 #ifdef MODEST_PLATFORM_MAEMO
523 modest_osso_save_state();
524 #endif /* MODEST_PLATFORM_MAEMO */
526 g_debug ("closing down, clearing %d item(s) from operation queue",
527 modest_mail_operation_queue_num_elements
528 (modest_runtime_get_mail_operation_queue()));
530 /* cancel all outstanding operations */
531 modest_mail_operation_queue_cancel_all
532 (modest_runtime_get_mail_operation_queue());
534 g_debug ("queue has been cleared");
536 /* note: when modest-tny-account-store is finalized,
537 it will automatically set all network connections
544 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
548 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
550 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
551 /* gtk_widget_destroy (GTK_WIDGET (win)); */
552 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
553 /* gboolean ret_value; */
554 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
555 /* } else if (MODEST_IS_WINDOW (win)) { */
556 /* gtk_widget_destroy (GTK_WIDGET (win)); */
558 /* g_return_if_reached (); */
563 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
565 GtkClipboard *clipboard = NULL;
566 gchar *selection = NULL;
568 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
569 selection = gtk_clipboard_wait_for_text (clipboard);
571 /* Question: why is the clipboard being used here?
572 * It doesn't really make a lot of sense. */
576 modest_address_book_add_address (selection);
582 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
584 /* This is currently only implemented for Maemo */
585 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
586 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
587 modest_run_account_setup_wizard (win);
590 /* Show the list of accounts: */
591 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
592 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW (win));
594 /* Don't make this a modal window, because secondary windows will then
595 * be unusable, freezing the UI: */
596 /* gtk_window_set_modal (GTK_WINDOW (account_win), TRUE); */
597 modest_maemo_show_dialog_and_forget (GTK_WINDOW (win), account_win);
600 GtkWidget *dialog, *label;
602 /* Create the widgets */
604 dialog = gtk_dialog_new_with_buttons ("Message",
606 GTK_DIALOG_DESTROY_WITH_PARENT,
610 label = gtk_label_new ("Hello World!");
612 /* Ensure that the dialog box is destroyed when the user responds. */
614 g_signal_connect_swapped (dialog, "response",
615 G_CALLBACK (gtk_widget_destroy),
618 /* Add the label, and show everything we've added to the dialog. */
620 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
622 gtk_widget_show_all (dialog);
623 #endif /* MODEST_PLATFORM_MAEMO */
627 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
629 ModestWindow *main_window = MODEST_WINDOW (user_data);
631 /* Save any changes. */
632 modest_connection_specific_smtp_window_save_server_accounts (
633 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
634 modest_window_get_active_account (main_window));
635 gtk_widget_destroy (GTK_WIDGET (window));
641 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
643 /* This is currently only implemented for Maemo,
644 * because it requires an API (libconic) to detect different connection
647 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
649 /* Create the window if necessary: */
650 const gchar *active_account_name = modest_window_get_active_account (win);
652 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
653 * or show the default account?
654 * If we show the default account then the account name should be shown in
655 * the window when we show it. */
656 if (!active_account_name) {
657 g_warning ("%s: No account is active.", __FUNCTION__);
661 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
662 modest_connection_specific_smtp_window_fill_with_connections (
663 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
664 modest_runtime_get_account_mgr(),
665 active_account_name);
667 /* Show the window: */
668 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
669 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
670 gtk_widget_show (specific_window);
672 /* Save changes when the window is hidden: */
673 g_signal_connect (specific_window, "hide",
674 G_CALLBACK (on_smtp_servers_window_hide), win);
675 #endif /* MODEST_PLATFORM_MAEMO */
679 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
681 ModestWindow *msg_win = NULL;
683 TnyFolder *folder = NULL;
684 gchar *account_name = NULL;
685 gchar *from_str = NULL;
686 /* GError *err = NULL; */
687 TnyAccount *account = NULL;
688 ModestWindowMgr *mgr;
689 gchar *signature = NULL, *blank_and_signature = NULL;
691 /* if there are no accounts yet, just show the wizard */
692 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
693 const gboolean created = modest_run_account_setup_wizard (win);
698 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
700 account_name = g_strdup (modest_window_get_active_account (win));
702 g_printerr ("modest: no account found\n");
706 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
708 TNY_ACCOUNT_TYPE_STORE);
710 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
714 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
716 g_printerr ("modest: failed get from string for '%s'\n", account_name);
720 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
721 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
722 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
723 MODEST_ACCOUNT_SIGNATURE, FALSE);
724 blank_and_signature = g_strconcat ("\n", signature, NULL);
727 blank_and_signature = g_strdup ("");
730 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
732 g_printerr ("modest: failed to create new msg\n");
736 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
738 g_printerr ("modest: failed to find Drafts folder\n");
743 /* Create and register edit window */
744 /* This is destroyed by TOOD. */
745 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
746 mgr = modest_runtime_get_window_mgr ();
747 modest_window_mgr_register_window (mgr, msg_win);
750 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
752 gtk_widget_show_all (GTK_WIDGET (msg_win));
755 g_free (account_name);
757 g_free (blank_and_signature);
759 g_object_unref (msg_win);
761 g_object_unref (G_OBJECT(account));
763 g_object_unref (G_OBJECT(msg));
765 g_object_unref (G_OBJECT(folder));
769 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
773 ModestMailOperationStatus status;
775 /* If there is no message or the operation was not successful */
776 status = modest_mail_operation_get_status (mail_op);
777 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
779 /* Remove the header from the preregistered uids */
780 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
790 open_msg_cb (ModestMailOperation *mail_op,
795 ModestWindowMgr *mgr = NULL;
796 ModestWindow *parent_win = NULL;
797 ModestWindow *win = NULL;
798 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
799 gchar *account = NULL;
802 /* Do nothing if there was any problem with the mail
803 operation. The error will be shown by the error_handler of
804 the mail operation */
805 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
809 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
810 folder = tny_header_get_folder (header);
812 /* Mark header as read */
813 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
816 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
818 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
820 /* Gets folder type (OUTBOX headers will be opened in edit window */
821 if (modest_tny_folder_is_local_folder (folder))
822 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
824 /* If the header is in the drafts folder then open the editor,
825 else the message view window */
826 if ((folder_type == TNY_FOLDER_TYPE_DRAFTS) ||
827 (folder_type == TNY_FOLDER_TYPE_OUTBOX)) {
828 /* we cannot edit without a valid account... */
829 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
830 const gboolean created = modest_run_account_setup_wizard(parent_win);
834 win = modest_msg_edit_window_new (msg, account, TRUE);
837 gchar *uid = modest_tny_folder_get_header_unique_id (header);
839 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
840 GtkWidget *header_view;
841 GtkTreeSelection *sel;
842 GList *sel_list = NULL;
845 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
846 MODEST_WIDGET_TYPE_HEADER_VIEW);
848 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
849 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
851 if (sel_list != NULL) {
852 GtkTreeRowReference *row_reference;
854 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
855 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
856 g_list_free (sel_list);
858 win = modest_msg_view_window_new_with_header_model (
859 msg, account, (const gchar*) uid,
860 model, row_reference);
861 gtk_tree_row_reference_free (row_reference);
863 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
866 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
871 /* Register and show new window */
873 mgr = modest_runtime_get_window_mgr ();
874 modest_window_mgr_register_window (mgr, win);
875 g_object_unref (win);
876 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
877 gtk_widget_show_all (GTK_WIDGET(win));
880 /* Update toolbar dimming state */
881 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
882 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
888 g_object_unref (parent_win);
889 g_object_unref (folder);
893 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
897 GObject *win = modest_mail_operation_get_source (mail_op);
899 error = modest_mail_operation_get_error (mail_op);
900 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, error->code, error->message);
902 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
904 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
907 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
908 _("mail_ni_ui_folder_get_msg_folder_error"));
912 g_object_unref (win);
916 * This function is used by both modest_ui_actions_on_open and
917 * modest_ui_actions_on_header_activated. This way we always do the
918 * same when trying to open messages.
921 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
923 ModestWindowMgr *mgr = NULL;
924 TnyIterator *iter = NULL;
925 ModestMailOperation *mail_op = NULL;
926 TnyList *not_opened_headers = NULL;
927 TnyHeaderFlags flags = 0;
929 /* Look if we already have a message view for each header. If
930 true, then remove the header from the list of headers to
932 mgr = modest_runtime_get_window_mgr ();
933 iter = tny_list_create_iterator (headers);
934 not_opened_headers = tny_simple_list_new ();
936 while (!tny_iterator_is_done (iter)) {
938 ModestWindow *window = NULL;
939 TnyHeader *header = NULL;
940 gboolean found = FALSE;
942 header = TNY_HEADER (tny_iterator_get_current (iter));
944 flags = tny_header_get_flags (header);
947 found = modest_window_mgr_find_registered_header (mgr, header, &window);
949 /* Do not open again the message and present the
950 window to the user */
953 gtk_window_present (GTK_WINDOW (window));
955 /* the header has been registered already, we don't do
956 * anything but wait for the window to come up*/
957 g_debug ("header %p already registered, waiting for window", header);
959 tny_list_append (not_opened_headers, G_OBJECT (header));
963 g_object_unref (header);
965 tny_iterator_next (iter);
967 g_object_unref (iter);
970 /* If some messages would have to be downloaded, ask the user to
971 * make a connection. It's generally easier to do this here (in the mainloop)
972 * than later in a thread:
974 if (tny_list_get_length (not_opened_headers) > 0) {
976 gboolean found = FALSE;
978 iter = tny_list_create_iterator (not_opened_headers);
979 while (!tny_iterator_is_done (iter) && !found) {
980 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
981 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
984 tny_iterator_next (iter);
986 g_object_unref (header);
988 g_object_unref (iter);
990 if (found && !modest_platform_connect_and_wait (GTK_WINDOW (win), NULL)) {
991 g_object_unref (not_opened_headers);
996 /* Register the headers before actually creating the windows: */
997 TnyIterator *iter_not_opened = tny_list_create_iterator (not_opened_headers);
998 while (!tny_iterator_is_done (iter_not_opened)) {
999 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1001 modest_window_mgr_register_header (mgr, header);
1002 g_object_unref (header);
1005 tny_iterator_next (iter_not_opened);
1007 g_object_unref (iter_not_opened);
1008 iter_not_opened = NULL;
1010 /* Open each message */
1011 if (tny_list_get_length (not_opened_headers) > 0) {
1012 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1014 modest_ui_actions_get_msgs_full_error_handler,
1016 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1017 if (tny_list_get_length (not_opened_headers) > 1) {
1018 modest_mail_operation_get_msgs_full (mail_op,
1024 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1025 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1026 modest_mail_operation_get_msg (mail_op, header, open_msg_cb, NULL);
1027 g_object_unref (header);
1028 g_object_unref (iter);
1030 g_object_unref (mail_op);
1034 if (not_opened_headers != NULL)
1035 g_object_unref (not_opened_headers);
1039 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1044 headers = get_selected_headers (win);
1049 _modest_ui_actions_open (headers, win);
1051 g_object_unref(headers);
1056 free_reply_forward_helper (gpointer data)
1058 ReplyForwardHelper *helper;
1060 helper = (ReplyForwardHelper *) data;
1061 g_free (helper->account_name);
1062 g_slice_free (ReplyForwardHelper, helper);
1066 reply_forward_cb (ModestMailOperation *mail_op,
1072 ReplyForwardHelper *rf_helper;
1073 ModestWindow *msg_win = NULL;
1074 ModestEditType edit_type;
1076 TnyAccount *account = NULL;
1077 ModestWindowMgr *mgr = NULL;
1078 gchar *signature = NULL;
1080 /* If there was any error. The mail operation could be NULL,
1081 this means that we already have the message downloaded and
1082 that we didn't do a mail operation to retrieve it */
1083 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1086 g_return_if_fail (user_data != NULL);
1087 rf_helper = (ReplyForwardHelper *) user_data;
1089 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1090 rf_helper->account_name);
1091 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
1092 rf_helper->account_name,
1093 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
1094 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
1095 rf_helper->account_name,
1096 MODEST_ACCOUNT_SIGNATURE, FALSE);
1099 /* Create reply mail */
1100 switch (rf_helper->action) {
1103 modest_tny_msg_create_reply_msg (msg, header, from, signature,
1104 rf_helper->reply_forward_type,
1105 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1107 case ACTION_REPLY_TO_ALL:
1109 modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1110 MODEST_TNY_MSG_REPLY_MODE_ALL);
1111 edit_type = MODEST_EDIT_TYPE_REPLY;
1113 case ACTION_FORWARD:
1115 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1116 edit_type = MODEST_EDIT_TYPE_FORWARD;
1119 g_return_if_reached ();
1126 g_printerr ("modest: failed to create message\n");
1130 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1131 rf_helper->account_name,
1132 TNY_ACCOUNT_TYPE_STORE);
1134 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1138 /* Create and register the windows */
1139 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1140 mgr = modest_runtime_get_window_mgr ();
1141 modest_window_mgr_register_window (mgr, msg_win);
1143 if (rf_helper->parent_window != NULL) {
1144 gdouble parent_zoom;
1146 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1147 modest_window_set_zoom (msg_win, parent_zoom);
1150 /* Show edit window */
1151 gtk_widget_show_all (GTK_WIDGET (msg_win));
1155 g_object_unref (msg_win);
1157 g_object_unref (G_OBJECT (new_msg));
1159 g_object_unref (G_OBJECT (account));
1160 /* g_object_unref (msg); */
1161 free_reply_forward_helper (rf_helper);
1165 * Checks a list of headers. If any of them are not currently
1166 * downloaded (CACHED) then it asks the user for permission to
1169 * Returns FALSE if the user does not want to download the
1170 * messages. Returns TRUE if the user allowed the download or if all
1171 * of them are currently downloaded
1174 download_uncached_messages (TnyList *header_list,
1180 gint uncached_messages = 0;
1182 iter = tny_list_create_iterator (header_list);
1183 while (!tny_iterator_is_done (iter)) {
1186 header = TNY_HEADER (tny_iterator_get_current (iter));
1188 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1189 uncached_messages ++;
1190 g_object_unref (header);
1193 tny_iterator_next (iter);
1195 g_object_unref (iter);
1197 /* Ask for user permission to download the messages */
1199 if (uncached_messages > 0) {
1200 GtkResponseType response;
1202 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1203 _("emev_nc_include_original"));
1206 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1207 ngettext("mcen_nc_get_msg",
1209 uncached_messages));
1210 if (response == GTK_RESPONSE_CANCEL)
1213 /* If a download will be necessary, make sure that we have a connection: */
1214 retval = modest_platform_connect_and_wait(win, NULL);
1222 * Common code for the reply and forward actions
1225 reply_forward (ReplyForwardAction action, ModestWindow *win)
1227 ModestMailOperation *mail_op = NULL;
1228 TnyList *header_list = NULL;
1229 ReplyForwardHelper *rf_helper = NULL;
1230 guint reply_forward_type;
1231 gboolean continue_download = TRUE;
1232 gboolean do_retrieve = TRUE;
1234 g_return_if_fail (MODEST_IS_WINDOW(win));
1236 /* we need an account when editing */
1237 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1238 const gboolean created = modest_run_account_setup_wizard (win);
1243 header_list = get_selected_headers (win);
1247 reply_forward_type =
1248 modest_conf_get_int (modest_runtime_get_conf (),
1249 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1252 /* Check that the messages have been previously downloaded */
1253 do_retrieve = (action == ACTION_FORWARD) || (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1255 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win), TRUE);
1256 if (!continue_download) {
1257 g_object_unref (header_list);
1261 /* We assume that we can only select messages of the
1262 same folder and that we reply all of them from the
1263 same account. In fact the interface currently only
1264 allows single selection */
1267 rf_helper = g_slice_new0 (ReplyForwardHelper);
1268 rf_helper->reply_forward_type = reply_forward_type;
1269 rf_helper->action = action;
1270 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1272 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1273 rf_helper->parent_window = GTK_WIDGET (win);
1274 if (!rf_helper->account_name)
1275 rf_helper->account_name =
1276 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1278 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1281 /* Get header and message. Do not free them here, the
1282 reply_forward_cb must do it */
1283 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1284 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1285 if (!msg || !header) {
1287 g_object_unref (msg);
1288 g_printerr ("modest: no message found\n");
1291 reply_forward_cb (NULL, header, msg, rf_helper);
1294 g_object_unref (header);
1299 /* Only reply/forward to one message */
1300 iter = tny_list_create_iterator (header_list);
1301 header = TNY_HEADER (tny_iterator_get_current (iter));
1302 g_object_unref (iter);
1305 /* Retrieve messages */
1307 mail_op = modest_mail_operation_new_with_error_handling (
1308 MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1310 modest_ui_actions_get_msgs_full_error_handler,
1312 modest_mail_operation_queue_add (
1313 modest_runtime_get_mail_operation_queue (), mail_op);
1315 modest_mail_operation_get_msg (mail_op,
1320 g_object_unref(mail_op);
1322 /* we put a ref here to prevent double unref as the reply
1323 * forward callback unrefs the header at its end */
1324 reply_forward_cb (NULL, header, NULL, rf_helper);
1328 g_object_unref (header);
1334 g_object_unref (header_list);
1338 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1340 g_return_if_fail (MODEST_IS_WINDOW(win));
1342 reply_forward (ACTION_REPLY, win);
1346 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1348 g_return_if_fail (MODEST_IS_WINDOW(win));
1350 reply_forward (ACTION_FORWARD, win);
1354 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1356 g_return_if_fail (MODEST_IS_WINDOW(win));
1358 reply_forward (ACTION_REPLY_TO_ALL, win);
1362 modest_ui_actions_on_next (GtkAction *action,
1363 ModestWindow *window)
1365 if (MODEST_IS_MAIN_WINDOW (window)) {
1366 GtkWidget *header_view;
1368 header_view = modest_main_window_get_child_widget (
1369 MODEST_MAIN_WINDOW(window),
1370 MODEST_WIDGET_TYPE_HEADER_VIEW);
1374 modest_header_view_select_next (
1375 MODEST_HEADER_VIEW(header_view));
1376 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1377 modest_msg_view_window_select_next_message (
1378 MODEST_MSG_VIEW_WINDOW (window));
1380 g_return_if_reached ();
1385 modest_ui_actions_on_prev (GtkAction *action,
1386 ModestWindow *window)
1388 g_return_if_fail (MODEST_IS_WINDOW(window));
1390 if (MODEST_IS_MAIN_WINDOW (window)) {
1391 GtkWidget *header_view;
1392 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1393 MODEST_WIDGET_TYPE_HEADER_VIEW);
1397 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1398 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1399 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1401 g_return_if_reached ();
1406 modest_ui_actions_on_sort (GtkAction *action,
1407 ModestWindow *window)
1409 g_return_if_fail (MODEST_IS_WINDOW(window));
1411 if (MODEST_IS_MAIN_WINDOW (window)) {
1412 GtkWidget *header_view;
1413 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1414 MODEST_WIDGET_TYPE_HEADER_VIEW);
1416 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1421 /* Show sorting dialog */
1422 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1427 new_messages_arrived (ModestMailOperation *self,
1431 ModestMainWindow *win = NULL;
1432 GtkWidget *folder_view = NULL;
1433 TnyFolderStore *folder = NULL;
1434 gboolean folder_empty = FALSE;
1436 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
1437 win = MODEST_MAIN_WINDOW (user_data);
1439 /* Set contents style of headers view */
1440 if (modest_main_window_get_contents_style (win) == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1441 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1442 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1443 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1446 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1449 modest_main_window_set_contents_style (win,
1450 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1453 /* Notify new messages have been downloaded */
1454 if (new_messages > 0)
1455 modest_platform_on_new_msg ();
1459 * This function performs the send & receive required actions. The
1460 * window is used to create the mail operation. Typically it should
1461 * always be the main window, but we pass it as argument in order to
1465 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1467 gchar *acc_name = NULL;
1468 ModestMailOperation *mail_op;
1470 /* If no account name was provided then get the current account, and if
1471 there is no current account then pick the default one: */
1472 if (!account_name) {
1473 acc_name = g_strdup (modest_window_get_active_account(win));
1475 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1477 g_printerr ("modest: cannot get default account\n");
1481 acc_name = g_strdup (account_name);
1484 /* Set send/receive operation in progress */
1485 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1487 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1489 modest_ui_actions_send_receive_error_handler,
1492 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1493 G_CALLBACK (_on_send_receive_progress_changed),
1496 /* Send & receive. */
1497 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1498 /* Receive and then send. The operation is tagged initially as
1499 a receive operation because the account update performs a
1500 receive and then a send. The operation changes its type
1501 internally, so the progress objects will receive the proper
1502 progress information */
1503 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1504 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, win);
1505 g_object_unref (G_OBJECT (mail_op));
1513 modest_ui_actions_do_cancel_send (const gchar *account_name,
1516 TnyTransportAccount *transport_account;
1517 TnySendQueue *send_queue = NULL;
1518 GError *error = NULL;
1520 /* Get transport account */
1522 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1523 (modest_runtime_get_account_store(),
1525 TNY_ACCOUNT_TYPE_TRANSPORT));
1526 if (!transport_account) {
1527 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1532 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1533 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1534 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1535 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1536 "modest: could not find send queue for account\n");
1538 /* Keeep messages in outbox folder */
1539 tny_send_queue_cancel (send_queue, FALSE, &error);
1543 if (transport_account != NULL)
1544 g_object_unref (G_OBJECT (transport_account));
1548 modest_ui_actions_cancel_send_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_cancel_send ((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_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1569 /* Check if accounts exist */
1570 gboolean accounts_exist =
1571 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1573 /* If not, allow the user to create an account before trying to send/receive. */
1574 if (!accounts_exist)
1575 modest_ui_actions_on_accounts (NULL, win);
1577 /* Cancel all sending operaitons */
1578 modest_ui_actions_cancel_send_all (win);
1582 * Refreshes all accounts. This function will be used by automatic
1586 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1588 GSList *account_names, *iter;
1590 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1593 iter = account_names;
1595 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1596 iter = g_slist_next (iter);
1599 modest_account_mgr_free_account_names (account_names);
1600 account_names = NULL;
1604 modest_do_refresh_current_folder(ModestWindow *win)
1606 /* Refresh currently selected folder. Note that if we only
1607 want to retreive the headers, then the refresh only will
1608 invoke a poke_status over all folders, i.e., only the
1609 total/unread count will be updated */
1610 if (MODEST_IS_MAIN_WINDOW (win)) {
1611 GtkWidget *header_view, *folder_view;
1612 TnyFolderStore *folder_store;
1614 /* Get folder and header view */
1616 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1617 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1619 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1621 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1623 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1624 MODEST_WIDGET_TYPE_HEADER_VIEW);
1626 /* We do not need to set the contents style
1627 because it hasn't changed. We also do not
1628 need to save the widget status. Just force
1630 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1631 TNY_FOLDER (folder_store),
1632 folder_refreshed_cb,
1633 MODEST_MAIN_WINDOW (win));
1637 g_object_unref (folder_store);
1643 * Handler of the click on Send&Receive button in the main toolbar
1646 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1648 /* Check if accounts exist */
1649 gboolean accounts_exist =
1650 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1652 /* If not, allow the user to create an account before trying to send/receive. */
1653 if (!accounts_exist)
1654 modest_ui_actions_on_accounts (NULL, win);
1656 modest_do_refresh_current_folder (win);
1658 /* Refresh the active account */
1659 modest_ui_actions_do_send_receive (NULL, win);
1664 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1667 GtkWidget *header_view;
1669 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1671 header_view = modest_main_window_get_child_widget (main_window,
1672 MODEST_WIDGET_TYPE_HEADER_VIEW);
1676 conf = modest_runtime_get_conf ();
1678 /* what is saved/restored is depending on the style; thus; we save with
1679 * old style, then update the style, and restore for this new style
1681 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1683 if (modest_header_view_get_style
1684 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1685 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1686 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1688 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1689 MODEST_HEADER_VIEW_STYLE_DETAILS);
1691 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1692 MODEST_CONF_HEADER_VIEW_KEY);
1697 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1699 ModestMainWindow *main_window)
1701 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1702 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1704 /* in the case the folder is empty, show the empty folder message and focus
1706 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1707 if (modest_header_view_is_empty (header_view)) {
1708 TnyFolder *folder = modest_header_view_get_folder (header_view);
1709 GtkWidget *folder_view =
1710 modest_main_window_get_child_widget (main_window,
1711 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1713 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1714 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1718 /* If no header has been selected then exit */
1723 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1724 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1726 /* Update Main window title */
1727 if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
1728 const gchar *subject = tny_header_get_subject (header);
1729 if (subject && strlen(subject) > 0)
1730 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1732 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1735 /* Update toolbar dimming state */
1736 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1740 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1742 ModestMainWindow *main_window)
1746 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1751 headers = tny_simple_list_new ();
1752 tny_list_prepend (headers, G_OBJECT (header));
1754 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1756 g_object_unref (headers);
1760 set_active_account_from_tny_account (TnyAccount *account,
1761 ModestWindow *window)
1763 const gchar *server_acc_name = tny_account_get_id (account);
1765 /* We need the TnyAccount provided by the
1766 account store because that is the one that
1767 knows the name of the Modest account */
1768 TnyAccount *modest_server_account = modest_server_account =
1769 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1770 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1773 const gchar *modest_acc_name =
1774 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1775 modest_window_set_active_account (window, modest_acc_name);
1776 g_object_unref (modest_server_account);
1781 folder_refreshed_cb (ModestMailOperation *mail_op,
1785 ModestMainWindow *win = NULL;
1786 GtkWidget *header_view;
1787 TnyFolder *current_folder;
1788 gboolean folder_empty = TRUE;
1789 gboolean all_marked_as_deleted = TRUE;
1791 g_return_if_fail (TNY_IS_FOLDER (folder));
1793 win = MODEST_MAIN_WINDOW (user_data);
1795 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1798 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1799 if (current_folder != NULL && folder != current_folder) {
1804 /* Check if folder is empty and set headers view contents style */
1805 folder_empty = (tny_folder_get_all_count (folder) == 0);
1806 all_marked_as_deleted = modest_header_view_is_empty (MODEST_HEADER_VIEW(header_view));
1807 folder_empty = folder_empty || all_marked_as_deleted ;
1810 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1811 modest_main_window_set_contents_style (win,
1812 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1814 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1819 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1820 TnyFolderStore *folder_store,
1822 ModestMainWindow *main_window)
1825 GtkWidget *header_view;
1827 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1829 header_view = modest_main_window_get_child_widget(main_window,
1830 MODEST_WIDGET_TYPE_HEADER_VIEW);
1834 conf = modest_runtime_get_conf ();
1836 if (TNY_IS_ACCOUNT (folder_store)) {
1838 /* Update active account */
1839 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1840 /* Show account details */
1841 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1844 if (TNY_IS_FOLDER (folder_store) && selected) {
1846 /* Update the active account */
1847 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1849 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1850 g_object_unref (account);
1854 /* Set the header style by default, it could
1855 be changed later by the refresh callback to
1857 modest_main_window_set_contents_style (main_window,
1858 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1860 /* Set folder on header view. This function
1861 will call tny_folder_refresh_async so we
1862 pass a callback that will be called when
1863 finished. We use that callback to set the
1864 empty view if there are no messages */
1865 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1866 TNY_FOLDER (folder_store),
1867 folder_refreshed_cb,
1870 /* Restore configuration. We need to do this
1871 *after* the set_folder because the widget
1872 memory asks the header view about its
1874 modest_widget_memory_restore (modest_runtime_get_conf (),
1875 G_OBJECT(header_view),
1876 MODEST_CONF_HEADER_VIEW_KEY);
1878 /* Update the active account */
1879 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1880 /* Save only if we're seeing headers */
1881 if (modest_main_window_get_contents_style (main_window) ==
1882 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1883 modest_widget_memory_save (conf, G_OBJECT (header_view),
1884 MODEST_CONF_HEADER_VIEW_KEY);
1885 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1889 /* Update toolbar dimming state */
1890 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1894 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1901 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1903 online = tny_device_is_online (modest_runtime_get_device());
1906 /* already online -- the item is simply not there... */
1907 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1909 GTK_MESSAGE_WARNING,
1911 _("The %s you selected cannot be found"),
1913 gtk_dialog_run (GTK_DIALOG(dialog));
1915 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1919 GTK_RESPONSE_REJECT,
1921 GTK_RESPONSE_ACCEPT,
1923 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1924 "Do you want to get online?"), item);
1925 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1926 gtk_label_new (txt), FALSE, FALSE, 0);
1927 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1930 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1931 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1932 /* TODO: Comment about why is this commented out: */
1933 /* modest_platform_connect_and_wait (); */
1936 gtk_widget_destroy (dialog);
1940 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1943 /* g_message ("%s %s", __FUNCTION__, link); */
1948 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1951 modest_platform_activate_uri (link);
1955 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1958 modest_platform_show_uri_popup (link);
1962 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1965 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1969 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1970 const gchar *address,
1973 /* g_message ("%s %s", __FUNCTION__, address); */
1977 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1979 TnyTransportAccount *transport_account;
1980 ModestMailOperation *mail_operation;
1982 gchar *account_name, *from;
1983 ModestAccountMgr *account_mgr;
1984 gchar *info_text = NULL;
1986 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1988 data = modest_msg_edit_window_get_msg_data (edit_window);
1990 account_mgr = modest_runtime_get_account_mgr();
1991 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1993 account_name = modest_account_mgr_get_default_account (account_mgr);
1994 if (!account_name) {
1995 g_printerr ("modest: no account found\n");
1996 modest_msg_edit_window_free_msg_data (edit_window, data);
2000 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2001 account_name = g_strdup (data->account_name);
2005 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2006 (modest_runtime_get_account_store(),
2008 TNY_ACCOUNT_TYPE_TRANSPORT));
2009 if (!transport_account) {
2010 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2011 g_free (account_name);
2012 modest_msg_edit_window_free_msg_data (edit_window, data);
2015 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2017 /* Create the mail operation */
2018 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
2019 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2021 modest_mail_operation_save_to_drafts (mail_operation,
2033 data->priority_flags);
2036 g_free (account_name);
2037 g_object_unref (G_OBJECT (transport_account));
2038 g_object_unref (G_OBJECT (mail_operation));
2040 modest_msg_edit_window_free_msg_data (edit_window, data);
2042 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2043 modest_platform_information_banner (NULL, NULL, info_text);
2047 /* For instance, when clicking the Send toolbar button when editing a message: */
2049 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2051 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2053 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2056 /* Offer the connection dialog, if necessary: */
2057 if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
2060 /* FIXME: Code added just for testing. The final version will
2061 use the send queue provided by tinymail and some
2063 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2064 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2066 account_name = modest_account_mgr_get_default_account (account_mgr);
2068 if (!account_name) {
2069 /* Run account setup wizard */
2070 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2075 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2077 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2078 account_name = g_strdup (data->account_name);
2081 /* Get the currently-active transport account for this modest account: */
2082 TnyTransportAccount *transport_account =
2083 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2084 (modest_runtime_get_account_store(),
2086 if (!transport_account) {
2087 /* Run account setup wizard */
2088 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2093 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2095 /* mail content checks and dialogs */
2096 if (data->subject == NULL || data->subject[0] == '\0') {
2097 GtkResponseType response;
2098 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
2099 _("mcen_nc_subject_is_empty_send"));
2100 if (response == GTK_RESPONSE_CANCEL) {
2101 g_free (account_name);
2106 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
2107 GtkResponseType response;
2108 gchar *note_message;
2109 gchar *note_subject = data->subject;
2110 if (note_subject == NULL || note_subject[0] == '\0')
2111 note_subject = _("mail_va_no_subject");
2112 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
2113 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
2115 g_free (note_message);
2116 if (response == GTK_RESPONSE_CANCEL) {
2117 g_free (account_name);
2122 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2124 /* Create the mail operation */
2125 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
2126 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2128 modest_mail_operation_send_new_mail (mail_operation,
2139 data->priority_flags);
2143 g_free (account_name);
2144 g_object_unref (G_OBJECT (transport_account));
2145 g_object_unref (G_OBJECT (mail_operation));
2147 modest_msg_edit_window_free_msg_data (edit_window, data);
2148 modest_msg_edit_window_set_sent (edit_window, TRUE);
2150 /* Save settings and close the window: */
2151 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2155 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2156 ModestMsgEditWindow *window)
2158 ModestMsgEditFormatState *format_state = NULL;
2160 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2161 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2163 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2166 format_state = modest_msg_edit_window_get_format_state (window);
2167 g_return_if_fail (format_state != NULL);
2169 format_state->bold = gtk_toggle_action_get_active (action);
2170 modest_msg_edit_window_set_format_state (window, format_state);
2171 g_free (format_state);
2176 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2177 ModestMsgEditWindow *window)
2179 ModestMsgEditFormatState *format_state = NULL;
2181 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2182 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2184 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2187 format_state = modest_msg_edit_window_get_format_state (window);
2188 g_return_if_fail (format_state != NULL);
2190 format_state->italics = gtk_toggle_action_get_active (action);
2191 modest_msg_edit_window_set_format_state (window, format_state);
2192 g_free (format_state);
2197 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2198 ModestMsgEditWindow *window)
2200 ModestMsgEditFormatState *format_state = NULL;
2202 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2203 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2205 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2208 format_state = modest_msg_edit_window_get_format_state (window);
2209 g_return_if_fail (format_state != NULL);
2211 format_state->bullet = gtk_toggle_action_get_active (action);
2212 modest_msg_edit_window_set_format_state (window, format_state);
2213 g_free (format_state);
2218 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2219 GtkRadioAction *selected,
2220 ModestMsgEditWindow *window)
2222 ModestMsgEditFormatState *format_state = NULL;
2223 GtkJustification value;
2225 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2227 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2230 value = gtk_radio_action_get_current_value (selected);
2232 format_state = modest_msg_edit_window_get_format_state (window);
2233 g_return_if_fail (format_state != NULL);
2235 format_state->justification = value;
2236 modest_msg_edit_window_set_format_state (window, format_state);
2237 g_free (format_state);
2241 modest_ui_actions_on_select_editor_color (GtkAction *action,
2242 ModestMsgEditWindow *window)
2244 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2245 g_return_if_fail (GTK_IS_ACTION (action));
2247 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2250 modest_msg_edit_window_select_color (window);
2254 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2255 ModestMsgEditWindow *window)
2257 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2258 g_return_if_fail (GTK_IS_ACTION (action));
2260 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2263 modest_msg_edit_window_select_background_color (window);
2267 modest_ui_actions_on_insert_image (GtkAction *action,
2268 ModestMsgEditWindow *window)
2270 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2271 g_return_if_fail (GTK_IS_ACTION (action));
2273 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2276 modest_msg_edit_window_insert_image (window);
2280 modest_ui_actions_on_attach_file (GtkAction *action,
2281 ModestMsgEditWindow *window)
2283 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2284 g_return_if_fail (GTK_IS_ACTION (action));
2286 modest_msg_edit_window_offer_attach_file (window);
2290 modest_ui_actions_on_remove_attachments (GtkAction *action,
2291 ModestMsgEditWindow *window)
2293 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2294 g_return_if_fail (GTK_IS_ACTION (action));
2296 modest_msg_edit_window_remove_attachments (window, NULL);
2300 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2303 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2304 const GError *error = modest_mail_operation_get_error (mail_op);
2308 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2309 modest_mail_operation_get_error (mail_op)->message);
2314 modest_ui_actions_create_folder(GtkWidget *parent_window,
2315 GtkWidget *folder_view)
2317 TnyFolderStore *parent_folder;
2319 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2321 if (parent_folder) {
2322 gboolean finished = FALSE;
2324 gchar *folder_name = NULL, *suggested_name = NULL;
2325 const gchar *proto_str = NULL;
2326 TnyAccount *account;
2328 if (TNY_IS_ACCOUNT (parent_folder))
2329 account = g_object_ref (parent_folder);
2331 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2332 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2334 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2335 MODEST_PROTOCOL_STORE_POP) {
2337 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2339 g_object_unref (account);
2341 /* Run the new folder dialog */
2343 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2348 g_free (suggested_name);
2349 suggested_name = NULL;
2351 if (result == GTK_RESPONSE_REJECT) {
2354 ModestMailOperation *mail_op;
2355 TnyFolder *new_folder = NULL;
2357 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2358 G_OBJECT(parent_window),
2359 modest_ui_actions_new_folder_error_handler,
2362 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2364 new_folder = modest_mail_operation_create_folder (mail_op,
2366 (const gchar *) folder_name);
2368 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2371 g_object_unref (new_folder);
2374 g_object_unref (mail_op);
2377 suggested_name = folder_name;
2381 g_object_unref (parent_folder);
2386 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2388 GtkWidget *folder_view;
2390 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2392 folder_view = modest_main_window_get_child_widget (main_window,
2393 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2397 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2401 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2404 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2405 const GError *error = NULL;
2406 const gchar *message = NULL;
2408 /* Get error message */
2409 error = modest_mail_operation_get_error (mail_op);
2410 if (error != NULL && error->message != NULL) {
2411 message = error->message;
2413 message = _("!!! FIXME: Unable to rename");
2416 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2421 modest_ui_actions_on_rename_folder (GtkAction *action,
2422 ModestMainWindow *main_window)
2424 TnyFolderStore *folder;
2425 GtkWidget *folder_view;
2426 GtkWidget *header_view;
2428 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2430 folder_view = modest_main_window_get_child_widget (main_window,
2431 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2435 header_view = modest_main_window_get_child_widget (main_window,
2436 MODEST_WIDGET_TYPE_HEADER_VIEW);
2441 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2445 /* Offer the connection dialog if necessary: */
2446 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2447 g_object_unref (G_OBJECT (folder));
2452 if (TNY_IS_FOLDER (folder)) {
2455 const gchar *current_name;
2457 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2458 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
2459 current_name, &folder_name);
2461 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
2462 ModestMailOperation *mail_op;
2465 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2466 G_OBJECT(main_window),
2467 modest_ui_actions_rename_folder_error_handler,
2470 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2473 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2475 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2476 TNY_FOLDER(folder), TRUE);
2478 modest_header_view_clear ((ModestHeaderView *) header_view);
2480 modest_mail_operation_rename_folder (mail_op,
2481 TNY_FOLDER (folder),
2482 (const gchar *) folder_name);
2484 g_object_unref (mail_op);
2485 g_free (folder_name);
2488 g_object_unref (folder);
2492 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2495 GObject *win = modest_mail_operation_get_source (mail_op);
2497 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2498 _("mail_in_ui_folder_delete_error"));
2499 g_object_unref (win);
2503 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2505 TnyFolderStore *folder;
2506 GtkWidget *folder_view;
2510 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
2512 folder_view = modest_main_window_get_child_widget (main_window,
2513 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2517 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2519 /* Show an error if it's an account */
2520 if (!TNY_IS_FOLDER (folder)) {
2521 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2522 _("mail_in_ui_folder_delete_error"));
2523 g_object_unref (G_OBJECT (folder));
2527 /* Offer the connection dialog if necessary: */
2528 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2529 g_object_unref (G_OBJECT (folder));
2534 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2535 tny_folder_get_name (TNY_FOLDER (folder)));
2536 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2537 (const gchar *) message);
2540 if (response == GTK_RESPONSE_OK) {
2541 ModestMailOperation *mail_op =
2542 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2543 G_OBJECT(main_window),
2544 modest_ui_actions_delete_folder_error_handler,
2547 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2549 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2550 g_object_unref (G_OBJECT (mail_op));
2553 g_object_unref (G_OBJECT (folder));
2557 modest_ui_actions_on_delete_folder (GtkAction *action,
2558 ModestMainWindow *main_window)
2560 GtkWidget *folder_view;
2561 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2563 delete_folder (main_window, FALSE);
2564 folder_view = modest_main_window_get_child_widget (main_window,
2565 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2568 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2572 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2574 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2576 delete_folder (main_window, TRUE);
2581 show_error (GtkWidget *parent_widget, const gchar* text)
2583 hildon_banner_show_information(parent_widget, NULL, text);
2586 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2588 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2595 gtk_dialog_run (dialog);
2596 gtk_widget_destroy (GTK_WIDGET (dialog));
2601 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2602 const gchar* server_account_name,
2607 ModestMainWindow *main_window)
2609 g_return_if_fail(server_account_name);
2610 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2612 /* Initalize output parameters: */
2619 #ifdef MODEST_PLATFORM_MAEMO
2620 /* Maemo uses a different (awkward) button order,
2621 * It should probably just use gtk_alternative_dialog_button_order ().
2623 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2627 GTK_RESPONSE_ACCEPT,
2629 GTK_RESPONSE_REJECT,
2632 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2636 GTK_RESPONSE_REJECT,
2638 GTK_RESPONSE_ACCEPT,
2640 #endif /* MODEST_PLATFORM_MAEMO */
2642 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2644 gchar *server_name = modest_server_account_get_hostname (
2645 modest_runtime_get_account_mgr(), server_account_name);
2646 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2647 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2652 /* This causes a warning because the logical ID has no %s in it,
2653 * though the translation does, but there is not much we can do about that: */
2654 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2655 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2658 g_free (server_name);
2662 gchar *initial_username = modest_server_account_get_username (
2663 modest_runtime_get_account_mgr(), server_account_name);
2665 GtkWidget *entry_username = gtk_entry_new ();
2666 if (initial_username)
2667 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2668 /* Dim this if a connection has ever succeeded with this username,
2669 * as per the UI spec: */
2670 const gboolean username_known =
2671 modest_server_account_get_username_has_succeeded(
2672 modest_runtime_get_account_mgr(), server_account_name);
2673 gtk_widget_set_sensitive (entry_username, !username_known);
2675 #ifdef MODEST_PLATFORM_MAEMO
2676 /* Auto-capitalization is the default, so let's turn it off: */
2677 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2679 /* Create a size group to be used by all captions.
2680 * Note that HildonCaption does not create a default size group if we do not specify one.
2681 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2682 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2684 GtkWidget *caption = hildon_caption_new (sizegroup,
2685 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2686 gtk_widget_show (entry_username);
2687 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2688 FALSE, FALSE, MODEST_MARGIN_HALF);
2689 gtk_widget_show (caption);
2691 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2693 #endif /* MODEST_PLATFORM_MAEMO */
2696 GtkWidget *entry_password = gtk_entry_new ();
2697 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2698 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2700 #ifdef MODEST_PLATFORM_MAEMO
2701 /* Auto-capitalization is the default, so let's turn it off: */
2702 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2703 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2705 caption = hildon_caption_new (sizegroup,
2706 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2707 gtk_widget_show (entry_password);
2708 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2709 FALSE, FALSE, MODEST_MARGIN_HALF);
2710 gtk_widget_show (caption);
2711 g_object_unref (sizegroup);
2713 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2715 #endif /* MODEST_PLATFORM_MAEMO */
2717 /* This is not in the Maemo UI spec:
2718 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2719 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2723 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2725 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2727 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2729 modest_server_account_set_username (
2730 modest_runtime_get_account_mgr(), server_account_name,
2733 const gboolean username_was_changed =
2734 (strcmp (*username, initial_username) != 0);
2735 if (username_was_changed) {
2736 g_warning ("%s: tinymail does not yet support changing the "
2737 "username in the get_password() callback.\n", __FUNCTION__);
2742 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2744 /* We do not save the password in the configuration,
2745 * because this function is only called for passwords that should
2746 * not be remembered:
2747 modest_server_account_set_password (
2748 modest_runtime_get_account_mgr(), server_account_name,
2757 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2769 /* This is not in the Maemo UI spec:
2770 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2776 gtk_widget_destroy (dialog);
2778 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2782 modest_ui_actions_on_cut (GtkAction *action,
2783 ModestWindow *window)
2785 GtkWidget *focused_widget;
2786 GtkClipboard *clipboard;
2788 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2789 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2790 if (GTK_IS_EDITABLE (focused_widget)) {
2791 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2792 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2793 gtk_clipboard_store (clipboard);
2794 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2795 GtkTextBuffer *buffer;
2797 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2798 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2799 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2800 gtk_clipboard_store (clipboard);
2801 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2802 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2803 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2804 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2809 modest_ui_actions_on_copy (GtkAction *action,
2810 ModestWindow *window)
2812 GtkClipboard *clipboard;
2813 GtkWidget *focused_widget;
2815 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2816 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2818 if (GTK_IS_LABEL (focused_widget)) {
2819 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2820 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2821 gtk_clipboard_store (clipboard);
2822 } else if (GTK_IS_EDITABLE (focused_widget)) {
2823 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2824 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2825 gtk_clipboard_store (clipboard);
2826 } else if (GTK_IS_HTML (focused_widget)) {
2827 gtk_html_copy (GTK_HTML (focused_widget));
2828 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2829 gtk_clipboard_store (clipboard);
2830 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2831 GtkTextBuffer *buffer;
2832 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2833 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2834 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2835 gtk_clipboard_store (clipboard);
2836 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2837 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2838 TnyIterator *iter = tny_list_create_iterator (header_list);
2839 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2841 gboolean ask = FALSE;
2843 TnyFolder *folder = tny_header_get_folder (header);
2844 TnyAccount *account = tny_folder_get_account (folder);
2845 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2846 /* If it's POP then ask */
2847 ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2848 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2849 g_object_unref (account);
2850 g_object_unref (folder);
2851 g_object_unref (header);
2854 g_object_unref (iter);
2856 /* Check that the messages have been previously downloaded */
2857 gboolean continue_download = TRUE;
2859 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window), FALSE);
2860 if (continue_download)
2861 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2862 g_object_unref (header_list);
2863 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2864 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2867 /* Show information banner */
2868 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2873 modest_ui_actions_on_undo (GtkAction *action,
2874 ModestWindow *window)
2876 ModestEmailClipboard *clipboard = NULL;
2878 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2879 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2880 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2881 /* Clear clipboard source */
2882 clipboard = modest_runtime_get_email_clipboard ();
2883 modest_email_clipboard_clear (clipboard);
2886 g_return_if_reached ();
2891 modest_ui_actions_on_redo (GtkAction *action,
2892 ModestWindow *window)
2894 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2895 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
2898 g_return_if_reached ();
2904 paste_msgs_cb (const GObject *object, gpointer user_data)
2906 g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2907 g_return_if_fail (GTK_IS_WIDGET (user_data));
2909 /* destroy information note */
2910 gtk_widget_destroy (GTK_WIDGET(user_data));
2914 paste_as_attachment_free (gpointer data)
2916 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
2918 gtk_widget_destroy (helper->banner);
2919 g_object_unref (helper->banner);
2924 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
2929 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
2930 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
2935 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
2940 modest_ui_actions_on_paste (GtkAction *action,
2941 ModestWindow *window)
2943 GtkWidget *focused_widget = NULL;
2944 GtkWidget *inf_note = NULL;
2945 ModestMailOperation *mail_op = NULL;
2947 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2948 if (GTK_IS_EDITABLE (focused_widget)) {
2949 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2950 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2951 ModestEmailClipboard *e_clipboard = NULL;
2952 e_clipboard = modest_runtime_get_email_clipboard ();
2953 if (modest_email_clipboard_cleared (e_clipboard)) {
2954 GtkTextBuffer *buffer;
2955 GtkClipboard *clipboard;
2957 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2958 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2959 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2960 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2961 ModestMailOperation *mail_op;
2962 TnyFolder *src_folder;
2965 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
2966 helper->window = MODEST_MSG_EDIT_WINDOW (window);
2967 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2968 _CS("ckct_nw_pasting"));
2969 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
2970 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2972 if (helper->banner != NULL) {
2973 g_object_ref (G_OBJECT (helper->banner));
2974 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
2975 gtk_widget_show (GTK_WIDGET (helper->banner));
2979 modest_mail_operation_get_msgs_full (mail_op,
2981 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
2983 paste_as_attachment_free);
2986 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2987 ModestEmailClipboard *clipboard = NULL;
2988 TnyFolder *src_folder = NULL;
2989 TnyFolderStore *folder_store = NULL;
2990 TnyList *data = NULL;
2991 gboolean delete = FALSE;
2993 /* Check clipboard source */
2994 clipboard = modest_runtime_get_email_clipboard ();
2995 if (modest_email_clipboard_cleared (clipboard))
2998 /* Get elements to paste */
2999 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
3001 /* Create a new mail operation */
3002 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
3004 /* Get destination folder */
3005 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
3007 /* transfer messages */
3011 /* Ask for user confirmation */
3012 response = msgs_move_to_confirmation (GTK_WINDOW (window),
3013 TNY_FOLDER (folder_store),
3017 if (response == GTK_RESPONSE_OK) {
3018 /* Launch notification */
3019 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3020 _CS("ckct_nw_pasting"));
3021 if (inf_note != NULL) {
3022 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3023 gtk_widget_show (GTK_WIDGET(inf_note));
3026 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3027 modest_mail_operation_xfer_msgs (mail_op,
3029 TNY_FOLDER (folder_store),
3034 g_object_unref (mail_op);
3037 } else if (src_folder != NULL) {
3038 /* Launch notification */
3039 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3040 _CS("ckct_nw_pasting"));
3041 if (inf_note != NULL) {
3042 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3043 gtk_widget_show (GTK_WIDGET(inf_note));
3046 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3047 modest_mail_operation_xfer_folder (mail_op,
3057 g_object_unref (data);
3058 if (src_folder != NULL)
3059 g_object_unref (src_folder);
3060 if (folder_store != NULL)
3061 g_object_unref (folder_store);
3067 modest_ui_actions_on_select_all (GtkAction *action,
3068 ModestWindow *window)
3070 GtkWidget *focused_widget;
3072 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3073 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3074 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3075 } else if (GTK_IS_LABEL (focused_widget)) {
3076 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3077 } else if (GTK_IS_EDITABLE (focused_widget)) {
3078 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3079 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3080 GtkTextBuffer *buffer;
3081 GtkTextIter start, end;
3083 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3084 gtk_text_buffer_get_start_iter (buffer, &start);
3085 gtk_text_buffer_get_end_iter (buffer, &end);
3086 gtk_text_buffer_select_range (buffer, &start, &end);
3087 } else if (GTK_IS_HTML (focused_widget)) {
3088 gtk_html_select_all (GTK_HTML (focused_widget));
3089 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3090 GtkWidget *header_view = focused_widget;
3091 GtkTreeSelection *selection = NULL;
3093 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
3094 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3095 MODEST_WIDGET_TYPE_HEADER_VIEW);
3097 /* Select all messages */
3098 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3099 gtk_tree_selection_select_all (selection);
3101 /* Set focuse on header view */
3102 gtk_widget_grab_focus (header_view);
3108 modest_ui_actions_on_mark_as_read (GtkAction *action,
3109 ModestWindow *window)
3111 g_return_if_fail (MODEST_IS_WINDOW(window));
3113 /* Mark each header as read */
3114 do_headers_action (window, headers_action_mark_as_read, NULL);
3118 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3119 ModestWindow *window)
3121 g_return_if_fail (MODEST_IS_WINDOW(window));
3123 /* Mark each header as read */
3124 do_headers_action (window, headers_action_mark_as_unread, NULL);
3128 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3129 GtkRadioAction *selected,
3130 ModestWindow *window)
3134 value = gtk_radio_action_get_current_value (selected);
3135 if (MODEST_IS_WINDOW (window)) {
3136 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3140 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3141 GtkRadioAction *selected,
3142 ModestWindow *window)
3144 TnyHeaderFlags flags;
3145 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3147 flags = gtk_radio_action_get_current_value (selected);
3148 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3151 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3152 GtkRadioAction *selected,
3153 ModestWindow *window)
3157 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3159 file_format = gtk_radio_action_get_current_value (selected);
3160 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3165 modest_ui_actions_on_zoom_plus (GtkAction *action,
3166 ModestWindow *window)
3168 g_return_if_fail (MODEST_IS_WINDOW (window));
3170 modest_window_zoom_plus (MODEST_WINDOW (window));
3174 modest_ui_actions_on_zoom_minus (GtkAction *action,
3175 ModestWindow *window)
3177 g_return_if_fail (MODEST_IS_WINDOW (window));
3179 modest_window_zoom_minus (MODEST_WINDOW (window));
3183 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3184 ModestWindow *window)
3186 ModestWindowMgr *mgr;
3187 gboolean fullscreen, active;
3188 g_return_if_fail (MODEST_IS_WINDOW (window));
3190 mgr = modest_runtime_get_window_mgr ();
3192 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3193 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3195 if (active != fullscreen) {
3196 modest_window_mgr_set_fullscreen_mode (mgr, active);
3197 gtk_window_present (GTK_WINDOW (window));
3202 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3203 ModestWindow *window)
3205 ModestWindowMgr *mgr;
3206 gboolean fullscreen;
3208 g_return_if_fail (MODEST_IS_WINDOW (window));
3210 mgr = modest_runtime_get_window_mgr ();
3211 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3212 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3214 gtk_window_present (GTK_WINDOW (window));
3218 * Used by modest_ui_actions_on_details to call do_headers_action
3221 headers_action_show_details (TnyHeader *header,
3222 ModestWindow *window,
3229 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3232 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3233 gtk_widget_show_all (dialog);
3234 gtk_dialog_run (GTK_DIALOG (dialog));
3236 gtk_widget_destroy (dialog);
3240 * Show the folder details in a ModestDetailsDialog widget
3243 show_folder_details (TnyFolder *folder,
3249 dialog = modest_details_dialog_new_with_folder (window, folder);
3252 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3253 gtk_widget_show_all (dialog);
3254 gtk_dialog_run (GTK_DIALOG (dialog));
3256 gtk_widget_destroy (dialog);
3260 * Show the header details in a ModestDetailsDialog widget
3263 modest_ui_actions_on_details (GtkAction *action,
3266 TnyList * headers_list;
3270 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3273 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3276 g_object_unref (msg);
3278 headers_list = get_selected_headers (win);
3282 iter = tny_list_create_iterator (headers_list);
3284 header = TNY_HEADER (tny_iterator_get_current (iter));
3286 headers_action_show_details (header, win, NULL);
3287 g_object_unref (header);
3290 g_object_unref (iter);
3291 g_object_unref (headers_list);
3293 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3294 GtkWidget *folder_view, *header_view;
3296 /* Check which widget has the focus */
3297 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3298 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3299 if (gtk_widget_is_focus (folder_view)) {
3300 TnyFolderStore *folder_store
3301 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3302 if (!folder_store) {
3303 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3306 /* Show only when it's a folder */
3307 /* This function should not be called for account items,
3308 * because we dim the menu item for them. */
3309 if (TNY_IS_FOLDER (folder_store)) {
3310 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3313 g_object_unref (folder_store);
3316 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3317 MODEST_WIDGET_TYPE_HEADER_VIEW);
3318 /* Show details of each header */
3319 do_headers_action (win, headers_action_show_details, header_view);
3325 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3326 ModestMsgEditWindow *window)
3328 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3330 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3334 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3335 ModestMsgEditWindow *window)
3337 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3339 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3343 modest_ui_actions_toggle_folders_view (GtkAction *action,
3344 ModestMainWindow *main_window)
3346 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3348 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3349 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3351 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3355 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3356 ModestWindow *window)
3358 gboolean active, fullscreen = FALSE;
3359 ModestWindowMgr *mgr;
3361 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3363 /* Check if we want to toggle the toolbar vuew in fullscreen
3365 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3366 "ViewShowToolbarFullScreen")) {
3370 /* Toggle toolbar */
3371 mgr = modest_runtime_get_window_mgr ();
3372 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
3376 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3377 ModestMsgEditWindow *window)
3379 modest_msg_edit_window_select_font (window);
3383 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3384 const gchar *display_name,
3387 /* Do not change the application name if the widget has not
3388 the focus. This callback could be called even if the folder
3389 view has not the focus, because the handled signal could be
3390 emitted when the folder view is redrawn */
3391 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3393 gtk_window_set_title (window, display_name);
3395 gtk_window_set_title (window, " ");
3400 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3402 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3403 modest_msg_edit_window_select_contacts (window);
3407 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3409 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3410 modest_msg_edit_window_check_names (window, FALSE);
3414 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3416 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3417 GTK_WIDGET (user_data));
3421 create_move_to_dialog (GtkWindow *win,
3422 GtkWidget *folder_view,
3423 GtkWidget **tree_view)
3425 GtkWidget *dialog, *scroll;
3426 GtkWidget *new_button;
3428 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3430 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3433 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
3434 /* We do this manually so GTK+ does not associate a response ID for
3436 new_button = gtk_button_new_from_stock (GTK_STOCK_NEW);
3437 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3438 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
3440 /* Create scrolled window */
3441 scroll = gtk_scrolled_window_new (NULL, NULL);
3442 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3443 GTK_POLICY_AUTOMATIC,
3444 GTK_POLICY_AUTOMATIC);
3446 /* Create folder view */
3447 *tree_view = modest_platform_create_folder_view (NULL);
3449 g_signal_connect (G_OBJECT (new_button), "clicked", G_CALLBACK(create_move_to_dialog_on_new_folder), *tree_view);
3451 /* It could happen that we're trying to move a message from a
3452 window (msg window for example) after the main window was
3453 closed, so we can not just get the model of the folder
3455 if (MODEST_IS_FOLDER_VIEW (folder_view))
3456 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
3457 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
3459 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3460 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3462 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3464 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3466 /* Add scroll to dialog */
3467 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3468 scroll, TRUE, TRUE, 0);
3470 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3471 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3477 * Returns TRUE if at least one of the headers of the list belongs to
3478 * a message that has been fully retrieved.
3481 has_retrieved_msgs (TnyList *list)
3484 gboolean found = FALSE;
3486 iter = tny_list_create_iterator (list);
3487 while (!tny_iterator_is_done (iter) && !found) {
3489 TnyHeaderFlags flags = 0;
3491 header = TNY_HEADER (tny_iterator_get_current (iter));
3493 flags = tny_header_get_flags (header);
3494 if (flags & TNY_HEADER_FLAG_CACHED)
3495 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3498 g_object_unref (header);
3502 tny_iterator_next (iter);
3504 g_object_unref (iter);
3510 * Shows a confirmation dialog to the user when we're moving messages
3511 * from a remote server to the local storage. Returns the dialog
3512 * response. If it's other kind of movement the it always returns
3516 msgs_move_to_confirmation (GtkWindow *win,
3517 TnyFolder *dest_folder,
3521 gint response = GTK_RESPONSE_OK;
3523 /* If the destination is a local folder (or MMC folder )*/
3524 if (!modest_tny_folder_is_remote_folder (dest_folder)) {
3525 /* if (modest_tny_folder_is_local_folder (dest_folder)) { */
3526 TnyFolder *src_folder = NULL;
3527 TnyIterator *iter = NULL;
3528 TnyHeader *header = NULL;
3530 /* Get source folder */
3531 iter = tny_list_create_iterator (headers);
3532 header = TNY_HEADER (tny_iterator_get_current (iter));
3534 src_folder = tny_header_get_folder (header);
3535 g_object_unref (header);
3538 g_object_unref (iter);
3540 /* if no src_folder, message may be an attahcment */
3541 if (src_folder == NULL)
3542 return GTK_RESPONSE_CANCEL;
3544 /* If the source is a remote folder */
3545 /* if (!modest_tny_folder_is_local_folder (src_folder)) { */
3546 if (modest_tny_folder_is_remote_folder (src_folder)) {
3547 const gchar *message = NULL;
3548 gboolean cached = has_retrieved_msgs (headers);
3550 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
3551 tny_list_get_length (headers));
3553 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
3554 tny_list_get_length (headers));
3556 if (cached && !delete)
3557 response = GTK_RESPONSE_OK;
3559 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
3560 (const gchar *) message);
3563 g_object_unref (src_folder);
3572 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
3574 ModestMsgViewWindow *self = NULL;
3576 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
3577 self = MODEST_MSG_VIEW_WINDOW (object);
3579 if (!modest_msg_view_window_select_next_message (self))
3580 if (!modest_msg_view_window_select_previous_message (self))
3581 /* No more messages to view, so close this window */
3582 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3586 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3589 GObject *win = modest_mail_operation_get_source (mail_op);
3590 const GError *error = NULL;
3591 const gchar *message = NULL;
3593 /* Get error message */
3594 error = modest_mail_operation_get_error (mail_op);
3595 if (error != NULL && error->message != NULL) {
3596 message = error->message;
3598 message = _("mail_in_ui_folder_move_target_error");
3601 /* Show notification dialog */
3602 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3603 g_object_unref (win);
3607 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3610 GObject *win = modest_mail_operation_get_source (mail_op);
3611 const GError *error = modest_mail_operation_get_error (mail_op);
3613 g_return_if_fail (error != NULL);
3614 if (error->message != NULL)
3615 g_printerr ("modest: %s\n", error->message);
3617 g_printerr ("modest: unkonw error on send&receive operation");
3619 /* Show error message */
3620 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3621 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3622 /* _CS("sfil_ib_unable_to_receive")); */
3624 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3625 /* _CS("sfil_ib_unable_to_send")); */
3626 g_object_unref (win);
3630 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3637 gint pending_purges = 0;
3638 gboolean some_purged = FALSE;
3639 ModestWindow *win = MODEST_WINDOW (user_data);
3640 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3642 /* If there was any error */
3643 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
3644 modest_window_mgr_unregister_header (mgr, header);
3648 /* Once the message has been retrieved for purging, we check if
3649 * it's all ok for purging */
3651 parts = tny_simple_list_new ();
3652 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3653 iter = tny_list_create_iterator (parts);
3655 while (!tny_iterator_is_done (iter)) {
3657 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3658 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
3659 if (tny_mime_part_is_purged (part))
3666 g_object_unref (part);
3668 tny_iterator_next (iter);
3671 if (pending_purges>0) {
3673 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3675 if (response == GTK_RESPONSE_OK) {
3676 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3677 tny_iterator_first (iter);
3678 while (!tny_iterator_is_done (iter)) {
3681 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3682 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
3683 tny_mime_part_set_purged (part);
3686 g_object_unref (part);
3688 tny_iterator_next (iter);
3691 tny_msg_rewrite_cache (msg);
3694 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3697 /* remove attachments */
3698 tny_iterator_first (iter);
3699 while (!tny_iterator_is_done (iter)) {
3702 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3704 /* One for the reference given by tny_iterator_get_current(): */
3705 g_object_unref (part);
3707 /* TODO: Is this meant to remove the attachment by doing another unref()?
3708 * Otherwise, this seems useless. */
3711 tny_iterator_next (iter);
3713 modest_window_mgr_unregister_header (mgr, header);
3715 g_object_unref (iter);
3716 g_object_unref (parts);
3720 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3721 ModestMainWindow *win)
3723 GtkWidget *header_view;
3724 TnyList *header_list;
3727 TnyHeaderFlags flags;
3728 ModestWindow *msg_view_window = NULL;
3731 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3733 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3734 MODEST_WIDGET_TYPE_HEADER_VIEW);
3736 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3738 if (tny_list_get_length (header_list) == 1) {
3739 iter = tny_list_create_iterator (header_list);
3740 header = TNY_HEADER (tny_iterator_get_current (iter));
3741 g_object_unref (iter);
3746 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3747 header, &msg_view_window);
3748 flags = tny_header_get_flags (header);
3749 if (!(flags & TNY_HEADER_FLAG_CACHED))
3752 if (msg_view_window != NULL)
3753 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3755 /* do nothing; uid was registered before, so window is probably on it's way */
3756 g_warning ("debug: header %p has already been registered", header);
3759 ModestMailOperation *mail_op = NULL;
3760 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3761 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3763 modest_ui_actions_get_msgs_full_error_handler,
3765 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3766 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3768 g_object_unref (mail_op);
3771 g_object_unref (header);
3773 g_object_unref (header_list);
3777 * Utility function that transfer messages from both the main window
3778 * and the msg view window when using the "Move to" dialog
3781 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
3784 TnyList *headers = NULL;
3786 TnyAccount *dst_account = NULL;
3787 const gchar *proto_str = NULL;
3788 gboolean dst_is_pop = FALSE;
3790 if (!TNY_IS_FOLDER (dst_folder)) {
3791 modest_platform_information_banner (GTK_WIDGET (win),
3793 _CS("ckdg_ib_unable_to_move_to_current_location"));
3797 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
3798 proto_str = tny_account_get_proto (dst_account);
3799 dst_is_pop = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
3800 MODEST_PROTOCOL_STORE_POP);
3801 g_object_unref (dst_account);
3803 /* Get selected headers */
3804 headers = get_selected_headers (MODEST_WINDOW (win));
3807 modest_platform_information_banner (GTK_WIDGET (win),
3809 ngettext("mail_in_ui_folder_move_target_error",
3810 "mail_in_ui_folder_move_targets_error",
3811 tny_list_get_length (headers)));
3812 g_object_unref (headers);
3816 /* Ask for user confirmation */
3817 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3818 TNY_FOLDER (dst_folder),
3822 /* Transfer messages */
3823 if (response == GTK_RESPONSE_OK) {
3824 ModestMailOperation *mail_op =
3825 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3827 modest_ui_actions_move_folder_error_handler,
3829 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3832 modest_mail_operation_xfer_msgs (mail_op,
3834 TNY_FOLDER (dst_folder),
3836 (MODEST_IS_MSG_VIEW_WINDOW (win)) ? transfer_msgs_from_viewer_cb : NULL,
3839 g_object_unref (G_OBJECT (mail_op));
3841 g_object_unref (headers);
3846 * UI handler for the "Move to" action when invoked from the
3850 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3851 GtkWidget *folder_view,
3852 TnyFolderStore *dst_folder,
3853 ModestMainWindow *win)
3855 GtkWidget *header_view = NULL;
3856 ModestMailOperation *mail_op = NULL;
3857 TnyFolderStore *src_folder;
3859 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3861 /* Get the source folder */
3862 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3864 /* Offer the connection dialog if necessary, if the source folder is in a networked account: */
3865 if (!modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3869 /* Get header view */
3871 modest_main_window_get_child_widget (win, MODEST_WIDGET_TYPE_HEADER_VIEW);
3873 /* Get folder or messages to transfer */
3874 if (gtk_widget_is_focus (folder_view)) {
3876 /* Allow only to transfer folders to the local root folder */
3877 if (TNY_IS_ACCOUNT (dst_folder) &&
3878 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder))
3881 /* Clean folder on header view before moving it */
3882 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3884 if (TNY_IS_FOLDER (src_folder)) {
3886 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3888 modest_ui_actions_move_folder_error_handler,
3890 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3893 modest_mail_operation_xfer_folder (mail_op,
3894 TNY_FOLDER (src_folder),
3897 /* Unref mail operation */
3898 g_object_unref (G_OBJECT (mail_op));
3900 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
3902 } else if (gtk_widget_is_focus (header_view)) {
3903 /* Transfer messages */
3904 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3909 g_object_unref (src_folder);
3914 * UI handler for the "Move to" action when invoked from the
3915 * ModestMsgViewWindow
3918 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3919 TnyFolderStore *dst_folder,
3920 ModestMsgViewWindow *win)
3922 TnyHeader *header = NULL;
3923 TnyFolder *src_folder;
3925 /* Create header list */
3926 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3927 src_folder = tny_header_get_folder(header);
3928 g_object_unref (header);
3930 /* Transfer the message */
3931 if (modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (src_folder)))
3932 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3934 g_object_unref (src_folder);
3938 modest_ui_actions_on_move_to (GtkAction *action,
3941 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3943 TnyFolderStore *dst_folder = NULL;
3944 ModestMainWindow *main_window;
3946 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3947 MODEST_IS_MSG_VIEW_WINDOW (win));
3949 /* Get the main window if exists */
3950 if (MODEST_IS_MAIN_WINDOW (win))
3951 main_window = MODEST_MAIN_WINDOW (win);
3954 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3956 /* Get the folder view widget if exists */
3958 folder_view = modest_main_window_get_child_widget (main_window,
3959 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3963 /* Create and run the dialog */
3964 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
3965 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3966 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3967 result = gtk_dialog_run (GTK_DIALOG(dialog));
3968 g_object_ref (tree_view);
3969 gtk_widget_destroy (dialog);
3971 if (result != GTK_RESPONSE_ACCEPT)
3974 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3975 /* Offer the connection dialog if necessary: */
3976 if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3979 /* Do window specific stuff */
3980 if (MODEST_IS_MAIN_WINDOW (win))
3981 modest_ui_actions_on_main_window_move_to (action,
3984 MODEST_MAIN_WINDOW (win));
3986 modest_ui_actions_on_msg_view_window_move_to (action,
3988 MODEST_MSG_VIEW_WINDOW (win));
3991 g_object_unref (dst_folder);
3995 * Calls #HeadersFunc for each header already selected in the main
3996 * window or the message currently being shown in the msg view window
3999 do_headers_action (ModestWindow *win,
4003 TnyList *headers_list = NULL;
4004 TnyIterator *iter = NULL;
4005 TnyHeader *header = NULL;
4006 TnyFolder *folder = NULL;
4009 headers_list = get_selected_headers (win);
4013 /* Get the folder */
4014 iter = tny_list_create_iterator (headers_list);
4015 header = TNY_HEADER (tny_iterator_get_current (iter));
4017 folder = tny_header_get_folder (header);
4018 g_object_unref (header);
4021 /* Call the function for each header */
4022 while (!tny_iterator_is_done (iter)) {
4023 header = TNY_HEADER (tny_iterator_get_current (iter));
4024 func (header, win, user_data);
4025 g_object_unref (header);
4026 tny_iterator_next (iter);
4029 /* Trick: do a poke status in order to speed up the signaling
4031 tny_folder_poke_status (folder);
4034 g_object_unref (folder);
4035 g_object_unref (iter);
4036 g_object_unref (headers_list);
4040 modest_ui_actions_view_attachment (GtkAction *action,
4041 ModestWindow *window)
4043 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4044 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4046 /* not supported window for this action */
4047 g_return_if_reached ();
4052 modest_ui_actions_save_attachments (GtkAction *action,
4053 ModestWindow *window)
4055 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4056 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4058 /* not supported window for this action */
4059 g_return_if_reached ();
4064 modest_ui_actions_remove_attachments (GtkAction *action,
4065 ModestWindow *window)
4067 if (MODEST_IS_MAIN_WINDOW (window)) {
4068 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4069 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4070 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4072 /* not supported window for this action */
4073 g_return_if_reached ();
4078 modest_ui_actions_on_settings (GtkAction *action,
4083 dialog = modest_platform_get_global_settings_dialog ();
4084 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4085 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4086 gtk_widget_show_all (dialog);
4088 gtk_dialog_run (GTK_DIALOG (dialog));
4090 gtk_widget_destroy (dialog);
4094 modest_ui_actions_on_help (GtkAction *action,
4097 const gchar *help_id = NULL;
4099 if (MODEST_IS_MAIN_WINDOW (win)) {
4100 const gchar *action_name;
4101 action_name = gtk_action_get_name (action);
4103 if (!strcmp (action_name, "FolderViewCSMHelp") ||
4104 !strcmp (action_name, "HeaderViewCSMHelp")) {
4105 GtkWidget *folder_view;
4106 TnyFolderStore *folder_store;
4107 /* Get selected folder */
4108 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4109 MODEST_WIDGET_TYPE_FOLDER_VIEW);
4110 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4112 /* Switch help_id */
4113 if (TNY_IS_FOLDER (folder_store)) {
4114 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4115 case TNY_FOLDER_TYPE_NORMAL:
4116 help_id = "applications_email_managefolders";
4118 case TNY_FOLDER_TYPE_INBOX:
4119 help_id = "applications_email_inbox";
4121 case TNY_FOLDER_TYPE_OUTBOX:
4122 help_id = "applications_email_outbox";
4124 case TNY_FOLDER_TYPE_SENT:
4125 help_id = "applications_email_sent";
4127 case TNY_FOLDER_TYPE_DRAFTS:
4128 help_id = "applications_email_drafts";
4130 case TNY_FOLDER_TYPE_ARCHIVE:
4131 help_id = "applications_email_managefolders";
4134 help_id = "applications_email_managefolders";
4137 help_id = "applications_email_mainview";
4139 g_object_unref (folder_store);
4141 help_id = "applications_email_mainview";
4143 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4144 help_id = "applications_email_viewer";
4145 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4146 help_id = "applications_email_editor";
4148 modest_platform_show_help (GTK_WINDOW (win), help_id);
4152 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4153 ModestWindow *window)
4155 ModestMailOperation *mail_op;
4159 headers = get_selected_headers (window);
4163 /* Create mail operation */
4164 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4166 modest_ui_actions_get_msgs_full_error_handler,
4168 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4169 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4172 g_object_unref (headers);
4173 g_object_unref (mail_op);
4177 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4178 ModestWindow *window)
4180 g_return_if_fail (MODEST_IS_WINDOW (window));
4183 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4187 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4188 ModestWindow *window)
4190 g_return_if_fail (MODEST_IS_WINDOW (window));
4193 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4197 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4198 ModestWindow *window)
4200 g_return_if_fail (MODEST_IS_WINDOW (window));
4203 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4207 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4208 ModestWindow *window)
4210 g_return_if_fail (MODEST_IS_WINDOW (window));
4213 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4217 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4218 ModestWindow *window)
4220 g_return_if_fail (MODEST_IS_WINDOW (window));
4223 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4227 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4228 ModestWindow *window)
4230 g_return_if_fail (MODEST_IS_WINDOW (window));
4233 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4237 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4238 ModestWindow *window)
4240 g_return_if_fail (MODEST_IS_WINDOW (window));
4243 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4247 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4248 ModestWindow *window)
4250 g_return_if_fail (MODEST_IS_WINDOW (window));
4253 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4257 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4259 g_return_if_fail (MODEST_IS_WINDOW (window));
4262 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4266 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4268 g_return_if_fail (MODEST_IS_WINDOW (window));
4270 modest_platform_show_search_messages (GTK_WINDOW (window));
4274 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4276 g_return_if_fail (MODEST_IS_WINDOW (win));
4277 modest_platform_show_addressbook (GTK_WINDOW (win));
4282 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4283 ModestWindow *window)
4285 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4287 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4291 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
4292 ModestMailOperationState *state,
4295 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4297 /* Set send/receive operation finished */
4298 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4299 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));