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);
147 msgs_move_to_confirmation (GtkWindow *win,
148 TnyFolder *dest_folder,
153 /* Show the account creation wizard dialog.
154 * returns: TRUE if an account was created. FALSE if the user cancelled.
157 modest_run_account_setup_wizard (ModestWindow *win)
159 gboolean result = FALSE;
160 ModestEasysetupWizardDialog *wizard;
163 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ());
165 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
167 wizard = modest_easysetup_wizard_dialog_new_or_present ();
169 /* if wizard == NULL it means there is already a easy setup thingy running;
170 * in that case, don't do anything here; the call above will present it instead */
172 g_message ("%s: easysetup wizard already running", __FUNCTION__);
176 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
178 /* Don't make this a modal window, because secondary windows will then
179 * be unusable, freezing the UI: */
180 /* gtk_window_set_modal (GTK_WINDOW (wizard), TRUE); */
182 gint dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
183 if (dialog_response == GTK_RESPONSE_CANCEL)
186 /* Check whether an account was created: */
187 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
190 gtk_widget_destroy (GTK_WIDGET (wizard));
197 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
200 const gchar *authors[] = {
201 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
204 about = gtk_about_dialog_new ();
205 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
206 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
207 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
208 _("Copyright (c) 2006, Nokia Corporation\n"
209 "All rights reserved."));
210 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
211 _("a modest e-mail client\n\n"
212 "design and implementation: Dirk-Jan C. Binnema\n"
213 "contributions from the fine people at KC and Ig\n"
214 "uses the tinymail email framework written by Philip van Hoof"));
215 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
216 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
217 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
218 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
220 gtk_dialog_run (GTK_DIALOG (about));
221 gtk_widget_destroy(about);
225 * Gets the list of currently selected messages. If the win is the
226 * main window, then it returns a newly allocated list of the headers
227 * selected in the header view. If win is the msg view window, then
228 * the value returned is a list with just a single header.
230 * The caller of this funcion must free the list.
233 get_selected_headers (ModestWindow *win)
235 if (MODEST_IS_MAIN_WINDOW(win)) {
236 GtkWidget *header_view;
238 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
239 MODEST_WIDGET_TYPE_HEADER_VIEW);
240 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
242 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
243 /* for MsgViewWindows, we simply return a list with one element */
245 TnyList *list = NULL;
247 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
248 if (header != NULL) {
249 list = tny_simple_list_new ();
250 tny_list_prepend (list, G_OBJECT(header));
251 g_object_unref (G_OBJECT(header));
261 headers_action_mark_as_read (TnyHeader *header,
265 TnyHeaderFlags flags;
267 g_return_if_fail (TNY_IS_HEADER(header));
269 flags = tny_header_get_flags (header);
270 if (flags & TNY_HEADER_FLAG_SEEN) return;
271 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
275 headers_action_mark_as_unread (TnyHeader *header,
279 TnyHeaderFlags flags;
281 g_return_if_fail (TNY_IS_HEADER(header));
283 flags = tny_header_get_flags (header);
284 if (flags & TNY_HEADER_FLAG_SEEN) {
285 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
289 /** A convenience method, because deleting a message is
290 * otherwise complicated, and it's best to change it in one place
293 void modest_do_message_delete (TnyHeader *header, ModestWindow *win)
295 ModestMailOperation *mail_op = NULL;
296 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE,
297 win ? G_OBJECT(win) : NULL);
298 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
301 /* Always delete. TODO: Move to trash still not supported */
302 modest_mail_operation_remove_msg (mail_op, header, FALSE);
303 g_object_unref (G_OBJECT (mail_op));
307 headers_action_delete (TnyHeader *header,
311 modest_do_message_delete (header, win);
314 /** After deleing a message that is currently visible in a window,
315 * show the next message from the list, or close the window if there are no more messages.
317 void modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
319 /* Close msg view window or select next */
320 if (modest_msg_view_window_last_message_selected (win) &&
321 modest_msg_view_window_first_message_selected (win)) {
322 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
324 if (!modest_msg_view_window_select_next_message (win)) {
326 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
332 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
334 TnyList *header_list = NULL;
335 TnyIterator *iter = NULL;
336 TnyHeader *header = NULL;
337 gchar *message = NULL;
340 ModestWindowMgr *mgr;
341 GtkWidget *header_view = NULL;
343 g_return_if_fail (MODEST_IS_WINDOW(win));
345 /* Check first if the header view has the focus */
346 if (MODEST_IS_MAIN_WINDOW (win)) {
348 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
349 MODEST_WIDGET_TYPE_HEADER_VIEW);
350 if (!gtk_widget_is_focus (header_view))
354 /* Get the headers, either from the header view (if win is the main window),
355 * or from the message view window: */
356 header_list = get_selected_headers (win);
357 if (!header_list) return;
359 /* Check if any of the headers are already opened, or in the process of being opened */
360 if (MODEST_IS_MAIN_WINDOW (win)) {
362 iter = tny_list_create_iterator (header_list);
364 mgr = modest_runtime_get_window_mgr ();
365 while (!tny_iterator_is_done (iter) && !found) {
366 header = TNY_HEADER (tny_iterator_get_current (iter));
368 found = modest_window_mgr_find_registered_header (mgr, header, NULL);
369 g_object_unref (header);
372 tny_iterator_next (iter);
374 g_object_unref (iter);
379 num = g_strdup_printf ("%d", tny_list_get_length (header_list));
380 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
382 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
386 g_object_unref (header_list);
392 if (tny_list_get_length(header_list) == 1) {
393 iter = tny_list_create_iterator (header_list);
394 header = TNY_HEADER (tny_iterator_get_current (iter));
396 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
397 g_object_unref (header);
400 g_object_unref (iter);
402 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
403 tny_list_get_length(header_list)), desc);
405 /* Confirmation dialog */
406 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
410 if (response == GTK_RESPONSE_OK) {
411 ModestWindow *main_window = NULL;
412 ModestWindowMgr *mgr = NULL;
413 GtkTreeModel *model = NULL;
414 GtkTreeSelection *sel = NULL;
415 GList *sel_list = NULL, *tmp = NULL;
416 GtkTreeRowReference *row_reference = NULL;
417 GtkTreePath *next_path = NULL;
418 TnyFolder *folder = NULL;
421 /* Find last selected row */
422 if (MODEST_IS_MAIN_WINDOW (win)) {
423 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
424 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
425 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
426 for (tmp=sel_list; tmp; tmp=tmp->next) {
427 if (tmp->next == NULL) {
428 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
429 gtk_tree_path_next (next_path);
430 row_reference = gtk_tree_row_reference_new (model, next_path);
431 gtk_tree_path_free (next_path);
436 /* Remove each header. If it's a view window header_view == NULL */
437 do_headers_action (win, headers_action_delete, header_view);
439 /* refresh the header view (removing marked-as-deleted)*/
440 modest_header_view_refilter (MODEST_HEADER_VIEW(header_view));
442 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
443 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
445 /* Get main window */
446 mgr = modest_runtime_get_window_mgr ();
447 main_window = modest_window_mgr_get_main_window (mgr);
450 /* Move cursor to next row */
453 /* Select next row */
454 if (gtk_tree_row_reference_valid (row_reference)) {
455 next_path = gtk_tree_row_reference_get_path (row_reference);
456 gtk_tree_selection_select_path (sel, next_path);
457 gtk_tree_path_free (next_path);
459 if (row_reference != NULL)
460 gtk_tree_row_reference_free (row_reference);
463 /* Get folder from first header and sync it */
464 iter = tny_list_create_iterator (header_list);
465 header = TNY_HEADER (tny_iterator_get_current (iter));
466 folder = tny_header_get_folder (header);
467 if (TNY_IS_CAMEL_IMAP_FOLDER (folder))
468 /* tny_folder_sync_async(folder, FALSE, NULL, NULL, NULL); /\* FALSE --> don't expunge *\/ */
469 tny_folder_sync (folder, FALSE, &err); /* FALSE --> don't expunge */
470 else if (TNY_IS_CAMEL_POP_FOLDER (folder))
471 /* tny_folder_sync_async(folder, FALSE, NULL, NULL, NULL); /\* TRUE --> dont expunge *\/ */
472 tny_folder_sync (folder, TRUE, &err); /* TRUE --> expunge */
475 /* tny_folder_sync_async(folder, TRUE, NULL, NULL, NULL); /\* TRUE --> expunge *\/ */
476 tny_folder_sync (folder, TRUE, &err); /* TRUE --> expunge */
479 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, err->code, err->message);
483 g_object_unref (header);
484 g_object_unref (iter);
485 g_object_unref (folder);
487 /* Update toolbar dimming state */
488 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
491 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
492 g_list_free (sel_list);
498 g_object_unref (header_list);
504 /* delete either message or folder, based on where we are */
506 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
508 g_return_if_fail (MODEST_IS_WINDOW(win));
510 /* Check first if the header view has the focus */
511 if (MODEST_IS_MAIN_WINDOW (win)) {
513 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
514 MODEST_WIDGET_TYPE_FOLDER_VIEW);
515 if (gtk_widget_is_focus (w)) {
516 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
520 modest_ui_actions_on_delete_message (action, win);
526 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
528 #ifdef MODEST_PLATFORM_MAEMO
529 modest_osso_save_state();
530 #endif /* MODEST_PLATFORM_MAEMO */
532 g_debug ("closing down, clearing %d item(s) from operation queue",
533 modest_mail_operation_queue_num_elements
534 (modest_runtime_get_mail_operation_queue()));
536 /* cancel all outstanding operations */
537 modest_mail_operation_queue_cancel_all
538 (modest_runtime_get_mail_operation_queue());
540 g_debug ("queue has been cleared");
542 /* note: when modest-tny-account-store is finalized,
543 it will automatically set all network connections
550 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
554 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
556 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
557 /* gtk_widget_destroy (GTK_WIDGET (win)); */
558 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
559 /* gboolean ret_value; */
560 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
561 /* } else if (MODEST_IS_WINDOW (win)) { */
562 /* gtk_widget_destroy (GTK_WIDGET (win)); */
564 /* g_return_if_reached (); */
569 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
571 GtkClipboard *clipboard = NULL;
572 gchar *selection = NULL;
574 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
575 selection = gtk_clipboard_wait_for_text (clipboard);
577 /* Question: why is the clipboard being used here?
578 * It doesn't really make a lot of sense. */
582 modest_address_book_add_address (selection);
588 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
590 /* This is currently only implemented for Maemo */
591 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
592 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
593 modest_run_account_setup_wizard (win);
596 /* Show the list of accounts: */
597 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
598 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW (win));
600 /* Don't make this a modal window, because secondary windows will then
601 * be unusable, freezing the UI: */
602 /* gtk_window_set_modal (GTK_WINDOW (account_win), TRUE); */
603 modest_maemo_show_dialog_and_forget (GTK_WINDOW (win), account_win);
606 GtkWidget *dialog, *label;
608 /* Create the widgets */
610 dialog = gtk_dialog_new_with_buttons ("Message",
612 GTK_DIALOG_DESTROY_WITH_PARENT,
616 label = gtk_label_new ("Hello World!");
618 /* Ensure that the dialog box is destroyed when the user responds. */
620 g_signal_connect_swapped (dialog, "response",
621 G_CALLBACK (gtk_widget_destroy),
624 /* Add the label, and show everything we've added to the dialog. */
626 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
628 gtk_widget_show_all (dialog);
629 #endif /* MODEST_PLATFORM_MAEMO */
633 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
635 ModestWindow *main_window = MODEST_WINDOW (user_data);
637 /* Save any changes. */
638 modest_connection_specific_smtp_window_save_server_accounts (
639 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
640 modest_window_get_active_account (main_window));
641 gtk_widget_destroy (GTK_WIDGET (window));
647 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
649 /* This is currently only implemented for Maemo,
650 * because it requires an API (libconic) to detect different connection
653 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
655 /* Create the window if necessary: */
656 const gchar *active_account_name = modest_window_get_active_account (win);
658 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
659 * or show the default account?
660 * If we show the default account then the account name should be shown in
661 * the window when we show it. */
662 if (!active_account_name) {
663 g_warning ("%s: No account is active.", __FUNCTION__);
667 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
668 modest_connection_specific_smtp_window_fill_with_connections (
669 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
670 modest_runtime_get_account_mgr(),
671 active_account_name);
673 /* Show the window: */
674 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
675 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
676 gtk_widget_show (specific_window);
678 /* Save changes when the window is hidden: */
679 g_signal_connect (specific_window, "hide",
680 G_CALLBACK (on_smtp_servers_window_hide), win);
681 #endif /* MODEST_PLATFORM_MAEMO */
685 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
687 ModestWindow *msg_win = NULL;
689 TnyFolder *folder = NULL;
690 gchar *account_name = NULL;
691 gchar *from_str = NULL;
692 /* GError *err = NULL; */
693 TnyAccount *account = NULL;
694 ModestWindowMgr *mgr;
695 gchar *signature = NULL, *blank_and_signature = NULL;
697 /* if there are no accounts yet, just show the wizard */
698 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
699 const gboolean created = modest_run_account_setup_wizard (win);
704 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
706 account_name = g_strdup (modest_window_get_active_account (win));
708 g_printerr ("modest: no account found\n");
712 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
714 TNY_ACCOUNT_TYPE_STORE);
716 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
720 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
722 g_printerr ("modest: failed get from string for '%s'\n", account_name);
726 gboolean use_signature = FALSE;
727 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr (), account_name, &use_signature);
730 blank_and_signature = g_strconcat ("\n", signature, NULL);
732 blank_and_signature = g_strdup ("");
737 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
739 g_printerr ("modest: failed to create new msg\n");
743 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
745 g_printerr ("modest: failed to find Drafts folder\n");
750 /* Create and register edit window */
751 /* This is destroyed by TODO. */
752 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
753 mgr = modest_runtime_get_window_mgr ();
754 modest_window_mgr_register_window (mgr, msg_win);
757 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
759 gtk_widget_show_all (GTK_WIDGET (msg_win));
762 g_free (account_name);
764 g_free (blank_and_signature);
766 g_object_unref (msg_win);
768 g_object_unref (G_OBJECT(account));
770 g_object_unref (G_OBJECT(msg));
772 g_object_unref (G_OBJECT(folder));
776 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
780 ModestMailOperationStatus status;
782 /* If there is no message or the operation was not successful */
783 status = modest_mail_operation_get_status (mail_op);
784 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
786 /* Remove the header from the preregistered uids */
787 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
797 open_msg_cb (ModestMailOperation *mail_op,
802 ModestWindowMgr *mgr = NULL;
803 ModestWindow *parent_win = NULL;
804 ModestWindow *win = NULL;
805 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
806 gchar *account = NULL;
809 /* Do nothing if there was any problem with the mail
810 operation. The error will be shown by the error_handler of
811 the mail operation */
812 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
816 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
817 folder = tny_header_get_folder (header);
819 /* Mark header as read */
820 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
823 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
825 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
827 /* Gets folder type (OUTBOX headers will be opened in edit window */
828 if (modest_tny_folder_is_local_folder (folder))
829 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
831 /* If the header is in the drafts folder then open the editor,
832 else the message view window */
833 if ((folder_type == TNY_FOLDER_TYPE_DRAFTS) ||
834 (folder_type == TNY_FOLDER_TYPE_OUTBOX)) {
835 /* we cannot edit without a valid account... */
836 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
837 const gboolean created = modest_run_account_setup_wizard(parent_win);
841 win = modest_msg_edit_window_new (msg, account, TRUE);
844 gchar *uid = modest_tny_folder_get_header_unique_id (header);
846 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
847 GtkWidget *header_view;
848 GtkTreeSelection *sel;
849 GList *sel_list = NULL;
852 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
853 MODEST_WIDGET_TYPE_HEADER_VIEW);
855 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
856 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
858 if (sel_list != NULL) {
859 GtkTreeRowReference *row_reference;
861 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
862 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
863 g_list_free (sel_list);
865 win = modest_msg_view_window_new_with_header_model (
866 msg, account, (const gchar*) uid,
867 model, row_reference);
868 gtk_tree_row_reference_free (row_reference);
870 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
873 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
878 /* Register and show new window */
880 mgr = modest_runtime_get_window_mgr ();
881 modest_window_mgr_register_window (mgr, win);
882 g_object_unref (win);
883 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
884 gtk_widget_show_all (GTK_WIDGET(win));
887 /* Update toolbar dimming state */
888 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
889 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
895 g_object_unref (parent_win);
896 g_object_unref (folder);
900 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
904 GObject *win = modest_mail_operation_get_source (mail_op);
906 error = modest_mail_operation_get_error (mail_op);
907 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, error->code, error->message);
909 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
911 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
914 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
915 _("mail_ni_ui_folder_get_msg_folder_error"));
919 g_object_unref (win);
923 * This function is used by both modest_ui_actions_on_open and
924 * modest_ui_actions_on_header_activated. This way we always do the
925 * same when trying to open messages.
928 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
930 ModestWindowMgr *mgr = NULL;
931 TnyIterator *iter = NULL;
932 ModestMailOperation *mail_op = NULL;
933 TnyList *not_opened_headers = NULL;
934 TnyHeaderFlags flags = 0;
936 g_return_if_fail (headers != NULL);
938 /* Check that only one message is selected for opening */
939 if (tny_list_get_length (headers) != 1) {
940 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
941 _("mcen_ib_select_one_message"));
946 /* Look if we already have a message view for each header. If
947 true, then remove the header from the list of headers to
949 mgr = modest_runtime_get_window_mgr ();
950 iter = tny_list_create_iterator (headers);
951 not_opened_headers = tny_simple_list_new ();
953 while (!tny_iterator_is_done (iter)) {
955 ModestWindow *window = NULL;
956 TnyHeader *header = NULL;
957 gboolean found = FALSE;
959 header = TNY_HEADER (tny_iterator_get_current (iter));
961 flags = tny_header_get_flags (header);
964 found = modest_window_mgr_find_registered_header (mgr, header, &window);
966 /* Do not open again the message and present the
967 window to the user */
970 gtk_window_present (GTK_WINDOW (window));
972 /* the header has been registered already, we don't do
973 * anything but wait for the window to come up*/
974 g_debug ("header %p already registered, waiting for window", header);
976 tny_list_append (not_opened_headers, G_OBJECT (header));
980 g_object_unref (header);
982 tny_iterator_next (iter);
984 g_object_unref (iter);
987 /* If some messages would have to be downloaded, ask the user to
988 * make a connection. It's generally easier to do this here (in the mainloop)
989 * than later in a thread:
991 if (tny_list_get_length (not_opened_headers) > 0) {
993 gboolean found = FALSE;
995 iter = tny_list_create_iterator (not_opened_headers);
996 while (!tny_iterator_is_done (iter) && !found) {
997 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
998 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1001 tny_iterator_next (iter);
1003 g_object_unref (header);
1005 g_object_unref (iter);
1007 if (found && !modest_platform_connect_and_wait (GTK_WINDOW (win), NULL)) {
1008 g_object_unref (not_opened_headers);
1013 /* Register the headers before actually creating the windows: */
1014 TnyIterator *iter_not_opened = tny_list_create_iterator (not_opened_headers);
1015 while (!tny_iterator_is_done (iter_not_opened)) {
1016 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1018 modest_window_mgr_register_header (mgr, header);
1019 g_object_unref (header);
1022 tny_iterator_next (iter_not_opened);
1024 g_object_unref (iter_not_opened);
1025 iter_not_opened = NULL;
1027 /* Open each message */
1028 if (tny_list_get_length (not_opened_headers) > 0) {
1029 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1031 modest_ui_actions_get_msgs_full_error_handler,
1033 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1034 if (tny_list_get_length (not_opened_headers) > 1) {
1035 modest_mail_operation_get_msgs_full (mail_op,
1041 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1042 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1043 modest_mail_operation_get_msg (mail_op, header, open_msg_cb, NULL);
1044 g_object_unref (header);
1045 g_object_unref (iter);
1047 g_object_unref (mail_op);
1051 if (not_opened_headers != NULL)
1052 g_object_unref (not_opened_headers);
1056 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1061 headers = get_selected_headers (win);
1066 _modest_ui_actions_open (headers, win);
1068 g_object_unref(headers);
1073 free_reply_forward_helper (gpointer data)
1075 ReplyForwardHelper *helper;
1077 helper = (ReplyForwardHelper *) data;
1078 g_free (helper->account_name);
1079 g_slice_free (ReplyForwardHelper, helper);
1083 reply_forward_cb (ModestMailOperation *mail_op,
1089 ReplyForwardHelper *rf_helper;
1090 ModestWindow *msg_win = NULL;
1091 ModestEditType edit_type;
1093 TnyAccount *account = NULL;
1094 ModestWindowMgr *mgr = NULL;
1095 gchar *signature = NULL;
1097 /* If there was any error. The mail operation could be NULL,
1098 this means that we already have the message downloaded and
1099 that we didn't do a mail operation to retrieve it */
1100 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1103 g_return_if_fail (user_data != NULL);
1104 rf_helper = (ReplyForwardHelper *) user_data;
1106 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1107 rf_helper->account_name);
1108 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
1109 rf_helper->account_name,
1110 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
1111 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
1112 rf_helper->account_name,
1113 MODEST_ACCOUNT_SIGNATURE, FALSE);
1116 /* Create reply mail */
1117 switch (rf_helper->action) {
1120 modest_tny_msg_create_reply_msg (msg, header, from, signature,
1121 rf_helper->reply_forward_type,
1122 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1124 case ACTION_REPLY_TO_ALL:
1126 modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1127 MODEST_TNY_MSG_REPLY_MODE_ALL);
1128 edit_type = MODEST_EDIT_TYPE_REPLY;
1130 case ACTION_FORWARD:
1132 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1133 edit_type = MODEST_EDIT_TYPE_FORWARD;
1136 g_return_if_reached ();
1143 g_printerr ("modest: failed to create message\n");
1147 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1148 rf_helper->account_name,
1149 TNY_ACCOUNT_TYPE_STORE);
1151 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1155 /* Create and register the windows */
1156 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1157 mgr = modest_runtime_get_window_mgr ();
1158 modest_window_mgr_register_window (mgr, msg_win);
1160 if (rf_helper->parent_window != NULL) {
1161 gdouble parent_zoom;
1163 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1164 modest_window_set_zoom (msg_win, parent_zoom);
1167 /* Show edit window */
1168 gtk_widget_show_all (GTK_WIDGET (msg_win));
1172 g_object_unref (msg_win);
1174 g_object_unref (G_OBJECT (new_msg));
1176 g_object_unref (G_OBJECT (account));
1177 /* g_object_unref (msg); */
1178 free_reply_forward_helper (rf_helper);
1182 * Checks a list of headers. If any of them are not currently
1183 * downloaded (CACHED) then it asks the user for permission to
1186 * Returns FALSE if the user does not want to download the
1187 * messages. Returns TRUE if the user allowed the download or if all
1188 * of them are currently downloaded
1191 download_uncached_messages (TnyList *header_list,
1196 gint uncached_messages = 0;
1198 iter = tny_list_create_iterator (header_list);
1199 while (!tny_iterator_is_done (iter)) {
1202 header = TNY_HEADER (tny_iterator_get_current (iter));
1204 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1205 uncached_messages ++;
1206 g_object_unref (header);
1209 tny_iterator_next (iter);
1211 g_object_unref (iter);
1213 /* Ask for user permission to download the messages */
1215 if (uncached_messages > 0) {
1216 gboolean download = TRUE;
1217 if (!tny_device_is_online (modest_runtime_get_device())) {
1218 GtkResponseType response =
1219 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1220 ngettext("mcen_nc_get_msg",
1222 uncached_messages));
1223 if (response == GTK_RESPONSE_CANCEL) download = FALSE;
1226 /* If a download will be necessary, make sure that we have a connection: */
1227 retval = modest_platform_connect_and_wait(win, NULL);
1237 * Common code for the reply and forward actions
1240 reply_forward (ReplyForwardAction action, ModestWindow *win)
1242 ModestMailOperation *mail_op = NULL;
1243 TnyList *header_list = NULL;
1244 ReplyForwardHelper *rf_helper = NULL;
1245 guint reply_forward_type;
1246 gboolean continue_download = TRUE;
1247 gboolean do_retrieve = TRUE;
1249 g_return_if_fail (MODEST_IS_WINDOW(win));
1251 /* we need an account when editing */
1252 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1253 const gboolean created = modest_run_account_setup_wizard (win);
1258 header_list = get_selected_headers (win);
1262 reply_forward_type =
1263 modest_conf_get_int (modest_runtime_get_conf (),
1264 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1267 /* Check that the messages have been previously downloaded */
1268 do_retrieve = (action == ACTION_FORWARD) || (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1270 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
1271 if (!continue_download) {
1272 g_object_unref (header_list);
1276 /* We assume that we can only select messages of the
1277 same folder and that we reply all of them from the
1278 same account. In fact the interface currently only
1279 allows single selection */
1282 rf_helper = g_slice_new0 (ReplyForwardHelper);
1283 rf_helper->reply_forward_type = reply_forward_type;
1284 rf_helper->action = action;
1285 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1287 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1288 rf_helper->parent_window = GTK_WIDGET (win);
1289 if (!rf_helper->account_name)
1290 rf_helper->account_name =
1291 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1293 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1296 /* Get header and message. Do not free them here, the
1297 reply_forward_cb must do it */
1298 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1299 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1300 if (!msg || !header) {
1302 g_object_unref (msg);
1303 g_printerr ("modest: no message found\n");
1306 reply_forward_cb (NULL, header, msg, rf_helper);
1309 g_object_unref (header);
1314 /* Only reply/forward to one message */
1315 iter = tny_list_create_iterator (header_list);
1316 header = TNY_HEADER (tny_iterator_get_current (iter));
1317 g_object_unref (iter);
1320 /* Retrieve messages */
1322 mail_op = modest_mail_operation_new_with_error_handling (
1323 MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1325 modest_ui_actions_get_msgs_full_error_handler,
1327 modest_mail_operation_queue_add (
1328 modest_runtime_get_mail_operation_queue (), mail_op);
1330 modest_mail_operation_get_msg (mail_op,
1335 g_object_unref(mail_op);
1337 /* we put a ref here to prevent double unref as the reply
1338 * forward callback unrefs the header at its end */
1339 reply_forward_cb (NULL, header, NULL, rf_helper);
1343 g_object_unref (header);
1349 g_object_unref (header_list);
1353 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1355 g_return_if_fail (MODEST_IS_WINDOW(win));
1357 reply_forward (ACTION_REPLY, win);
1361 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1363 g_return_if_fail (MODEST_IS_WINDOW(win));
1365 reply_forward (ACTION_FORWARD, win);
1369 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1371 g_return_if_fail (MODEST_IS_WINDOW(win));
1373 reply_forward (ACTION_REPLY_TO_ALL, win);
1377 modest_ui_actions_on_next (GtkAction *action,
1378 ModestWindow *window)
1380 if (MODEST_IS_MAIN_WINDOW (window)) {
1381 GtkWidget *header_view;
1383 header_view = modest_main_window_get_child_widget (
1384 MODEST_MAIN_WINDOW(window),
1385 MODEST_WIDGET_TYPE_HEADER_VIEW);
1389 modest_header_view_select_next (
1390 MODEST_HEADER_VIEW(header_view));
1391 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1392 modest_msg_view_window_select_next_message (
1393 MODEST_MSG_VIEW_WINDOW (window));
1395 g_return_if_reached ();
1400 modest_ui_actions_on_prev (GtkAction *action,
1401 ModestWindow *window)
1403 g_return_if_fail (MODEST_IS_WINDOW(window));
1405 if (MODEST_IS_MAIN_WINDOW (window)) {
1406 GtkWidget *header_view;
1407 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1408 MODEST_WIDGET_TYPE_HEADER_VIEW);
1412 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1413 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1414 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1416 g_return_if_reached ();
1421 modest_ui_actions_on_sort (GtkAction *action,
1422 ModestWindow *window)
1424 g_return_if_fail (MODEST_IS_WINDOW(window));
1426 if (MODEST_IS_MAIN_WINDOW (window)) {
1427 GtkWidget *header_view;
1428 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1429 MODEST_WIDGET_TYPE_HEADER_VIEW);
1431 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1436 /* Show sorting dialog */
1437 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1442 new_messages_arrived (ModestMailOperation *self,
1446 ModestMainWindow *win = NULL;
1447 GtkWidget *folder_view = NULL;
1448 TnyFolderStore *folder = NULL;
1449 gboolean folder_empty = FALSE;
1451 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
1452 win = MODEST_MAIN_WINDOW (user_data);
1454 /* Set contents style of headers view */
1455 if (modest_main_window_get_contents_style (win) == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1456 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1457 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1458 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1461 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1464 modest_main_window_set_contents_style (win,
1465 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1468 /* Notify new messages have been downloaded */
1469 if (new_messages > 0)
1470 modest_platform_on_new_msg ();
1474 * This function performs the send & receive required actions. The
1475 * window is used to create the mail operation. Typically it should
1476 * always be the main window, but we pass it as argument in order to
1480 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1482 gchar *acc_name = NULL;
1483 ModestMailOperation *mail_op;
1485 /* If no account name was provided then get the current account, and if
1486 there is no current account then pick the default one: */
1487 if (!account_name) {
1488 acc_name = g_strdup (modest_window_get_active_account(win));
1490 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1492 g_printerr ("modest: cannot get default account\n");
1496 acc_name = g_strdup (account_name);
1499 /* Set send/receive operation in progress */
1500 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1502 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1504 modest_ui_actions_send_receive_error_handler,
1507 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1508 G_CALLBACK (_on_send_receive_progress_changed),
1511 /* Send & receive. */
1512 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1513 /* Receive and then send. The operation is tagged initially as
1514 a receive operation because the account update performs a
1515 receive and then a send. The operation changes its type
1516 internally, so the progress objects will receive the proper
1517 progress information */
1518 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1519 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, win);
1520 g_object_unref (G_OBJECT (mail_op));
1528 modest_ui_actions_do_cancel_send (const gchar *account_name,
1531 TnyTransportAccount *transport_account;
1532 TnySendQueue *send_queue = NULL;
1533 GError *error = NULL;
1535 /* Get transport account */
1537 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1538 (modest_runtime_get_account_store(),
1540 TNY_ACCOUNT_TYPE_TRANSPORT));
1541 if (!transport_account) {
1542 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1547 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1548 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1549 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1550 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1551 "modest: could not find send queue for account\n");
1553 /* Keeep messages in outbox folder */
1554 tny_send_queue_cancel (send_queue, FALSE, &error);
1558 if (transport_account != NULL)
1559 g_object_unref (G_OBJECT (transport_account));
1563 modest_ui_actions_cancel_send_all (ModestWindow *win)
1565 GSList *account_names, *iter;
1567 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1570 iter = account_names;
1572 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1573 iter = g_slist_next (iter);
1576 modest_account_mgr_free_account_names (account_names);
1577 account_names = NULL;
1581 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1584 /* Check if accounts exist */
1585 gboolean accounts_exist =
1586 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1588 /* If not, allow the user to create an account before trying to send/receive. */
1589 if (!accounts_exist)
1590 modest_ui_actions_on_accounts (NULL, win);
1592 /* Cancel all sending operaitons */
1593 modest_ui_actions_cancel_send_all (win);
1597 * Refreshes all accounts. This function will be used by automatic
1601 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1603 GSList *account_names, *iter;
1605 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1608 iter = account_names;
1610 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1611 iter = g_slist_next (iter);
1614 modest_account_mgr_free_account_names (account_names);
1615 account_names = NULL;
1619 modest_do_refresh_current_folder(ModestWindow *win)
1621 /* Refresh currently selected folder. Note that if we only
1622 want to retreive the headers, then the refresh only will
1623 invoke a poke_status over all folders, i.e., only the
1624 total/unread count will be updated */
1625 if (MODEST_IS_MAIN_WINDOW (win)) {
1626 GtkWidget *header_view, *folder_view;
1627 TnyFolderStore *folder_store;
1629 /* Get folder and header view */
1631 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1632 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1634 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1636 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1638 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1639 MODEST_WIDGET_TYPE_HEADER_VIEW);
1641 /* We do not need to set the contents style
1642 because it hasn't changed. We also do not
1643 need to save the widget status. Just force
1645 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1646 TNY_FOLDER (folder_store),
1647 folder_refreshed_cb,
1648 MODEST_MAIN_WINDOW (win));
1652 g_object_unref (folder_store);
1658 * Handler of the click on Send&Receive button in the main toolbar
1661 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1663 /* Check if accounts exist */
1664 gboolean accounts_exist =
1665 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1667 /* If not, allow the user to create an account before trying to send/receive. */
1668 if (!accounts_exist)
1669 modest_ui_actions_on_accounts (NULL, win);
1671 modest_do_refresh_current_folder (win);
1673 /* Refresh the active account */
1674 modest_ui_actions_do_send_receive (NULL, win);
1679 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1682 GtkWidget *header_view;
1684 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1686 header_view = modest_main_window_get_child_widget (main_window,
1687 MODEST_WIDGET_TYPE_HEADER_VIEW);
1691 conf = modest_runtime_get_conf ();
1693 /* what is saved/restored is depending on the style; thus; we save with
1694 * old style, then update the style, and restore for this new style
1696 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1698 if (modest_header_view_get_style
1699 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1700 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1701 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1703 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1704 MODEST_HEADER_VIEW_STYLE_DETAILS);
1706 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1707 MODEST_CONF_HEADER_VIEW_KEY);
1712 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1714 ModestMainWindow *main_window)
1716 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1717 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1719 /* in the case the folder is empty, show the empty folder message and focus
1721 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1722 if (modest_header_view_is_empty (header_view)) {
1723 TnyFolder *folder = modest_header_view_get_folder (header_view);
1724 GtkWidget *folder_view =
1725 modest_main_window_get_child_widget (main_window,
1726 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1728 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1729 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1733 /* If no header has been selected then exit */
1738 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1739 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1741 /* Update toolbar dimming state */
1742 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1746 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1748 ModestMainWindow *main_window)
1752 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1758 /* headers = tny_simple_list_new (); */
1759 /* tny_list_prepend (headers, G_OBJECT (header)); */
1760 headers = modest_header_view_get_selected_headers (header_view);
1762 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1764 g_object_unref (headers);
1768 set_active_account_from_tny_account (TnyAccount *account,
1769 ModestWindow *window)
1771 const gchar *server_acc_name = tny_account_get_id (account);
1773 /* We need the TnyAccount provided by the
1774 account store because that is the one that
1775 knows the name of the Modest account */
1776 TnyAccount *modest_server_account = modest_server_account =
1777 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1778 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1781 const gchar *modest_acc_name =
1782 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1783 modest_window_set_active_account (window, modest_acc_name);
1784 g_object_unref (modest_server_account);
1789 folder_refreshed_cb (ModestMailOperation *mail_op,
1793 ModestMainWindow *win = NULL;
1794 GtkWidget *header_view;
1795 TnyFolder *current_folder;
1796 gboolean folder_empty = FALSE;
1797 gboolean all_marked_as_deleted = FALSE;
1799 g_return_if_fail (TNY_IS_FOLDER (folder));
1801 win = MODEST_MAIN_WINDOW (user_data);
1803 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1806 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1807 if (current_folder != NULL && folder != current_folder) {
1812 /* Check if folder is empty and set headers view contents style */
1813 folder_empty = (tny_folder_get_all_count (folder) == 0);
1814 all_marked_as_deleted = modest_header_view_is_empty (MODEST_HEADER_VIEW(header_view));
1815 folder_empty = folder_empty || all_marked_as_deleted ;
1818 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1819 modest_main_window_set_contents_style (win,
1820 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1822 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1827 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1828 TnyFolderStore *folder_store,
1830 ModestMainWindow *main_window)
1833 GtkWidget *header_view;
1835 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1837 header_view = modest_main_window_get_child_widget(main_window,
1838 MODEST_WIDGET_TYPE_HEADER_VIEW);
1842 conf = modest_runtime_get_conf ();
1844 if (TNY_IS_ACCOUNT (folder_store)) {
1846 /* Update active account */
1847 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1848 /* Show account details */
1849 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1852 if (TNY_IS_FOLDER (folder_store) && selected) {
1854 /* Update the active account */
1855 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1857 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1858 g_object_unref (account);
1862 /* Set the header style by default, it could
1863 be changed later by the refresh callback to
1865 modest_main_window_set_contents_style (main_window,
1866 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1868 /* Set folder on header view. This function
1869 will call tny_folder_refresh_async so we
1870 pass a callback that will be called when
1871 finished. We use that callback to set the
1872 empty view if there are no messages */
1873 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1874 TNY_FOLDER (folder_store),
1875 folder_refreshed_cb,
1878 /* Restore configuration. We need to do this
1879 *after* the set_folder because the widget
1880 memory asks the header view about its
1882 modest_widget_memory_restore (modest_runtime_get_conf (),
1883 G_OBJECT(header_view),
1884 MODEST_CONF_HEADER_VIEW_KEY);
1886 /* Update the active account */
1887 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1888 /* Save only if we're seeing headers */
1889 if (modest_main_window_get_contents_style (main_window) ==
1890 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1891 modest_widget_memory_save (conf, G_OBJECT (header_view),
1892 MODEST_CONF_HEADER_VIEW_KEY);
1893 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1897 /* Update toolbar dimming state */
1898 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1902 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1909 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1911 online = tny_device_is_online (modest_runtime_get_device());
1914 /* already online -- the item is simply not there... */
1915 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1917 GTK_MESSAGE_WARNING,
1919 _("The %s you selected cannot be found"),
1921 gtk_dialog_run (GTK_DIALOG(dialog));
1923 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1927 GTK_RESPONSE_REJECT,
1929 GTK_RESPONSE_ACCEPT,
1931 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1932 "Do you want to get online?"), item);
1933 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1934 gtk_label_new (txt), FALSE, FALSE, 0);
1935 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1938 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1939 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1940 /* TODO: Comment about why is this commented out: */
1941 /* modest_platform_connect_and_wait (); */
1944 gtk_widget_destroy (dialog);
1948 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1951 /* g_message ("%s %s", __FUNCTION__, link); */
1956 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1959 modest_platform_activate_uri (link);
1963 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1966 modest_platform_show_uri_popup (link);
1970 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1973 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1977 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1978 const gchar *address,
1981 /* g_message ("%s %s", __FUNCTION__, address); */
1985 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1987 TnyTransportAccount *transport_account;
1988 ModestMailOperation *mail_operation;
1990 gchar *account_name, *from;
1991 ModestAccountMgr *account_mgr;
1992 gchar *info_text = NULL;
1994 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1996 data = modest_msg_edit_window_get_msg_data (edit_window);
1998 account_mgr = modest_runtime_get_account_mgr();
1999 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2001 account_name = modest_account_mgr_get_default_account (account_mgr);
2002 if (!account_name) {
2003 g_printerr ("modest: no account found\n");
2004 modest_msg_edit_window_free_msg_data (edit_window, data);
2008 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2009 account_name = g_strdup (data->account_name);
2013 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2014 (modest_runtime_get_account_store(),
2016 TNY_ACCOUNT_TYPE_TRANSPORT));
2017 if (!transport_account) {
2018 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2019 g_free (account_name);
2020 modest_msg_edit_window_free_msg_data (edit_window, data);
2023 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2025 /* Create the mail operation */
2026 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
2027 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2029 modest_mail_operation_save_to_drafts (mail_operation,
2041 data->priority_flags);
2044 g_free (account_name);
2045 g_object_unref (G_OBJECT (transport_account));
2046 g_object_unref (G_OBJECT (mail_operation));
2048 modest_msg_edit_window_free_msg_data (edit_window, data);
2050 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2051 modest_platform_information_banner (NULL, NULL, info_text);
2055 /* For instance, when clicking the Send toolbar button when editing a message: */
2057 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2059 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2061 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2064 /* Offer the connection dialog, if necessary: */
2065 if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
2068 /* FIXME: Code added just for testing. The final version will
2069 use the send queue provided by tinymail and some
2071 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2072 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2074 account_name = modest_account_mgr_get_default_account (account_mgr);
2076 if (!account_name) {
2077 /* Run account setup wizard */
2078 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2083 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2085 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2086 account_name = g_strdup (data->account_name);
2089 /* Get the currently-active transport account for this modest account: */
2090 TnyTransportAccount *transport_account =
2091 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2092 (modest_runtime_get_account_store(),
2094 if (!transport_account) {
2095 /* Run account setup wizard */
2096 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2101 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2103 /* modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent")); */
2105 /* Create the mail operation */
2106 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
2107 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2109 modest_mail_operation_send_new_mail (mail_operation,
2120 data->priority_flags);
2124 g_free (account_name);
2125 g_object_unref (G_OBJECT (transport_account));
2126 g_object_unref (G_OBJECT (mail_operation));
2128 modest_msg_edit_window_free_msg_data (edit_window, data);
2129 modest_msg_edit_window_set_sent (edit_window, TRUE);
2131 /* Save settings and close the window: */
2132 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2136 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2137 ModestMsgEditWindow *window)
2139 ModestMsgEditFormatState *format_state = NULL;
2141 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2142 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2144 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2147 format_state = modest_msg_edit_window_get_format_state (window);
2148 g_return_if_fail (format_state != NULL);
2150 format_state->bold = gtk_toggle_action_get_active (action);
2151 modest_msg_edit_window_set_format_state (window, format_state);
2152 g_free (format_state);
2157 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2158 ModestMsgEditWindow *window)
2160 ModestMsgEditFormatState *format_state = NULL;
2162 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2163 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2165 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2168 format_state = modest_msg_edit_window_get_format_state (window);
2169 g_return_if_fail (format_state != NULL);
2171 format_state->italics = gtk_toggle_action_get_active (action);
2172 modest_msg_edit_window_set_format_state (window, format_state);
2173 g_free (format_state);
2178 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2179 ModestMsgEditWindow *window)
2181 ModestMsgEditFormatState *format_state = NULL;
2183 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2184 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2186 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2189 format_state = modest_msg_edit_window_get_format_state (window);
2190 g_return_if_fail (format_state != NULL);
2192 format_state->bullet = gtk_toggle_action_get_active (action);
2193 modest_msg_edit_window_set_format_state (window, format_state);
2194 g_free (format_state);
2199 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2200 GtkRadioAction *selected,
2201 ModestMsgEditWindow *window)
2203 ModestMsgEditFormatState *format_state = NULL;
2204 GtkJustification value;
2206 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2208 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2211 value = gtk_radio_action_get_current_value (selected);
2213 format_state = modest_msg_edit_window_get_format_state (window);
2214 g_return_if_fail (format_state != NULL);
2216 format_state->justification = value;
2217 modest_msg_edit_window_set_format_state (window, format_state);
2218 g_free (format_state);
2222 modest_ui_actions_on_select_editor_color (GtkAction *action,
2223 ModestMsgEditWindow *window)
2225 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2226 g_return_if_fail (GTK_IS_ACTION (action));
2228 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2231 modest_msg_edit_window_select_color (window);
2235 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2236 ModestMsgEditWindow *window)
2238 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2239 g_return_if_fail (GTK_IS_ACTION (action));
2241 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2244 modest_msg_edit_window_select_background_color (window);
2248 modest_ui_actions_on_insert_image (GtkAction *action,
2249 ModestMsgEditWindow *window)
2251 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2252 g_return_if_fail (GTK_IS_ACTION (action));
2254 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2257 modest_msg_edit_window_insert_image (window);
2261 modest_ui_actions_on_attach_file (GtkAction *action,
2262 ModestMsgEditWindow *window)
2264 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2265 g_return_if_fail (GTK_IS_ACTION (action));
2267 modest_msg_edit_window_offer_attach_file (window);
2271 modest_ui_actions_on_remove_attachments (GtkAction *action,
2272 ModestMsgEditWindow *window)
2274 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2275 g_return_if_fail (GTK_IS_ACTION (action));
2277 modest_msg_edit_window_remove_attachments (window, NULL);
2281 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2284 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2285 const GError *error = modest_mail_operation_get_error (mail_op);
2289 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2290 modest_mail_operation_get_error (mail_op)->message);
2295 modest_ui_actions_create_folder(GtkWidget *parent_window,
2296 GtkWidget *folder_view)
2298 TnyFolderStore *parent_folder;
2300 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2302 if (parent_folder) {
2303 gboolean finished = FALSE;
2305 gchar *folder_name = NULL, *suggested_name = NULL;
2306 const gchar *proto_str = NULL;
2307 TnyAccount *account;
2309 if (TNY_IS_ACCOUNT (parent_folder))
2310 account = g_object_ref (parent_folder);
2312 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2313 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2315 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2316 MODEST_PROTOCOL_STORE_POP) {
2318 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2320 g_object_unref (account);
2322 /* Run the new folder dialog */
2324 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2329 g_free (suggested_name);
2330 suggested_name = NULL;
2332 if (result == GTK_RESPONSE_REJECT) {
2335 ModestMailOperation *mail_op;
2336 TnyFolder *new_folder = NULL;
2338 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2339 G_OBJECT(parent_window),
2340 modest_ui_actions_new_folder_error_handler,
2343 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2345 new_folder = modest_mail_operation_create_folder (mail_op,
2347 (const gchar *) folder_name);
2349 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2352 g_object_unref (new_folder);
2355 g_object_unref (mail_op);
2358 suggested_name = folder_name;
2362 g_object_unref (parent_folder);
2367 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2369 GtkWidget *folder_view;
2371 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2373 folder_view = modest_main_window_get_child_widget (main_window,
2374 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2378 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2382 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2385 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2386 const GError *error = NULL;
2387 const gchar *message = NULL;
2389 /* Get error message */
2390 error = modest_mail_operation_get_error (mail_op);
2391 if (error != NULL && error->message != NULL) {
2392 message = error->message;
2394 message = _("!!! FIXME: Unable to rename");
2397 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2402 modest_ui_actions_on_rename_folder (GtkAction *action,
2403 ModestMainWindow *main_window)
2405 TnyFolderStore *folder;
2406 GtkWidget *folder_view;
2407 GtkWidget *header_view;
2409 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2411 folder_view = modest_main_window_get_child_widget (main_window,
2412 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2416 header_view = modest_main_window_get_child_widget (main_window,
2417 MODEST_WIDGET_TYPE_HEADER_VIEW);
2422 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2426 /* Offer the connection dialog if necessary: */
2427 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2428 g_object_unref (G_OBJECT (folder));
2433 if (TNY_IS_FOLDER (folder)) {
2436 const gchar *current_name;
2437 TnyFolderStore *parent;
2439 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2440 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
2441 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
2442 parent, current_name,
2444 g_object_unref (parent);
2446 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
2447 ModestMailOperation *mail_op;
2450 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2451 G_OBJECT(main_window),
2452 modest_ui_actions_rename_folder_error_handler,
2456 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2459 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2461 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2462 TNY_FOLDER(folder), TRUE);
2464 modest_header_view_clear ((ModestHeaderView *) header_view);
2466 modest_mail_operation_rename_folder (mail_op,
2467 TNY_FOLDER (folder),
2468 (const gchar *) folder_name);
2470 g_object_unref (mail_op);
2471 g_free (folder_name);
2474 g_object_unref (folder);
2478 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2481 GObject *win = modest_mail_operation_get_source (mail_op);
2483 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2484 _("mail_in_ui_folder_delete_error"));
2485 g_object_unref (win);
2489 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2491 TnyFolderStore *folder;
2492 GtkWidget *folder_view;
2496 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
2498 folder_view = modest_main_window_get_child_widget (main_window,
2499 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2503 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2505 /* Show an error if it's an account */
2506 if (!TNY_IS_FOLDER (folder)) {
2507 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2508 _("mail_in_ui_folder_delete_error"));
2509 g_object_unref (G_OBJECT (folder));
2513 /* Offer the connection dialog if necessary: */
2514 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2515 g_object_unref (G_OBJECT (folder));
2520 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2521 tny_folder_get_name (TNY_FOLDER (folder)));
2522 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2523 (const gchar *) message);
2526 if (response == GTK_RESPONSE_OK) {
2527 ModestMailOperation *mail_op =
2528 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2529 G_OBJECT(main_window),
2530 modest_ui_actions_delete_folder_error_handler,
2533 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2535 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2536 g_object_unref (G_OBJECT (mail_op));
2539 g_object_unref (G_OBJECT (folder));
2543 modest_ui_actions_on_delete_folder (GtkAction *action,
2544 ModestMainWindow *main_window)
2546 GtkWidget *folder_view;
2547 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2549 delete_folder (main_window, FALSE);
2550 folder_view = modest_main_window_get_child_widget (main_window,
2551 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2554 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2558 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2560 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2562 delete_folder (main_window, TRUE);
2567 show_error (GtkWidget *parent_widget, const gchar* text)
2569 hildon_banner_show_information(parent_widget, NULL, text);
2572 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2574 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2581 gtk_dialog_run (dialog);
2582 gtk_widget_destroy (GTK_WIDGET (dialog));
2587 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2588 const gchar* server_account_name,
2593 ModestMainWindow *main_window)
2595 g_return_if_fail(server_account_name);
2596 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2598 /* Initalize output parameters: */
2605 #ifdef MODEST_PLATFORM_MAEMO
2606 /* Maemo uses a different (awkward) button order,
2607 * It should probably just use gtk_alternative_dialog_button_order ().
2609 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2613 GTK_RESPONSE_ACCEPT,
2615 GTK_RESPONSE_REJECT,
2618 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2622 GTK_RESPONSE_REJECT,
2624 GTK_RESPONSE_ACCEPT,
2626 #endif /* MODEST_PLATFORM_MAEMO */
2628 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2630 gchar *server_name = modest_server_account_get_hostname (
2631 modest_runtime_get_account_mgr(), server_account_name);
2632 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2633 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2638 /* This causes a warning because the logical ID has no %s in it,
2639 * though the translation does, but there is not much we can do about that: */
2640 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2641 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2644 g_free (server_name);
2648 gchar *initial_username = modest_server_account_get_username (
2649 modest_runtime_get_account_mgr(), server_account_name);
2651 GtkWidget *entry_username = gtk_entry_new ();
2652 if (initial_username)
2653 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2654 /* Dim this if a connection has ever succeeded with this username,
2655 * as per the UI spec: */
2656 const gboolean username_known =
2657 modest_server_account_get_username_has_succeeded(
2658 modest_runtime_get_account_mgr(), server_account_name);
2659 gtk_widget_set_sensitive (entry_username, !username_known);
2661 #ifdef MODEST_PLATFORM_MAEMO
2662 /* Auto-capitalization is the default, so let's turn it off: */
2663 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2665 /* Create a size group to be used by all captions.
2666 * Note that HildonCaption does not create a default size group if we do not specify one.
2667 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2668 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2670 GtkWidget *caption = hildon_caption_new (sizegroup,
2671 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2672 gtk_widget_show (entry_username);
2673 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2674 FALSE, FALSE, MODEST_MARGIN_HALF);
2675 gtk_widget_show (caption);
2677 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2679 #endif /* MODEST_PLATFORM_MAEMO */
2682 GtkWidget *entry_password = gtk_entry_new ();
2683 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2684 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2686 #ifdef MODEST_PLATFORM_MAEMO
2687 /* Auto-capitalization is the default, so let's turn it off: */
2688 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2689 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2691 caption = hildon_caption_new (sizegroup,
2692 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2693 gtk_widget_show (entry_password);
2694 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2695 FALSE, FALSE, MODEST_MARGIN_HALF);
2696 gtk_widget_show (caption);
2697 g_object_unref (sizegroup);
2699 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2701 #endif /* MODEST_PLATFORM_MAEMO */
2703 /* This is not in the Maemo UI spec:
2704 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2705 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2709 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2711 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2713 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2715 modest_server_account_set_username (
2716 modest_runtime_get_account_mgr(), server_account_name,
2719 const gboolean username_was_changed =
2720 (strcmp (*username, initial_username) != 0);
2721 if (username_was_changed) {
2722 g_warning ("%s: tinymail does not yet support changing the "
2723 "username in the get_password() callback.\n", __FUNCTION__);
2728 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2730 /* We do not save the password in the configuration,
2731 * because this function is only called for passwords that should
2732 * not be remembered:
2733 modest_server_account_set_password (
2734 modest_runtime_get_account_mgr(), server_account_name,
2743 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2755 /* This is not in the Maemo UI spec:
2756 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2762 gtk_widget_destroy (dialog);
2764 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2768 modest_ui_actions_on_cut (GtkAction *action,
2769 ModestWindow *window)
2771 GtkWidget *focused_widget;
2772 GtkClipboard *clipboard;
2774 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2775 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2776 if (GTK_IS_EDITABLE (focused_widget)) {
2777 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2778 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2779 gtk_clipboard_store (clipboard);
2780 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2781 GtkTextBuffer *buffer;
2783 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2784 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2785 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2786 gtk_clipboard_store (clipboard);
2787 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2788 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2789 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2790 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2795 modest_ui_actions_on_copy (GtkAction *action,
2796 ModestWindow *window)
2798 GtkClipboard *clipboard;
2799 GtkWidget *focused_widget;
2801 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2802 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2804 if (GTK_IS_LABEL (focused_widget)) {
2805 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2806 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2807 gtk_clipboard_store (clipboard);
2808 } else if (GTK_IS_EDITABLE (focused_widget)) {
2809 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2810 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2811 gtk_clipboard_store (clipboard);
2812 } else if (GTK_IS_HTML (focused_widget)) {
2813 gtk_html_copy (GTK_HTML (focused_widget));
2814 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2815 gtk_clipboard_store (clipboard);
2816 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2817 GtkTextBuffer *buffer;
2818 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2819 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2820 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2821 gtk_clipboard_store (clipboard);
2822 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2823 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2824 TnyIterator *iter = tny_list_create_iterator (header_list);
2825 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2827 gboolean ask = FALSE;
2829 TnyFolder *folder = tny_header_get_folder (header);
2830 TnyAccount *account = tny_folder_get_account (folder);
2831 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2832 /* If it's POP then ask */
2833 ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2834 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2835 g_object_unref (account);
2836 g_object_unref (folder);
2837 g_object_unref (header);
2840 g_object_unref (iter);
2842 /* Check that the messages have been previously downloaded */
2843 gboolean continue_download = TRUE;
2845 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window));
2846 if (continue_download)
2847 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2848 g_object_unref (header_list);
2849 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2850 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2853 /* Show information banner */
2854 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2859 modest_ui_actions_on_undo (GtkAction *action,
2860 ModestWindow *window)
2862 ModestEmailClipboard *clipboard = NULL;
2864 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2865 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2866 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2867 /* Clear clipboard source */
2868 clipboard = modest_runtime_get_email_clipboard ();
2869 modest_email_clipboard_clear (clipboard);
2872 g_return_if_reached ();
2877 modest_ui_actions_on_redo (GtkAction *action,
2878 ModestWindow *window)
2880 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2881 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
2884 g_return_if_reached ();
2890 paste_msgs_cb (const GObject *object, gpointer user_data)
2892 g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2893 g_return_if_fail (GTK_IS_WIDGET (user_data));
2895 /* destroy information note */
2896 gtk_widget_destroy (GTK_WIDGET(user_data));
2900 paste_as_attachment_free (gpointer data)
2902 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
2904 gtk_widget_destroy (helper->banner);
2905 g_object_unref (helper->banner);
2910 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
2915 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
2916 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
2921 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
2926 modest_ui_actions_on_paste (GtkAction *action,
2927 ModestWindow *window)
2929 GtkWidget *focused_widget = NULL;
2930 GtkWidget *inf_note = NULL;
2931 ModestMailOperation *mail_op = NULL;
2933 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2934 if (GTK_IS_EDITABLE (focused_widget)) {
2935 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2936 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2937 ModestEmailClipboard *e_clipboard = NULL;
2938 e_clipboard = modest_runtime_get_email_clipboard ();
2939 if (modest_email_clipboard_cleared (e_clipboard)) {
2940 GtkTextBuffer *buffer;
2941 GtkClipboard *clipboard;
2943 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2944 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2945 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2946 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2947 ModestMailOperation *mail_op;
2948 TnyFolder *src_folder;
2951 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
2952 helper->window = MODEST_MSG_EDIT_WINDOW (window);
2953 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2954 _CS("ckct_nw_pasting"));
2955 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
2956 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2958 if (helper->banner != NULL) {
2959 g_object_ref (G_OBJECT (helper->banner));
2960 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
2961 gtk_widget_show (GTK_WIDGET (helper->banner));
2965 modest_mail_operation_get_msgs_full (mail_op,
2967 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
2969 paste_as_attachment_free);
2972 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2973 ModestEmailClipboard *clipboard = NULL;
2974 TnyFolder *src_folder = NULL;
2975 TnyFolderStore *folder_store = NULL;
2976 TnyList *data = NULL;
2977 gboolean delete = FALSE;
2979 /* Check clipboard source */
2980 clipboard = modest_runtime_get_email_clipboard ();
2981 if (modest_email_clipboard_cleared (clipboard))
2984 /* Get elements to paste */
2985 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2987 /* Create a new mail operation */
2988 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2990 /* Get destination folder */
2991 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2993 /* transfer messages */
2997 /* Ask for user confirmation */
2998 response = msgs_move_to_confirmation (GTK_WINDOW (window),
2999 TNY_FOLDER (folder_store),
3003 if (response == GTK_RESPONSE_OK) {
3004 /* Launch notification */
3005 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3006 _CS("ckct_nw_pasting"));
3007 if (inf_note != NULL) {
3008 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3009 gtk_widget_show (GTK_WIDGET(inf_note));
3012 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3013 modest_mail_operation_xfer_msgs (mail_op,
3015 TNY_FOLDER (folder_store),
3020 g_object_unref (mail_op);
3023 } else if (src_folder != NULL) {
3024 /* Launch notification */
3025 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3026 _CS("ckct_nw_pasting"));
3027 if (inf_note != NULL) {
3028 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3029 gtk_widget_show (GTK_WIDGET(inf_note));
3032 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3033 modest_mail_operation_xfer_folder (mail_op,
3043 g_object_unref (data);
3044 if (src_folder != NULL)
3045 g_object_unref (src_folder);
3046 if (folder_store != NULL)
3047 g_object_unref (folder_store);
3053 modest_ui_actions_on_select_all (GtkAction *action,
3054 ModestWindow *window)
3056 GtkWidget *focused_widget;
3058 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3059 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3060 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3061 } else if (GTK_IS_LABEL (focused_widget)) {
3062 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3063 } else if (GTK_IS_EDITABLE (focused_widget)) {
3064 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3065 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3066 GtkTextBuffer *buffer;
3067 GtkTextIter start, end;
3069 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3070 gtk_text_buffer_get_start_iter (buffer, &start);
3071 gtk_text_buffer_get_end_iter (buffer, &end);
3072 gtk_text_buffer_select_range (buffer, &start, &end);
3073 } else if (GTK_IS_HTML (focused_widget)) {
3074 gtk_html_select_all (GTK_HTML (focused_widget));
3075 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3076 GtkWidget *header_view = focused_widget;
3077 GtkTreeSelection *selection = NULL;
3079 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
3080 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3081 MODEST_WIDGET_TYPE_HEADER_VIEW);
3083 /* Select all messages */
3084 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3085 gtk_tree_selection_select_all (selection);
3087 /* Set focuse on header view */
3088 gtk_widget_grab_focus (header_view);
3094 modest_ui_actions_on_mark_as_read (GtkAction *action,
3095 ModestWindow *window)
3097 g_return_if_fail (MODEST_IS_WINDOW(window));
3099 /* Mark each header as read */
3100 do_headers_action (window, headers_action_mark_as_read, NULL);
3104 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3105 ModestWindow *window)
3107 g_return_if_fail (MODEST_IS_WINDOW(window));
3109 /* Mark each header as read */
3110 do_headers_action (window, headers_action_mark_as_unread, NULL);
3114 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3115 GtkRadioAction *selected,
3116 ModestWindow *window)
3120 value = gtk_radio_action_get_current_value (selected);
3121 if (MODEST_IS_WINDOW (window)) {
3122 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3126 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3127 GtkRadioAction *selected,
3128 ModestWindow *window)
3130 TnyHeaderFlags flags;
3131 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3133 flags = gtk_radio_action_get_current_value (selected);
3134 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3137 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3138 GtkRadioAction *selected,
3139 ModestWindow *window)
3143 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3145 file_format = gtk_radio_action_get_current_value (selected);
3146 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3151 modest_ui_actions_on_zoom_plus (GtkAction *action,
3152 ModestWindow *window)
3154 g_return_if_fail (MODEST_IS_WINDOW (window));
3156 modest_window_zoom_plus (MODEST_WINDOW (window));
3160 modest_ui_actions_on_zoom_minus (GtkAction *action,
3161 ModestWindow *window)
3163 g_return_if_fail (MODEST_IS_WINDOW (window));
3165 modest_window_zoom_minus (MODEST_WINDOW (window));
3169 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3170 ModestWindow *window)
3172 ModestWindowMgr *mgr;
3173 gboolean fullscreen, active;
3174 g_return_if_fail (MODEST_IS_WINDOW (window));
3176 mgr = modest_runtime_get_window_mgr ();
3178 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3179 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3181 if (active != fullscreen) {
3182 modest_window_mgr_set_fullscreen_mode (mgr, active);
3183 gtk_window_present (GTK_WINDOW (window));
3188 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3189 ModestWindow *window)
3191 ModestWindowMgr *mgr;
3192 gboolean fullscreen;
3194 g_return_if_fail (MODEST_IS_WINDOW (window));
3196 mgr = modest_runtime_get_window_mgr ();
3197 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3198 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3200 gtk_window_present (GTK_WINDOW (window));
3204 * Used by modest_ui_actions_on_details to call do_headers_action
3207 headers_action_show_details (TnyHeader *header,
3208 ModestWindow *window,
3215 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3218 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3219 gtk_widget_show_all (dialog);
3220 gtk_dialog_run (GTK_DIALOG (dialog));
3222 gtk_widget_destroy (dialog);
3226 * Show the folder details in a ModestDetailsDialog widget
3229 show_folder_details (TnyFolder *folder,
3235 dialog = modest_details_dialog_new_with_folder (window, folder);
3238 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3239 gtk_widget_show_all (dialog);
3240 gtk_dialog_run (GTK_DIALOG (dialog));
3242 gtk_widget_destroy (dialog);
3246 * Show the header details in a ModestDetailsDialog widget
3249 modest_ui_actions_on_details (GtkAction *action,
3252 TnyList * headers_list;
3256 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3259 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3262 g_object_unref (msg);
3264 headers_list = get_selected_headers (win);
3268 iter = tny_list_create_iterator (headers_list);
3270 header = TNY_HEADER (tny_iterator_get_current (iter));
3272 headers_action_show_details (header, win, NULL);
3273 g_object_unref (header);
3276 g_object_unref (iter);
3277 g_object_unref (headers_list);
3279 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3280 GtkWidget *folder_view, *header_view;
3282 /* Check which widget has the focus */
3283 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3284 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3285 if (gtk_widget_is_focus (folder_view)) {
3286 TnyFolderStore *folder_store
3287 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3288 if (!folder_store) {
3289 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3292 /* Show only when it's a folder */
3293 /* This function should not be called for account items,
3294 * because we dim the menu item for them. */
3295 if (TNY_IS_FOLDER (folder_store)) {
3296 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3299 g_object_unref (folder_store);
3302 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3303 MODEST_WIDGET_TYPE_HEADER_VIEW);
3304 /* Show details of each header */
3305 do_headers_action (win, headers_action_show_details, header_view);
3311 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3312 ModestMsgEditWindow *window)
3314 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3316 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3320 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3321 ModestMsgEditWindow *window)
3323 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3325 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3329 modest_ui_actions_toggle_folders_view (GtkAction *action,
3330 ModestMainWindow *main_window)
3332 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3334 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3335 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3337 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3341 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3342 ModestWindow *window)
3344 gboolean active, fullscreen = FALSE;
3345 ModestWindowMgr *mgr;
3347 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3349 /* Check if we want to toggle the toolbar vuew in fullscreen
3351 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3352 "ViewShowToolbarFullScreen")) {
3356 /* Toggle toolbar */
3357 mgr = modest_runtime_get_window_mgr ();
3358 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
3362 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3363 ModestMsgEditWindow *window)
3365 modest_msg_edit_window_select_font (window);
3369 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3370 const gchar *display_name,
3373 /* Do not change the application name if the widget has not
3374 the focus. This callback could be called even if the folder
3375 view has not the focus, because the handled signal could be
3376 emitted when the folder view is redrawn */
3377 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3379 gtk_window_set_title (window, display_name);
3381 gtk_window_set_title (window, " ");
3386 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3388 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3389 modest_msg_edit_window_select_contacts (window);
3393 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3395 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3396 modest_msg_edit_window_check_names (window, FALSE);
3400 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3402 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3403 GTK_WIDGET (user_data));
3407 create_move_to_dialog (GtkWindow *win,
3408 GtkWidget *folder_view,
3409 GtkWidget **tree_view)
3411 GtkWidget *dialog, *scroll;
3412 GtkWidget *new_button;
3414 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3416 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3419 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
3420 /* We do this manually so GTK+ does not associate a response ID for
3422 new_button = gtk_button_new_from_stock (GTK_STOCK_NEW);
3423 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3424 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
3426 /* Create scrolled window */
3427 scroll = gtk_scrolled_window_new (NULL, NULL);
3428 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3429 GTK_POLICY_AUTOMATIC,
3430 GTK_POLICY_AUTOMATIC);
3432 /* Create folder view */
3433 *tree_view = modest_platform_create_folder_view (NULL);
3434 /* *tree_view = modest_folder_view_new (NULL); */
3436 g_signal_connect (G_OBJECT (new_button), "clicked", G_CALLBACK(create_move_to_dialog_on_new_folder), *tree_view);
3438 /* It could happen that we're trying to move a message from a
3439 window (msg window for example) after the main window was
3440 closed, so we can not just get the model of the folder
3442 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
3443 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
3444 MODEST_FOLDER_VIEW(*tree_view));
3446 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3447 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3449 /* Hide special folders */
3450 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3452 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3454 /* Add scroll to dialog */
3455 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3456 scroll, TRUE, TRUE, 0);
3458 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3459 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3465 * Returns TRUE if at least one of the headers of the list belongs to
3466 * a message that has been fully retrieved.
3468 #if 0 /* no longer in use. delete in 2007.10 */
3470 has_retrieved_msgs (TnyList *list)
3473 gboolean found = FALSE;
3475 iter = tny_list_create_iterator (list);
3476 while (!tny_iterator_is_done (iter) && !found) {
3478 TnyHeaderFlags flags = 0;
3480 header = TNY_HEADER (tny_iterator_get_current (iter));
3482 flags = tny_header_get_flags (header);
3483 if (flags & TNY_HEADER_FLAG_CACHED)
3484 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3487 g_object_unref (header);
3491 tny_iterator_next (iter);
3493 g_object_unref (iter);
3501 * Shows a confirmation dialog to the user when we're moving messages
3502 * from a remote server to the local storage. Returns the dialog
3503 * response. If it's other kind of movement the it always returns
3507 msgs_move_to_confirmation (GtkWindow *win,
3508 TnyFolder *dest_folder,
3512 gint response = GTK_RESPONSE_OK;
3514 /* If the destination is a local folder (or MMC folder )*/
3515 if (!modest_tny_folder_is_remote_folder (dest_folder)) {
3520 TnyFolder *src_folder = NULL;
3521 TnyIterator *iter = NULL;
3522 TnyHeader *header = NULL;
3524 /* get the device */
3526 device = modest_runtime_get_device ();
3528 is_online = tny_device_is_online (device);
3530 g_warning ("failed to get tny device"); /* should not happend */
3534 /* Get source folder */
3535 iter = tny_list_create_iterator (headers);
3536 header = TNY_HEADER (tny_iterator_get_current (iter));
3538 src_folder = tny_header_get_folder (header);
3539 g_object_unref (header);
3542 g_object_unref (iter);
3544 /* if no src_folder, message may be an attahcment */
3545 if (src_folder == NULL)
3546 return GTK_RESPONSE_CANCEL;
3548 /* If the source is a remote folder */
3549 if (!is_online && modest_tny_folder_is_remote_folder (src_folder)) {
3551 const gchar *message = NULL;
3552 message = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs",
3553 tny_list_get_length (headers));
3554 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
3555 (const gchar *) message);
3557 response = GTK_RESPONSE_OK;
3559 g_object_unref (src_folder);
3568 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
3570 ModestMsgViewWindow *self = NULL;
3572 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
3573 self = MODEST_MSG_VIEW_WINDOW (object);
3575 if (!modest_msg_view_window_select_next_message (self))
3576 if (!modest_msg_view_window_select_previous_message (self))
3577 /* No more messages to view, so close this window */
3578 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3582 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3585 GObject *win = modest_mail_operation_get_source (mail_op);
3586 const GError *error = NULL;
3587 const gchar *message = NULL;
3589 /* Get error message */
3590 error = modest_mail_operation_get_error (mail_op);
3591 if (error != NULL && error->message != NULL) {
3592 message = error->message;
3594 message = _("mail_in_ui_folder_move_target_error");
3597 /* Show notification dialog */
3598 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3599 g_object_unref (win);
3603 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3606 GObject *win = modest_mail_operation_get_source (mail_op);
3607 const GError *error = modest_mail_operation_get_error (mail_op);
3609 g_return_if_fail (error != NULL);
3610 if (error->message != NULL)
3611 g_printerr ("modest: %s\n", error->message);
3613 g_printerr ("modest: unkonw error on send&receive operation");
3615 /* Show error message */
3616 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3617 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3618 /* _CS("sfil_ib_unable_to_receive")); */
3620 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3621 /* _CS("sfil_ib_unable_to_send")); */
3622 g_object_unref (win);
3626 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3633 gint pending_purges = 0;
3634 gboolean some_purged = FALSE;
3635 ModestWindow *win = MODEST_WINDOW (user_data);
3636 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3638 /* If there was any error */
3639 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
3640 modest_window_mgr_unregister_header (mgr, header);
3644 /* Once the message has been retrieved for purging, we check if
3645 * it's all ok for purging */
3647 parts = tny_simple_list_new ();
3648 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3649 iter = tny_list_create_iterator (parts);
3651 while (!tny_iterator_is_done (iter)) {
3653 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3654 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
3655 if (tny_mime_part_is_purged (part))
3662 g_object_unref (part);
3664 tny_iterator_next (iter);
3667 if (pending_purges>0) {
3669 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3671 if (response == GTK_RESPONSE_OK) {
3672 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3673 tny_iterator_first (iter);
3674 while (!tny_iterator_is_done (iter)) {
3677 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3678 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
3679 tny_mime_part_set_purged (part);
3682 g_object_unref (part);
3684 tny_iterator_next (iter);
3687 tny_msg_rewrite_cache (msg);
3690 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3693 /* remove attachments */
3694 tny_iterator_first (iter);
3695 while (!tny_iterator_is_done (iter)) {
3698 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3700 /* One for the reference given by tny_iterator_get_current(): */
3701 g_object_unref (part);
3703 /* TODO: Is this meant to remove the attachment by doing another unref()?
3704 * Otherwise, this seems useless. */
3707 tny_iterator_next (iter);
3709 modest_window_mgr_unregister_header (mgr, header);
3711 g_object_unref (iter);
3712 g_object_unref (parts);
3716 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3717 ModestMainWindow *win)
3719 GtkWidget *header_view;
3720 TnyList *header_list;
3723 TnyHeaderFlags flags;
3724 ModestWindow *msg_view_window = NULL;
3727 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3729 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3730 MODEST_WIDGET_TYPE_HEADER_VIEW);
3732 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3734 if (tny_list_get_length (header_list) == 1) {
3735 iter = tny_list_create_iterator (header_list);
3736 header = TNY_HEADER (tny_iterator_get_current (iter));
3737 g_object_unref (iter);
3742 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3743 header, &msg_view_window);
3744 flags = tny_header_get_flags (header);
3745 if (!(flags & TNY_HEADER_FLAG_CACHED))
3748 if (msg_view_window != NULL)
3749 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3751 /* do nothing; uid was registered before, so window is probably on it's way */
3752 g_warning ("debug: header %p has already been registered", header);
3755 ModestMailOperation *mail_op = NULL;
3756 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3757 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3759 modest_ui_actions_get_msgs_full_error_handler,
3761 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3762 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3764 g_object_unref (mail_op);
3767 g_object_unref (header);
3769 g_object_unref (header_list);
3773 * Utility function that transfer messages from both the main window
3774 * and the msg view window when using the "Move to" dialog
3777 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
3780 TnyList *headers = NULL;
3782 TnyAccount *dst_account = NULL;
3783 const gchar *proto_str = NULL;
3784 gboolean dst_is_pop = FALSE;
3786 if (!TNY_IS_FOLDER (dst_folder)) {
3787 modest_platform_information_banner (GTK_WIDGET (win),
3789 _CS("ckdg_ib_unable_to_move_to_current_location"));
3793 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
3794 proto_str = tny_account_get_proto (dst_account);
3796 /* tinymail will return NULL for local folders it seems */
3797 dst_is_pop = proto_str &&
3798 (modest_protocol_info_get_transport_store_protocol (proto_str) ==
3799 MODEST_PROTOCOL_STORE_POP);
3801 g_object_unref (dst_account);
3803 /* Get selected headers */
3804 headers = get_selected_headers (MODEST_WINDOW (win));
3807 modest_platform_information_banner (GTK_WIDGET (win),
3809 ngettext("mail_in_ui_folder_move_target_error",
3810 "mail_in_ui_folder_move_targets_error",
3811 tny_list_get_length (headers)));
3812 g_object_unref (headers);
3816 /* Ask for user confirmation */
3817 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3818 TNY_FOLDER (dst_folder),
3822 /* Transfer messages */
3823 if (response == GTK_RESPONSE_OK) {
3824 ModestMailOperation *mail_op =
3825 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3827 modest_ui_actions_move_folder_error_handler,
3829 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3832 modest_mail_operation_xfer_msgs (mail_op,
3834 TNY_FOLDER (dst_folder),
3836 (MODEST_IS_MSG_VIEW_WINDOW (win)) ? transfer_msgs_from_viewer_cb : NULL,
3839 g_object_unref (G_OBJECT (mail_op));
3841 g_object_unref (headers);
3845 * UI handler for the "Move to" action when invoked from the
3849 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3850 GtkWidget *folder_view,
3851 TnyFolderStore *dst_folder,
3852 ModestMainWindow *win)
3854 GtkWidget *header_view = NULL;
3855 ModestMailOperation *mail_op = NULL;
3856 TnyFolderStore *src_folder;
3858 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3860 /* Get the source folder */
3861 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3863 /* Offer the connection dialog if necessary, if the source folder is in a networked account: */
3864 if (!modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3868 /* Get header view */
3870 modest_main_window_get_child_widget (win, MODEST_WIDGET_TYPE_HEADER_VIEW);
3872 /* Get folder or messages to transfer */
3873 if (gtk_widget_is_focus (folder_view)) {
3875 /* Allow only to transfer folders to the local root folder */
3876 if (TNY_IS_ACCOUNT (dst_folder) &&
3877 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder))
3880 /* Clean folder on header view before moving it */
3881 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3883 if (TNY_IS_FOLDER (src_folder)) {
3885 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3887 modest_ui_actions_move_folder_error_handler,
3889 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3892 modest_mail_operation_xfer_folder (mail_op,
3893 TNY_FOLDER (src_folder),
3896 /* Unref mail operation */
3897 g_object_unref (G_OBJECT (mail_op));
3899 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
3901 } else if (gtk_widget_is_focus (header_view)) {
3902 /* Transfer messages */
3903 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3908 g_object_unref (src_folder);
3913 * UI handler for the "Move to" action when invoked from the
3914 * ModestMsgViewWindow
3917 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3918 TnyFolderStore *dst_folder,
3919 ModestMsgViewWindow *win)
3921 TnyHeader *header = NULL;
3922 TnyFolder *src_folder;
3924 /* Create header list */
3925 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3926 src_folder = tny_header_get_folder(header);
3927 g_object_unref (header);
3929 /* Transfer the message */
3930 if (modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (src_folder)))
3931 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3933 g_object_unref (src_folder);
3937 modest_ui_actions_on_move_to (GtkAction *action,
3940 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3942 TnyFolderStore *dst_folder = NULL;
3943 ModestMainWindow *main_window;
3945 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3946 MODEST_IS_MSG_VIEW_WINDOW (win));
3948 /* Get the main window if exists */
3949 if (MODEST_IS_MAIN_WINDOW (win))
3950 main_window = MODEST_MAIN_WINDOW (win);
3953 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3955 /* Get the folder view widget if exists */
3957 folder_view = modest_main_window_get_child_widget (main_window,
3958 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3962 /* Create and run the dialog */
3963 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
3964 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3965 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3966 result = gtk_dialog_run (GTK_DIALOG(dialog));
3967 g_object_ref (tree_view);
3968 gtk_widget_destroy (dialog);
3970 if (result != GTK_RESPONSE_ACCEPT)
3973 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3974 /* Offer the connection dialog if necessary: */
3975 if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3978 /* Do window specific stuff */
3979 if (MODEST_IS_MAIN_WINDOW (win))
3980 modest_ui_actions_on_main_window_move_to (action,
3983 MODEST_MAIN_WINDOW (win));
3985 modest_ui_actions_on_msg_view_window_move_to (action,
3987 MODEST_MSG_VIEW_WINDOW (win));
3990 g_object_unref (dst_folder);
3994 * Calls #HeadersFunc for each header already selected in the main
3995 * window or the message currently being shown in the msg view window
3998 do_headers_action (ModestWindow *win,
4002 TnyList *headers_list = NULL;
4003 TnyIterator *iter = NULL;
4004 TnyHeader *header = NULL;
4005 TnyFolder *folder = NULL;
4008 headers_list = get_selected_headers (win);
4012 /* Get the folder */
4013 iter = tny_list_create_iterator (headers_list);
4014 header = TNY_HEADER (tny_iterator_get_current (iter));
4016 folder = tny_header_get_folder (header);
4017 g_object_unref (header);
4020 /* Call the function for each header */
4021 while (!tny_iterator_is_done (iter)) {
4022 header = TNY_HEADER (tny_iterator_get_current (iter));
4023 func (header, win, user_data);
4024 g_object_unref (header);
4025 tny_iterator_next (iter);
4028 /* Trick: do a poke status in order to speed up the signaling
4030 tny_folder_poke_status (folder);
4033 g_object_unref (folder);
4034 g_object_unref (iter);
4035 g_object_unref (headers_list);
4039 modest_ui_actions_view_attachment (GtkAction *action,
4040 ModestWindow *window)
4042 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4043 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4045 /* not supported window for this action */
4046 g_return_if_reached ();
4051 modest_ui_actions_save_attachments (GtkAction *action,
4052 ModestWindow *window)
4054 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4055 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4057 /* not supported window for this action */
4058 g_return_if_reached ();
4063 modest_ui_actions_remove_attachments (GtkAction *action,
4064 ModestWindow *window)
4066 if (MODEST_IS_MAIN_WINDOW (window)) {
4067 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4068 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4069 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4071 /* not supported window for this action */
4072 g_return_if_reached ();
4077 modest_ui_actions_on_settings (GtkAction *action,
4082 dialog = modest_platform_get_global_settings_dialog ();
4083 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4084 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4085 gtk_widget_show_all (dialog);
4087 gtk_dialog_run (GTK_DIALOG (dialog));
4089 gtk_widget_destroy (dialog);
4093 modest_ui_actions_on_help (GtkAction *action,
4096 const gchar *help_id = NULL;
4098 if (MODEST_IS_MAIN_WINDOW (win)) {
4099 const gchar *action_name;
4100 action_name = gtk_action_get_name (action);
4102 if (!strcmp (action_name, "FolderViewCSMHelp") ||
4103 !strcmp (action_name, "HeaderViewCSMHelp")) {
4104 GtkWidget *folder_view;
4105 TnyFolderStore *folder_store;
4106 /* Get selected folder */
4107 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4108 MODEST_WIDGET_TYPE_FOLDER_VIEW);
4109 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4111 /* Switch help_id */
4112 if (TNY_IS_FOLDER (folder_store)) {
4113 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4114 case TNY_FOLDER_TYPE_NORMAL:
4115 help_id = "applications_email_managefolders";
4117 case TNY_FOLDER_TYPE_INBOX:
4118 help_id = "applications_email_inbox";
4120 case TNY_FOLDER_TYPE_OUTBOX:
4121 help_id = "applications_email_outbox";
4123 case TNY_FOLDER_TYPE_SENT:
4124 help_id = "applications_email_sent";
4126 case TNY_FOLDER_TYPE_DRAFTS:
4127 help_id = "applications_email_drafts";
4129 case TNY_FOLDER_TYPE_ARCHIVE:
4130 help_id = "applications_email_managefolders";
4133 help_id = "applications_email_managefolders";
4136 help_id = "applications_email_mainview";
4138 g_object_unref (folder_store);
4140 help_id = "applications_email_mainview";
4142 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4143 help_id = "applications_email_viewer";
4144 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4145 help_id = "applications_email_editor";
4147 modest_platform_show_help (GTK_WINDOW (win), help_id);
4151 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4152 ModestWindow *window)
4154 ModestMailOperation *mail_op;
4158 headers = get_selected_headers (window);
4162 /* Create mail operation */
4163 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4165 modest_ui_actions_get_msgs_full_error_handler,
4167 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4168 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4171 g_object_unref (headers);
4172 g_object_unref (mail_op);
4176 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4177 ModestWindow *window)
4179 g_return_if_fail (MODEST_IS_WINDOW (window));
4182 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4186 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4187 ModestWindow *window)
4189 g_return_if_fail (MODEST_IS_WINDOW (window));
4192 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4196 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4197 ModestWindow *window)
4199 g_return_if_fail (MODEST_IS_WINDOW (window));
4202 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4206 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4207 ModestWindow *window)
4209 g_return_if_fail (MODEST_IS_WINDOW (window));
4212 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4216 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4217 ModestWindow *window)
4219 g_return_if_fail (MODEST_IS_WINDOW (window));
4222 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4226 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4227 ModestWindow *window)
4229 g_return_if_fail (MODEST_IS_WINDOW (window));
4232 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4236 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4237 ModestWindow *window)
4239 g_return_if_fail (MODEST_IS_WINDOW (window));
4242 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4246 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4247 ModestWindow *window)
4249 g_return_if_fail (MODEST_IS_WINDOW (window));
4252 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4256 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4258 g_return_if_fail (MODEST_IS_WINDOW (window));
4261 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4265 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4267 g_return_if_fail (MODEST_IS_WINDOW (window));
4269 modest_platform_show_search_messages (GTK_WINDOW (window));
4273 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4275 g_return_if_fail (MODEST_IS_WINDOW (win));
4276 modest_platform_show_addressbook (GTK_WINDOW (win));
4281 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4282 ModestWindow *window)
4284 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4286 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4290 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
4291 ModestMailOperationState *state,
4294 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4296 /* Set send/receive operation finished */
4297 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4298 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));