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 gboolean use_signature = FALSE;
721 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr (), account_name, &use_signature);
724 blank_and_signature = g_strconcat ("\n", signature, NULL);
726 blank_and_signature = g_strdup ("");
731 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
733 g_printerr ("modest: failed to create new msg\n");
737 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
739 g_printerr ("modest: failed to find Drafts folder\n");
744 /* Create and register edit window */
745 /* This is destroyed by TODO. */
746 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
747 mgr = modest_runtime_get_window_mgr ();
748 modest_window_mgr_register_window (mgr, msg_win);
751 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
753 gtk_widget_show_all (GTK_WIDGET (msg_win));
756 g_free (account_name);
758 g_free (blank_and_signature);
760 g_object_unref (msg_win);
762 g_object_unref (G_OBJECT(account));
764 g_object_unref (G_OBJECT(msg));
766 g_object_unref (G_OBJECT(folder));
770 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
774 ModestMailOperationStatus status;
776 /* If there is no message or the operation was not successful */
777 status = modest_mail_operation_get_status (mail_op);
778 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
780 /* Remove the header from the preregistered uids */
781 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
791 open_msg_cb (ModestMailOperation *mail_op,
796 ModestWindowMgr *mgr = NULL;
797 ModestWindow *parent_win = NULL;
798 ModestWindow *win = NULL;
799 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
800 gchar *account = NULL;
803 /* Do nothing if there was any problem with the mail
804 operation. The error will be shown by the error_handler of
805 the mail operation */
806 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
810 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
811 folder = tny_header_get_folder (header);
813 /* Mark header as read */
814 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
817 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
819 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
821 /* Gets folder type (OUTBOX headers will be opened in edit window */
822 if (modest_tny_folder_is_local_folder (folder))
823 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
825 /* If the header is in the drafts folder then open the editor,
826 else the message view window */
827 if ((folder_type == TNY_FOLDER_TYPE_DRAFTS) ||
828 (folder_type == TNY_FOLDER_TYPE_OUTBOX)) {
829 /* we cannot edit without a valid account... */
830 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
831 const gboolean created = modest_run_account_setup_wizard(parent_win);
835 win = modest_msg_edit_window_new (msg, account, TRUE);
838 gchar *uid = modest_tny_folder_get_header_unique_id (header);
840 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
841 GtkWidget *header_view;
842 GtkTreeSelection *sel;
843 GList *sel_list = NULL;
846 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
847 MODEST_WIDGET_TYPE_HEADER_VIEW);
849 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
850 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
852 if (sel_list != NULL) {
853 GtkTreeRowReference *row_reference;
855 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
856 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
857 g_list_free (sel_list);
859 win = modest_msg_view_window_new_with_header_model (
860 msg, account, (const gchar*) uid,
861 model, row_reference);
862 gtk_tree_row_reference_free (row_reference);
864 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
867 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
872 /* Register and show new window */
874 mgr = modest_runtime_get_window_mgr ();
875 modest_window_mgr_register_window (mgr, win);
876 g_object_unref (win);
877 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
878 gtk_widget_show_all (GTK_WIDGET(win));
881 /* Update toolbar dimming state */
882 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
883 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
889 g_object_unref (parent_win);
890 g_object_unref (folder);
894 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
898 GObject *win = modest_mail_operation_get_source (mail_op);
900 error = modest_mail_operation_get_error (mail_op);
901 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, error->code, error->message);
903 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
905 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
908 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
909 _("mail_ni_ui_folder_get_msg_folder_error"));
913 g_object_unref (win);
917 * This function is used by both modest_ui_actions_on_open and
918 * modest_ui_actions_on_header_activated. This way we always do the
919 * same when trying to open messages.
922 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
924 ModestWindowMgr *mgr = NULL;
925 TnyIterator *iter = NULL;
926 ModestMailOperation *mail_op = NULL;
927 TnyList *not_opened_headers = NULL;
928 TnyHeaderFlags flags = 0;
930 /* Look if we already have a message view for each header. If
931 true, then remove the header from the list of headers to
933 mgr = modest_runtime_get_window_mgr ();
934 iter = tny_list_create_iterator (headers);
935 not_opened_headers = tny_simple_list_new ();
937 while (!tny_iterator_is_done (iter)) {
939 ModestWindow *window = NULL;
940 TnyHeader *header = NULL;
941 gboolean found = FALSE;
943 header = TNY_HEADER (tny_iterator_get_current (iter));
945 flags = tny_header_get_flags (header);
948 found = modest_window_mgr_find_registered_header (mgr, header, &window);
950 /* Do not open again the message and present the
951 window to the user */
954 gtk_window_present (GTK_WINDOW (window));
956 /* the header has been registered already, we don't do
957 * anything but wait for the window to come up*/
958 g_debug ("header %p already registered, waiting for window", header);
960 tny_list_append (not_opened_headers, G_OBJECT (header));
964 g_object_unref (header);
966 tny_iterator_next (iter);
968 g_object_unref (iter);
971 /* If some messages would have to be downloaded, ask the user to
972 * make a connection. It's generally easier to do this here (in the mainloop)
973 * than later in a thread:
975 if (tny_list_get_length (not_opened_headers) > 0) {
977 gboolean found = FALSE;
979 iter = tny_list_create_iterator (not_opened_headers);
980 while (!tny_iterator_is_done (iter) && !found) {
981 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
982 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
985 tny_iterator_next (iter);
987 g_object_unref (header);
989 g_object_unref (iter);
991 if (found && !modest_platform_connect_and_wait (GTK_WINDOW (win), NULL)) {
992 g_object_unref (not_opened_headers);
997 /* Register the headers before actually creating the windows: */
998 TnyIterator *iter_not_opened = tny_list_create_iterator (not_opened_headers);
999 while (!tny_iterator_is_done (iter_not_opened)) {
1000 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1002 modest_window_mgr_register_header (mgr, header);
1003 g_object_unref (header);
1006 tny_iterator_next (iter_not_opened);
1008 g_object_unref (iter_not_opened);
1009 iter_not_opened = NULL;
1011 /* Open each message */
1012 if (tny_list_get_length (not_opened_headers) > 0) {
1013 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1015 modest_ui_actions_get_msgs_full_error_handler,
1017 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1018 if (tny_list_get_length (not_opened_headers) > 1) {
1019 modest_mail_operation_get_msgs_full (mail_op,
1025 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1026 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1027 modest_mail_operation_get_msg (mail_op, header, open_msg_cb, NULL);
1028 g_object_unref (header);
1029 g_object_unref (iter);
1031 g_object_unref (mail_op);
1035 if (not_opened_headers != NULL)
1036 g_object_unref (not_opened_headers);
1040 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1045 headers = get_selected_headers (win);
1050 _modest_ui_actions_open (headers, win);
1052 g_object_unref(headers);
1057 free_reply_forward_helper (gpointer data)
1059 ReplyForwardHelper *helper;
1061 helper = (ReplyForwardHelper *) data;
1062 g_free (helper->account_name);
1063 g_slice_free (ReplyForwardHelper, helper);
1067 reply_forward_cb (ModestMailOperation *mail_op,
1073 ReplyForwardHelper *rf_helper;
1074 ModestWindow *msg_win = NULL;
1075 ModestEditType edit_type;
1077 TnyAccount *account = NULL;
1078 ModestWindowMgr *mgr = NULL;
1079 gchar *signature = NULL;
1081 /* If there was any error. The mail operation could be NULL,
1082 this means that we already have the message downloaded and
1083 that we didn't do a mail operation to retrieve it */
1084 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1087 g_return_if_fail (user_data != NULL);
1088 rf_helper = (ReplyForwardHelper *) user_data;
1090 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1091 rf_helper->account_name);
1092 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
1093 rf_helper->account_name,
1094 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
1095 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
1096 rf_helper->account_name,
1097 MODEST_ACCOUNT_SIGNATURE, FALSE);
1100 /* Create reply mail */
1101 switch (rf_helper->action) {
1104 modest_tny_msg_create_reply_msg (msg, header, from, signature,
1105 rf_helper->reply_forward_type,
1106 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1108 case ACTION_REPLY_TO_ALL:
1110 modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1111 MODEST_TNY_MSG_REPLY_MODE_ALL);
1112 edit_type = MODEST_EDIT_TYPE_REPLY;
1114 case ACTION_FORWARD:
1116 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1117 edit_type = MODEST_EDIT_TYPE_FORWARD;
1120 g_return_if_reached ();
1127 g_printerr ("modest: failed to create message\n");
1131 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1132 rf_helper->account_name,
1133 TNY_ACCOUNT_TYPE_STORE);
1135 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1139 /* Create and register the windows */
1140 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1141 mgr = modest_runtime_get_window_mgr ();
1142 modest_window_mgr_register_window (mgr, msg_win);
1144 if (rf_helper->parent_window != NULL) {
1145 gdouble parent_zoom;
1147 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1148 modest_window_set_zoom (msg_win, parent_zoom);
1151 /* Show edit window */
1152 gtk_widget_show_all (GTK_WIDGET (msg_win));
1156 g_object_unref (msg_win);
1158 g_object_unref (G_OBJECT (new_msg));
1160 g_object_unref (G_OBJECT (account));
1161 /* g_object_unref (msg); */
1162 free_reply_forward_helper (rf_helper);
1166 * Checks a list of headers. If any of them are not currently
1167 * downloaded (CACHED) then it asks the user for permission to
1170 * Returns FALSE if the user does not want to download the
1171 * messages. Returns TRUE if the user allowed the download or if all
1172 * of them are currently downloaded
1175 download_uncached_messages (TnyList *header_list,
1181 gint uncached_messages = 0;
1183 iter = tny_list_create_iterator (header_list);
1184 while (!tny_iterator_is_done (iter)) {
1187 header = TNY_HEADER (tny_iterator_get_current (iter));
1189 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1190 uncached_messages ++;
1191 g_object_unref (header);
1194 tny_iterator_next (iter);
1196 g_object_unref (iter);
1198 /* Ask for user permission to download the messages */
1200 if (uncached_messages > 0) {
1201 GtkResponseType response;
1203 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1204 _("emev_nc_include_original"));
1207 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1208 ngettext("mcen_nc_get_msg",
1210 uncached_messages));
1211 if (response == GTK_RESPONSE_CANCEL)
1214 /* If a download will be necessary, make sure that we have a connection: */
1215 retval = modest_platform_connect_and_wait(win, NULL);
1223 * Common code for the reply and forward actions
1226 reply_forward (ReplyForwardAction action, ModestWindow *win)
1228 ModestMailOperation *mail_op = NULL;
1229 TnyList *header_list = NULL;
1230 ReplyForwardHelper *rf_helper = NULL;
1231 guint reply_forward_type;
1232 gboolean continue_download = TRUE;
1233 gboolean do_retrieve = TRUE;
1235 g_return_if_fail (MODEST_IS_WINDOW(win));
1237 /* we need an account when editing */
1238 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1239 const gboolean created = modest_run_account_setup_wizard (win);
1244 header_list = get_selected_headers (win);
1248 reply_forward_type =
1249 modest_conf_get_int (modest_runtime_get_conf (),
1250 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1253 /* Check that the messages have been previously downloaded */
1254 do_retrieve = (action == ACTION_FORWARD) || (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1256 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win), TRUE);
1257 if (!continue_download) {
1258 g_object_unref (header_list);
1262 /* We assume that we can only select messages of the
1263 same folder and that we reply all of them from the
1264 same account. In fact the interface currently only
1265 allows single selection */
1268 rf_helper = g_slice_new0 (ReplyForwardHelper);
1269 rf_helper->reply_forward_type = reply_forward_type;
1270 rf_helper->action = action;
1271 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1273 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1274 rf_helper->parent_window = GTK_WIDGET (win);
1275 if (!rf_helper->account_name)
1276 rf_helper->account_name =
1277 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1279 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1282 /* Get header and message. Do not free them here, the
1283 reply_forward_cb must do it */
1284 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1285 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1286 if (!msg || !header) {
1288 g_object_unref (msg);
1289 g_printerr ("modest: no message found\n");
1292 reply_forward_cb (NULL, header, msg, rf_helper);
1295 g_object_unref (header);
1300 /* Only reply/forward to one message */
1301 iter = tny_list_create_iterator (header_list);
1302 header = TNY_HEADER (tny_iterator_get_current (iter));
1303 g_object_unref (iter);
1306 /* Retrieve messages */
1308 mail_op = modest_mail_operation_new_with_error_handling (
1309 MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1311 modest_ui_actions_get_msgs_full_error_handler,
1313 modest_mail_operation_queue_add (
1314 modest_runtime_get_mail_operation_queue (), mail_op);
1316 modest_mail_operation_get_msg (mail_op,
1321 g_object_unref(mail_op);
1323 /* we put a ref here to prevent double unref as the reply
1324 * forward callback unrefs the header at its end */
1325 reply_forward_cb (NULL, header, NULL, rf_helper);
1329 g_object_unref (header);
1335 g_object_unref (header_list);
1339 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1341 g_return_if_fail (MODEST_IS_WINDOW(win));
1343 reply_forward (ACTION_REPLY, win);
1347 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1349 g_return_if_fail (MODEST_IS_WINDOW(win));
1351 reply_forward (ACTION_FORWARD, win);
1355 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1357 g_return_if_fail (MODEST_IS_WINDOW(win));
1359 reply_forward (ACTION_REPLY_TO_ALL, win);
1363 modest_ui_actions_on_next (GtkAction *action,
1364 ModestWindow *window)
1366 if (MODEST_IS_MAIN_WINDOW (window)) {
1367 GtkWidget *header_view;
1369 header_view = modest_main_window_get_child_widget (
1370 MODEST_MAIN_WINDOW(window),
1371 MODEST_WIDGET_TYPE_HEADER_VIEW);
1375 modest_header_view_select_next (
1376 MODEST_HEADER_VIEW(header_view));
1377 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1378 modest_msg_view_window_select_next_message (
1379 MODEST_MSG_VIEW_WINDOW (window));
1381 g_return_if_reached ();
1386 modest_ui_actions_on_prev (GtkAction *action,
1387 ModestWindow *window)
1389 g_return_if_fail (MODEST_IS_WINDOW(window));
1391 if (MODEST_IS_MAIN_WINDOW (window)) {
1392 GtkWidget *header_view;
1393 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1394 MODEST_WIDGET_TYPE_HEADER_VIEW);
1398 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1399 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1400 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1402 g_return_if_reached ();
1407 modest_ui_actions_on_sort (GtkAction *action,
1408 ModestWindow *window)
1410 g_return_if_fail (MODEST_IS_WINDOW(window));
1412 if (MODEST_IS_MAIN_WINDOW (window)) {
1413 GtkWidget *header_view;
1414 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1415 MODEST_WIDGET_TYPE_HEADER_VIEW);
1417 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1422 /* Show sorting dialog */
1423 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1428 new_messages_arrived (ModestMailOperation *self,
1432 ModestMainWindow *win = NULL;
1433 GtkWidget *folder_view = NULL;
1434 TnyFolderStore *folder = NULL;
1435 gboolean folder_empty = FALSE;
1437 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
1438 win = MODEST_MAIN_WINDOW (user_data);
1440 /* Set contents style of headers view */
1441 if (modest_main_window_get_contents_style (win) == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1442 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1443 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1444 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1447 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1450 modest_main_window_set_contents_style (win,
1451 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1454 /* Notify new messages have been downloaded */
1455 if (new_messages > 0)
1456 modest_platform_on_new_msg ();
1460 * This function performs the send & receive required actions. The
1461 * window is used to create the mail operation. Typically it should
1462 * always be the main window, but we pass it as argument in order to
1466 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1468 gchar *acc_name = NULL;
1469 ModestMailOperation *mail_op;
1471 /* If no account name was provided then get the current account, and if
1472 there is no current account then pick the default one: */
1473 if (!account_name) {
1474 acc_name = g_strdup (modest_window_get_active_account(win));
1476 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1478 g_printerr ("modest: cannot get default account\n");
1482 acc_name = g_strdup (account_name);
1485 /* Set send/receive operation in progress */
1486 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1488 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1490 modest_ui_actions_send_receive_error_handler,
1493 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1494 G_CALLBACK (_on_send_receive_progress_changed),
1497 /* Send & receive. */
1498 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1499 /* Receive and then send. The operation is tagged initially as
1500 a receive operation because the account update performs a
1501 receive and then a send. The operation changes its type
1502 internally, so the progress objects will receive the proper
1503 progress information */
1504 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1505 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, win);
1506 g_object_unref (G_OBJECT (mail_op));
1514 modest_ui_actions_do_cancel_send (const gchar *account_name,
1517 TnyTransportAccount *transport_account;
1518 TnySendQueue *send_queue = NULL;
1519 GError *error = NULL;
1521 /* Get transport account */
1523 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1524 (modest_runtime_get_account_store(),
1526 TNY_ACCOUNT_TYPE_TRANSPORT));
1527 if (!transport_account) {
1528 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1533 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1534 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1535 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1536 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1537 "modest: could not find send queue for account\n");
1539 /* Keeep messages in outbox folder */
1540 tny_send_queue_cancel (send_queue, FALSE, &error);
1544 if (transport_account != NULL)
1545 g_object_unref (G_OBJECT (transport_account));
1549 modest_ui_actions_cancel_send_all (ModestWindow *win)
1551 GSList *account_names, *iter;
1553 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1556 iter = account_names;
1558 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1559 iter = g_slist_next (iter);
1562 modest_account_mgr_free_account_names (account_names);
1563 account_names = NULL;
1567 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1570 /* Check if accounts exist */
1571 gboolean accounts_exist =
1572 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1574 /* If not, allow the user to create an account before trying to send/receive. */
1575 if (!accounts_exist)
1576 modest_ui_actions_on_accounts (NULL, win);
1578 /* Cancel all sending operaitons */
1579 modest_ui_actions_cancel_send_all (win);
1583 * Refreshes all accounts. This function will be used by automatic
1587 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1589 GSList *account_names, *iter;
1591 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1594 iter = account_names;
1596 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1597 iter = g_slist_next (iter);
1600 modest_account_mgr_free_account_names (account_names);
1601 account_names = NULL;
1605 modest_do_refresh_current_folder(ModestWindow *win)
1607 /* Refresh currently selected folder. Note that if we only
1608 want to retreive the headers, then the refresh only will
1609 invoke a poke_status over all folders, i.e., only the
1610 total/unread count will be updated */
1611 if (MODEST_IS_MAIN_WINDOW (win)) {
1612 GtkWidget *header_view, *folder_view;
1613 TnyFolderStore *folder_store;
1615 /* Get folder and header view */
1617 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1618 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1620 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1622 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1624 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1625 MODEST_WIDGET_TYPE_HEADER_VIEW);
1627 /* We do not need to set the contents style
1628 because it hasn't changed. We also do not
1629 need to save the widget status. Just force
1631 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1632 TNY_FOLDER (folder_store),
1633 folder_refreshed_cb,
1634 MODEST_MAIN_WINDOW (win));
1638 g_object_unref (folder_store);
1644 * Handler of the click on Send&Receive button in the main toolbar
1647 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1649 /* Check if accounts exist */
1650 gboolean accounts_exist =
1651 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1653 /* If not, allow the user to create an account before trying to send/receive. */
1654 if (!accounts_exist)
1655 modest_ui_actions_on_accounts (NULL, win);
1657 modest_do_refresh_current_folder (win);
1659 /* Refresh the active account */
1660 modest_ui_actions_do_send_receive (NULL, win);
1665 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1668 GtkWidget *header_view;
1670 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1672 header_view = modest_main_window_get_child_widget (main_window,
1673 MODEST_WIDGET_TYPE_HEADER_VIEW);
1677 conf = modest_runtime_get_conf ();
1679 /* what is saved/restored is depending on the style; thus; we save with
1680 * old style, then update the style, and restore for this new style
1682 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1684 if (modest_header_view_get_style
1685 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1686 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1687 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1689 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1690 MODEST_HEADER_VIEW_STYLE_DETAILS);
1692 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1693 MODEST_CONF_HEADER_VIEW_KEY);
1698 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1700 ModestMainWindow *main_window)
1702 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1703 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1705 /* in the case the folder is empty, show the empty folder message and focus
1707 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1708 if (modest_header_view_is_empty (header_view)) {
1709 TnyFolder *folder = modest_header_view_get_folder (header_view);
1710 GtkWidget *folder_view =
1711 modest_main_window_get_child_widget (main_window,
1712 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1714 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1715 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1719 /* If no header has been selected then exit */
1724 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1725 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1727 /* Update Main window title */
1728 if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
1729 const gchar *subject = tny_header_get_subject (header);
1730 if (subject && strlen(subject) > 0)
1731 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1733 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1736 /* Update toolbar dimming state */
1737 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1741 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1743 ModestMainWindow *main_window)
1747 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1752 headers = tny_simple_list_new ();
1753 tny_list_prepend (headers, G_OBJECT (header));
1755 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1757 g_object_unref (headers);
1761 set_active_account_from_tny_account (TnyAccount *account,
1762 ModestWindow *window)
1764 const gchar *server_acc_name = tny_account_get_id (account);
1766 /* We need the TnyAccount provided by the
1767 account store because that is the one that
1768 knows the name of the Modest account */
1769 TnyAccount *modest_server_account = modest_server_account =
1770 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1771 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1774 const gchar *modest_acc_name =
1775 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1776 modest_window_set_active_account (window, modest_acc_name);
1777 g_object_unref (modest_server_account);
1782 folder_refreshed_cb (ModestMailOperation *mail_op,
1786 ModestMainWindow *win = NULL;
1787 GtkWidget *header_view;
1788 TnyFolder *current_folder;
1789 gboolean folder_empty = TRUE;
1790 gboolean all_marked_as_deleted = TRUE;
1792 g_return_if_fail (TNY_IS_FOLDER (folder));
1794 win = MODEST_MAIN_WINDOW (user_data);
1796 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1799 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1800 if (current_folder != NULL && folder != current_folder) {
1805 /* Check if folder is empty and set headers view contents style */
1806 folder_empty = (tny_folder_get_all_count (folder) == 0);
1807 all_marked_as_deleted = modest_header_view_is_empty (MODEST_HEADER_VIEW(header_view));
1808 folder_empty = folder_empty || all_marked_as_deleted ;
1811 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1812 modest_main_window_set_contents_style (win,
1813 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1815 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1820 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1821 TnyFolderStore *folder_store,
1823 ModestMainWindow *main_window)
1826 GtkWidget *header_view;
1828 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1830 header_view = modest_main_window_get_child_widget(main_window,
1831 MODEST_WIDGET_TYPE_HEADER_VIEW);
1835 conf = modest_runtime_get_conf ();
1837 if (TNY_IS_ACCOUNT (folder_store)) {
1839 /* Update active account */
1840 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1841 /* Show account details */
1842 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1845 if (TNY_IS_FOLDER (folder_store) && selected) {
1847 /* Update the active account */
1848 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1850 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1851 g_object_unref (account);
1855 /* Set the header style by default, it could
1856 be changed later by the refresh callback to
1858 modest_main_window_set_contents_style (main_window,
1859 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1861 /* Set folder on header view. This function
1862 will call tny_folder_refresh_async so we
1863 pass a callback that will be called when
1864 finished. We use that callback to set the
1865 empty view if there are no messages */
1866 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1867 TNY_FOLDER (folder_store),
1868 folder_refreshed_cb,
1871 /* Restore configuration. We need to do this
1872 *after* the set_folder because the widget
1873 memory asks the header view about its
1875 modest_widget_memory_restore (modest_runtime_get_conf (),
1876 G_OBJECT(header_view),
1877 MODEST_CONF_HEADER_VIEW_KEY);
1879 /* Update the active account */
1880 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1881 /* Save only if we're seeing headers */
1882 if (modest_main_window_get_contents_style (main_window) ==
1883 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1884 modest_widget_memory_save (conf, G_OBJECT (header_view),
1885 MODEST_CONF_HEADER_VIEW_KEY);
1886 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1890 /* Update toolbar dimming state */
1891 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1895 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1902 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1904 online = tny_device_is_online (modest_runtime_get_device());
1907 /* already online -- the item is simply not there... */
1908 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1910 GTK_MESSAGE_WARNING,
1912 _("The %s you selected cannot be found"),
1914 gtk_dialog_run (GTK_DIALOG(dialog));
1916 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1920 GTK_RESPONSE_REJECT,
1922 GTK_RESPONSE_ACCEPT,
1924 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1925 "Do you want to get online?"), item);
1926 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1927 gtk_label_new (txt), FALSE, FALSE, 0);
1928 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1931 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1932 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1933 /* TODO: Comment about why is this commented out: */
1934 /* modest_platform_connect_and_wait (); */
1937 gtk_widget_destroy (dialog);
1941 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1944 /* g_message ("%s %s", __FUNCTION__, link); */
1949 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1952 modest_platform_activate_uri (link);
1956 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1959 modest_platform_show_uri_popup (link);
1963 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1966 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1970 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1971 const gchar *address,
1974 /* g_message ("%s %s", __FUNCTION__, address); */
1978 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1980 TnyTransportAccount *transport_account;
1981 ModestMailOperation *mail_operation;
1983 gchar *account_name, *from;
1984 ModestAccountMgr *account_mgr;
1985 gchar *info_text = NULL;
1987 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1989 data = modest_msg_edit_window_get_msg_data (edit_window);
1991 account_mgr = modest_runtime_get_account_mgr();
1992 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1994 account_name = modest_account_mgr_get_default_account (account_mgr);
1995 if (!account_name) {
1996 g_printerr ("modest: no account found\n");
1997 modest_msg_edit_window_free_msg_data (edit_window, data);
2001 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2002 account_name = g_strdup (data->account_name);
2006 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2007 (modest_runtime_get_account_store(),
2009 TNY_ACCOUNT_TYPE_TRANSPORT));
2010 if (!transport_account) {
2011 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2012 g_free (account_name);
2013 modest_msg_edit_window_free_msg_data (edit_window, data);
2016 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2018 /* Create the mail operation */
2019 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
2020 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2022 modest_mail_operation_save_to_drafts (mail_operation,
2034 data->priority_flags);
2037 g_free (account_name);
2038 g_object_unref (G_OBJECT (transport_account));
2039 g_object_unref (G_OBJECT (mail_operation));
2041 modest_msg_edit_window_free_msg_data (edit_window, data);
2043 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2044 modest_platform_information_banner (NULL, NULL, info_text);
2048 /* For instance, when clicking the Send toolbar button when editing a message: */
2050 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2052 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2054 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2057 /* Offer the connection dialog, if necessary: */
2058 if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
2061 /* FIXME: Code added just for testing. The final version will
2062 use the send queue provided by tinymail and some
2064 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2065 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2067 account_name = modest_account_mgr_get_default_account (account_mgr);
2069 if (!account_name) {
2070 /* Run account setup wizard */
2071 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2076 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2078 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2079 account_name = g_strdup (data->account_name);
2082 /* Get the currently-active transport account for this modest account: */
2083 TnyTransportAccount *transport_account =
2084 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2085 (modest_runtime_get_account_store(),
2087 if (!transport_account) {
2088 /* Run account setup wizard */
2089 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2094 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2096 /* mail content checks and dialogs */
2097 if (data->subject == NULL || data->subject[0] == '\0') {
2098 GtkResponseType response;
2099 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
2100 _("mcen_nc_subject_is_empty_send"));
2101 if (response == GTK_RESPONSE_CANCEL) {
2102 g_free (account_name);
2107 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
2108 GtkResponseType response;
2109 gchar *note_message;
2110 gchar *note_subject = data->subject;
2111 if (note_subject == NULL || note_subject[0] == '\0')
2112 note_subject = _("mail_va_no_subject");
2113 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
2114 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
2116 g_free (note_message);
2117 if (response == GTK_RESPONSE_CANCEL) {
2118 g_free (account_name);
2123 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2125 /* Create the mail operation */
2126 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
2127 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2129 modest_mail_operation_send_new_mail (mail_operation,
2140 data->priority_flags);
2144 g_free (account_name);
2145 g_object_unref (G_OBJECT (transport_account));
2146 g_object_unref (G_OBJECT (mail_operation));
2148 modest_msg_edit_window_free_msg_data (edit_window, data);
2149 modest_msg_edit_window_set_sent (edit_window, TRUE);
2151 /* Save settings and close the window: */
2152 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2156 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2157 ModestMsgEditWindow *window)
2159 ModestMsgEditFormatState *format_state = NULL;
2161 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2162 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2164 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2167 format_state = modest_msg_edit_window_get_format_state (window);
2168 g_return_if_fail (format_state != NULL);
2170 format_state->bold = gtk_toggle_action_get_active (action);
2171 modest_msg_edit_window_set_format_state (window, format_state);
2172 g_free (format_state);
2177 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2178 ModestMsgEditWindow *window)
2180 ModestMsgEditFormatState *format_state = NULL;
2182 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2183 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2185 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2188 format_state = modest_msg_edit_window_get_format_state (window);
2189 g_return_if_fail (format_state != NULL);
2191 format_state->italics = gtk_toggle_action_get_active (action);
2192 modest_msg_edit_window_set_format_state (window, format_state);
2193 g_free (format_state);
2198 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2199 ModestMsgEditWindow *window)
2201 ModestMsgEditFormatState *format_state = NULL;
2203 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2204 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2206 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2209 format_state = modest_msg_edit_window_get_format_state (window);
2210 g_return_if_fail (format_state != NULL);
2212 format_state->bullet = gtk_toggle_action_get_active (action);
2213 modest_msg_edit_window_set_format_state (window, format_state);
2214 g_free (format_state);
2219 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2220 GtkRadioAction *selected,
2221 ModestMsgEditWindow *window)
2223 ModestMsgEditFormatState *format_state = NULL;
2224 GtkJustification value;
2226 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2228 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2231 value = gtk_radio_action_get_current_value (selected);
2233 format_state = modest_msg_edit_window_get_format_state (window);
2234 g_return_if_fail (format_state != NULL);
2236 format_state->justification = value;
2237 modest_msg_edit_window_set_format_state (window, format_state);
2238 g_free (format_state);
2242 modest_ui_actions_on_select_editor_color (GtkAction *action,
2243 ModestMsgEditWindow *window)
2245 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2246 g_return_if_fail (GTK_IS_ACTION (action));
2248 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2251 modest_msg_edit_window_select_color (window);
2255 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2256 ModestMsgEditWindow *window)
2258 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2259 g_return_if_fail (GTK_IS_ACTION (action));
2261 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2264 modest_msg_edit_window_select_background_color (window);
2268 modest_ui_actions_on_insert_image (GtkAction *action,
2269 ModestMsgEditWindow *window)
2271 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2272 g_return_if_fail (GTK_IS_ACTION (action));
2274 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2277 modest_msg_edit_window_insert_image (window);
2281 modest_ui_actions_on_attach_file (GtkAction *action,
2282 ModestMsgEditWindow *window)
2284 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2285 g_return_if_fail (GTK_IS_ACTION (action));
2287 modest_msg_edit_window_offer_attach_file (window);
2291 modest_ui_actions_on_remove_attachments (GtkAction *action,
2292 ModestMsgEditWindow *window)
2294 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2295 g_return_if_fail (GTK_IS_ACTION (action));
2297 modest_msg_edit_window_remove_attachments (window, NULL);
2301 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2304 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2305 const GError *error = modest_mail_operation_get_error (mail_op);
2309 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2310 modest_mail_operation_get_error (mail_op)->message);
2315 modest_ui_actions_create_folder(GtkWidget *parent_window,
2316 GtkWidget *folder_view)
2318 TnyFolderStore *parent_folder;
2320 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2322 if (parent_folder) {
2323 gboolean finished = FALSE;
2325 gchar *folder_name = NULL, *suggested_name = NULL;
2326 const gchar *proto_str = NULL;
2327 TnyAccount *account;
2329 if (TNY_IS_ACCOUNT (parent_folder))
2330 account = g_object_ref (parent_folder);
2332 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2333 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2335 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2336 MODEST_PROTOCOL_STORE_POP) {
2338 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2340 g_object_unref (account);
2342 /* Run the new folder dialog */
2344 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2349 g_free (suggested_name);
2350 suggested_name = NULL;
2352 if (result == GTK_RESPONSE_REJECT) {
2355 ModestMailOperation *mail_op;
2356 TnyFolder *new_folder = NULL;
2358 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2359 G_OBJECT(parent_window),
2360 modest_ui_actions_new_folder_error_handler,
2363 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2365 new_folder = modest_mail_operation_create_folder (mail_op,
2367 (const gchar *) folder_name);
2369 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2372 g_object_unref (new_folder);
2375 g_object_unref (mail_op);
2378 suggested_name = folder_name;
2382 g_object_unref (parent_folder);
2387 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2389 GtkWidget *folder_view;
2391 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2393 folder_view = modest_main_window_get_child_widget (main_window,
2394 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2398 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2402 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2405 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2406 const GError *error = NULL;
2407 const gchar *message = NULL;
2409 /* Get error message */
2410 error = modest_mail_operation_get_error (mail_op);
2411 if (error != NULL && error->message != NULL) {
2412 message = error->message;
2414 message = _("!!! FIXME: Unable to rename");
2417 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2422 modest_ui_actions_on_rename_folder (GtkAction *action,
2423 ModestMainWindow *main_window)
2425 TnyFolderStore *folder;
2426 GtkWidget *folder_view;
2427 GtkWidget *header_view;
2429 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2431 folder_view = modest_main_window_get_child_widget (main_window,
2432 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2436 header_view = modest_main_window_get_child_widget (main_window,
2437 MODEST_WIDGET_TYPE_HEADER_VIEW);
2442 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2446 /* Offer the connection dialog if necessary: */
2447 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2448 g_object_unref (G_OBJECT (folder));
2453 if (TNY_IS_FOLDER (folder)) {
2456 const gchar *current_name;
2458 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2459 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
2460 current_name, &folder_name);
2462 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
2463 ModestMailOperation *mail_op;
2466 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2467 G_OBJECT(main_window),
2468 modest_ui_actions_rename_folder_error_handler,
2471 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2474 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2476 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2477 TNY_FOLDER(folder), TRUE);
2479 modest_header_view_clear ((ModestHeaderView *) header_view);
2481 modest_mail_operation_rename_folder (mail_op,
2482 TNY_FOLDER (folder),
2483 (const gchar *) folder_name);
2485 g_object_unref (mail_op);
2486 g_free (folder_name);
2489 g_object_unref (folder);
2493 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2496 GObject *win = modest_mail_operation_get_source (mail_op);
2498 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2499 _("mail_in_ui_folder_delete_error"));
2500 g_object_unref (win);
2504 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2506 TnyFolderStore *folder;
2507 GtkWidget *folder_view;
2511 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
2513 folder_view = modest_main_window_get_child_widget (main_window,
2514 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2518 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2520 /* Show an error if it's an account */
2521 if (!TNY_IS_FOLDER (folder)) {
2522 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2523 _("mail_in_ui_folder_delete_error"));
2524 g_object_unref (G_OBJECT (folder));
2528 /* Offer the connection dialog if necessary: */
2529 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2530 g_object_unref (G_OBJECT (folder));
2535 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2536 tny_folder_get_name (TNY_FOLDER (folder)));
2537 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2538 (const gchar *) message);
2541 if (response == GTK_RESPONSE_OK) {
2542 ModestMailOperation *mail_op =
2543 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2544 G_OBJECT(main_window),
2545 modest_ui_actions_delete_folder_error_handler,
2548 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2550 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2551 g_object_unref (G_OBJECT (mail_op));
2554 g_object_unref (G_OBJECT (folder));
2558 modest_ui_actions_on_delete_folder (GtkAction *action,
2559 ModestMainWindow *main_window)
2561 GtkWidget *folder_view;
2562 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2564 delete_folder (main_window, FALSE);
2565 folder_view = modest_main_window_get_child_widget (main_window,
2566 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2569 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2573 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2575 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2577 delete_folder (main_window, TRUE);
2582 show_error (GtkWidget *parent_widget, const gchar* text)
2584 hildon_banner_show_information(parent_widget, NULL, text);
2587 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2589 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2596 gtk_dialog_run (dialog);
2597 gtk_widget_destroy (GTK_WIDGET (dialog));
2602 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2603 const gchar* server_account_name,
2608 ModestMainWindow *main_window)
2610 g_return_if_fail(server_account_name);
2611 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2613 /* Initalize output parameters: */
2620 #ifdef MODEST_PLATFORM_MAEMO
2621 /* Maemo uses a different (awkward) button order,
2622 * It should probably just use gtk_alternative_dialog_button_order ().
2624 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2628 GTK_RESPONSE_ACCEPT,
2630 GTK_RESPONSE_REJECT,
2633 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2637 GTK_RESPONSE_REJECT,
2639 GTK_RESPONSE_ACCEPT,
2641 #endif /* MODEST_PLATFORM_MAEMO */
2643 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2645 gchar *server_name = modest_server_account_get_hostname (
2646 modest_runtime_get_account_mgr(), server_account_name);
2647 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2648 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2653 /* This causes a warning because the logical ID has no %s in it,
2654 * though the translation does, but there is not much we can do about that: */
2655 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2656 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2659 g_free (server_name);
2663 gchar *initial_username = modest_server_account_get_username (
2664 modest_runtime_get_account_mgr(), server_account_name);
2666 GtkWidget *entry_username = gtk_entry_new ();
2667 if (initial_username)
2668 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2669 /* Dim this if a connection has ever succeeded with this username,
2670 * as per the UI spec: */
2671 const gboolean username_known =
2672 modest_server_account_get_username_has_succeeded(
2673 modest_runtime_get_account_mgr(), server_account_name);
2674 gtk_widget_set_sensitive (entry_username, !username_known);
2676 #ifdef MODEST_PLATFORM_MAEMO
2677 /* Auto-capitalization is the default, so let's turn it off: */
2678 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2680 /* Create a size group to be used by all captions.
2681 * Note that HildonCaption does not create a default size group if we do not specify one.
2682 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2683 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2685 GtkWidget *caption = hildon_caption_new (sizegroup,
2686 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2687 gtk_widget_show (entry_username);
2688 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2689 FALSE, FALSE, MODEST_MARGIN_HALF);
2690 gtk_widget_show (caption);
2692 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2694 #endif /* MODEST_PLATFORM_MAEMO */
2697 GtkWidget *entry_password = gtk_entry_new ();
2698 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2699 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2701 #ifdef MODEST_PLATFORM_MAEMO
2702 /* Auto-capitalization is the default, so let's turn it off: */
2703 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2704 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2706 caption = hildon_caption_new (sizegroup,
2707 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2708 gtk_widget_show (entry_password);
2709 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2710 FALSE, FALSE, MODEST_MARGIN_HALF);
2711 gtk_widget_show (caption);
2712 g_object_unref (sizegroup);
2714 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2716 #endif /* MODEST_PLATFORM_MAEMO */
2718 /* This is not in the Maemo UI spec:
2719 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2720 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2724 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2726 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2728 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2730 modest_server_account_set_username (
2731 modest_runtime_get_account_mgr(), server_account_name,
2734 const gboolean username_was_changed =
2735 (strcmp (*username, initial_username) != 0);
2736 if (username_was_changed) {
2737 g_warning ("%s: tinymail does not yet support changing the "
2738 "username in the get_password() callback.\n", __FUNCTION__);
2743 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2745 /* We do not save the password in the configuration,
2746 * because this function is only called for passwords that should
2747 * not be remembered:
2748 modest_server_account_set_password (
2749 modest_runtime_get_account_mgr(), server_account_name,
2758 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2770 /* This is not in the Maemo UI spec:
2771 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2777 gtk_widget_destroy (dialog);
2779 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2783 modest_ui_actions_on_cut (GtkAction *action,
2784 ModestWindow *window)
2786 GtkWidget *focused_widget;
2787 GtkClipboard *clipboard;
2789 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2790 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2791 if (GTK_IS_EDITABLE (focused_widget)) {
2792 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2793 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2794 gtk_clipboard_store (clipboard);
2795 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2796 GtkTextBuffer *buffer;
2798 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2799 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2800 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2801 gtk_clipboard_store (clipboard);
2802 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2803 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2804 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2805 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2810 modest_ui_actions_on_copy (GtkAction *action,
2811 ModestWindow *window)
2813 GtkClipboard *clipboard;
2814 GtkWidget *focused_widget;
2816 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2817 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2819 if (GTK_IS_LABEL (focused_widget)) {
2820 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2821 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2822 gtk_clipboard_store (clipboard);
2823 } else if (GTK_IS_EDITABLE (focused_widget)) {
2824 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2825 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2826 gtk_clipboard_store (clipboard);
2827 } else if (GTK_IS_HTML (focused_widget)) {
2828 gtk_html_copy (GTK_HTML (focused_widget));
2829 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2830 gtk_clipboard_store (clipboard);
2831 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2832 GtkTextBuffer *buffer;
2833 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2834 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2835 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2836 gtk_clipboard_store (clipboard);
2837 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2838 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2839 TnyIterator *iter = tny_list_create_iterator (header_list);
2840 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2842 gboolean ask = FALSE;
2844 TnyFolder *folder = tny_header_get_folder (header);
2845 TnyAccount *account = tny_folder_get_account (folder);
2846 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2847 /* If it's POP then ask */
2848 ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2849 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2850 g_object_unref (account);
2851 g_object_unref (folder);
2852 g_object_unref (header);
2855 g_object_unref (iter);
2857 /* Check that the messages have been previously downloaded */
2858 gboolean continue_download = TRUE;
2860 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window), FALSE);
2861 if (continue_download)
2862 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2863 g_object_unref (header_list);
2864 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2865 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2868 /* Show information banner */
2869 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2874 modest_ui_actions_on_undo (GtkAction *action,
2875 ModestWindow *window)
2877 ModestEmailClipboard *clipboard = NULL;
2879 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2880 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2881 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2882 /* Clear clipboard source */
2883 clipboard = modest_runtime_get_email_clipboard ();
2884 modest_email_clipboard_clear (clipboard);
2887 g_return_if_reached ();
2892 modest_ui_actions_on_redo (GtkAction *action,
2893 ModestWindow *window)
2895 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2896 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
2899 g_return_if_reached ();
2905 paste_msgs_cb (const GObject *object, gpointer user_data)
2907 g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2908 g_return_if_fail (GTK_IS_WIDGET (user_data));
2910 /* destroy information note */
2911 gtk_widget_destroy (GTK_WIDGET(user_data));
2915 paste_as_attachment_free (gpointer data)
2917 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
2919 gtk_widget_destroy (helper->banner);
2920 g_object_unref (helper->banner);
2925 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
2930 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
2931 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
2936 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
2941 modest_ui_actions_on_paste (GtkAction *action,
2942 ModestWindow *window)
2944 GtkWidget *focused_widget = NULL;
2945 GtkWidget *inf_note = NULL;
2946 ModestMailOperation *mail_op = NULL;
2948 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2949 if (GTK_IS_EDITABLE (focused_widget)) {
2950 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2951 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2952 ModestEmailClipboard *e_clipboard = NULL;
2953 e_clipboard = modest_runtime_get_email_clipboard ();
2954 if (modest_email_clipboard_cleared (e_clipboard)) {
2955 GtkTextBuffer *buffer;
2956 GtkClipboard *clipboard;
2958 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2959 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2960 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2961 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2962 ModestMailOperation *mail_op;
2963 TnyFolder *src_folder;
2966 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
2967 helper->window = MODEST_MSG_EDIT_WINDOW (window);
2968 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2969 _CS("ckct_nw_pasting"));
2970 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
2971 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2973 if (helper->banner != NULL) {
2974 g_object_ref (G_OBJECT (helper->banner));
2975 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
2976 gtk_widget_show (GTK_WIDGET (helper->banner));
2980 modest_mail_operation_get_msgs_full (mail_op,
2982 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
2984 paste_as_attachment_free);
2987 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2988 ModestEmailClipboard *clipboard = NULL;
2989 TnyFolder *src_folder = NULL;
2990 TnyFolderStore *folder_store = NULL;
2991 TnyList *data = NULL;
2992 gboolean delete = FALSE;
2994 /* Check clipboard source */
2995 clipboard = modest_runtime_get_email_clipboard ();
2996 if (modest_email_clipboard_cleared (clipboard))
2999 /* Get elements to paste */
3000 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
3002 /* Create a new mail operation */
3003 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
3005 /* Get destination folder */
3006 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
3008 /* transfer messages */
3012 /* Ask for user confirmation */
3013 response = msgs_move_to_confirmation (GTK_WINDOW (window),
3014 TNY_FOLDER (folder_store),
3018 if (response == GTK_RESPONSE_OK) {
3019 /* Launch notification */
3020 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3021 _CS("ckct_nw_pasting"));
3022 if (inf_note != NULL) {
3023 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3024 gtk_widget_show (GTK_WIDGET(inf_note));
3027 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3028 modest_mail_operation_xfer_msgs (mail_op,
3030 TNY_FOLDER (folder_store),
3035 g_object_unref (mail_op);
3038 } else if (src_folder != NULL) {
3039 /* Launch notification */
3040 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3041 _CS("ckct_nw_pasting"));
3042 if (inf_note != NULL) {
3043 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3044 gtk_widget_show (GTK_WIDGET(inf_note));
3047 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3048 modest_mail_operation_xfer_folder (mail_op,
3058 g_object_unref (data);
3059 if (src_folder != NULL)
3060 g_object_unref (src_folder);
3061 if (folder_store != NULL)
3062 g_object_unref (folder_store);
3068 modest_ui_actions_on_select_all (GtkAction *action,
3069 ModestWindow *window)
3071 GtkWidget *focused_widget;
3073 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3074 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3075 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3076 } else if (GTK_IS_LABEL (focused_widget)) {
3077 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3078 } else if (GTK_IS_EDITABLE (focused_widget)) {
3079 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3080 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3081 GtkTextBuffer *buffer;
3082 GtkTextIter start, end;
3084 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3085 gtk_text_buffer_get_start_iter (buffer, &start);
3086 gtk_text_buffer_get_end_iter (buffer, &end);
3087 gtk_text_buffer_select_range (buffer, &start, &end);
3088 } else if (GTK_IS_HTML (focused_widget)) {
3089 gtk_html_select_all (GTK_HTML (focused_widget));
3090 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3091 GtkWidget *header_view = focused_widget;
3092 GtkTreeSelection *selection = NULL;
3094 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
3095 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3096 MODEST_WIDGET_TYPE_HEADER_VIEW);
3098 /* Select all messages */
3099 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3100 gtk_tree_selection_select_all (selection);
3102 /* Set focuse on header view */
3103 gtk_widget_grab_focus (header_view);
3109 modest_ui_actions_on_mark_as_read (GtkAction *action,
3110 ModestWindow *window)
3112 g_return_if_fail (MODEST_IS_WINDOW(window));
3114 /* Mark each header as read */
3115 do_headers_action (window, headers_action_mark_as_read, NULL);
3119 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3120 ModestWindow *window)
3122 g_return_if_fail (MODEST_IS_WINDOW(window));
3124 /* Mark each header as read */
3125 do_headers_action (window, headers_action_mark_as_unread, NULL);
3129 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3130 GtkRadioAction *selected,
3131 ModestWindow *window)
3135 value = gtk_radio_action_get_current_value (selected);
3136 if (MODEST_IS_WINDOW (window)) {
3137 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3141 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3142 GtkRadioAction *selected,
3143 ModestWindow *window)
3145 TnyHeaderFlags flags;
3146 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3148 flags = gtk_radio_action_get_current_value (selected);
3149 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3152 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3153 GtkRadioAction *selected,
3154 ModestWindow *window)
3158 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3160 file_format = gtk_radio_action_get_current_value (selected);
3161 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3166 modest_ui_actions_on_zoom_plus (GtkAction *action,
3167 ModestWindow *window)
3169 g_return_if_fail (MODEST_IS_WINDOW (window));
3171 modest_window_zoom_plus (MODEST_WINDOW (window));
3175 modest_ui_actions_on_zoom_minus (GtkAction *action,
3176 ModestWindow *window)
3178 g_return_if_fail (MODEST_IS_WINDOW (window));
3180 modest_window_zoom_minus (MODEST_WINDOW (window));
3184 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3185 ModestWindow *window)
3187 ModestWindowMgr *mgr;
3188 gboolean fullscreen, active;
3189 g_return_if_fail (MODEST_IS_WINDOW (window));
3191 mgr = modest_runtime_get_window_mgr ();
3193 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3194 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3196 if (active != fullscreen) {
3197 modest_window_mgr_set_fullscreen_mode (mgr, active);
3198 gtk_window_present (GTK_WINDOW (window));
3203 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3204 ModestWindow *window)
3206 ModestWindowMgr *mgr;
3207 gboolean fullscreen;
3209 g_return_if_fail (MODEST_IS_WINDOW (window));
3211 mgr = modest_runtime_get_window_mgr ();
3212 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3213 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3215 gtk_window_present (GTK_WINDOW (window));
3219 * Used by modest_ui_actions_on_details to call do_headers_action
3222 headers_action_show_details (TnyHeader *header,
3223 ModestWindow *window,
3230 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3233 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3234 gtk_widget_show_all (dialog);
3235 gtk_dialog_run (GTK_DIALOG (dialog));
3237 gtk_widget_destroy (dialog);
3241 * Show the folder details in a ModestDetailsDialog widget
3244 show_folder_details (TnyFolder *folder,
3250 dialog = modest_details_dialog_new_with_folder (window, folder);
3253 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3254 gtk_widget_show_all (dialog);
3255 gtk_dialog_run (GTK_DIALOG (dialog));
3257 gtk_widget_destroy (dialog);
3261 * Show the header details in a ModestDetailsDialog widget
3264 modest_ui_actions_on_details (GtkAction *action,
3267 TnyList * headers_list;
3271 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3274 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3277 g_object_unref (msg);
3279 headers_list = get_selected_headers (win);
3283 iter = tny_list_create_iterator (headers_list);
3285 header = TNY_HEADER (tny_iterator_get_current (iter));
3287 headers_action_show_details (header, win, NULL);
3288 g_object_unref (header);
3291 g_object_unref (iter);
3292 g_object_unref (headers_list);
3294 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3295 GtkWidget *folder_view, *header_view;
3297 /* Check which widget has the focus */
3298 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3299 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3300 if (gtk_widget_is_focus (folder_view)) {
3301 TnyFolderStore *folder_store
3302 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3303 if (!folder_store) {
3304 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3307 /* Show only when it's a folder */
3308 /* This function should not be called for account items,
3309 * because we dim the menu item for them. */
3310 if (TNY_IS_FOLDER (folder_store)) {
3311 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3314 g_object_unref (folder_store);
3317 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3318 MODEST_WIDGET_TYPE_HEADER_VIEW);
3319 /* Show details of each header */
3320 do_headers_action (win, headers_action_show_details, header_view);
3326 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3327 ModestMsgEditWindow *window)
3329 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3331 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3335 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3336 ModestMsgEditWindow *window)
3338 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3340 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3344 modest_ui_actions_toggle_folders_view (GtkAction *action,
3345 ModestMainWindow *main_window)
3347 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3349 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3350 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3352 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3356 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3357 ModestWindow *window)
3359 gboolean active, fullscreen = FALSE;
3360 ModestWindowMgr *mgr;
3362 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3364 /* Check if we want to toggle the toolbar vuew in fullscreen
3366 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3367 "ViewShowToolbarFullScreen")) {
3371 /* Toggle toolbar */
3372 mgr = modest_runtime_get_window_mgr ();
3373 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
3377 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3378 ModestMsgEditWindow *window)
3380 modest_msg_edit_window_select_font (window);
3384 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3385 const gchar *display_name,
3388 /* Do not change the application name if the widget has not
3389 the focus. This callback could be called even if the folder
3390 view has not the focus, because the handled signal could be
3391 emitted when the folder view is redrawn */
3392 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3394 gtk_window_set_title (window, display_name);
3396 gtk_window_set_title (window, " ");
3401 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3403 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3404 modest_msg_edit_window_select_contacts (window);
3408 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3410 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3411 modest_msg_edit_window_check_names (window, FALSE);
3415 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3417 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3418 GTK_WIDGET (user_data));
3422 create_move_to_dialog (GtkWindow *win,
3423 GtkWidget *folder_view,
3424 GtkWidget **tree_view)
3426 GtkWidget *dialog, *scroll;
3427 GtkWidget *new_button;
3429 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3431 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3434 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
3435 /* We do this manually so GTK+ does not associate a response ID for
3437 new_button = gtk_button_new_from_stock (GTK_STOCK_NEW);
3438 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3439 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
3441 /* Create scrolled window */
3442 scroll = gtk_scrolled_window_new (NULL, NULL);
3443 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3444 GTK_POLICY_AUTOMATIC,
3445 GTK_POLICY_AUTOMATIC);
3447 /* Create folder view */
3448 *tree_view = modest_platform_create_folder_view (NULL);
3450 g_signal_connect (G_OBJECT (new_button), "clicked", G_CALLBACK(create_move_to_dialog_on_new_folder), *tree_view);
3452 /* It could happen that we're trying to move a message from a
3453 window (msg window for example) after the main window was
3454 closed, so we can not just get the model of the folder
3456 if (MODEST_IS_FOLDER_VIEW (folder_view))
3457 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
3458 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
3460 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3461 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3463 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3465 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3467 /* Add scroll to dialog */
3468 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3469 scroll, TRUE, TRUE, 0);
3471 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3472 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3478 * Returns TRUE if at least one of the headers of the list belongs to
3479 * a message that has been fully retrieved.
3482 has_retrieved_msgs (TnyList *list)
3485 gboolean found = FALSE;
3487 iter = tny_list_create_iterator (list);
3488 while (!tny_iterator_is_done (iter) && !found) {
3490 TnyHeaderFlags flags = 0;
3492 header = TNY_HEADER (tny_iterator_get_current (iter));
3494 flags = tny_header_get_flags (header);
3495 if (flags & TNY_HEADER_FLAG_CACHED)
3496 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3499 g_object_unref (header);
3503 tny_iterator_next (iter);
3505 g_object_unref (iter);
3511 * Shows a confirmation dialog to the user when we're moving messages
3512 * from a remote server to the local storage. Returns the dialog
3513 * response. If it's other kind of movement the it always returns
3517 msgs_move_to_confirmation (GtkWindow *win,
3518 TnyFolder *dest_folder,
3522 gint response = GTK_RESPONSE_OK;
3524 /* If the destination is a local folder (or MMC folder )*/
3525 if (!modest_tny_folder_is_remote_folder (dest_folder)) {
3526 /* if (modest_tny_folder_is_local_folder (dest_folder)) { */
3527 TnyFolder *src_folder = NULL;
3528 TnyIterator *iter = NULL;
3529 TnyHeader *header = NULL;
3531 /* Get source folder */
3532 iter = tny_list_create_iterator (headers);
3533 header = TNY_HEADER (tny_iterator_get_current (iter));
3535 src_folder = tny_header_get_folder (header);
3536 g_object_unref (header);
3539 g_object_unref (iter);
3541 /* if no src_folder, message may be an attahcment */
3542 if (src_folder == NULL)
3543 return GTK_RESPONSE_CANCEL;
3545 /* If the source is a remote folder */
3546 /* if (!modest_tny_folder_is_local_folder (src_folder)) { */
3547 if (modest_tny_folder_is_remote_folder (src_folder)) {
3548 const gchar *message = NULL;
3549 gboolean cached = has_retrieved_msgs (headers);
3551 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
3552 tny_list_get_length (headers));
3554 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
3555 tny_list_get_length (headers));
3557 if (cached && !delete)
3558 response = GTK_RESPONSE_OK;
3560 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
3561 (const gchar *) message);
3564 g_object_unref (src_folder);
3573 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
3575 ModestMsgViewWindow *self = NULL;
3577 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
3578 self = MODEST_MSG_VIEW_WINDOW (object);
3580 if (!modest_msg_view_window_select_next_message (self))
3581 if (!modest_msg_view_window_select_previous_message (self))
3582 /* No more messages to view, so close this window */
3583 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3587 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3590 GObject *win = modest_mail_operation_get_source (mail_op);
3591 const GError *error = NULL;
3592 const gchar *message = NULL;
3594 /* Get error message */
3595 error = modest_mail_operation_get_error (mail_op);
3596 if (error != NULL && error->message != NULL) {
3597 message = error->message;
3599 message = _("mail_in_ui_folder_move_target_error");
3602 /* Show notification dialog */
3603 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3604 g_object_unref (win);
3608 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3611 GObject *win = modest_mail_operation_get_source (mail_op);
3612 const GError *error = modest_mail_operation_get_error (mail_op);
3614 g_return_if_fail (error != NULL);
3615 if (error->message != NULL)
3616 g_printerr ("modest: %s\n", error->message);
3618 g_printerr ("modest: unkonw error on send&receive operation");
3620 /* Show error message */
3621 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3622 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3623 /* _CS("sfil_ib_unable_to_receive")); */
3625 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3626 /* _CS("sfil_ib_unable_to_send")); */
3627 g_object_unref (win);
3631 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3638 gint pending_purges = 0;
3639 gboolean some_purged = FALSE;
3640 ModestWindow *win = MODEST_WINDOW (user_data);
3641 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3643 /* If there was any error */
3644 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
3645 modest_window_mgr_unregister_header (mgr, header);
3649 /* Once the message has been retrieved for purging, we check if
3650 * it's all ok for purging */
3652 parts = tny_simple_list_new ();
3653 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3654 iter = tny_list_create_iterator (parts);
3656 while (!tny_iterator_is_done (iter)) {
3658 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3659 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
3660 if (tny_mime_part_is_purged (part))
3667 g_object_unref (part);
3669 tny_iterator_next (iter);
3672 if (pending_purges>0) {
3674 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3676 if (response == GTK_RESPONSE_OK) {
3677 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3678 tny_iterator_first (iter);
3679 while (!tny_iterator_is_done (iter)) {
3682 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3683 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
3684 tny_mime_part_set_purged (part);
3687 g_object_unref (part);
3689 tny_iterator_next (iter);
3692 tny_msg_rewrite_cache (msg);
3695 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3698 /* remove attachments */
3699 tny_iterator_first (iter);
3700 while (!tny_iterator_is_done (iter)) {
3703 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3705 /* One for the reference given by tny_iterator_get_current(): */
3706 g_object_unref (part);
3708 /* TODO: Is this meant to remove the attachment by doing another unref()?
3709 * Otherwise, this seems useless. */
3712 tny_iterator_next (iter);
3714 modest_window_mgr_unregister_header (mgr, header);
3716 g_object_unref (iter);
3717 g_object_unref (parts);
3721 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3722 ModestMainWindow *win)
3724 GtkWidget *header_view;
3725 TnyList *header_list;
3728 TnyHeaderFlags flags;
3729 ModestWindow *msg_view_window = NULL;
3732 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3734 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3735 MODEST_WIDGET_TYPE_HEADER_VIEW);
3737 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3739 if (tny_list_get_length (header_list) == 1) {
3740 iter = tny_list_create_iterator (header_list);
3741 header = TNY_HEADER (tny_iterator_get_current (iter));
3742 g_object_unref (iter);
3747 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3748 header, &msg_view_window);
3749 flags = tny_header_get_flags (header);
3750 if (!(flags & TNY_HEADER_FLAG_CACHED))
3753 if (msg_view_window != NULL)
3754 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3756 /* do nothing; uid was registered before, so window is probably on it's way */
3757 g_warning ("debug: header %p has already been registered", header);
3760 ModestMailOperation *mail_op = NULL;
3761 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3762 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3764 modest_ui_actions_get_msgs_full_error_handler,
3766 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3767 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3769 g_object_unref (mail_op);
3772 g_object_unref (header);
3774 g_object_unref (header_list);
3778 * Utility function that transfer messages from both the main window
3779 * and the msg view window when using the "Move to" dialog
3782 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
3785 TnyList *headers = NULL;
3787 TnyAccount *dst_account = NULL;
3788 const gchar *proto_str = NULL;
3789 gboolean dst_is_pop = FALSE;
3791 if (!TNY_IS_FOLDER (dst_folder)) {
3792 modest_platform_information_banner (GTK_WIDGET (win),
3794 _CS("ckdg_ib_unable_to_move_to_current_location"));
3798 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
3799 proto_str = tny_account_get_proto (dst_account);
3800 dst_is_pop = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
3801 MODEST_PROTOCOL_STORE_POP);
3802 g_object_unref (dst_account);
3804 /* Get selected headers */
3805 headers = get_selected_headers (MODEST_WINDOW (win));
3808 modest_platform_information_banner (GTK_WIDGET (win),
3810 ngettext("mail_in_ui_folder_move_target_error",
3811 "mail_in_ui_folder_move_targets_error",
3812 tny_list_get_length (headers)));
3813 g_object_unref (headers);
3817 /* Ask for user confirmation */
3818 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3819 TNY_FOLDER (dst_folder),
3823 /* Transfer messages */
3824 if (response == GTK_RESPONSE_OK) {
3825 ModestMailOperation *mail_op =
3826 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3828 modest_ui_actions_move_folder_error_handler,
3830 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3833 modest_mail_operation_xfer_msgs (mail_op,
3835 TNY_FOLDER (dst_folder),
3837 (MODEST_IS_MSG_VIEW_WINDOW (win)) ? transfer_msgs_from_viewer_cb : NULL,
3840 g_object_unref (G_OBJECT (mail_op));
3842 g_object_unref (headers);
3847 * UI handler for the "Move to" action when invoked from the
3851 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3852 GtkWidget *folder_view,
3853 TnyFolderStore *dst_folder,
3854 ModestMainWindow *win)
3856 GtkWidget *header_view = NULL;
3857 ModestMailOperation *mail_op = NULL;
3858 TnyFolderStore *src_folder;
3860 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3862 /* Get the source folder */
3863 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3865 /* Offer the connection dialog if necessary, if the source folder is in a networked account: */
3866 if (!modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3870 /* Get header view */
3872 modest_main_window_get_child_widget (win, MODEST_WIDGET_TYPE_HEADER_VIEW);
3874 /* Get folder or messages to transfer */
3875 if (gtk_widget_is_focus (folder_view)) {
3877 /* Allow only to transfer folders to the local root folder */
3878 if (TNY_IS_ACCOUNT (dst_folder) &&
3879 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder))
3882 /* Clean folder on header view before moving it */
3883 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3885 if (TNY_IS_FOLDER (src_folder)) {
3887 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3889 modest_ui_actions_move_folder_error_handler,
3891 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3894 modest_mail_operation_xfer_folder (mail_op,
3895 TNY_FOLDER (src_folder),
3898 /* Unref mail operation */
3899 g_object_unref (G_OBJECT (mail_op));
3901 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
3903 } else if (gtk_widget_is_focus (header_view)) {
3904 /* Transfer messages */
3905 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3910 g_object_unref (src_folder);
3915 * UI handler for the "Move to" action when invoked from the
3916 * ModestMsgViewWindow
3919 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3920 TnyFolderStore *dst_folder,
3921 ModestMsgViewWindow *win)
3923 TnyHeader *header = NULL;
3924 TnyFolder *src_folder;
3926 /* Create header list */
3927 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3928 src_folder = tny_header_get_folder(header);
3929 g_object_unref (header);
3931 /* Transfer the message */
3932 if (modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (src_folder)))
3933 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3935 g_object_unref (src_folder);
3939 modest_ui_actions_on_move_to (GtkAction *action,
3942 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3944 TnyFolderStore *dst_folder = NULL;
3945 ModestMainWindow *main_window;
3947 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3948 MODEST_IS_MSG_VIEW_WINDOW (win));
3950 /* Get the main window if exists */
3951 if (MODEST_IS_MAIN_WINDOW (win))
3952 main_window = MODEST_MAIN_WINDOW (win);
3955 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3957 /* Get the folder view widget if exists */
3959 folder_view = modest_main_window_get_child_widget (main_window,
3960 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3964 /* Create and run the dialog */
3965 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
3966 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3967 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3968 result = gtk_dialog_run (GTK_DIALOG(dialog));
3969 g_object_ref (tree_view);
3970 gtk_widget_destroy (dialog);
3972 if (result != GTK_RESPONSE_ACCEPT)
3975 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3976 /* Offer the connection dialog if necessary: */
3977 if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3980 /* Do window specific stuff */
3981 if (MODEST_IS_MAIN_WINDOW (win))
3982 modest_ui_actions_on_main_window_move_to (action,
3985 MODEST_MAIN_WINDOW (win));
3987 modest_ui_actions_on_msg_view_window_move_to (action,
3989 MODEST_MSG_VIEW_WINDOW (win));
3992 g_object_unref (dst_folder);
3996 * Calls #HeadersFunc for each header already selected in the main
3997 * window or the message currently being shown in the msg view window
4000 do_headers_action (ModestWindow *win,
4004 TnyList *headers_list = NULL;
4005 TnyIterator *iter = NULL;
4006 TnyHeader *header = NULL;
4007 TnyFolder *folder = NULL;
4010 headers_list = get_selected_headers (win);
4014 /* Get the folder */
4015 iter = tny_list_create_iterator (headers_list);
4016 header = TNY_HEADER (tny_iterator_get_current (iter));
4018 folder = tny_header_get_folder (header);
4019 g_object_unref (header);
4022 /* Call the function for each header */
4023 while (!tny_iterator_is_done (iter)) {
4024 header = TNY_HEADER (tny_iterator_get_current (iter));
4025 func (header, win, user_data);
4026 g_object_unref (header);
4027 tny_iterator_next (iter);
4030 /* Trick: do a poke status in order to speed up the signaling
4032 tny_folder_poke_status (folder);
4035 g_object_unref (folder);
4036 g_object_unref (iter);
4037 g_object_unref (headers_list);
4041 modest_ui_actions_view_attachment (GtkAction *action,
4042 ModestWindow *window)
4044 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4045 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4047 /* not supported window for this action */
4048 g_return_if_reached ();
4053 modest_ui_actions_save_attachments (GtkAction *action,
4054 ModestWindow *window)
4056 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4057 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4059 /* not supported window for this action */
4060 g_return_if_reached ();
4065 modest_ui_actions_remove_attachments (GtkAction *action,
4066 ModestWindow *window)
4068 if (MODEST_IS_MAIN_WINDOW (window)) {
4069 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4070 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4071 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4073 /* not supported window for this action */
4074 g_return_if_reached ();
4079 modest_ui_actions_on_settings (GtkAction *action,
4084 dialog = modest_platform_get_global_settings_dialog ();
4085 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4086 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4087 gtk_widget_show_all (dialog);
4089 gtk_dialog_run (GTK_DIALOG (dialog));
4091 gtk_widget_destroy (dialog);
4095 modest_ui_actions_on_help (GtkAction *action,
4098 const gchar *help_id = NULL;
4100 if (MODEST_IS_MAIN_WINDOW (win)) {
4101 const gchar *action_name;
4102 action_name = gtk_action_get_name (action);
4104 if (!strcmp (action_name, "FolderViewCSMHelp") ||
4105 !strcmp (action_name, "HeaderViewCSMHelp")) {
4106 GtkWidget *folder_view;
4107 TnyFolderStore *folder_store;
4108 /* Get selected folder */
4109 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4110 MODEST_WIDGET_TYPE_FOLDER_VIEW);
4111 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4113 /* Switch help_id */
4114 if (TNY_IS_FOLDER (folder_store)) {
4115 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4116 case TNY_FOLDER_TYPE_NORMAL:
4117 help_id = "applications_email_managefolders";
4119 case TNY_FOLDER_TYPE_INBOX:
4120 help_id = "applications_email_inbox";
4122 case TNY_FOLDER_TYPE_OUTBOX:
4123 help_id = "applications_email_outbox";
4125 case TNY_FOLDER_TYPE_SENT:
4126 help_id = "applications_email_sent";
4128 case TNY_FOLDER_TYPE_DRAFTS:
4129 help_id = "applications_email_drafts";
4131 case TNY_FOLDER_TYPE_ARCHIVE:
4132 help_id = "applications_email_managefolders";
4135 help_id = "applications_email_managefolders";
4138 help_id = "applications_email_mainview";
4140 g_object_unref (folder_store);
4142 help_id = "applications_email_mainview";
4144 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4145 help_id = "applications_email_viewer";
4146 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4147 help_id = "applications_email_editor";
4149 modest_platform_show_help (GTK_WINDOW (win), help_id);
4153 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4154 ModestWindow *window)
4156 ModestMailOperation *mail_op;
4160 headers = get_selected_headers (window);
4164 /* Create mail operation */
4165 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4167 modest_ui_actions_get_msgs_full_error_handler,
4169 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4170 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4173 g_object_unref (headers);
4174 g_object_unref (mail_op);
4178 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4179 ModestWindow *window)
4181 g_return_if_fail (MODEST_IS_WINDOW (window));
4184 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4188 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4189 ModestWindow *window)
4191 g_return_if_fail (MODEST_IS_WINDOW (window));
4194 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4198 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4199 ModestWindow *window)
4201 g_return_if_fail (MODEST_IS_WINDOW (window));
4204 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4208 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4209 ModestWindow *window)
4211 g_return_if_fail (MODEST_IS_WINDOW (window));
4214 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4218 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4219 ModestWindow *window)
4221 g_return_if_fail (MODEST_IS_WINDOW (window));
4224 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4228 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4229 ModestWindow *window)
4231 g_return_if_fail (MODEST_IS_WINDOW (window));
4234 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4238 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4239 ModestWindow *window)
4241 g_return_if_fail (MODEST_IS_WINDOW (window));
4244 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4248 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4249 ModestWindow *window)
4251 g_return_if_fail (MODEST_IS_WINDOW (window));
4254 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4258 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4260 g_return_if_fail (MODEST_IS_WINDOW (window));
4263 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4267 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4269 g_return_if_fail (MODEST_IS_WINDOW (window));
4271 modest_platform_show_search_messages (GTK_WINDOW (window));
4275 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4277 g_return_if_fail (MODEST_IS_WINDOW (win));
4278 modest_platform_show_addressbook (GTK_WINDOW (win));
4283 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4284 ModestWindow *window)
4286 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4288 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4292 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
4293 ModestMailOperationState *state,
4296 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4298 /* Set send/receive operation finished */
4299 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4300 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));