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 (msg,
863 gtk_tree_row_reference_free (row_reference);
865 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
868 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
873 /* Register and show new window */
875 mgr = modest_runtime_get_window_mgr ();
876 modest_window_mgr_register_window (mgr, win);
877 g_object_unref (win);
878 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
879 gtk_widget_show_all (GTK_WIDGET(win));
882 /* Update toolbar dimming state */
883 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
884 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
890 g_object_unref (parent_win);
891 g_object_unref (folder);
895 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
899 GObject *win = modest_mail_operation_get_source (mail_op);
901 error = modest_mail_operation_get_error (mail_op);
902 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, error->code, error->message);
904 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
906 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
909 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
910 _("mail_ni_ui_folder_get_msg_folder_error"));
914 g_object_unref (win);
918 * This function is used by both modest_ui_actions_on_open and
919 * modest_ui_actions_on_header_activated. This way we always do the
920 * same when trying to open messages.
923 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
925 ModestWindowMgr *mgr = NULL;
926 TnyIterator *iter = NULL;
927 ModestMailOperation *mail_op = NULL;
928 TnyList *not_opened_headers = NULL;
929 TnyHeaderFlags flags = 0;
931 /* Look if we already have a message view for each header. If
932 true, then remove the header from the list of headers to
934 mgr = modest_runtime_get_window_mgr ();
935 iter = tny_list_create_iterator (headers);
936 not_opened_headers = tny_simple_list_new ();
938 while (!tny_iterator_is_done (iter)) {
940 ModestWindow *window = NULL;
941 TnyHeader *header = NULL;
942 gboolean found = FALSE;
944 header = TNY_HEADER (tny_iterator_get_current (iter));
946 flags = tny_header_get_flags (header);
949 found = modest_window_mgr_find_registered_header (mgr, header, &window);
951 /* Do not open again the message and present the
952 window to the user */
955 gtk_window_present (GTK_WINDOW (window));
957 /* the header has been registered already, we don't do
958 * anything but wait for the window to come up*/
959 g_debug ("header %p already registered, waiting for window", header);
961 tny_list_append (not_opened_headers, G_OBJECT (header));
965 g_object_unref (header);
967 tny_iterator_next (iter);
969 g_object_unref (iter);
972 /* If some messages would have to be downloaded, ask the user to
973 * make a connection. It's generally easier to do this here (in the mainloop)
974 * than later in a thread:
976 if (tny_list_get_length (not_opened_headers) > 0) {
978 gboolean found = FALSE;
980 iter = tny_list_create_iterator (not_opened_headers);
981 while (!tny_iterator_is_done (iter) && !found) {
982 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
983 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
986 tny_iterator_next (iter);
988 g_object_unref (header);
990 g_object_unref (iter);
992 if (found && !modest_platform_connect_and_wait (GTK_WINDOW (win), NULL)) {
993 g_object_unref (not_opened_headers);
998 /* Register the headers before actually creating the windows: */
999 TnyIterator *iter_not_opened = tny_list_create_iterator (not_opened_headers);
1000 while (!tny_iterator_is_done (iter_not_opened)) {
1001 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1003 modest_window_mgr_register_header (mgr, header);
1004 g_object_unref (header);
1007 tny_iterator_next (iter_not_opened);
1009 g_object_unref (iter_not_opened);
1010 iter_not_opened = NULL;
1012 /* Open each message */
1013 if (tny_list_get_length (not_opened_headers) > 0) {
1014 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1016 modest_ui_actions_get_msgs_full_error_handler,
1018 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1019 if (tny_list_get_length (not_opened_headers) > 1) {
1020 modest_mail_operation_get_msgs_full (mail_op,
1026 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1027 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1028 modest_mail_operation_get_msg (mail_op, header, open_msg_cb, NULL);
1029 g_object_unref (header);
1030 g_object_unref (iter);
1032 g_object_unref (mail_op);
1036 if (not_opened_headers != NULL)
1037 g_object_unref (not_opened_headers);
1041 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1046 headers = get_selected_headers (win);
1051 _modest_ui_actions_open (headers, win);
1053 g_object_unref(headers);
1058 free_reply_forward_helper (gpointer data)
1060 ReplyForwardHelper *helper;
1062 helper = (ReplyForwardHelper *) data;
1063 g_free (helper->account_name);
1064 g_slice_free (ReplyForwardHelper, helper);
1068 reply_forward_cb (ModestMailOperation *mail_op,
1074 ReplyForwardHelper *rf_helper;
1075 ModestWindow *msg_win = NULL;
1076 ModestEditType edit_type;
1078 TnyAccount *account = NULL;
1079 ModestWindowMgr *mgr = NULL;
1080 gchar *signature = NULL;
1082 /* If there was any error. The mail operation could be NULL,
1083 this means that we already have the message downloaded and
1084 that we didn't do a mail operation to retrieve it */
1085 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1088 g_return_if_fail (user_data != NULL);
1089 rf_helper = (ReplyForwardHelper *) user_data;
1091 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1092 rf_helper->account_name);
1093 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
1094 rf_helper->account_name,
1095 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
1096 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
1097 rf_helper->account_name,
1098 MODEST_ACCOUNT_SIGNATURE, FALSE);
1101 /* Create reply mail */
1102 switch (rf_helper->action) {
1105 modest_tny_msg_create_reply_msg (msg, header, from, signature,
1106 rf_helper->reply_forward_type,
1107 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1109 case ACTION_REPLY_TO_ALL:
1111 modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1112 MODEST_TNY_MSG_REPLY_MODE_ALL);
1113 edit_type = MODEST_EDIT_TYPE_REPLY;
1115 case ACTION_FORWARD:
1117 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1118 edit_type = MODEST_EDIT_TYPE_FORWARD;
1121 g_return_if_reached ();
1128 g_printerr ("modest: failed to create message\n");
1132 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1133 rf_helper->account_name,
1134 TNY_ACCOUNT_TYPE_STORE);
1136 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1140 /* Create and register the windows */
1141 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1142 mgr = modest_runtime_get_window_mgr ();
1143 modest_window_mgr_register_window (mgr, msg_win);
1145 if (rf_helper->parent_window != NULL) {
1146 gdouble parent_zoom;
1148 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1149 modest_window_set_zoom (msg_win, parent_zoom);
1152 /* Show edit window */
1153 gtk_widget_show_all (GTK_WIDGET (msg_win));
1157 g_object_unref (msg_win);
1159 g_object_unref (G_OBJECT (new_msg));
1161 g_object_unref (G_OBJECT (account));
1162 /* g_object_unref (msg); */
1163 free_reply_forward_helper (rf_helper);
1167 * Checks a list of headers. If any of them are not currently
1168 * downloaded (CACHED) then it asks the user for permission to
1171 * Returns FALSE if the user does not want to download the
1172 * messages. Returns TRUE if the user allowed the download or if all
1173 * of them are currently downloaded
1176 download_uncached_messages (TnyList *header_list,
1182 gint uncached_messages = 0;
1184 iter = tny_list_create_iterator (header_list);
1185 while (!tny_iterator_is_done (iter)) {
1188 header = TNY_HEADER (tny_iterator_get_current (iter));
1190 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1191 uncached_messages ++;
1192 g_object_unref (header);
1195 tny_iterator_next (iter);
1197 g_object_unref (iter);
1199 /* Ask for user permission to download the messages */
1201 if (uncached_messages > 0) {
1202 GtkResponseType response;
1204 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1205 _("emev_nc_include_original"));
1208 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1209 ngettext("mcen_nc_get_msg",
1211 uncached_messages));
1212 if (response == GTK_RESPONSE_CANCEL)
1215 /* If a download will be necessary, make sure that we have a connection: */
1216 retval = modest_platform_connect_and_wait(win, NULL);
1224 * Common code for the reply and forward actions
1227 reply_forward (ReplyForwardAction action, ModestWindow *win)
1229 ModestMailOperation *mail_op = NULL;
1230 TnyList *header_list = NULL;
1231 ReplyForwardHelper *rf_helper = NULL;
1232 guint reply_forward_type;
1233 gboolean continue_download = TRUE;
1234 gboolean do_retrieve = TRUE;
1236 g_return_if_fail (MODEST_IS_WINDOW(win));
1238 /* we need an account when editing */
1239 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1240 const gboolean created = modest_run_account_setup_wizard (win);
1245 header_list = get_selected_headers (win);
1249 reply_forward_type =
1250 modest_conf_get_int (modest_runtime_get_conf (),
1251 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1254 /* Check that the messages have been previously downloaded */
1255 do_retrieve = (action == ACTION_FORWARD) || (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1257 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win), TRUE);
1258 if (!continue_download) {
1259 g_object_unref (header_list);
1263 /* We assume that we can only select messages of the
1264 same folder and that we reply all of them from the
1265 same account. In fact the interface currently only
1266 allows single selection */
1269 rf_helper = g_slice_new0 (ReplyForwardHelper);
1270 rf_helper->reply_forward_type = reply_forward_type;
1271 rf_helper->action = action;
1272 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1274 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1275 rf_helper->parent_window = GTK_WIDGET (win);
1276 if (!rf_helper->account_name)
1277 rf_helper->account_name =
1278 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1280 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1283 /* Get header and message. Do not free them here, the
1284 reply_forward_cb must do it */
1285 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1286 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1287 if (!msg || !header) {
1289 g_object_unref (msg);
1290 g_printerr ("modest: no message found\n");
1293 reply_forward_cb (NULL, header, msg, rf_helper);
1296 g_object_unref (header);
1301 /* Only reply/forward to one message */
1302 iter = tny_list_create_iterator (header_list);
1303 header = TNY_HEADER (tny_iterator_get_current (iter));
1304 g_object_unref (iter);
1307 /* Retrieve messages */
1309 mail_op = modest_mail_operation_new_with_error_handling (
1310 MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1312 modest_ui_actions_get_msgs_full_error_handler,
1314 modest_mail_operation_queue_add (
1315 modest_runtime_get_mail_operation_queue (), mail_op);
1317 modest_mail_operation_get_msg (mail_op,
1322 g_object_unref(mail_op);
1324 /* we put a ref here to prevent double unref as the reply
1325 * forward callback unrefs the header at its end */
1326 reply_forward_cb (NULL, header, NULL, rf_helper);
1330 g_object_unref (header);
1336 g_object_unref (header_list);
1340 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1342 g_return_if_fail (MODEST_IS_WINDOW(win));
1344 reply_forward (ACTION_REPLY, win);
1348 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1350 g_return_if_fail (MODEST_IS_WINDOW(win));
1352 reply_forward (ACTION_FORWARD, win);
1356 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1358 g_return_if_fail (MODEST_IS_WINDOW(win));
1360 reply_forward (ACTION_REPLY_TO_ALL, win);
1364 modest_ui_actions_on_next (GtkAction *action,
1365 ModestWindow *window)
1367 if (MODEST_IS_MAIN_WINDOW (window)) {
1368 GtkWidget *header_view;
1370 header_view = modest_main_window_get_child_widget (
1371 MODEST_MAIN_WINDOW(window),
1372 MODEST_WIDGET_TYPE_HEADER_VIEW);
1376 modest_header_view_select_next (
1377 MODEST_HEADER_VIEW(header_view));
1378 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1379 modest_msg_view_window_select_next_message (
1380 MODEST_MSG_VIEW_WINDOW (window));
1382 g_return_if_reached ();
1387 modest_ui_actions_on_prev (GtkAction *action,
1388 ModestWindow *window)
1390 g_return_if_fail (MODEST_IS_WINDOW(window));
1392 if (MODEST_IS_MAIN_WINDOW (window)) {
1393 GtkWidget *header_view;
1394 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1395 MODEST_WIDGET_TYPE_HEADER_VIEW);
1399 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1400 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1401 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1403 g_return_if_reached ();
1408 modest_ui_actions_on_sort (GtkAction *action,
1409 ModestWindow *window)
1411 g_return_if_fail (MODEST_IS_WINDOW(window));
1413 if (MODEST_IS_MAIN_WINDOW (window)) {
1414 GtkWidget *header_view;
1415 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1416 MODEST_WIDGET_TYPE_HEADER_VIEW);
1418 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1423 /* Show sorting dialog */
1424 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1429 new_messages_arrived (ModestMailOperation *self,
1433 ModestMainWindow *win = NULL;
1434 GtkWidget *folder_view = NULL;
1435 TnyFolderStore *folder = NULL;
1436 gboolean folder_empty = FALSE;
1438 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
1439 win = MODEST_MAIN_WINDOW (user_data);
1441 /* Set contents style of headers view */
1442 if (modest_main_window_get_contents_style (win) == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1443 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1444 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1445 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1448 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1451 modest_main_window_set_contents_style (win,
1452 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1455 /* Notify new messages have been downloaded */
1456 if (new_messages > 0)
1457 modest_platform_on_new_msg ();
1461 * This function performs the send & receive required actions. The
1462 * window is used to create the mail operation. Typically it should
1463 * always be the main window, but we pass it as argument in order to
1467 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1469 gchar *acc_name = NULL;
1470 ModestMailOperation *mail_op;
1472 /* If no account name was provided then get the current account, and if
1473 there is no current account then pick the default one: */
1474 if (!account_name) {
1475 acc_name = g_strdup (modest_window_get_active_account(win));
1477 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1479 g_printerr ("modest: cannot get default account\n");
1483 acc_name = g_strdup (account_name);
1486 /* Set send/receive operation in progress */
1487 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1489 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1491 modest_ui_actions_send_receive_error_handler,
1494 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1495 G_CALLBACK (_on_send_receive_progress_changed),
1498 /* Send & receive. */
1499 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1500 /* Receive and then send. The operation is tagged initially as
1501 a receive operation because the account update performs a
1502 receive and then a send. The operation changes its type
1503 internally, so the progress objects will receive the proper
1504 progress information */
1505 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1506 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, win);
1507 g_object_unref (G_OBJECT (mail_op));
1515 modest_ui_actions_do_cancel_send (const gchar *account_name,
1518 TnyTransportAccount *transport_account;
1519 TnySendQueue *send_queue = NULL;
1520 GError *error = NULL;
1522 /* Get transport account */
1524 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1525 (modest_runtime_get_account_store(),
1527 TNY_ACCOUNT_TYPE_TRANSPORT));
1528 if (!transport_account) {
1529 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1534 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1535 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1536 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1537 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1538 "modest: could not find send queue for account\n");
1540 /* Keeep messages in outbox folder */
1541 tny_send_queue_cancel (send_queue, FALSE, &error);
1545 if (transport_account != NULL)
1546 g_object_unref (G_OBJECT (transport_account));
1550 modest_ui_actions_cancel_send_all (ModestWindow *win)
1552 GSList *account_names, *iter;
1554 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1557 iter = account_names;
1559 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1560 iter = g_slist_next (iter);
1563 modest_account_mgr_free_account_names (account_names);
1564 account_names = NULL;
1568 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1571 /* Check if accounts exist */
1572 gboolean accounts_exist =
1573 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1575 /* If not, allow the user to create an account before trying to send/receive. */
1576 if (!accounts_exist)
1577 modest_ui_actions_on_accounts (NULL, win);
1579 /* Cancel all sending operaitons */
1580 modest_ui_actions_cancel_send_all (win);
1584 * Refreshes all accounts. This function will be used by automatic
1588 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1590 GSList *account_names, *iter;
1592 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1595 iter = account_names;
1597 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1598 iter = g_slist_next (iter);
1601 modest_account_mgr_free_account_names (account_names);
1602 account_names = NULL;
1606 modest_do_refresh_current_folder(ModestWindow *win)
1608 /* Refresh currently selected folder. Note that if we only
1609 want to retreive the headers, then the refresh only will
1610 invoke a poke_status over all folders, i.e., only the
1611 total/unread count will be updated */
1612 if (MODEST_IS_MAIN_WINDOW (win)) {
1613 GtkWidget *header_view, *folder_view;
1614 TnyFolderStore *folder_store;
1616 /* Get folder and header view */
1618 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1619 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1621 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1623 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1625 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1626 MODEST_WIDGET_TYPE_HEADER_VIEW);
1628 /* We do not need to set the contents style
1629 because it hasn't changed. We also do not
1630 need to save the widget status. Just force
1632 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1633 TNY_FOLDER (folder_store),
1634 folder_refreshed_cb,
1635 MODEST_MAIN_WINDOW (win));
1639 g_object_unref (folder_store);
1645 * Handler of the click on Send&Receive button in the main toolbar
1648 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1650 /* Check if accounts exist */
1651 gboolean accounts_exist =
1652 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1654 /* If not, allow the user to create an account before trying to send/receive. */
1655 if (!accounts_exist)
1656 modest_ui_actions_on_accounts (NULL, win);
1658 modest_do_refresh_current_folder (win);
1660 /* Refresh the active account */
1661 modest_ui_actions_do_send_receive (NULL, win);
1666 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1669 GtkWidget *header_view;
1671 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1673 header_view = modest_main_window_get_child_widget (main_window,
1674 MODEST_WIDGET_TYPE_HEADER_VIEW);
1678 conf = modest_runtime_get_conf ();
1680 /* what is saved/restored is depending on the style; thus; we save with
1681 * old style, then update the style, and restore for this new style
1683 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1685 if (modest_header_view_get_style
1686 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1687 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1688 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1690 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1691 MODEST_HEADER_VIEW_STYLE_DETAILS);
1693 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1694 MODEST_CONF_HEADER_VIEW_KEY);
1699 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1701 ModestMainWindow *main_window)
1703 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1704 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1706 /* in the case the folder is empty, show the empty folder message and focus
1708 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1709 if (modest_header_view_is_empty (header_view)) {
1710 TnyFolder *folder = modest_header_view_get_folder (header_view);
1711 GtkWidget *folder_view =
1712 modest_main_window_get_child_widget (main_window,
1713 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1715 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1716 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1720 /* If no header has been selected then exit */
1725 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1726 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1728 /* Update Main window title */
1729 if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
1730 const gchar *subject = tny_header_get_subject (header);
1731 if (subject && strlen(subject) > 0)
1732 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1734 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1737 /* Update toolbar dimming state */
1738 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1742 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1744 ModestMainWindow *main_window)
1748 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1753 headers = tny_simple_list_new ();
1754 tny_list_prepend (headers, G_OBJECT (header));
1756 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1758 g_object_unref (headers);
1762 set_active_account_from_tny_account (TnyAccount *account,
1763 ModestWindow *window)
1765 const gchar *server_acc_name = tny_account_get_id (account);
1767 /* We need the TnyAccount provided by the
1768 account store because that is the one that
1769 knows the name of the Modest account */
1770 TnyAccount *modest_server_account = modest_server_account =
1771 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1772 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1775 const gchar *modest_acc_name =
1776 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1777 modest_window_set_active_account (window, modest_acc_name);
1778 g_object_unref (modest_server_account);
1783 folder_refreshed_cb (ModestMailOperation *mail_op,
1787 ModestMainWindow *win = NULL;
1788 GtkWidget *header_view;
1789 TnyFolder *current_folder;
1790 gboolean folder_empty = TRUE;
1791 gboolean all_marked_as_deleted = TRUE;
1793 g_return_if_fail (TNY_IS_FOLDER (folder));
1795 win = MODEST_MAIN_WINDOW (user_data);
1797 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1800 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1801 if (current_folder != NULL && folder != current_folder) {
1806 /* Check if folder is empty and set headers view contents style */
1807 folder_empty = (tny_folder_get_all_count (folder) == 0);
1808 all_marked_as_deleted = modest_header_view_is_empty (MODEST_HEADER_VIEW(header_view));
1809 folder_empty = folder_empty || all_marked_as_deleted ;
1812 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1813 modest_main_window_set_contents_style (win,
1814 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1816 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1821 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1822 TnyFolderStore *folder_store,
1824 ModestMainWindow *main_window)
1827 GtkWidget *header_view;
1829 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1831 header_view = modest_main_window_get_child_widget(main_window,
1832 MODEST_WIDGET_TYPE_HEADER_VIEW);
1836 conf = modest_runtime_get_conf ();
1838 if (TNY_IS_ACCOUNT (folder_store)) {
1840 /* Update active account */
1841 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1842 /* Show account details */
1843 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1846 if (TNY_IS_FOLDER (folder_store) && selected) {
1848 /* Update the active account */
1849 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1851 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1852 g_object_unref (account);
1856 /* Set the header style by default, it could
1857 be changed later by the refresh callback to
1859 modest_main_window_set_contents_style (main_window,
1860 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1862 /* Set folder on header view. This function
1863 will call tny_folder_refresh_async so we
1864 pass a callback that will be called when
1865 finished. We use that callback to set the
1866 empty view if there are no messages */
1867 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1868 TNY_FOLDER (folder_store),
1869 folder_refreshed_cb,
1872 /* Restore configuration. We need to do this
1873 *after* the set_folder because the widget
1874 memory asks the header view about its
1876 modest_widget_memory_restore (modest_runtime_get_conf (),
1877 G_OBJECT(header_view),
1878 MODEST_CONF_HEADER_VIEW_KEY);
1880 /* Update the active account */
1881 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1882 /* Save only if we're seeing headers */
1883 if (modest_main_window_get_contents_style (main_window) ==
1884 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1885 modest_widget_memory_save (conf, G_OBJECT (header_view),
1886 MODEST_CONF_HEADER_VIEW_KEY);
1887 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1891 /* Update toolbar dimming state */
1892 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1896 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1903 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1905 online = tny_device_is_online (modest_runtime_get_device());
1908 /* already online -- the item is simply not there... */
1909 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1911 GTK_MESSAGE_WARNING,
1913 _("The %s you selected cannot be found"),
1915 gtk_dialog_run (GTK_DIALOG(dialog));
1917 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1921 GTK_RESPONSE_REJECT,
1923 GTK_RESPONSE_ACCEPT,
1925 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1926 "Do you want to get online?"), item);
1927 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1928 gtk_label_new (txt), FALSE, FALSE, 0);
1929 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1932 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1933 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1934 /* TODO: Comment about why is this commented out: */
1935 /* modest_platform_connect_and_wait (); */
1938 gtk_widget_destroy (dialog);
1942 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1945 /* g_message ("%s %s", __FUNCTION__, link); */
1950 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1953 modest_platform_activate_uri (link);
1957 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1960 modest_platform_show_uri_popup (link);
1964 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1967 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1971 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1972 const gchar *address,
1975 /* g_message ("%s %s", __FUNCTION__, address); */
1979 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1981 TnyTransportAccount *transport_account;
1982 ModestMailOperation *mail_operation;
1984 gchar *account_name, *from;
1985 ModestAccountMgr *account_mgr;
1986 gchar *info_text = NULL;
1988 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1990 data = modest_msg_edit_window_get_msg_data (edit_window);
1992 account_mgr = modest_runtime_get_account_mgr();
1993 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1995 account_name = modest_account_mgr_get_default_account (account_mgr);
1996 if (!account_name) {
1997 g_printerr ("modest: no account found\n");
1998 modest_msg_edit_window_free_msg_data (edit_window, data);
2002 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2003 account_name = g_strdup (data->account_name);
2007 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2008 (modest_runtime_get_account_store(),
2010 TNY_ACCOUNT_TYPE_TRANSPORT));
2011 if (!transport_account) {
2012 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2013 g_free (account_name);
2014 modest_msg_edit_window_free_msg_data (edit_window, data);
2017 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2019 /* Create the mail operation */
2020 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
2021 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2023 modest_mail_operation_save_to_drafts (mail_operation,
2035 data->priority_flags);
2038 g_free (account_name);
2039 g_object_unref (G_OBJECT (transport_account));
2040 g_object_unref (G_OBJECT (mail_operation));
2042 modest_msg_edit_window_free_msg_data (edit_window, data);
2044 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2045 modest_platform_information_banner (NULL, NULL, info_text);
2049 /* For instance, when clicking the Send toolbar button when editing a message: */
2051 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2053 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2055 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2058 /* Offer the connection dialog, if necessary: */
2059 if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
2062 /* FIXME: Code added just for testing. The final version will
2063 use the send queue provided by tinymail and some
2065 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2066 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2068 account_name = modest_account_mgr_get_default_account (account_mgr);
2070 if (!account_name) {
2071 /* Run account setup wizard */
2072 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2077 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2079 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2080 account_name = g_strdup (data->account_name);
2083 /* Get the currently-active transport account for this modest account: */
2084 TnyTransportAccount *transport_account =
2085 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2086 (modest_runtime_get_account_store(),
2088 if (!transport_account) {
2089 /* Run account setup wizard */
2090 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2095 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2097 /* mail content checks and dialogs */
2098 if (data->subject == NULL || data->subject[0] == '\0') {
2099 GtkResponseType response;
2100 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
2101 _("mcen_nc_subject_is_empty_send"));
2102 if (response == GTK_RESPONSE_CANCEL) {
2103 g_free (account_name);
2108 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
2109 GtkResponseType response;
2110 gchar *note_message;
2111 gchar *note_subject = data->subject;
2112 if (note_subject == NULL || note_subject[0] == '\0')
2113 note_subject = _("mail_va_no_subject");
2114 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
2115 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
2117 g_free (note_message);
2118 if (response == GTK_RESPONSE_CANCEL) {
2119 g_free (account_name);
2124 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2126 /* Create the mail operation */
2127 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
2128 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2130 modest_mail_operation_send_new_mail (mail_operation,
2141 data->priority_flags);
2145 g_free (account_name);
2146 g_object_unref (G_OBJECT (transport_account));
2147 g_object_unref (G_OBJECT (mail_operation));
2149 modest_msg_edit_window_free_msg_data (edit_window, data);
2150 modest_msg_edit_window_set_sent (edit_window, TRUE);
2152 /* Save settings and close the window: */
2153 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2157 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2158 ModestMsgEditWindow *window)
2160 ModestMsgEditFormatState *format_state = NULL;
2162 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2163 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2165 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2168 format_state = modest_msg_edit_window_get_format_state (window);
2169 g_return_if_fail (format_state != NULL);
2171 format_state->bold = gtk_toggle_action_get_active (action);
2172 modest_msg_edit_window_set_format_state (window, format_state);
2173 g_free (format_state);
2178 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2179 ModestMsgEditWindow *window)
2181 ModestMsgEditFormatState *format_state = NULL;
2183 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2184 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2186 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2189 format_state = modest_msg_edit_window_get_format_state (window);
2190 g_return_if_fail (format_state != NULL);
2192 format_state->italics = gtk_toggle_action_get_active (action);
2193 modest_msg_edit_window_set_format_state (window, format_state);
2194 g_free (format_state);
2199 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2200 ModestMsgEditWindow *window)
2202 ModestMsgEditFormatState *format_state = NULL;
2204 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2205 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2207 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2210 format_state = modest_msg_edit_window_get_format_state (window);
2211 g_return_if_fail (format_state != NULL);
2213 format_state->bullet = gtk_toggle_action_get_active (action);
2214 modest_msg_edit_window_set_format_state (window, format_state);
2215 g_free (format_state);
2220 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2221 GtkRadioAction *selected,
2222 ModestMsgEditWindow *window)
2224 ModestMsgEditFormatState *format_state = NULL;
2225 GtkJustification value;
2227 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2229 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2232 value = gtk_radio_action_get_current_value (selected);
2234 format_state = modest_msg_edit_window_get_format_state (window);
2235 g_return_if_fail (format_state != NULL);
2237 format_state->justification = value;
2238 modest_msg_edit_window_set_format_state (window, format_state);
2239 g_free (format_state);
2243 modest_ui_actions_on_select_editor_color (GtkAction *action,
2244 ModestMsgEditWindow *window)
2246 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2247 g_return_if_fail (GTK_IS_ACTION (action));
2249 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2252 modest_msg_edit_window_select_color (window);
2256 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2257 ModestMsgEditWindow *window)
2259 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2260 g_return_if_fail (GTK_IS_ACTION (action));
2262 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2265 modest_msg_edit_window_select_background_color (window);
2269 modest_ui_actions_on_insert_image (GtkAction *action,
2270 ModestMsgEditWindow *window)
2272 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2273 g_return_if_fail (GTK_IS_ACTION (action));
2275 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2278 modest_msg_edit_window_insert_image (window);
2282 modest_ui_actions_on_attach_file (GtkAction *action,
2283 ModestMsgEditWindow *window)
2285 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2286 g_return_if_fail (GTK_IS_ACTION (action));
2288 modest_msg_edit_window_offer_attach_file (window);
2292 modest_ui_actions_on_remove_attachments (GtkAction *action,
2293 ModestMsgEditWindow *window)
2295 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2296 g_return_if_fail (GTK_IS_ACTION (action));
2298 modest_msg_edit_window_remove_attachments (window, NULL);
2302 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2305 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2306 const GError *error = modest_mail_operation_get_error (mail_op);
2310 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2311 modest_mail_operation_get_error (mail_op)->message);
2316 modest_ui_actions_create_folder(GtkWidget *parent_window,
2317 GtkWidget *folder_view)
2319 TnyFolderStore *parent_folder;
2321 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2323 if (parent_folder) {
2324 gboolean finished = FALSE;
2326 gchar *folder_name = NULL, *suggested_name = NULL;
2327 const gchar *proto_str = NULL;
2328 TnyAccount *account;
2330 if (TNY_IS_ACCOUNT (parent_folder))
2331 account = g_object_ref (parent_folder);
2333 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2334 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2336 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2337 MODEST_PROTOCOL_STORE_POP) {
2339 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2341 g_object_unref (account);
2343 /* Run the new folder dialog */
2345 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2350 g_free (suggested_name);
2351 suggested_name = NULL;
2353 if (result == GTK_RESPONSE_REJECT) {
2356 ModestMailOperation *mail_op;
2357 TnyFolder *new_folder = NULL;
2359 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2360 G_OBJECT(parent_window),
2361 modest_ui_actions_new_folder_error_handler,
2364 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2366 new_folder = modest_mail_operation_create_folder (mail_op,
2368 (const gchar *) folder_name);
2370 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2373 g_object_unref (new_folder);
2376 g_object_unref (mail_op);
2379 suggested_name = folder_name;
2383 g_object_unref (parent_folder);
2388 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2390 GtkWidget *folder_view;
2392 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2394 folder_view = modest_main_window_get_child_widget (main_window,
2395 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2399 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2403 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2406 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2407 const GError *error = NULL;
2408 const gchar *message = NULL;
2410 /* Get error message */
2411 error = modest_mail_operation_get_error (mail_op);
2412 if (error != NULL && error->message != NULL) {
2413 message = error->message;
2415 message = _("!!! FIXME: Unable to rename");
2418 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2423 modest_ui_actions_on_rename_folder (GtkAction *action,
2424 ModestMainWindow *main_window)
2426 TnyFolderStore *folder;
2427 GtkWidget *folder_view;
2428 GtkWidget *header_view;
2430 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2432 folder_view = modest_main_window_get_child_widget (main_window,
2433 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2437 header_view = modest_main_window_get_child_widget (main_window,
2438 MODEST_WIDGET_TYPE_HEADER_VIEW);
2443 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2447 /* Offer the connection dialog if necessary: */
2448 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2449 g_object_unref (G_OBJECT (folder));
2454 if (TNY_IS_FOLDER (folder)) {
2457 const gchar *current_name;
2459 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2460 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
2461 current_name, &folder_name);
2463 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
2464 ModestMailOperation *mail_op;
2467 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2468 G_OBJECT(main_window),
2469 modest_ui_actions_rename_folder_error_handler,
2472 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2475 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2477 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2478 TNY_FOLDER(folder), TRUE);
2480 modest_header_view_clear ((ModestHeaderView *) header_view);
2482 modest_mail_operation_rename_folder (mail_op,
2483 TNY_FOLDER (folder),
2484 (const gchar *) folder_name);
2486 g_object_unref (mail_op);
2487 g_free (folder_name);
2490 g_object_unref (folder);
2494 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2497 GObject *win = modest_mail_operation_get_source (mail_op);
2499 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2500 _("mail_in_ui_folder_delete_error"));
2501 g_object_unref (win);
2505 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2507 TnyFolderStore *folder;
2508 GtkWidget *folder_view;
2512 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
2514 folder_view = modest_main_window_get_child_widget (main_window,
2515 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2519 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2521 /* Show an error if it's an account */
2522 if (!TNY_IS_FOLDER (folder)) {
2523 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2524 _("mail_in_ui_folder_delete_error"));
2525 g_object_unref (G_OBJECT (folder));
2529 /* Offer the connection dialog if necessary: */
2530 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2531 g_object_unref (G_OBJECT (folder));
2536 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2537 tny_folder_get_name (TNY_FOLDER (folder)));
2538 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2539 (const gchar *) message);
2542 if (response == GTK_RESPONSE_OK) {
2543 ModestMailOperation *mail_op =
2544 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2545 G_OBJECT(main_window),
2546 modest_ui_actions_delete_folder_error_handler,
2549 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2551 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2552 g_object_unref (G_OBJECT (mail_op));
2555 g_object_unref (G_OBJECT (folder));
2559 modest_ui_actions_on_delete_folder (GtkAction *action,
2560 ModestMainWindow *main_window)
2562 GtkWidget *folder_view;
2563 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2565 delete_folder (main_window, FALSE);
2566 folder_view = modest_main_window_get_child_widget (main_window,
2567 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2570 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2574 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2576 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2578 delete_folder (main_window, TRUE);
2583 show_error (GtkWidget *parent_widget, const gchar* text)
2585 hildon_banner_show_information(parent_widget, NULL, text);
2588 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2590 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2597 gtk_dialog_run (dialog);
2598 gtk_widget_destroy (GTK_WIDGET (dialog));
2603 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2604 const gchar* server_account_name,
2609 ModestMainWindow *main_window)
2611 g_return_if_fail(server_account_name);
2612 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2614 /* Initalize output parameters: */
2621 #ifdef MODEST_PLATFORM_MAEMO
2622 /* Maemo uses a different (awkward) button order,
2623 * It should probably just use gtk_alternative_dialog_button_order ().
2625 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2629 GTK_RESPONSE_ACCEPT,
2631 GTK_RESPONSE_REJECT,
2634 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2638 GTK_RESPONSE_REJECT,
2640 GTK_RESPONSE_ACCEPT,
2642 #endif /* MODEST_PLATFORM_MAEMO */
2644 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2646 gchar *server_name = modest_server_account_get_hostname (
2647 modest_runtime_get_account_mgr(), server_account_name);
2648 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2649 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2654 /* This causes a warning because the logical ID has no %s in it,
2655 * though the translation does, but there is not much we can do about that: */
2656 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2657 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2660 g_free (server_name);
2664 gchar *initial_username = modest_server_account_get_username (
2665 modest_runtime_get_account_mgr(), server_account_name);
2667 GtkWidget *entry_username = gtk_entry_new ();
2668 if (initial_username)
2669 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2670 /* Dim this if a connection has ever succeeded with this username,
2671 * as per the UI spec: */
2672 const gboolean username_known =
2673 modest_server_account_get_username_has_succeeded(
2674 modest_runtime_get_account_mgr(), server_account_name);
2675 gtk_widget_set_sensitive (entry_username, !username_known);
2677 #ifdef MODEST_PLATFORM_MAEMO
2678 /* Auto-capitalization is the default, so let's turn it off: */
2679 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2681 /* Create a size group to be used by all captions.
2682 * Note that HildonCaption does not create a default size group if we do not specify one.
2683 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2684 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2686 GtkWidget *caption = hildon_caption_new (sizegroup,
2687 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2688 gtk_widget_show (entry_username);
2689 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2690 FALSE, FALSE, MODEST_MARGIN_HALF);
2691 gtk_widget_show (caption);
2693 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2695 #endif /* MODEST_PLATFORM_MAEMO */
2698 GtkWidget *entry_password = gtk_entry_new ();
2699 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2700 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2702 #ifdef MODEST_PLATFORM_MAEMO
2703 /* Auto-capitalization is the default, so let's turn it off: */
2704 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2705 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2707 caption = hildon_caption_new (sizegroup,
2708 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2709 gtk_widget_show (entry_password);
2710 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2711 FALSE, FALSE, MODEST_MARGIN_HALF);
2712 gtk_widget_show (caption);
2713 g_object_unref (sizegroup);
2715 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2717 #endif /* MODEST_PLATFORM_MAEMO */
2719 /* This is not in the Maemo UI spec:
2720 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2721 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2725 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2727 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2729 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2731 modest_server_account_set_username (
2732 modest_runtime_get_account_mgr(), server_account_name,
2735 const gboolean username_was_changed =
2736 (strcmp (*username, initial_username) != 0);
2737 if (username_was_changed) {
2738 g_warning ("%s: tinymail does not yet support changing the "
2739 "username in the get_password() callback.\n", __FUNCTION__);
2744 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2746 /* We do not save the password in the configuration,
2747 * because this function is only called for passwords that should
2748 * not be remembered:
2749 modest_server_account_set_password (
2750 modest_runtime_get_account_mgr(), server_account_name,
2759 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2771 /* This is not in the Maemo UI spec:
2772 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2778 gtk_widget_destroy (dialog);
2780 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2784 modest_ui_actions_on_cut (GtkAction *action,
2785 ModestWindow *window)
2787 GtkWidget *focused_widget;
2788 GtkClipboard *clipboard;
2790 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2791 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2792 if (GTK_IS_EDITABLE (focused_widget)) {
2793 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2794 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2795 gtk_clipboard_store (clipboard);
2796 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2797 GtkTextBuffer *buffer;
2799 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2800 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2801 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2802 gtk_clipboard_store (clipboard);
2803 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2804 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2805 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2806 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2811 modest_ui_actions_on_copy (GtkAction *action,
2812 ModestWindow *window)
2814 GtkClipboard *clipboard;
2815 GtkWidget *focused_widget;
2817 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2818 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2820 if (GTK_IS_LABEL (focused_widget)) {
2821 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2822 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2823 gtk_clipboard_store (clipboard);
2824 } else if (GTK_IS_EDITABLE (focused_widget)) {
2825 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2826 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2827 gtk_clipboard_store (clipboard);
2828 } else if (GTK_IS_HTML (focused_widget)) {
2829 gtk_html_copy (GTK_HTML (focused_widget));
2830 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2831 gtk_clipboard_store (clipboard);
2832 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2833 GtkTextBuffer *buffer;
2834 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2835 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2836 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2837 gtk_clipboard_store (clipboard);
2838 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2839 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2840 TnyIterator *iter = tny_list_create_iterator (header_list);
2841 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2843 gboolean ask = FALSE;
2845 TnyFolder *folder = tny_header_get_folder (header);
2846 TnyAccount *account = tny_folder_get_account (folder);
2847 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2848 /* If it's POP then ask */
2849 ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2850 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2851 g_object_unref (account);
2852 g_object_unref (folder);
2853 g_object_unref (header);
2856 g_object_unref (iter);
2858 /* Check that the messages have been previously downloaded */
2859 gboolean continue_download = TRUE;
2861 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window), FALSE);
2862 if (continue_download)
2863 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2864 g_object_unref (header_list);
2865 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2866 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2869 /* Show information banner */
2870 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2875 modest_ui_actions_on_undo (GtkAction *action,
2876 ModestWindow *window)
2878 ModestEmailClipboard *clipboard = NULL;
2880 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2881 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2882 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2883 /* Clear clipboard source */
2884 clipboard = modest_runtime_get_email_clipboard ();
2885 modest_email_clipboard_clear (clipboard);
2888 g_return_if_reached ();
2893 modest_ui_actions_on_redo (GtkAction *action,
2894 ModestWindow *window)
2896 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2897 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
2900 g_return_if_reached ();
2906 paste_msgs_cb (const GObject *object, gpointer user_data)
2908 g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2909 g_return_if_fail (GTK_IS_WIDGET (user_data));
2911 /* destroy information note */
2912 gtk_widget_destroy (GTK_WIDGET(user_data));
2916 paste_as_attachment_free (gpointer data)
2918 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
2920 gtk_widget_destroy (helper->banner);
2921 g_object_unref (helper->banner);
2926 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
2931 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
2932 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
2937 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
2942 modest_ui_actions_on_paste (GtkAction *action,
2943 ModestWindow *window)
2945 GtkWidget *focused_widget = NULL;
2946 GtkWidget *inf_note = NULL;
2947 ModestMailOperation *mail_op = NULL;
2949 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2950 if (GTK_IS_EDITABLE (focused_widget)) {
2951 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2952 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2953 ModestEmailClipboard *e_clipboard = NULL;
2954 e_clipboard = modest_runtime_get_email_clipboard ();
2955 if (modest_email_clipboard_cleared (e_clipboard)) {
2956 GtkTextBuffer *buffer;
2957 GtkClipboard *clipboard;
2959 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2960 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2961 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2962 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2963 ModestMailOperation *mail_op;
2964 TnyFolder *src_folder;
2967 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
2968 helper->window = MODEST_MSG_EDIT_WINDOW (window);
2969 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2970 _CS("ckct_nw_pasting"));
2971 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
2972 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2974 if (helper->banner != NULL) {
2975 g_object_ref (G_OBJECT (helper->banner));
2976 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
2977 gtk_widget_show (GTK_WIDGET (helper->banner));
2981 modest_mail_operation_get_msgs_full (mail_op,
2983 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
2985 paste_as_attachment_free);
2988 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2989 ModestEmailClipboard *clipboard = NULL;
2990 TnyFolder *src_folder = NULL;
2991 TnyFolderStore *folder_store = NULL;
2992 TnyList *data = NULL;
2993 gboolean delete = FALSE;
2995 /* Check clipboard source */
2996 clipboard = modest_runtime_get_email_clipboard ();
2997 if (modest_email_clipboard_cleared (clipboard))
3000 /* Get elements to paste */
3001 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
3003 /* Create a new mail operation */
3004 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
3006 /* Get destination folder */
3007 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
3009 /* transfer messages */
3013 /* Ask for user confirmation */
3014 response = msgs_move_to_confirmation (GTK_WINDOW (window),
3015 TNY_FOLDER (folder_store),
3019 if (response == GTK_RESPONSE_OK) {
3020 /* Launch notification */
3021 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3022 _CS("ckct_nw_pasting"));
3023 if (inf_note != NULL) {
3024 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3025 gtk_widget_show (GTK_WIDGET(inf_note));
3028 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3029 modest_mail_operation_xfer_msgs (mail_op,
3031 TNY_FOLDER (folder_store),
3036 g_object_unref (mail_op);
3039 } else if (src_folder != NULL) {
3040 /* Launch notification */
3041 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3042 _CS("ckct_nw_pasting"));
3043 if (inf_note != NULL) {
3044 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3045 gtk_widget_show (GTK_WIDGET(inf_note));
3048 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3049 modest_mail_operation_xfer_folder (mail_op,
3059 g_object_unref (data);
3060 if (src_folder != NULL)
3061 g_object_unref (src_folder);
3062 if (folder_store != NULL)
3063 g_object_unref (folder_store);
3069 modest_ui_actions_on_select_all (GtkAction *action,
3070 ModestWindow *window)
3072 GtkWidget *focused_widget;
3074 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3075 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3076 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3077 } else if (GTK_IS_LABEL (focused_widget)) {
3078 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3079 } else if (GTK_IS_EDITABLE (focused_widget)) {
3080 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3081 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3082 GtkTextBuffer *buffer;
3083 GtkTextIter start, end;
3085 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3086 gtk_text_buffer_get_start_iter (buffer, &start);
3087 gtk_text_buffer_get_end_iter (buffer, &end);
3088 gtk_text_buffer_select_range (buffer, &start, &end);
3089 } else if (GTK_IS_HTML (focused_widget)) {
3090 gtk_html_select_all (GTK_HTML (focused_widget));
3091 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3092 GtkWidget *header_view = focused_widget;
3093 GtkTreeSelection *selection = NULL;
3095 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
3096 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3097 MODEST_WIDGET_TYPE_HEADER_VIEW);
3099 /* Select all messages */
3100 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3101 gtk_tree_selection_select_all (selection);
3103 /* Set focuse on header view */
3104 gtk_widget_grab_focus (header_view);
3110 modest_ui_actions_on_mark_as_read (GtkAction *action,
3111 ModestWindow *window)
3113 g_return_if_fail (MODEST_IS_WINDOW(window));
3115 /* Mark each header as read */
3116 do_headers_action (window, headers_action_mark_as_read, NULL);
3120 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3121 ModestWindow *window)
3123 g_return_if_fail (MODEST_IS_WINDOW(window));
3125 /* Mark each header as read */
3126 do_headers_action (window, headers_action_mark_as_unread, NULL);
3130 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3131 GtkRadioAction *selected,
3132 ModestWindow *window)
3136 value = gtk_radio_action_get_current_value (selected);
3137 if (MODEST_IS_WINDOW (window)) {
3138 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3142 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3143 GtkRadioAction *selected,
3144 ModestWindow *window)
3146 TnyHeaderFlags flags;
3147 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3149 flags = gtk_radio_action_get_current_value (selected);
3150 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3153 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3154 GtkRadioAction *selected,
3155 ModestWindow *window)
3159 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3161 file_format = gtk_radio_action_get_current_value (selected);
3162 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3167 modest_ui_actions_on_zoom_plus (GtkAction *action,
3168 ModestWindow *window)
3170 g_return_if_fail (MODEST_IS_WINDOW (window));
3172 modest_window_zoom_plus (MODEST_WINDOW (window));
3176 modest_ui_actions_on_zoom_minus (GtkAction *action,
3177 ModestWindow *window)
3179 g_return_if_fail (MODEST_IS_WINDOW (window));
3181 modest_window_zoom_minus (MODEST_WINDOW (window));
3185 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3186 ModestWindow *window)
3188 ModestWindowMgr *mgr;
3189 gboolean fullscreen, active;
3190 g_return_if_fail (MODEST_IS_WINDOW (window));
3192 mgr = modest_runtime_get_window_mgr ();
3194 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3195 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3197 if (active != fullscreen) {
3198 modest_window_mgr_set_fullscreen_mode (mgr, active);
3199 gtk_window_present (GTK_WINDOW (window));
3204 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3205 ModestWindow *window)
3207 ModestWindowMgr *mgr;
3208 gboolean fullscreen;
3210 g_return_if_fail (MODEST_IS_WINDOW (window));
3212 mgr = modest_runtime_get_window_mgr ();
3213 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3214 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3216 gtk_window_present (GTK_WINDOW (window));
3220 * Used by modest_ui_actions_on_details to call do_headers_action
3223 headers_action_show_details (TnyHeader *header,
3224 ModestWindow *window,
3231 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3234 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3235 gtk_widget_show_all (dialog);
3236 gtk_dialog_run (GTK_DIALOG (dialog));
3238 gtk_widget_destroy (dialog);
3242 * Show the folder details in a ModestDetailsDialog widget
3245 show_folder_details (TnyFolder *folder,
3251 dialog = modest_details_dialog_new_with_folder (window, folder);
3254 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3255 gtk_widget_show_all (dialog);
3256 gtk_dialog_run (GTK_DIALOG (dialog));
3258 gtk_widget_destroy (dialog);
3262 * Show the header details in a ModestDetailsDialog widget
3265 modest_ui_actions_on_details (GtkAction *action,
3268 TnyList * headers_list;
3272 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3275 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3278 g_object_unref (msg);
3280 headers_list = get_selected_headers (win);
3284 iter = tny_list_create_iterator (headers_list);
3286 header = TNY_HEADER (tny_iterator_get_current (iter));
3288 headers_action_show_details (header, win, NULL);
3289 g_object_unref (header);
3292 g_object_unref (iter);
3293 g_object_unref (headers_list);
3295 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3296 GtkWidget *folder_view, *header_view;
3298 /* Check which widget has the focus */
3299 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3300 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3301 if (gtk_widget_is_focus (folder_view)) {
3302 TnyFolderStore *folder_store
3303 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3304 if (!folder_store) {
3305 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3308 /* Show only when it's a folder */
3309 /* This function should not be called for account items,
3310 * because we dim the menu item for them. */
3311 if (TNY_IS_FOLDER (folder_store)) {
3312 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3315 g_object_unref (folder_store);
3318 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3319 MODEST_WIDGET_TYPE_HEADER_VIEW);
3320 /* Show details of each header */
3321 do_headers_action (win, headers_action_show_details, header_view);
3327 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3328 ModestMsgEditWindow *window)
3330 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3332 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3336 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3337 ModestMsgEditWindow *window)
3339 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3341 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3345 modest_ui_actions_toggle_folders_view (GtkAction *action,
3346 ModestMainWindow *main_window)
3348 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3350 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3351 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3353 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3357 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3358 ModestWindow *window)
3360 gboolean active, fullscreen = FALSE;
3361 ModestWindowMgr *mgr;
3363 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3365 /* Check if we want to toggle the toolbar vuew in fullscreen
3367 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3368 "ViewShowToolbarFullScreen")) {
3372 /* Toggle toolbar */
3373 mgr = modest_runtime_get_window_mgr ();
3374 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
3378 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3379 ModestMsgEditWindow *window)
3381 modest_msg_edit_window_select_font (window);
3385 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3386 const gchar *display_name,
3389 /* Do not change the application name if the widget has not
3390 the focus. This callback could be called even if the folder
3391 view has not the focus, because the handled signal could be
3392 emitted when the folder view is redrawn */
3393 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3395 gtk_window_set_title (window, display_name);
3397 gtk_window_set_title (window, " ");
3402 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3404 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3405 modest_msg_edit_window_select_contacts (window);
3409 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3411 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3412 modest_msg_edit_window_check_names (window, FALSE);
3416 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3418 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3419 GTK_WIDGET (user_data));
3423 create_move_to_dialog (GtkWindow *win,
3424 GtkWidget *folder_view,
3425 GtkWidget **tree_view)
3427 GtkWidget *dialog, *scroll;
3428 GtkWidget *new_button;
3430 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3432 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3435 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
3436 /* We do this manually so GTK+ does not associate a response ID for
3438 new_button = gtk_button_new_from_stock (GTK_STOCK_NEW);
3439 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3440 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
3442 /* Create scrolled window */
3443 scroll = gtk_scrolled_window_new (NULL, NULL);
3444 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3445 GTK_POLICY_AUTOMATIC,
3446 GTK_POLICY_AUTOMATIC);
3448 /* Create folder view */
3449 *tree_view = modest_platform_create_folder_view (NULL);
3451 g_signal_connect (G_OBJECT (new_button), "clicked", G_CALLBACK(create_move_to_dialog_on_new_folder), *tree_view);
3453 /* It could happen that we're trying to move a message from a
3454 window (msg window for example) after the main window was
3455 closed, so we can not just get the model of the folder
3457 if (MODEST_IS_FOLDER_VIEW (folder_view))
3458 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
3459 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
3461 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3462 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3464 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3466 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3468 /* Add scroll to dialog */
3469 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3470 scroll, TRUE, TRUE, 0);
3472 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3473 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3479 * Returns TRUE if at least one of the headers of the list belongs to
3480 * a message that has been fully retrieved.
3483 has_retrieved_msgs (TnyList *list)
3486 gboolean found = FALSE;
3488 iter = tny_list_create_iterator (list);
3489 while (!tny_iterator_is_done (iter) && !found) {
3491 TnyHeaderFlags flags = 0;
3493 header = TNY_HEADER (tny_iterator_get_current (iter));
3495 flags = tny_header_get_flags (header);
3496 if (flags & TNY_HEADER_FLAG_CACHED)
3497 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3500 g_object_unref (header);
3504 tny_iterator_next (iter);
3506 g_object_unref (iter);
3512 * Shows a confirmation dialog to the user when we're moving messages
3513 * from a remote server to the local storage. Returns the dialog
3514 * response. If it's other kind of movement the it always returns
3518 msgs_move_to_confirmation (GtkWindow *win,
3519 TnyFolder *dest_folder,
3523 gint response = GTK_RESPONSE_OK;
3525 /* If the destination is a local folder (or MMC folder )*/
3526 if (!modest_tny_folder_is_remote_folder (dest_folder)) {
3527 /* if (modest_tny_folder_is_local_folder (dest_folder)) { */
3528 TnyFolder *src_folder = NULL;
3529 TnyIterator *iter = NULL;
3530 TnyHeader *header = NULL;
3532 /* Get source folder */
3533 iter = tny_list_create_iterator (headers);
3534 header = TNY_HEADER (tny_iterator_get_current (iter));
3536 src_folder = tny_header_get_folder (header);
3537 g_object_unref (header);
3540 g_object_unref (iter);
3542 /* if no src_folder, message may be an attahcment */
3543 if (src_folder == NULL)
3544 return GTK_RESPONSE_CANCEL;
3546 /* If the source is a remote folder */
3547 /* if (!modest_tny_folder_is_local_folder (src_folder)) { */
3548 if (modest_tny_folder_is_remote_folder (src_folder)) {
3549 const gchar *message = NULL;
3550 gboolean cached = has_retrieved_msgs (headers);
3552 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
3553 tny_list_get_length (headers));
3555 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
3556 tny_list_get_length (headers));
3558 if (cached && !delete)
3559 response = GTK_RESPONSE_OK;
3561 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
3562 (const gchar *) message);
3565 g_object_unref (src_folder);
3574 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
3576 ModestMsgViewWindow *self = NULL;
3578 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
3579 self = MODEST_MSG_VIEW_WINDOW (object);
3581 if (!modest_msg_view_window_select_next_message (self))
3582 if (!modest_msg_view_window_select_previous_message (self))
3583 /* No more messages to view, so close this window */
3584 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3588 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3591 GObject *win = modest_mail_operation_get_source (mail_op);
3592 const GError *error = NULL;
3593 const gchar *message = NULL;
3595 /* Get error message */
3596 error = modest_mail_operation_get_error (mail_op);
3597 if (error != NULL && error->message != NULL) {
3598 message = error->message;
3600 message = _("mail_in_ui_folder_move_target_error");
3603 /* Show notification dialog */
3604 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3605 g_object_unref (win);
3609 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3612 GObject *win = modest_mail_operation_get_source (mail_op);
3613 const GError *error = modest_mail_operation_get_error (mail_op);
3615 g_return_if_fail (error != NULL);
3616 if (error->message != NULL)
3617 g_printerr ("modest: %s\n", error->message);
3619 g_printerr ("modest: unkonw error on send&receive operation");
3621 /* Show error message */
3622 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3623 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3624 /* _CS("sfil_ib_unable_to_receive")); */
3626 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3627 /* _CS("sfil_ib_unable_to_send")); */
3628 g_object_unref (win);
3632 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3639 gint pending_purges = 0;
3640 gboolean some_purged = FALSE;
3641 ModestWindow *win = MODEST_WINDOW (user_data);
3642 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3644 /* If there was any error */
3645 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
3646 modest_window_mgr_unregister_header (mgr, header);
3650 /* Once the message has been retrieved for purging, we check if
3651 * it's all ok for purging */
3653 parts = tny_simple_list_new ();
3654 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3655 iter = tny_list_create_iterator (parts);
3657 while (!tny_iterator_is_done (iter)) {
3659 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3660 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
3661 if (tny_mime_part_is_purged (part))
3668 g_object_unref (part);
3670 tny_iterator_next (iter);
3673 if (pending_purges>0) {
3675 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3677 if (response == GTK_RESPONSE_OK) {
3678 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3679 tny_iterator_first (iter);
3680 while (!tny_iterator_is_done (iter)) {
3683 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3684 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
3685 tny_mime_part_set_purged (part);
3688 g_object_unref (part);
3690 tny_iterator_next (iter);
3693 tny_msg_rewrite_cache (msg);
3696 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3699 /* remove attachments */
3700 tny_iterator_first (iter);
3701 while (!tny_iterator_is_done (iter)) {
3704 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3706 /* One for the reference given by tny_iterator_get_current(): */
3707 g_object_unref (part);
3709 /* TODO: Is this meant to remove the attachment by doing another unref()?
3710 * Otherwise, this seems useless. */
3713 tny_iterator_next (iter);
3715 modest_window_mgr_unregister_header (mgr, header);
3717 g_object_unref (iter);
3718 g_object_unref (parts);
3722 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3723 ModestMainWindow *win)
3725 GtkWidget *header_view;
3726 TnyList *header_list;
3729 TnyHeaderFlags flags;
3730 ModestWindow *msg_view_window = NULL;
3733 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3735 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3736 MODEST_WIDGET_TYPE_HEADER_VIEW);
3738 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3740 if (tny_list_get_length (header_list) == 1) {
3741 iter = tny_list_create_iterator (header_list);
3742 header = TNY_HEADER (tny_iterator_get_current (iter));
3743 g_object_unref (iter);
3748 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3749 header, &msg_view_window);
3750 flags = tny_header_get_flags (header);
3751 if (!(flags & TNY_HEADER_FLAG_CACHED))
3754 if (msg_view_window != NULL)
3755 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3757 /* do nothing; uid was registered before, so window is probably on it's way */
3758 g_warning ("debug: header %p has already been registered", header);
3761 ModestMailOperation *mail_op = NULL;
3762 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3763 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3765 modest_ui_actions_get_msgs_full_error_handler,
3767 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3768 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3770 g_object_unref (mail_op);
3773 g_object_unref (header);
3775 g_object_unref (header_list);
3779 * Utility function that transfer messages from both the main window
3780 * and the msg view window when using the "Move to" dialog
3783 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
3786 TnyList *headers = NULL;
3788 TnyAccount *dst_account = NULL;
3789 const gchar *proto_str = NULL;
3790 gboolean dst_is_pop = FALSE;
3792 if (!TNY_IS_FOLDER (dst_folder)) {
3793 modest_platform_information_banner (GTK_WIDGET (win),
3795 _CS("ckdg_ib_unable_to_move_to_current_location"));
3799 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
3800 proto_str = tny_account_get_proto (dst_account);
3801 dst_is_pop = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
3802 MODEST_PROTOCOL_STORE_POP);
3803 g_object_unref (dst_account);
3805 /* Get selected headers */
3806 headers = get_selected_headers (MODEST_WINDOW (win));
3809 modest_platform_information_banner (GTK_WIDGET (win),
3811 ngettext("mail_in_ui_folder_move_target_error",
3812 "mail_in_ui_folder_move_targets_error",
3813 tny_list_get_length (headers)));
3814 g_object_unref (headers);
3818 /* Ask for user confirmation */
3819 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3820 TNY_FOLDER (dst_folder),
3824 /* Transfer messages */
3825 if (response == GTK_RESPONSE_OK) {
3826 ModestMailOperation *mail_op =
3827 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3829 modest_ui_actions_move_folder_error_handler,
3831 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3834 modest_mail_operation_xfer_msgs (mail_op,
3836 TNY_FOLDER (dst_folder),
3838 (MODEST_IS_MSG_VIEW_WINDOW (win)) ? transfer_msgs_from_viewer_cb : NULL,
3841 g_object_unref (G_OBJECT (mail_op));
3843 g_object_unref (headers);
3848 * UI handler for the "Move to" action when invoked from the
3852 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3853 GtkWidget *folder_view,
3854 TnyFolderStore *dst_folder,
3855 ModestMainWindow *win)
3857 GtkWidget *header_view = NULL;
3858 ModestMailOperation *mail_op = NULL;
3859 TnyFolderStore *src_folder;
3861 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3863 /* Get the source folder */
3864 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3866 /* Offer the connection dialog if necessary, if the source folder is in a networked account: */
3867 if (!modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3871 /* Get header view */
3873 modest_main_window_get_child_widget (win, MODEST_WIDGET_TYPE_HEADER_VIEW);
3875 /* Get folder or messages to transfer */
3876 if (gtk_widget_is_focus (folder_view)) {
3878 /* Allow only to transfer folders to the local root folder */
3879 if (TNY_IS_ACCOUNT (dst_folder) &&
3880 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder))
3883 /* Clean folder on header view before moving it */
3884 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3886 if (TNY_IS_FOLDER (src_folder)) {
3888 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3890 modest_ui_actions_move_folder_error_handler,
3892 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3895 modest_mail_operation_xfer_folder (mail_op,
3896 TNY_FOLDER (src_folder),
3899 /* Unref mail operation */
3900 g_object_unref (G_OBJECT (mail_op));
3902 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
3904 } else if (gtk_widget_is_focus (header_view)) {
3905 /* Transfer messages */
3906 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3911 g_object_unref (src_folder);
3916 * UI handler for the "Move to" action when invoked from the
3917 * ModestMsgViewWindow
3920 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3921 TnyFolderStore *dst_folder,
3922 ModestMsgViewWindow *win)
3924 TnyHeader *header = NULL;
3925 TnyFolder *src_folder;
3927 /* Create header list */
3928 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3929 src_folder = tny_header_get_folder(header);
3930 g_object_unref (header);
3932 /* Transfer the message */
3933 if (modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (src_folder)))
3934 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3936 g_object_unref (src_folder);
3940 modest_ui_actions_on_move_to (GtkAction *action,
3943 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3945 TnyFolderStore *dst_folder = NULL;
3946 ModestMainWindow *main_window;
3948 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3949 MODEST_IS_MSG_VIEW_WINDOW (win));
3951 /* Get the main window if exists */
3952 if (MODEST_IS_MAIN_WINDOW (win))
3953 main_window = MODEST_MAIN_WINDOW (win);
3956 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3958 /* Get the folder view widget if exists */
3960 folder_view = modest_main_window_get_child_widget (main_window,
3961 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3965 /* Create and run the dialog */
3966 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
3967 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3968 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3969 result = gtk_dialog_run (GTK_DIALOG(dialog));
3970 g_object_ref (tree_view);
3971 gtk_widget_destroy (dialog);
3973 if (result != GTK_RESPONSE_ACCEPT)
3976 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3977 /* Offer the connection dialog if necessary: */
3978 if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3981 /* Do window specific stuff */
3982 if (MODEST_IS_MAIN_WINDOW (win))
3983 modest_ui_actions_on_main_window_move_to (action,
3986 MODEST_MAIN_WINDOW (win));
3988 modest_ui_actions_on_msg_view_window_move_to (action,
3990 MODEST_MSG_VIEW_WINDOW (win));
3993 g_object_unref (dst_folder);
3997 * Calls #HeadersFunc for each header already selected in the main
3998 * window or the message currently being shown in the msg view window
4001 do_headers_action (ModestWindow *win,
4005 TnyList *headers_list = NULL;
4006 TnyIterator *iter = NULL;
4007 TnyHeader *header = NULL;
4008 TnyFolder *folder = NULL;
4011 headers_list = get_selected_headers (win);
4015 /* Get the folder */
4016 iter = tny_list_create_iterator (headers_list);
4017 header = TNY_HEADER (tny_iterator_get_current (iter));
4019 folder = tny_header_get_folder (header);
4020 g_object_unref (header);
4023 /* Call the function for each header */
4024 while (!tny_iterator_is_done (iter)) {
4025 header = TNY_HEADER (tny_iterator_get_current (iter));
4026 func (header, win, user_data);
4027 g_object_unref (header);
4028 tny_iterator_next (iter);
4031 /* Trick: do a poke status in order to speed up the signaling
4033 tny_folder_poke_status (folder);
4036 g_object_unref (folder);
4037 g_object_unref (iter);
4038 g_object_unref (headers_list);
4042 modest_ui_actions_view_attachment (GtkAction *action,
4043 ModestWindow *window)
4045 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4046 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4048 /* not supported window for this action */
4049 g_return_if_reached ();
4054 modest_ui_actions_save_attachments (GtkAction *action,
4055 ModestWindow *window)
4057 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4058 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4060 /* not supported window for this action */
4061 g_return_if_reached ();
4066 modest_ui_actions_remove_attachments (GtkAction *action,
4067 ModestWindow *window)
4069 if (MODEST_IS_MAIN_WINDOW (window)) {
4070 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4071 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4072 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4074 /* not supported window for this action */
4075 g_return_if_reached ();
4080 modest_ui_actions_on_settings (GtkAction *action,
4085 dialog = modest_platform_get_global_settings_dialog ();
4086 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4087 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4088 gtk_widget_show_all (dialog);
4090 gtk_dialog_run (GTK_DIALOG (dialog));
4092 gtk_widget_destroy (dialog);
4096 modest_ui_actions_on_help (GtkAction *action,
4099 const gchar *help_id = NULL;
4101 if (MODEST_IS_MAIN_WINDOW (win)) {
4102 const gchar *action_name;
4103 action_name = gtk_action_get_name (action);
4105 if (!strcmp (action_name, "FolderViewCSMHelp") ||
4106 !strcmp (action_name, "HeaderViewCSMHelp")) {
4107 GtkWidget *folder_view;
4108 TnyFolderStore *folder_store;
4109 /* Get selected folder */
4110 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4111 MODEST_WIDGET_TYPE_FOLDER_VIEW);
4112 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4114 /* Switch help_id */
4115 if (TNY_IS_FOLDER (folder_store)) {
4116 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4117 case TNY_FOLDER_TYPE_NORMAL:
4118 help_id = "applications_email_managefolders";
4120 case TNY_FOLDER_TYPE_INBOX:
4121 help_id = "applications_email_inbox";
4123 case TNY_FOLDER_TYPE_OUTBOX:
4124 help_id = "applications_email_outbox";
4126 case TNY_FOLDER_TYPE_SENT:
4127 help_id = "applications_email_sent";
4129 case TNY_FOLDER_TYPE_DRAFTS:
4130 help_id = "applications_email_drafts";
4132 case TNY_FOLDER_TYPE_ARCHIVE:
4133 help_id = "applications_email_managefolders";
4136 help_id = "applications_email_managefolders";
4139 help_id = "applications_email_mainview";
4141 g_object_unref (folder_store);
4143 help_id = "applications_email_mainview";
4145 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4146 help_id = "applications_email_viewer";
4147 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4148 help_id = "applications_email_editor";
4150 modest_platform_show_help (GTK_WINDOW (win), help_id);
4154 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4155 ModestWindow *window)
4157 ModestMailOperation *mail_op;
4161 headers = get_selected_headers (window);
4165 /* Create mail operation */
4166 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4168 modest_ui_actions_get_msgs_full_error_handler,
4170 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4171 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4174 g_object_unref (headers);
4175 g_object_unref (mail_op);
4179 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4180 ModestWindow *window)
4182 g_return_if_fail (MODEST_IS_WINDOW (window));
4185 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4189 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4190 ModestWindow *window)
4192 g_return_if_fail (MODEST_IS_WINDOW (window));
4195 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4199 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4200 ModestWindow *window)
4202 g_return_if_fail (MODEST_IS_WINDOW (window));
4205 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4209 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4210 ModestWindow *window)
4212 g_return_if_fail (MODEST_IS_WINDOW (window));
4215 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4219 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4220 ModestWindow *window)
4222 g_return_if_fail (MODEST_IS_WINDOW (window));
4225 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4229 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4230 ModestWindow *window)
4232 g_return_if_fail (MODEST_IS_WINDOW (window));
4235 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4239 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4240 ModestWindow *window)
4242 g_return_if_fail (MODEST_IS_WINDOW (window));
4245 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4249 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4250 ModestWindow *window)
4252 g_return_if_fail (MODEST_IS_WINDOW (window));
4255 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4259 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4261 g_return_if_fail (MODEST_IS_WINDOW (window));
4264 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4268 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4270 g_return_if_fail (MODEST_IS_WINDOW (window));
4272 modest_platform_show_search_messages (GTK_WINDOW (window));
4276 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4278 g_return_if_fail (MODEST_IS_WINDOW (win));
4279 modest_platform_show_addressbook (GTK_WINDOW (win));
4284 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4285 ModestWindow *window)
4287 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4289 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4293 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
4294 ModestMailOperationState *state,
4297 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4299 /* Set send/receive operation finished */
4300 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4301 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));