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 printf("DEBUG: %s\n", __FUNCTION__);
407 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
411 if (response == GTK_RESPONSE_OK) {
412 ModestWindow *main_window = NULL;
413 ModestWindowMgr *mgr = NULL;
414 GtkTreeModel *model = NULL;
415 GtkTreeSelection *sel = NULL;
416 GList *sel_list = NULL, *tmp = NULL;
417 GtkTreeRowReference *row_reference = NULL;
418 GtkTreePath *next_path = NULL;
419 TnyFolder *folder = NULL;
422 /* Find last selected row */
423 if (MODEST_IS_MAIN_WINDOW (win)) {
424 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
425 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
426 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
427 for (tmp=sel_list; tmp; tmp=tmp->next) {
428 if (tmp->next == NULL) {
429 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
430 gtk_tree_path_next (next_path);
431 row_reference = gtk_tree_row_reference_new (model, next_path);
432 gtk_tree_path_free (next_path);
437 /* Remove each header. If it's a view window header_view == NULL */
438 do_headers_action (win, headers_action_delete, header_view);
440 /* refresh the header view (removing marked-as-deleted)*/
441 modest_header_view_refilter (MODEST_HEADER_VIEW(header_view));
443 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
444 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
446 /* Get main window */
447 mgr = modest_runtime_get_window_mgr ();
448 main_window = modest_window_mgr_get_main_window (mgr);
451 /* Move cursor to next row */
454 /* Select next row */
455 if (gtk_tree_row_reference_valid (row_reference)) {
456 next_path = gtk_tree_row_reference_get_path (row_reference);
457 gtk_tree_selection_select_path (sel, next_path);
458 gtk_tree_path_free (next_path);
460 if (row_reference != NULL)
461 gtk_tree_row_reference_free (row_reference);
464 /* Get folder from first header and sync it */
465 iter = tny_list_create_iterator (header_list);
466 header = TNY_HEADER (tny_iterator_get_current (iter));
467 folder = tny_header_get_folder (header);
468 if (TNY_IS_CAMEL_IMAP_FOLDER (folder))
469 /* tny_folder_sync_async(folder, FALSE, NULL, NULL, NULL); /\* FALSE --> don't expunge *\/ */
470 tny_folder_sync (folder, FALSE, &err); /* FALSE --> don't expunge */
471 else if (TNY_IS_CAMEL_POP_FOLDER (folder))
472 /* tny_folder_sync_async(folder, FALSE, NULL, NULL, NULL); /\* TRUE --> dont expunge *\/ */
473 tny_folder_sync (folder, TRUE, &err); /* TRUE --> expunge */
476 /* tny_folder_sync_async(folder, TRUE, NULL, NULL, NULL); /\* TRUE --> expunge *\/ */
477 tny_folder_sync (folder, TRUE, &err); /* TRUE --> expunge */
480 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, err->code, err->message);
484 g_object_unref (header);
485 g_object_unref (iter);
486 g_object_unref (folder);
488 /* Update toolbar dimming state */
489 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
492 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
493 g_list_free (sel_list);
499 g_object_unref (header_list);
505 /* delete either message or folder, based on where we are */
507 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
509 g_return_if_fail (MODEST_IS_WINDOW(win));
511 /* Check first if the header view has the focus */
512 if (MODEST_IS_MAIN_WINDOW (win)) {
514 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
515 MODEST_WIDGET_TYPE_FOLDER_VIEW);
516 if (gtk_widget_is_focus (w)) {
517 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
521 modest_ui_actions_on_delete_message (action, win);
527 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
529 #ifdef MODEST_PLATFORM_MAEMO
530 modest_osso_save_state();
531 #endif /* MODEST_PLATFORM_MAEMO */
533 g_debug ("closing down, clearing %d item(s) from operation queue",
534 modest_mail_operation_queue_num_elements
535 (modest_runtime_get_mail_operation_queue()));
537 /* cancel all outstanding operations */
538 modest_mail_operation_queue_cancel_all
539 (modest_runtime_get_mail_operation_queue());
541 g_debug ("queue has been cleared");
543 /* note: when modest-tny-account-store is finalized,
544 it will automatically set all network connections
551 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
555 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
557 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
558 /* gtk_widget_destroy (GTK_WIDGET (win)); */
559 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
560 /* gboolean ret_value; */
561 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
562 /* } else if (MODEST_IS_WINDOW (win)) { */
563 /* gtk_widget_destroy (GTK_WIDGET (win)); */
565 /* g_return_if_reached (); */
570 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
572 GtkClipboard *clipboard = NULL;
573 gchar *selection = NULL;
575 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
576 selection = gtk_clipboard_wait_for_text (clipboard);
578 /* Question: why is the clipboard being used here?
579 * It doesn't really make a lot of sense. */
583 modest_address_book_add_address (selection);
589 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
591 /* This is currently only implemented for Maemo */
592 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
593 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
594 modest_run_account_setup_wizard (win);
597 /* Show the list of accounts: */
598 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
599 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW (win));
601 /* Don't make this a modal window, because secondary windows will then
602 * be unusable, freezing the UI: */
603 /* gtk_window_set_modal (GTK_WINDOW (account_win), TRUE); */
604 modest_maemo_show_dialog_and_forget (GTK_WINDOW (win), account_win);
607 GtkWidget *dialog, *label;
609 /* Create the widgets */
611 dialog = gtk_dialog_new_with_buttons ("Message",
613 GTK_DIALOG_DESTROY_WITH_PARENT,
617 label = gtk_label_new ("Hello World!");
619 /* Ensure that the dialog box is destroyed when the user responds. */
621 g_signal_connect_swapped (dialog, "response",
622 G_CALLBACK (gtk_widget_destroy),
625 /* Add the label, and show everything we've added to the dialog. */
627 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
629 gtk_widget_show_all (dialog);
630 #endif /* MODEST_PLATFORM_MAEMO */
634 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
636 ModestWindow *main_window = MODEST_WINDOW (user_data);
638 /* Save any changes. */
639 modest_connection_specific_smtp_window_save_server_accounts (
640 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
641 modest_window_get_active_account (main_window));
642 gtk_widget_destroy (GTK_WIDGET (window));
648 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
650 /* This is currently only implemented for Maemo,
651 * because it requires an API (libconic) to detect different connection
654 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
656 /* Create the window if necessary: */
657 const gchar *active_account_name = modest_window_get_active_account (win);
659 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
660 * or show the default account?
661 * If we show the default account then the account name should be shown in
662 * the window when we show it. */
663 if (!active_account_name) {
664 g_warning ("%s: No account is active.", __FUNCTION__);
668 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
669 modest_connection_specific_smtp_window_fill_with_connections (
670 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
671 modest_runtime_get_account_mgr(),
672 active_account_name);
674 /* Show the window: */
675 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
676 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
677 gtk_widget_show (specific_window);
679 /* Save changes when the window is hidden: */
680 g_signal_connect (specific_window, "hide",
681 G_CALLBACK (on_smtp_servers_window_hide), win);
682 #endif /* MODEST_PLATFORM_MAEMO */
686 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
688 ModestWindow *msg_win = NULL;
690 TnyFolder *folder = NULL;
691 gchar *account_name = NULL;
692 gchar *from_str = NULL;
693 /* GError *err = NULL; */
694 TnyAccount *account = NULL;
695 ModestWindowMgr *mgr;
696 gchar *signature = NULL, *blank_and_signature = NULL;
698 /* if there are no accounts yet, just show the wizard */
699 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
700 const gboolean created = modest_run_account_setup_wizard (win);
705 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
707 account_name = g_strdup (modest_window_get_active_account (win));
709 g_printerr ("modest: no account found\n");
713 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
715 TNY_ACCOUNT_TYPE_STORE);
717 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
721 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
723 g_printerr ("modest: failed get from string for '%s'\n", account_name);
727 gboolean use_signature = FALSE;
728 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr (), account_name, &use_signature);
731 blank_and_signature = g_strconcat ("\n", signature, NULL);
733 blank_and_signature = g_strdup ("");
738 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
740 g_printerr ("modest: failed to create new msg\n");
744 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
746 g_printerr ("modest: failed to find Drafts folder\n");
751 /* Create and register edit window */
752 /* This is destroyed by TODO. */
753 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
754 mgr = modest_runtime_get_window_mgr ();
755 modest_window_mgr_register_window (mgr, msg_win);
758 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
760 gtk_widget_show_all (GTK_WIDGET (msg_win));
763 g_free (account_name);
765 g_free (blank_and_signature);
767 g_object_unref (msg_win);
769 g_object_unref (G_OBJECT(account));
771 g_object_unref (G_OBJECT(msg));
773 g_object_unref (G_OBJECT(folder));
777 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
781 ModestMailOperationStatus status;
783 /* If there is no message or the operation was not successful */
784 status = modest_mail_operation_get_status (mail_op);
785 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
787 /* Remove the header from the preregistered uids */
788 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
798 open_msg_cb (ModestMailOperation *mail_op,
803 ModestWindowMgr *mgr = NULL;
804 ModestWindow *parent_win = NULL;
805 ModestWindow *win = NULL;
806 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
807 gchar *account = NULL;
810 /* Do nothing if there was any problem with the mail
811 operation. The error will be shown by the error_handler of
812 the mail operation */
813 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
817 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
818 folder = tny_header_get_folder (header);
820 /* Mark header as read */
821 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
824 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
826 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
828 /* Gets folder type (OUTBOX headers will be opened in edit window */
829 if (modest_tny_folder_is_local_folder (folder))
830 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
832 /* If the header is in the drafts folder then open the editor,
833 else the message view window */
834 if ((folder_type == TNY_FOLDER_TYPE_DRAFTS) ||
835 (folder_type == TNY_FOLDER_TYPE_OUTBOX)) {
836 /* we cannot edit without a valid account... */
837 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
838 const gboolean created = modest_run_account_setup_wizard(parent_win);
842 win = modest_msg_edit_window_new (msg, account, TRUE);
845 gchar *uid = modest_tny_folder_get_header_unique_id (header);
847 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
848 GtkWidget *header_view;
849 GtkTreeSelection *sel;
850 GList *sel_list = NULL;
853 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
854 MODEST_WIDGET_TYPE_HEADER_VIEW);
856 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
857 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
859 if (sel_list != NULL) {
860 GtkTreeRowReference *row_reference;
862 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
863 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
864 g_list_free (sel_list);
866 win = modest_msg_view_window_new_with_header_model (
867 msg, account, (const gchar*) uid,
868 model, row_reference);
869 gtk_tree_row_reference_free (row_reference);
871 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
874 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
879 /* Register and show new window */
881 mgr = modest_runtime_get_window_mgr ();
882 modest_window_mgr_register_window (mgr, win);
883 g_object_unref (win);
884 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
885 gtk_widget_show_all (GTK_WIDGET(win));
888 /* Update toolbar dimming state */
889 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
890 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
896 g_object_unref (parent_win);
897 g_object_unref (folder);
901 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
905 GObject *win = modest_mail_operation_get_source (mail_op);
907 error = modest_mail_operation_get_error (mail_op);
908 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, error->code, error->message);
910 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
912 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
915 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
916 _("mail_ni_ui_folder_get_msg_folder_error"));
920 g_object_unref (win);
924 * This function is used by both modest_ui_actions_on_open and
925 * modest_ui_actions_on_header_activated. This way we always do the
926 * same when trying to open messages.
929 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
931 ModestWindowMgr *mgr = NULL;
932 TnyIterator *iter = NULL;
933 ModestMailOperation *mail_op = NULL;
934 TnyList *not_opened_headers = NULL;
935 TnyHeaderFlags flags = 0;
937 /* Look if we already have a message view for each header. If
938 true, then remove the header from the list of headers to
940 mgr = modest_runtime_get_window_mgr ();
941 iter = tny_list_create_iterator (headers);
942 not_opened_headers = tny_simple_list_new ();
944 while (!tny_iterator_is_done (iter)) {
946 ModestWindow *window = NULL;
947 TnyHeader *header = NULL;
948 gboolean found = FALSE;
950 header = TNY_HEADER (tny_iterator_get_current (iter));
952 flags = tny_header_get_flags (header);
955 found = modest_window_mgr_find_registered_header (mgr, header, &window);
957 /* Do not open again the message and present the
958 window to the user */
961 gtk_window_present (GTK_WINDOW (window));
963 /* the header has been registered already, we don't do
964 * anything but wait for the window to come up*/
965 g_debug ("header %p already registered, waiting for window", header);
967 tny_list_append (not_opened_headers, G_OBJECT (header));
971 g_object_unref (header);
973 tny_iterator_next (iter);
975 g_object_unref (iter);
978 /* If some messages would have to be downloaded, ask the user to
979 * make a connection. It's generally easier to do this here (in the mainloop)
980 * than later in a thread:
982 if (tny_list_get_length (not_opened_headers) > 0) {
984 gboolean found = FALSE;
986 iter = tny_list_create_iterator (not_opened_headers);
987 while (!tny_iterator_is_done (iter) && !found) {
988 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
989 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
992 tny_iterator_next (iter);
994 g_object_unref (header);
996 g_object_unref (iter);
998 if (found && !modest_platform_connect_and_wait (GTK_WINDOW (win), NULL)) {
999 g_object_unref (not_opened_headers);
1004 /* Register the headers before actually creating the windows: */
1005 TnyIterator *iter_not_opened = tny_list_create_iterator (not_opened_headers);
1006 while (!tny_iterator_is_done (iter_not_opened)) {
1007 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1009 modest_window_mgr_register_header (mgr, header);
1010 g_object_unref (header);
1013 tny_iterator_next (iter_not_opened);
1015 g_object_unref (iter_not_opened);
1016 iter_not_opened = NULL;
1018 /* Open each message */
1019 if (tny_list_get_length (not_opened_headers) > 0) {
1020 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1022 modest_ui_actions_get_msgs_full_error_handler,
1024 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1025 if (tny_list_get_length (not_opened_headers) > 1) {
1026 modest_mail_operation_get_msgs_full (mail_op,
1032 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1033 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1034 modest_mail_operation_get_msg (mail_op, header, open_msg_cb, NULL);
1035 g_object_unref (header);
1036 g_object_unref (iter);
1038 g_object_unref (mail_op);
1042 if (not_opened_headers != NULL)
1043 g_object_unref (not_opened_headers);
1047 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1052 headers = get_selected_headers (win);
1057 _modest_ui_actions_open (headers, win);
1059 g_object_unref(headers);
1064 free_reply_forward_helper (gpointer data)
1066 ReplyForwardHelper *helper;
1068 helper = (ReplyForwardHelper *) data;
1069 g_free (helper->account_name);
1070 g_slice_free (ReplyForwardHelper, helper);
1074 reply_forward_cb (ModestMailOperation *mail_op,
1080 ReplyForwardHelper *rf_helper;
1081 ModestWindow *msg_win = NULL;
1082 ModestEditType edit_type;
1084 TnyAccount *account = NULL;
1085 ModestWindowMgr *mgr = NULL;
1086 gchar *signature = NULL;
1088 /* If there was any error. The mail operation could be NULL,
1089 this means that we already have the message downloaded and
1090 that we didn't do a mail operation to retrieve it */
1091 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1094 g_return_if_fail (user_data != NULL);
1095 rf_helper = (ReplyForwardHelper *) user_data;
1097 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1098 rf_helper->account_name);
1099 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
1100 rf_helper->account_name,
1101 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
1102 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
1103 rf_helper->account_name,
1104 MODEST_ACCOUNT_SIGNATURE, FALSE);
1107 /* Create reply mail */
1108 switch (rf_helper->action) {
1111 modest_tny_msg_create_reply_msg (msg, header, from, signature,
1112 rf_helper->reply_forward_type,
1113 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1115 case ACTION_REPLY_TO_ALL:
1117 modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1118 MODEST_TNY_MSG_REPLY_MODE_ALL);
1119 edit_type = MODEST_EDIT_TYPE_REPLY;
1121 case ACTION_FORWARD:
1123 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1124 edit_type = MODEST_EDIT_TYPE_FORWARD;
1127 g_return_if_reached ();
1134 g_printerr ("modest: failed to create message\n");
1138 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1139 rf_helper->account_name,
1140 TNY_ACCOUNT_TYPE_STORE);
1142 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1146 /* Create and register the windows */
1147 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1148 mgr = modest_runtime_get_window_mgr ();
1149 modest_window_mgr_register_window (mgr, msg_win);
1151 if (rf_helper->parent_window != NULL) {
1152 gdouble parent_zoom;
1154 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1155 modest_window_set_zoom (msg_win, parent_zoom);
1158 /* Show edit window */
1159 gtk_widget_show_all (GTK_WIDGET (msg_win));
1163 g_object_unref (msg_win);
1165 g_object_unref (G_OBJECT (new_msg));
1167 g_object_unref (G_OBJECT (account));
1168 /* g_object_unref (msg); */
1169 free_reply_forward_helper (rf_helper);
1173 * Checks a list of headers. If any of them are not currently
1174 * downloaded (CACHED) then it asks the user for permission to
1177 * Returns FALSE if the user does not want to download the
1178 * messages. Returns TRUE if the user allowed the download or if all
1179 * of them are currently downloaded
1182 download_uncached_messages (TnyList *header_list,
1187 gint uncached_messages = 0;
1189 iter = tny_list_create_iterator (header_list);
1190 while (!tny_iterator_is_done (iter)) {
1193 header = TNY_HEADER (tny_iterator_get_current (iter));
1195 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1196 uncached_messages ++;
1197 g_object_unref (header);
1200 tny_iterator_next (iter);
1202 g_object_unref (iter);
1204 /* Ask for user permission to download the messages */
1206 if (uncached_messages > 0) {
1207 gboolean download = TRUE;
1208 if (!tny_device_is_online (modest_runtime_get_device())) {
1209 GtkResponseType response =
1210 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1211 ngettext("mcen_nc_get_msg",
1213 uncached_messages));
1214 if (response == GTK_RESPONSE_CANCEL) download = FALSE;
1217 /* If a download will be necessary, make sure that we have a connection: */
1218 retval = modest_platform_connect_and_wait(win, NULL);
1228 * Common code for the reply and forward actions
1231 reply_forward (ReplyForwardAction action, ModestWindow *win)
1233 ModestMailOperation *mail_op = NULL;
1234 TnyList *header_list = NULL;
1235 ReplyForwardHelper *rf_helper = NULL;
1236 guint reply_forward_type;
1237 gboolean continue_download = TRUE;
1238 gboolean do_retrieve = TRUE;
1240 g_return_if_fail (MODEST_IS_WINDOW(win));
1242 /* we need an account when editing */
1243 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1244 const gboolean created = modest_run_account_setup_wizard (win);
1249 header_list = get_selected_headers (win);
1253 reply_forward_type =
1254 modest_conf_get_int (modest_runtime_get_conf (),
1255 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1258 /* Check that the messages have been previously downloaded */
1259 do_retrieve = (action == ACTION_FORWARD) || (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1261 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
1262 if (!continue_download) {
1263 g_object_unref (header_list);
1267 /* We assume that we can only select messages of the
1268 same folder and that we reply all of them from the
1269 same account. In fact the interface currently only
1270 allows single selection */
1273 rf_helper = g_slice_new0 (ReplyForwardHelper);
1274 rf_helper->reply_forward_type = reply_forward_type;
1275 rf_helper->action = action;
1276 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1278 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1279 rf_helper->parent_window = GTK_WIDGET (win);
1280 if (!rf_helper->account_name)
1281 rf_helper->account_name =
1282 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1284 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1287 /* Get header and message. Do not free them here, the
1288 reply_forward_cb must do it */
1289 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1290 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1291 if (!msg || !header) {
1293 g_object_unref (msg);
1294 g_printerr ("modest: no message found\n");
1297 reply_forward_cb (NULL, header, msg, rf_helper);
1300 g_object_unref (header);
1305 /* Only reply/forward to one message */
1306 iter = tny_list_create_iterator (header_list);
1307 header = TNY_HEADER (tny_iterator_get_current (iter));
1308 g_object_unref (iter);
1311 /* Retrieve messages */
1313 mail_op = modest_mail_operation_new_with_error_handling (
1314 MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1316 modest_ui_actions_get_msgs_full_error_handler,
1318 modest_mail_operation_queue_add (
1319 modest_runtime_get_mail_operation_queue (), mail_op);
1321 modest_mail_operation_get_msg (mail_op,
1326 g_object_unref(mail_op);
1328 /* we put a ref here to prevent double unref as the reply
1329 * forward callback unrefs the header at its end */
1330 reply_forward_cb (NULL, header, NULL, rf_helper);
1334 g_object_unref (header);
1340 g_object_unref (header_list);
1344 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1346 g_return_if_fail (MODEST_IS_WINDOW(win));
1348 reply_forward (ACTION_REPLY, win);
1352 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1354 g_return_if_fail (MODEST_IS_WINDOW(win));
1356 reply_forward (ACTION_FORWARD, win);
1360 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1362 g_return_if_fail (MODEST_IS_WINDOW(win));
1364 reply_forward (ACTION_REPLY_TO_ALL, win);
1368 modest_ui_actions_on_next (GtkAction *action,
1369 ModestWindow *window)
1371 if (MODEST_IS_MAIN_WINDOW (window)) {
1372 GtkWidget *header_view;
1374 header_view = modest_main_window_get_child_widget (
1375 MODEST_MAIN_WINDOW(window),
1376 MODEST_WIDGET_TYPE_HEADER_VIEW);
1380 modest_header_view_select_next (
1381 MODEST_HEADER_VIEW(header_view));
1382 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1383 modest_msg_view_window_select_next_message (
1384 MODEST_MSG_VIEW_WINDOW (window));
1386 g_return_if_reached ();
1391 modest_ui_actions_on_prev (GtkAction *action,
1392 ModestWindow *window)
1394 g_return_if_fail (MODEST_IS_WINDOW(window));
1396 if (MODEST_IS_MAIN_WINDOW (window)) {
1397 GtkWidget *header_view;
1398 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1399 MODEST_WIDGET_TYPE_HEADER_VIEW);
1403 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1404 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1405 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1407 g_return_if_reached ();
1412 modest_ui_actions_on_sort (GtkAction *action,
1413 ModestWindow *window)
1415 g_return_if_fail (MODEST_IS_WINDOW(window));
1417 if (MODEST_IS_MAIN_WINDOW (window)) {
1418 GtkWidget *header_view;
1419 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1420 MODEST_WIDGET_TYPE_HEADER_VIEW);
1422 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1427 /* Show sorting dialog */
1428 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1433 new_messages_arrived (ModestMailOperation *self,
1437 ModestMainWindow *win = NULL;
1438 GtkWidget *folder_view = NULL;
1439 TnyFolderStore *folder = NULL;
1440 gboolean folder_empty = FALSE;
1442 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
1443 win = MODEST_MAIN_WINDOW (user_data);
1445 /* Set contents style of headers view */
1446 if (modest_main_window_get_contents_style (win) == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1447 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1448 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1449 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1452 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1455 modest_main_window_set_contents_style (win,
1456 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1459 /* Notify new messages have been downloaded */
1460 if (new_messages > 0)
1461 modest_platform_on_new_msg ();
1465 * This function performs the send & receive required actions. The
1466 * window is used to create the mail operation. Typically it should
1467 * always be the main window, but we pass it as argument in order to
1471 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1473 gchar *acc_name = NULL;
1474 ModestMailOperation *mail_op;
1476 /* If no account name was provided then get the current account, and if
1477 there is no current account then pick the default one: */
1478 if (!account_name) {
1479 acc_name = g_strdup (modest_window_get_active_account(win));
1481 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1483 g_printerr ("modest: cannot get default account\n");
1487 acc_name = g_strdup (account_name);
1490 /* Set send/receive operation in progress */
1491 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1493 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1495 modest_ui_actions_send_receive_error_handler,
1498 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1499 G_CALLBACK (_on_send_receive_progress_changed),
1502 /* Send & receive. */
1503 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1504 /* Receive and then send. The operation is tagged initially as
1505 a receive operation because the account update performs a
1506 receive and then a send. The operation changes its type
1507 internally, so the progress objects will receive the proper
1508 progress information */
1509 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1510 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, win);
1511 g_object_unref (G_OBJECT (mail_op));
1519 modest_ui_actions_do_cancel_send (const gchar *account_name,
1522 TnyTransportAccount *transport_account;
1523 TnySendQueue *send_queue = NULL;
1524 GError *error = NULL;
1526 /* Get transport account */
1528 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1529 (modest_runtime_get_account_store(),
1531 TNY_ACCOUNT_TYPE_TRANSPORT));
1532 if (!transport_account) {
1533 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1538 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1539 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1540 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1541 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1542 "modest: could not find send queue for account\n");
1544 /* Keeep messages in outbox folder */
1545 tny_send_queue_cancel (send_queue, FALSE, &error);
1549 if (transport_account != NULL)
1550 g_object_unref (G_OBJECT (transport_account));
1554 modest_ui_actions_cancel_send_all (ModestWindow *win)
1556 GSList *account_names, *iter;
1558 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1561 iter = account_names;
1563 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1564 iter = g_slist_next (iter);
1567 modest_account_mgr_free_account_names (account_names);
1568 account_names = NULL;
1572 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1575 /* Check if accounts exist */
1576 gboolean accounts_exist =
1577 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1579 /* If not, allow the user to create an account before trying to send/receive. */
1580 if (!accounts_exist)
1581 modest_ui_actions_on_accounts (NULL, win);
1583 /* Cancel all sending operaitons */
1584 modest_ui_actions_cancel_send_all (win);
1588 * Refreshes all accounts. This function will be used by automatic
1592 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1594 GSList *account_names, *iter;
1596 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1599 iter = account_names;
1601 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1602 iter = g_slist_next (iter);
1605 modest_account_mgr_free_account_names (account_names);
1606 account_names = NULL;
1610 modest_do_refresh_current_folder(ModestWindow *win)
1612 /* Refresh currently selected folder. Note that if we only
1613 want to retreive the headers, then the refresh only will
1614 invoke a poke_status over all folders, i.e., only the
1615 total/unread count will be updated */
1616 if (MODEST_IS_MAIN_WINDOW (win)) {
1617 GtkWidget *header_view, *folder_view;
1618 TnyFolderStore *folder_store;
1620 /* Get folder and header view */
1622 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1623 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1625 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1627 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1629 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1630 MODEST_WIDGET_TYPE_HEADER_VIEW);
1632 /* We do not need to set the contents style
1633 because it hasn't changed. We also do not
1634 need to save the widget status. Just force
1636 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1637 TNY_FOLDER (folder_store),
1638 folder_refreshed_cb,
1639 MODEST_MAIN_WINDOW (win));
1643 g_object_unref (folder_store);
1649 * Handler of the click on Send&Receive button in the main toolbar
1652 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1654 /* Check if accounts exist */
1655 gboolean accounts_exist =
1656 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1658 /* If not, allow the user to create an account before trying to send/receive. */
1659 if (!accounts_exist)
1660 modest_ui_actions_on_accounts (NULL, win);
1662 modest_do_refresh_current_folder (win);
1664 /* Refresh the active account */
1665 modest_ui_actions_do_send_receive (NULL, win);
1670 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1673 GtkWidget *header_view;
1675 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1677 header_view = modest_main_window_get_child_widget (main_window,
1678 MODEST_WIDGET_TYPE_HEADER_VIEW);
1682 conf = modest_runtime_get_conf ();
1684 /* what is saved/restored is depending on the style; thus; we save with
1685 * old style, then update the style, and restore for this new style
1687 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1689 if (modest_header_view_get_style
1690 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1691 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1692 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1694 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1695 MODEST_HEADER_VIEW_STYLE_DETAILS);
1697 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1698 MODEST_CONF_HEADER_VIEW_KEY);
1703 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1705 ModestMainWindow *main_window)
1707 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1708 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1710 /* in the case the folder is empty, show the empty folder message and focus
1712 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1713 if (modest_header_view_is_empty (header_view)) {
1714 TnyFolder *folder = modest_header_view_get_folder (header_view);
1715 GtkWidget *folder_view =
1716 modest_main_window_get_child_widget (main_window,
1717 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1719 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1720 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1724 /* If no header has been selected then exit */
1729 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1730 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1732 /* Update toolbar dimming state */
1733 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1737 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1739 ModestMainWindow *main_window)
1743 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1748 headers = tny_simple_list_new ();
1749 tny_list_prepend (headers, G_OBJECT (header));
1751 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1753 g_object_unref (headers);
1757 set_active_account_from_tny_account (TnyAccount *account,
1758 ModestWindow *window)
1760 const gchar *server_acc_name = tny_account_get_id (account);
1762 /* We need the TnyAccount provided by the
1763 account store because that is the one that
1764 knows the name of the Modest account */
1765 TnyAccount *modest_server_account = modest_server_account =
1766 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1767 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1770 const gchar *modest_acc_name =
1771 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1772 modest_window_set_active_account (window, modest_acc_name);
1773 g_object_unref (modest_server_account);
1778 folder_refreshed_cb (ModestMailOperation *mail_op,
1782 ModestMainWindow *win = NULL;
1783 GtkWidget *header_view;
1784 TnyFolder *current_folder;
1785 gboolean folder_empty = FALSE;
1786 gboolean all_marked_as_deleted = FALSE;
1788 g_return_if_fail (TNY_IS_FOLDER (folder));
1790 win = MODEST_MAIN_WINDOW (user_data);
1792 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1795 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1796 if (current_folder != NULL && folder != current_folder) {
1801 /* Check if folder is empty and set headers view contents style */
1802 folder_empty = (tny_folder_get_all_count (folder) == 0);
1803 all_marked_as_deleted = modest_header_view_is_empty (MODEST_HEADER_VIEW(header_view));
1804 folder_empty = folder_empty || all_marked_as_deleted ;
1807 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1808 modest_main_window_set_contents_style (win,
1809 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1811 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1816 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1817 TnyFolderStore *folder_store,
1819 ModestMainWindow *main_window)
1822 GtkWidget *header_view;
1824 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1826 header_view = modest_main_window_get_child_widget(main_window,
1827 MODEST_WIDGET_TYPE_HEADER_VIEW);
1831 conf = modest_runtime_get_conf ();
1833 if (TNY_IS_ACCOUNT (folder_store)) {
1835 /* Update active account */
1836 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1837 /* Show account details */
1838 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1841 if (TNY_IS_FOLDER (folder_store) && selected) {
1843 /* Update the active account */
1844 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1846 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1847 g_object_unref (account);
1851 /* Set the header style by default, it could
1852 be changed later by the refresh callback to
1854 modest_main_window_set_contents_style (main_window,
1855 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1857 /* Set folder on header view. This function
1858 will call tny_folder_refresh_async so we
1859 pass a callback that will be called when
1860 finished. We use that callback to set the
1861 empty view if there are no messages */
1862 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1863 TNY_FOLDER (folder_store),
1864 folder_refreshed_cb,
1867 /* Restore configuration. We need to do this
1868 *after* the set_folder because the widget
1869 memory asks the header view about its
1871 modest_widget_memory_restore (modest_runtime_get_conf (),
1872 G_OBJECT(header_view),
1873 MODEST_CONF_HEADER_VIEW_KEY);
1875 /* Update the active account */
1876 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1877 /* Save only if we're seeing headers */
1878 if (modest_main_window_get_contents_style (main_window) ==
1879 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1880 modest_widget_memory_save (conf, G_OBJECT (header_view),
1881 MODEST_CONF_HEADER_VIEW_KEY);
1882 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1886 /* Update toolbar dimming state */
1887 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1891 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1898 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1900 online = tny_device_is_online (modest_runtime_get_device());
1903 /* already online -- the item is simply not there... */
1904 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1906 GTK_MESSAGE_WARNING,
1908 _("The %s you selected cannot be found"),
1910 gtk_dialog_run (GTK_DIALOG(dialog));
1912 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1916 GTK_RESPONSE_REJECT,
1918 GTK_RESPONSE_ACCEPT,
1920 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1921 "Do you want to get online?"), item);
1922 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1923 gtk_label_new (txt), FALSE, FALSE, 0);
1924 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1927 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1928 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1929 /* TODO: Comment about why is this commented out: */
1930 /* modest_platform_connect_and_wait (); */
1933 gtk_widget_destroy (dialog);
1937 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1940 /* g_message ("%s %s", __FUNCTION__, link); */
1945 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1948 modest_platform_activate_uri (link);
1952 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1955 modest_platform_show_uri_popup (link);
1959 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1962 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1966 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1967 const gchar *address,
1970 /* g_message ("%s %s", __FUNCTION__, address); */
1974 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1976 TnyTransportAccount *transport_account;
1977 ModestMailOperation *mail_operation;
1979 gchar *account_name, *from;
1980 ModestAccountMgr *account_mgr;
1981 gchar *info_text = NULL;
1983 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1985 data = modest_msg_edit_window_get_msg_data (edit_window);
1987 account_mgr = modest_runtime_get_account_mgr();
1988 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1990 account_name = modest_account_mgr_get_default_account (account_mgr);
1991 if (!account_name) {
1992 g_printerr ("modest: no account found\n");
1993 modest_msg_edit_window_free_msg_data (edit_window, data);
1997 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1998 account_name = g_strdup (data->account_name);
2002 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2003 (modest_runtime_get_account_store(),
2005 TNY_ACCOUNT_TYPE_TRANSPORT));
2006 if (!transport_account) {
2007 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2008 g_free (account_name);
2009 modest_msg_edit_window_free_msg_data (edit_window, data);
2012 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2014 /* Create the mail operation */
2015 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
2016 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2018 modest_mail_operation_save_to_drafts (mail_operation,
2030 data->priority_flags);
2033 g_free (account_name);
2034 g_object_unref (G_OBJECT (transport_account));
2035 g_object_unref (G_OBJECT (mail_operation));
2037 modest_msg_edit_window_free_msg_data (edit_window, data);
2039 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2040 modest_platform_information_banner (NULL, NULL, info_text);
2044 /* For instance, when clicking the Send toolbar button when editing a message: */
2046 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2048 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2050 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2053 /* Offer the connection dialog, if necessary: */
2054 if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
2057 /* FIXME: Code added just for testing. The final version will
2058 use the send queue provided by tinymail and some
2060 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2061 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2063 account_name = modest_account_mgr_get_default_account (account_mgr);
2065 if (!account_name) {
2066 /* Run account setup wizard */
2067 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2072 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2074 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2075 account_name = g_strdup (data->account_name);
2078 /* Get the currently-active transport account for this modest account: */
2079 TnyTransportAccount *transport_account =
2080 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2081 (modest_runtime_get_account_store(),
2083 if (!transport_account) {
2084 /* Run account setup wizard */
2085 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2090 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2092 /* modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent")); */
2094 /* Create the mail operation */
2095 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
2096 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2098 modest_mail_operation_send_new_mail (mail_operation,
2109 data->priority_flags);
2113 g_free (account_name);
2114 g_object_unref (G_OBJECT (transport_account));
2115 g_object_unref (G_OBJECT (mail_operation));
2117 modest_msg_edit_window_free_msg_data (edit_window, data);
2118 modest_msg_edit_window_set_sent (edit_window, TRUE);
2120 /* Save settings and close the window: */
2121 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2125 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2126 ModestMsgEditWindow *window)
2128 ModestMsgEditFormatState *format_state = NULL;
2130 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2131 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2133 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2136 format_state = modest_msg_edit_window_get_format_state (window);
2137 g_return_if_fail (format_state != NULL);
2139 format_state->bold = gtk_toggle_action_get_active (action);
2140 modest_msg_edit_window_set_format_state (window, format_state);
2141 g_free (format_state);
2146 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2147 ModestMsgEditWindow *window)
2149 ModestMsgEditFormatState *format_state = NULL;
2151 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2152 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2154 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2157 format_state = modest_msg_edit_window_get_format_state (window);
2158 g_return_if_fail (format_state != NULL);
2160 format_state->italics = gtk_toggle_action_get_active (action);
2161 modest_msg_edit_window_set_format_state (window, format_state);
2162 g_free (format_state);
2167 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2168 ModestMsgEditWindow *window)
2170 ModestMsgEditFormatState *format_state = NULL;
2172 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2173 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2175 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2178 format_state = modest_msg_edit_window_get_format_state (window);
2179 g_return_if_fail (format_state != NULL);
2181 format_state->bullet = gtk_toggle_action_get_active (action);
2182 modest_msg_edit_window_set_format_state (window, format_state);
2183 g_free (format_state);
2188 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2189 GtkRadioAction *selected,
2190 ModestMsgEditWindow *window)
2192 ModestMsgEditFormatState *format_state = NULL;
2193 GtkJustification value;
2195 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2197 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2200 value = gtk_radio_action_get_current_value (selected);
2202 format_state = modest_msg_edit_window_get_format_state (window);
2203 g_return_if_fail (format_state != NULL);
2205 format_state->justification = value;
2206 modest_msg_edit_window_set_format_state (window, format_state);
2207 g_free (format_state);
2211 modest_ui_actions_on_select_editor_color (GtkAction *action,
2212 ModestMsgEditWindow *window)
2214 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2215 g_return_if_fail (GTK_IS_ACTION (action));
2217 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2220 modest_msg_edit_window_select_color (window);
2224 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2225 ModestMsgEditWindow *window)
2227 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2228 g_return_if_fail (GTK_IS_ACTION (action));
2230 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2233 modest_msg_edit_window_select_background_color (window);
2237 modest_ui_actions_on_insert_image (GtkAction *action,
2238 ModestMsgEditWindow *window)
2240 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2241 g_return_if_fail (GTK_IS_ACTION (action));
2243 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2246 modest_msg_edit_window_insert_image (window);
2250 modest_ui_actions_on_attach_file (GtkAction *action,
2251 ModestMsgEditWindow *window)
2253 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2254 g_return_if_fail (GTK_IS_ACTION (action));
2256 modest_msg_edit_window_offer_attach_file (window);
2260 modest_ui_actions_on_remove_attachments (GtkAction *action,
2261 ModestMsgEditWindow *window)
2263 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2264 g_return_if_fail (GTK_IS_ACTION (action));
2266 modest_msg_edit_window_remove_attachments (window, NULL);
2270 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2273 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2274 const GError *error = modest_mail_operation_get_error (mail_op);
2278 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2279 modest_mail_operation_get_error (mail_op)->message);
2284 modest_ui_actions_create_folder(GtkWidget *parent_window,
2285 GtkWidget *folder_view)
2287 TnyFolderStore *parent_folder;
2289 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2291 if (parent_folder) {
2292 gboolean finished = FALSE;
2294 gchar *folder_name = NULL, *suggested_name = NULL;
2295 const gchar *proto_str = NULL;
2296 TnyAccount *account;
2298 if (TNY_IS_ACCOUNT (parent_folder))
2299 account = g_object_ref (parent_folder);
2301 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2302 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2304 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2305 MODEST_PROTOCOL_STORE_POP) {
2307 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2309 g_object_unref (account);
2311 /* Run the new folder dialog */
2313 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2318 g_free (suggested_name);
2319 suggested_name = NULL;
2321 if (result == GTK_RESPONSE_REJECT) {
2324 ModestMailOperation *mail_op;
2325 TnyFolder *new_folder = NULL;
2327 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2328 G_OBJECT(parent_window),
2329 modest_ui_actions_new_folder_error_handler,
2332 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2334 new_folder = modest_mail_operation_create_folder (mail_op,
2336 (const gchar *) folder_name);
2338 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2341 g_object_unref (new_folder);
2344 g_object_unref (mail_op);
2347 suggested_name = folder_name;
2351 g_object_unref (parent_folder);
2356 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2358 GtkWidget *folder_view;
2360 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2362 folder_view = modest_main_window_get_child_widget (main_window,
2363 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2367 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2371 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2374 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2375 const GError *error = NULL;
2376 const gchar *message = NULL;
2378 /* Get error message */
2379 error = modest_mail_operation_get_error (mail_op);
2380 if (error != NULL && error->message != NULL) {
2381 message = error->message;
2383 message = _("!!! FIXME: Unable to rename");
2386 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2391 modest_ui_actions_on_rename_folder (GtkAction *action,
2392 ModestMainWindow *main_window)
2394 TnyFolderStore *folder;
2395 GtkWidget *folder_view;
2396 GtkWidget *header_view;
2398 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2400 folder_view = modest_main_window_get_child_widget (main_window,
2401 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2405 header_view = modest_main_window_get_child_widget (main_window,
2406 MODEST_WIDGET_TYPE_HEADER_VIEW);
2411 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2415 /* Offer the connection dialog if necessary: */
2416 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2417 g_object_unref (G_OBJECT (folder));
2422 if (TNY_IS_FOLDER (folder)) {
2425 const gchar *current_name;
2427 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2428 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
2429 current_name, &folder_name);
2431 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
2432 ModestMailOperation *mail_op;
2435 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2436 G_OBJECT(main_window),
2437 modest_ui_actions_rename_folder_error_handler,
2441 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2444 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2446 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2447 TNY_FOLDER(folder), TRUE);
2449 modest_header_view_clear ((ModestHeaderView *) header_view);
2451 modest_mail_operation_rename_folder (mail_op,
2452 TNY_FOLDER (folder),
2453 (const gchar *) folder_name);
2455 g_object_unref (mail_op);
2456 g_free (folder_name);
2459 g_object_unref (folder);
2463 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2466 GObject *win = modest_mail_operation_get_source (mail_op);
2468 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2469 _("mail_in_ui_folder_delete_error"));
2470 g_object_unref (win);
2474 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2476 TnyFolderStore *folder;
2477 GtkWidget *folder_view;
2481 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
2483 folder_view = modest_main_window_get_child_widget (main_window,
2484 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2488 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2490 /* Show an error if it's an account */
2491 if (!TNY_IS_FOLDER (folder)) {
2492 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2493 _("mail_in_ui_folder_delete_error"));
2494 g_object_unref (G_OBJECT (folder));
2498 /* Offer the connection dialog if necessary: */
2499 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2500 g_object_unref (G_OBJECT (folder));
2505 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2506 tny_folder_get_name (TNY_FOLDER (folder)));
2507 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2508 (const gchar *) message);
2511 if (response == GTK_RESPONSE_OK) {
2512 ModestMailOperation *mail_op =
2513 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2514 G_OBJECT(main_window),
2515 modest_ui_actions_delete_folder_error_handler,
2518 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2520 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2521 g_object_unref (G_OBJECT (mail_op));
2524 g_object_unref (G_OBJECT (folder));
2528 modest_ui_actions_on_delete_folder (GtkAction *action,
2529 ModestMainWindow *main_window)
2531 GtkWidget *folder_view;
2532 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2534 delete_folder (main_window, FALSE);
2535 folder_view = modest_main_window_get_child_widget (main_window,
2536 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2539 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2543 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2545 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2547 delete_folder (main_window, TRUE);
2552 show_error (GtkWidget *parent_widget, const gchar* text)
2554 hildon_banner_show_information(parent_widget, NULL, text);
2557 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2559 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2566 gtk_dialog_run (dialog);
2567 gtk_widget_destroy (GTK_WIDGET (dialog));
2572 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2573 const gchar* server_account_name,
2578 ModestMainWindow *main_window)
2580 g_return_if_fail(server_account_name);
2581 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2583 /* Initalize output parameters: */
2590 #ifdef MODEST_PLATFORM_MAEMO
2591 /* Maemo uses a different (awkward) button order,
2592 * It should probably just use gtk_alternative_dialog_button_order ().
2594 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2598 GTK_RESPONSE_ACCEPT,
2600 GTK_RESPONSE_REJECT,
2603 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2607 GTK_RESPONSE_REJECT,
2609 GTK_RESPONSE_ACCEPT,
2611 #endif /* MODEST_PLATFORM_MAEMO */
2613 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2615 gchar *server_name = modest_server_account_get_hostname (
2616 modest_runtime_get_account_mgr(), server_account_name);
2617 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2618 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2623 /* This causes a warning because the logical ID has no %s in it,
2624 * though the translation does, but there is not much we can do about that: */
2625 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2626 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2629 g_free (server_name);
2633 gchar *initial_username = modest_server_account_get_username (
2634 modest_runtime_get_account_mgr(), server_account_name);
2636 GtkWidget *entry_username = gtk_entry_new ();
2637 if (initial_username)
2638 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2639 /* Dim this if a connection has ever succeeded with this username,
2640 * as per the UI spec: */
2641 const gboolean username_known =
2642 modest_server_account_get_username_has_succeeded(
2643 modest_runtime_get_account_mgr(), server_account_name);
2644 gtk_widget_set_sensitive (entry_username, !username_known);
2646 #ifdef MODEST_PLATFORM_MAEMO
2647 /* Auto-capitalization is the default, so let's turn it off: */
2648 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2650 /* Create a size group to be used by all captions.
2651 * Note that HildonCaption does not create a default size group if we do not specify one.
2652 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2653 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2655 GtkWidget *caption = hildon_caption_new (sizegroup,
2656 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2657 gtk_widget_show (entry_username);
2658 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2659 FALSE, FALSE, MODEST_MARGIN_HALF);
2660 gtk_widget_show (caption);
2662 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2664 #endif /* MODEST_PLATFORM_MAEMO */
2667 GtkWidget *entry_password = gtk_entry_new ();
2668 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2669 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2671 #ifdef MODEST_PLATFORM_MAEMO
2672 /* Auto-capitalization is the default, so let's turn it off: */
2673 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2674 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2676 caption = hildon_caption_new (sizegroup,
2677 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2678 gtk_widget_show (entry_password);
2679 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2680 FALSE, FALSE, MODEST_MARGIN_HALF);
2681 gtk_widget_show (caption);
2682 g_object_unref (sizegroup);
2684 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2686 #endif /* MODEST_PLATFORM_MAEMO */
2688 /* This is not in the Maemo UI spec:
2689 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2690 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2694 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2696 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2698 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2700 modest_server_account_set_username (
2701 modest_runtime_get_account_mgr(), server_account_name,
2704 const gboolean username_was_changed =
2705 (strcmp (*username, initial_username) != 0);
2706 if (username_was_changed) {
2707 g_warning ("%s: tinymail does not yet support changing the "
2708 "username in the get_password() callback.\n", __FUNCTION__);
2713 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2715 /* We do not save the password in the configuration,
2716 * because this function is only called for passwords that should
2717 * not be remembered:
2718 modest_server_account_set_password (
2719 modest_runtime_get_account_mgr(), server_account_name,
2728 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2740 /* This is not in the Maemo UI spec:
2741 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2747 gtk_widget_destroy (dialog);
2749 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2753 modest_ui_actions_on_cut (GtkAction *action,
2754 ModestWindow *window)
2756 GtkWidget *focused_widget;
2757 GtkClipboard *clipboard;
2759 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2760 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2761 if (GTK_IS_EDITABLE (focused_widget)) {
2762 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2763 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2764 gtk_clipboard_store (clipboard);
2765 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2766 GtkTextBuffer *buffer;
2768 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2769 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2770 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2771 gtk_clipboard_store (clipboard);
2772 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2773 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2774 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2775 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2780 modest_ui_actions_on_copy (GtkAction *action,
2781 ModestWindow *window)
2783 GtkClipboard *clipboard;
2784 GtkWidget *focused_widget;
2786 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2787 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2789 if (GTK_IS_LABEL (focused_widget)) {
2790 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2791 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2792 gtk_clipboard_store (clipboard);
2793 } else if (GTK_IS_EDITABLE (focused_widget)) {
2794 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2795 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2796 gtk_clipboard_store (clipboard);
2797 } else if (GTK_IS_HTML (focused_widget)) {
2798 gtk_html_copy (GTK_HTML (focused_widget));
2799 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2800 gtk_clipboard_store (clipboard);
2801 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2802 GtkTextBuffer *buffer;
2803 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2804 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2805 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2806 gtk_clipboard_store (clipboard);
2807 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2808 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2809 TnyIterator *iter = tny_list_create_iterator (header_list);
2810 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2812 gboolean ask = FALSE;
2814 TnyFolder *folder = tny_header_get_folder (header);
2815 TnyAccount *account = tny_folder_get_account (folder);
2816 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2817 /* If it's POP then ask */
2818 ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2819 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2820 g_object_unref (account);
2821 g_object_unref (folder);
2822 g_object_unref (header);
2825 g_object_unref (iter);
2827 /* Check that the messages have been previously downloaded */
2828 gboolean continue_download = TRUE;
2830 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window));
2831 if (continue_download)
2832 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2833 g_object_unref (header_list);
2834 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2835 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2838 /* Show information banner */
2839 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2844 modest_ui_actions_on_undo (GtkAction *action,
2845 ModestWindow *window)
2847 ModestEmailClipboard *clipboard = NULL;
2849 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2850 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2851 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2852 /* Clear clipboard source */
2853 clipboard = modest_runtime_get_email_clipboard ();
2854 modest_email_clipboard_clear (clipboard);
2857 g_return_if_reached ();
2862 modest_ui_actions_on_redo (GtkAction *action,
2863 ModestWindow *window)
2865 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2866 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
2869 g_return_if_reached ();
2875 paste_msgs_cb (const GObject *object, gpointer user_data)
2877 g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2878 g_return_if_fail (GTK_IS_WIDGET (user_data));
2880 /* destroy information note */
2881 gtk_widget_destroy (GTK_WIDGET(user_data));
2885 paste_as_attachment_free (gpointer data)
2887 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
2889 gtk_widget_destroy (helper->banner);
2890 g_object_unref (helper->banner);
2895 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
2900 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
2901 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
2906 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
2911 modest_ui_actions_on_paste (GtkAction *action,
2912 ModestWindow *window)
2914 GtkWidget *focused_widget = NULL;
2915 GtkWidget *inf_note = NULL;
2916 ModestMailOperation *mail_op = NULL;
2918 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2919 if (GTK_IS_EDITABLE (focused_widget)) {
2920 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2921 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2922 ModestEmailClipboard *e_clipboard = NULL;
2923 e_clipboard = modest_runtime_get_email_clipboard ();
2924 if (modest_email_clipboard_cleared (e_clipboard)) {
2925 GtkTextBuffer *buffer;
2926 GtkClipboard *clipboard;
2928 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2929 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2930 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2931 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2932 ModestMailOperation *mail_op;
2933 TnyFolder *src_folder;
2936 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
2937 helper->window = MODEST_MSG_EDIT_WINDOW (window);
2938 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2939 _CS("ckct_nw_pasting"));
2940 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
2941 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2943 if (helper->banner != NULL) {
2944 g_object_ref (G_OBJECT (helper->banner));
2945 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
2946 gtk_widget_show (GTK_WIDGET (helper->banner));
2950 modest_mail_operation_get_msgs_full (mail_op,
2952 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
2954 paste_as_attachment_free);
2957 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2958 ModestEmailClipboard *clipboard = NULL;
2959 TnyFolder *src_folder = NULL;
2960 TnyFolderStore *folder_store = NULL;
2961 TnyList *data = NULL;
2962 gboolean delete = FALSE;
2964 /* Check clipboard source */
2965 clipboard = modest_runtime_get_email_clipboard ();
2966 if (modest_email_clipboard_cleared (clipboard))
2969 /* Get elements to paste */
2970 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2972 /* Create a new mail operation */
2973 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2975 /* Get destination folder */
2976 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2978 /* transfer messages */
2982 /* Ask for user confirmation */
2983 response = msgs_move_to_confirmation (GTK_WINDOW (window),
2984 TNY_FOLDER (folder_store),
2988 if (response == GTK_RESPONSE_OK) {
2989 /* Launch notification */
2990 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2991 _CS("ckct_nw_pasting"));
2992 if (inf_note != NULL) {
2993 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
2994 gtk_widget_show (GTK_WIDGET(inf_note));
2997 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2998 modest_mail_operation_xfer_msgs (mail_op,
3000 TNY_FOLDER (folder_store),
3005 g_object_unref (mail_op);
3008 } else if (src_folder != NULL) {
3009 /* Launch notification */
3010 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3011 _CS("ckct_nw_pasting"));
3012 if (inf_note != NULL) {
3013 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3014 gtk_widget_show (GTK_WIDGET(inf_note));
3017 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3018 modest_mail_operation_xfer_folder (mail_op,
3028 g_object_unref (data);
3029 if (src_folder != NULL)
3030 g_object_unref (src_folder);
3031 if (folder_store != NULL)
3032 g_object_unref (folder_store);
3038 modest_ui_actions_on_select_all (GtkAction *action,
3039 ModestWindow *window)
3041 GtkWidget *focused_widget;
3043 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3044 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3045 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3046 } else if (GTK_IS_LABEL (focused_widget)) {
3047 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3048 } else if (GTK_IS_EDITABLE (focused_widget)) {
3049 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3050 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3051 GtkTextBuffer *buffer;
3052 GtkTextIter start, end;
3054 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3055 gtk_text_buffer_get_start_iter (buffer, &start);
3056 gtk_text_buffer_get_end_iter (buffer, &end);
3057 gtk_text_buffer_select_range (buffer, &start, &end);
3058 } else if (GTK_IS_HTML (focused_widget)) {
3059 gtk_html_select_all (GTK_HTML (focused_widget));
3060 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3061 GtkWidget *header_view = focused_widget;
3062 GtkTreeSelection *selection = NULL;
3064 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
3065 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3066 MODEST_WIDGET_TYPE_HEADER_VIEW);
3068 /* Select all messages */
3069 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3070 gtk_tree_selection_select_all (selection);
3072 /* Set focuse on header view */
3073 gtk_widget_grab_focus (header_view);
3079 modest_ui_actions_on_mark_as_read (GtkAction *action,
3080 ModestWindow *window)
3082 g_return_if_fail (MODEST_IS_WINDOW(window));
3084 /* Mark each header as read */
3085 do_headers_action (window, headers_action_mark_as_read, NULL);
3089 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3090 ModestWindow *window)
3092 g_return_if_fail (MODEST_IS_WINDOW(window));
3094 /* Mark each header as read */
3095 do_headers_action (window, headers_action_mark_as_unread, NULL);
3099 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3100 GtkRadioAction *selected,
3101 ModestWindow *window)
3105 value = gtk_radio_action_get_current_value (selected);
3106 if (MODEST_IS_WINDOW (window)) {
3107 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3111 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3112 GtkRadioAction *selected,
3113 ModestWindow *window)
3115 TnyHeaderFlags flags;
3116 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3118 flags = gtk_radio_action_get_current_value (selected);
3119 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3122 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3123 GtkRadioAction *selected,
3124 ModestWindow *window)
3128 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3130 file_format = gtk_radio_action_get_current_value (selected);
3131 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3136 modest_ui_actions_on_zoom_plus (GtkAction *action,
3137 ModestWindow *window)
3139 g_return_if_fail (MODEST_IS_WINDOW (window));
3141 modest_window_zoom_plus (MODEST_WINDOW (window));
3145 modest_ui_actions_on_zoom_minus (GtkAction *action,
3146 ModestWindow *window)
3148 g_return_if_fail (MODEST_IS_WINDOW (window));
3150 modest_window_zoom_minus (MODEST_WINDOW (window));
3154 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3155 ModestWindow *window)
3157 ModestWindowMgr *mgr;
3158 gboolean fullscreen, active;
3159 g_return_if_fail (MODEST_IS_WINDOW (window));
3161 mgr = modest_runtime_get_window_mgr ();
3163 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3164 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3166 if (active != fullscreen) {
3167 modest_window_mgr_set_fullscreen_mode (mgr, active);
3168 gtk_window_present (GTK_WINDOW (window));
3173 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3174 ModestWindow *window)
3176 ModestWindowMgr *mgr;
3177 gboolean fullscreen;
3179 g_return_if_fail (MODEST_IS_WINDOW (window));
3181 mgr = modest_runtime_get_window_mgr ();
3182 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3183 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3185 gtk_window_present (GTK_WINDOW (window));
3189 * Used by modest_ui_actions_on_details to call do_headers_action
3192 headers_action_show_details (TnyHeader *header,
3193 ModestWindow *window,
3200 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3203 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3204 gtk_widget_show_all (dialog);
3205 gtk_dialog_run (GTK_DIALOG (dialog));
3207 gtk_widget_destroy (dialog);
3211 * Show the folder details in a ModestDetailsDialog widget
3214 show_folder_details (TnyFolder *folder,
3220 dialog = modest_details_dialog_new_with_folder (window, folder);
3223 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3224 gtk_widget_show_all (dialog);
3225 gtk_dialog_run (GTK_DIALOG (dialog));
3227 gtk_widget_destroy (dialog);
3231 * Show the header details in a ModestDetailsDialog widget
3234 modest_ui_actions_on_details (GtkAction *action,
3237 TnyList * headers_list;
3241 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3244 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3247 g_object_unref (msg);
3249 headers_list = get_selected_headers (win);
3253 iter = tny_list_create_iterator (headers_list);
3255 header = TNY_HEADER (tny_iterator_get_current (iter));
3257 headers_action_show_details (header, win, NULL);
3258 g_object_unref (header);
3261 g_object_unref (iter);
3262 g_object_unref (headers_list);
3264 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3265 GtkWidget *folder_view, *header_view;
3267 /* Check which widget has the focus */
3268 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3269 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3270 if (gtk_widget_is_focus (folder_view)) {
3271 TnyFolderStore *folder_store
3272 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3273 if (!folder_store) {
3274 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3277 /* Show only when it's a folder */
3278 /* This function should not be called for account items,
3279 * because we dim the menu item for them. */
3280 if (TNY_IS_FOLDER (folder_store)) {
3281 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3284 g_object_unref (folder_store);
3287 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3288 MODEST_WIDGET_TYPE_HEADER_VIEW);
3289 /* Show details of each header */
3290 do_headers_action (win, headers_action_show_details, header_view);
3296 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3297 ModestMsgEditWindow *window)
3299 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3301 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3305 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3306 ModestMsgEditWindow *window)
3308 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3310 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3314 modest_ui_actions_toggle_folders_view (GtkAction *action,
3315 ModestMainWindow *main_window)
3317 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3319 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3320 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3322 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3326 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3327 ModestWindow *window)
3329 gboolean active, fullscreen = FALSE;
3330 ModestWindowMgr *mgr;
3332 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3334 /* Check if we want to toggle the toolbar vuew in fullscreen
3336 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3337 "ViewShowToolbarFullScreen")) {
3341 /* Toggle toolbar */
3342 mgr = modest_runtime_get_window_mgr ();
3343 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
3347 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3348 ModestMsgEditWindow *window)
3350 modest_msg_edit_window_select_font (window);
3354 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3355 const gchar *display_name,
3358 /* Do not change the application name if the widget has not
3359 the focus. This callback could be called even if the folder
3360 view has not the focus, because the handled signal could be
3361 emitted when the folder view is redrawn */
3362 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3364 gtk_window_set_title (window, display_name);
3366 gtk_window_set_title (window, " ");
3371 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3373 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3374 modest_msg_edit_window_select_contacts (window);
3378 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3380 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3381 modest_msg_edit_window_check_names (window, FALSE);
3385 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3387 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3388 GTK_WIDGET (user_data));
3392 create_move_to_dialog (GtkWindow *win,
3393 GtkWidget *folder_view,
3394 GtkWidget **tree_view)
3396 GtkWidget *dialog, *scroll;
3397 GtkWidget *new_button;
3399 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3401 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3404 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
3405 /* We do this manually so GTK+ does not associate a response ID for
3407 new_button = gtk_button_new_from_stock (GTK_STOCK_NEW);
3408 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3409 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
3411 /* Create scrolled window */
3412 scroll = gtk_scrolled_window_new (NULL, NULL);
3413 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3414 GTK_POLICY_AUTOMATIC,
3415 GTK_POLICY_AUTOMATIC);
3417 /* Create folder view */
3418 *tree_view = modest_platform_create_folder_view (NULL);
3419 /* *tree_view = modest_folder_view_new (NULL); */
3421 g_signal_connect (G_OBJECT (new_button), "clicked", G_CALLBACK(create_move_to_dialog_on_new_folder), *tree_view);
3423 /* It could happen that we're trying to move a message from a
3424 window (msg window for example) after the main window was
3425 closed, so we can not just get the model of the folder
3427 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
3428 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
3429 MODEST_FOLDER_VIEW(*tree_view));
3431 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3432 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3434 /* Hide special folders */
3435 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3437 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3439 /* Add scroll to dialog */
3440 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3441 scroll, TRUE, TRUE, 0);
3443 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3444 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3450 * Returns TRUE if at least one of the headers of the list belongs to
3451 * a message that has been fully retrieved.
3453 #if 0 /* no longer in use. delete in 2007.10 */
3455 has_retrieved_msgs (TnyList *list)
3458 gboolean found = FALSE;
3460 iter = tny_list_create_iterator (list);
3461 while (!tny_iterator_is_done (iter) && !found) {
3463 TnyHeaderFlags flags = 0;
3465 header = TNY_HEADER (tny_iterator_get_current (iter));
3467 flags = tny_header_get_flags (header);
3468 if (flags & TNY_HEADER_FLAG_CACHED)
3469 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3472 g_object_unref (header);
3476 tny_iterator_next (iter);
3478 g_object_unref (iter);
3486 * Shows a confirmation dialog to the user when we're moving messages
3487 * from a remote server to the local storage. Returns the dialog
3488 * response. If it's other kind of movement the it always returns
3492 msgs_move_to_confirmation (GtkWindow *win,
3493 TnyFolder *dest_folder,
3497 gint response = GTK_RESPONSE_OK;
3499 /* If the destination is a local folder (or MMC folder )*/
3500 if (!modest_tny_folder_is_remote_folder (dest_folder)) {
3505 TnyFolder *src_folder = NULL;
3506 TnyIterator *iter = NULL;
3507 TnyHeader *header = NULL;
3509 /* get the device */
3511 device = modest_runtime_get_device ();
3513 is_online = tny_device_is_online (device);
3515 g_warning ("failed to get tny device"); /* should not happend */
3519 /* Get source folder */
3520 iter = tny_list_create_iterator (headers);
3521 header = TNY_HEADER (tny_iterator_get_current (iter));
3523 src_folder = tny_header_get_folder (header);
3524 g_object_unref (header);
3527 g_object_unref (iter);
3529 /* if no src_folder, message may be an attahcment */
3530 if (src_folder == NULL)
3531 return GTK_RESPONSE_CANCEL;
3533 /* If the source is a remote folder */
3534 if (!is_online && modest_tny_folder_is_remote_folder (src_folder)) {
3536 const gchar *message = NULL;
3537 message = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs",
3538 tny_list_get_length (headers));
3539 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
3540 (const gchar *) message);
3542 response = GTK_RESPONSE_OK;
3544 g_object_unref (src_folder);
3553 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
3555 ModestMsgViewWindow *self = NULL;
3557 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
3558 self = MODEST_MSG_VIEW_WINDOW (object);
3560 if (!modest_msg_view_window_select_next_message (self))
3561 if (!modest_msg_view_window_select_previous_message (self))
3562 /* No more messages to view, so close this window */
3563 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3567 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3570 GObject *win = modest_mail_operation_get_source (mail_op);
3571 const GError *error = NULL;
3572 const gchar *message = NULL;
3574 /* Get error message */
3575 error = modest_mail_operation_get_error (mail_op);
3576 if (error != NULL && error->message != NULL) {
3577 message = error->message;
3579 message = _("mail_in_ui_folder_move_target_error");
3582 /* Show notification dialog */
3583 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3584 g_object_unref (win);
3588 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3591 GObject *win = modest_mail_operation_get_source (mail_op);
3592 const GError *error = modest_mail_operation_get_error (mail_op);
3594 g_return_if_fail (error != NULL);
3595 if (error->message != NULL)
3596 g_printerr ("modest: %s\n", error->message);
3598 g_printerr ("modest: unkonw error on send&receive operation");
3600 /* Show error message */
3601 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3602 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3603 /* _CS("sfil_ib_unable_to_receive")); */
3605 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3606 /* _CS("sfil_ib_unable_to_send")); */
3607 g_object_unref (win);
3611 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3618 gint pending_purges = 0;
3619 gboolean some_purged = FALSE;
3620 ModestWindow *win = MODEST_WINDOW (user_data);
3621 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3623 /* If there was any error */
3624 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
3625 modest_window_mgr_unregister_header (mgr, header);
3629 /* Once the message has been retrieved for purging, we check if
3630 * it's all ok for purging */
3632 parts = tny_simple_list_new ();
3633 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3634 iter = tny_list_create_iterator (parts);
3636 while (!tny_iterator_is_done (iter)) {
3638 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3639 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
3640 if (tny_mime_part_is_purged (part))
3647 g_object_unref (part);
3649 tny_iterator_next (iter);
3652 if (pending_purges>0) {
3654 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3656 if (response == GTK_RESPONSE_OK) {
3657 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3658 tny_iterator_first (iter);
3659 while (!tny_iterator_is_done (iter)) {
3662 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3663 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
3664 tny_mime_part_set_purged (part);
3667 g_object_unref (part);
3669 tny_iterator_next (iter);
3672 tny_msg_rewrite_cache (msg);
3675 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3678 /* remove attachments */
3679 tny_iterator_first (iter);
3680 while (!tny_iterator_is_done (iter)) {
3683 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3685 /* One for the reference given by tny_iterator_get_current(): */
3686 g_object_unref (part);
3688 /* TODO: Is this meant to remove the attachment by doing another unref()?
3689 * Otherwise, this seems useless. */
3692 tny_iterator_next (iter);
3694 modest_window_mgr_unregister_header (mgr, header);
3696 g_object_unref (iter);
3697 g_object_unref (parts);
3701 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3702 ModestMainWindow *win)
3704 GtkWidget *header_view;
3705 TnyList *header_list;
3708 TnyHeaderFlags flags;
3709 ModestWindow *msg_view_window = NULL;
3712 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3714 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3715 MODEST_WIDGET_TYPE_HEADER_VIEW);
3717 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3719 if (tny_list_get_length (header_list) == 1) {
3720 iter = tny_list_create_iterator (header_list);
3721 header = TNY_HEADER (tny_iterator_get_current (iter));
3722 g_object_unref (iter);
3727 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3728 header, &msg_view_window);
3729 flags = tny_header_get_flags (header);
3730 if (!(flags & TNY_HEADER_FLAG_CACHED))
3733 if (msg_view_window != NULL)
3734 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3736 /* do nothing; uid was registered before, so window is probably on it's way */
3737 g_warning ("debug: header %p has already been registered", header);
3740 ModestMailOperation *mail_op = NULL;
3741 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3742 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3744 modest_ui_actions_get_msgs_full_error_handler,
3746 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3747 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3749 g_object_unref (mail_op);
3752 g_object_unref (header);
3754 g_object_unref (header_list);
3758 * Utility function that transfer messages from both the main window
3759 * and the msg view window when using the "Move to" dialog
3762 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
3765 TnyList *headers = NULL;
3767 TnyAccount *dst_account = NULL;
3768 const gchar *proto_str = NULL;
3769 gboolean dst_is_pop = FALSE;
3771 if (!TNY_IS_FOLDER (dst_folder)) {
3772 modest_platform_information_banner (GTK_WIDGET (win),
3774 _CS("ckdg_ib_unable_to_move_to_current_location"));
3778 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
3779 proto_str = tny_account_get_proto (dst_account);
3781 /* tinymail will return NULL for local folders it seems */
3782 dst_is_pop = proto_str &&
3783 (modest_protocol_info_get_transport_store_protocol (proto_str) ==
3784 MODEST_PROTOCOL_STORE_POP);
3786 g_object_unref (dst_account);
3788 /* Get selected headers */
3789 headers = get_selected_headers (MODEST_WINDOW (win));
3792 modest_platform_information_banner (GTK_WIDGET (win),
3794 ngettext("mail_in_ui_folder_move_target_error",
3795 "mail_in_ui_folder_move_targets_error",
3796 tny_list_get_length (headers)));
3797 g_object_unref (headers);
3801 /* Ask for user confirmation */
3802 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3803 TNY_FOLDER (dst_folder),
3807 /* Transfer messages */
3808 if (response == GTK_RESPONSE_OK) {
3809 ModestMailOperation *mail_op =
3810 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3812 modest_ui_actions_move_folder_error_handler,
3814 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3817 modest_mail_operation_xfer_msgs (mail_op,
3819 TNY_FOLDER (dst_folder),
3821 (MODEST_IS_MSG_VIEW_WINDOW (win)) ? transfer_msgs_from_viewer_cb : NULL,
3824 g_object_unref (G_OBJECT (mail_op));
3826 g_object_unref (headers);
3830 * UI handler for the "Move to" action when invoked from the
3834 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3835 GtkWidget *folder_view,
3836 TnyFolderStore *dst_folder,
3837 ModestMainWindow *win)
3839 GtkWidget *header_view = NULL;
3840 ModestMailOperation *mail_op = NULL;
3841 TnyFolderStore *src_folder;
3843 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3845 /* Get the source folder */
3846 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3848 /* Offer the connection dialog if necessary, if the source folder is in a networked account: */
3849 if (!modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3853 /* Get header view */
3855 modest_main_window_get_child_widget (win, MODEST_WIDGET_TYPE_HEADER_VIEW);
3857 /* Get folder or messages to transfer */
3858 if (gtk_widget_is_focus (folder_view)) {
3860 /* Allow only to transfer folders to the local root folder */
3861 if (TNY_IS_ACCOUNT (dst_folder) &&
3862 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder))
3865 /* Clean folder on header view before moving it */
3866 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3868 if (TNY_IS_FOLDER (src_folder)) {
3870 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3872 modest_ui_actions_move_folder_error_handler,
3874 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3877 modest_mail_operation_xfer_folder (mail_op,
3878 TNY_FOLDER (src_folder),
3881 /* Unref mail operation */
3882 g_object_unref (G_OBJECT (mail_op));
3884 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
3886 } else if (gtk_widget_is_focus (header_view)) {
3887 /* Transfer messages */
3888 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3893 g_object_unref (src_folder);
3898 * UI handler for the "Move to" action when invoked from the
3899 * ModestMsgViewWindow
3902 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3903 TnyFolderStore *dst_folder,
3904 ModestMsgViewWindow *win)
3906 TnyHeader *header = NULL;
3907 TnyFolder *src_folder;
3909 /* Create header list */
3910 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3911 src_folder = tny_header_get_folder(header);
3912 g_object_unref (header);
3914 /* Transfer the message */
3915 if (modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (src_folder)))
3916 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3918 g_object_unref (src_folder);
3922 modest_ui_actions_on_move_to (GtkAction *action,
3925 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3927 TnyFolderStore *dst_folder = NULL;
3928 ModestMainWindow *main_window;
3930 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3931 MODEST_IS_MSG_VIEW_WINDOW (win));
3933 /* Get the main window if exists */
3934 if (MODEST_IS_MAIN_WINDOW (win))
3935 main_window = MODEST_MAIN_WINDOW (win);
3938 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3940 /* Get the folder view widget if exists */
3942 folder_view = modest_main_window_get_child_widget (main_window,
3943 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3947 /* Create and run the dialog */
3948 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
3949 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3950 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3951 result = gtk_dialog_run (GTK_DIALOG(dialog));
3952 g_object_ref (tree_view);
3953 gtk_widget_destroy (dialog);
3955 if (result != GTK_RESPONSE_ACCEPT)
3958 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3959 /* Offer the connection dialog if necessary: */
3960 if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3963 /* Do window specific stuff */
3964 if (MODEST_IS_MAIN_WINDOW (win))
3965 modest_ui_actions_on_main_window_move_to (action,
3968 MODEST_MAIN_WINDOW (win));
3970 modest_ui_actions_on_msg_view_window_move_to (action,
3972 MODEST_MSG_VIEW_WINDOW (win));
3975 g_object_unref (dst_folder);
3979 * Calls #HeadersFunc for each header already selected in the main
3980 * window or the message currently being shown in the msg view window
3983 do_headers_action (ModestWindow *win,
3987 TnyList *headers_list = NULL;
3988 TnyIterator *iter = NULL;
3989 TnyHeader *header = NULL;
3990 TnyFolder *folder = NULL;
3993 headers_list = get_selected_headers (win);
3997 /* Get the folder */
3998 iter = tny_list_create_iterator (headers_list);
3999 header = TNY_HEADER (tny_iterator_get_current (iter));
4001 folder = tny_header_get_folder (header);
4002 g_object_unref (header);
4005 /* Call the function for each header */
4006 while (!tny_iterator_is_done (iter)) {
4007 header = TNY_HEADER (tny_iterator_get_current (iter));
4008 func (header, win, user_data);
4009 g_object_unref (header);
4010 tny_iterator_next (iter);
4013 /* Trick: do a poke status in order to speed up the signaling
4015 tny_folder_poke_status (folder);
4018 g_object_unref (folder);
4019 g_object_unref (iter);
4020 g_object_unref (headers_list);
4024 modest_ui_actions_view_attachment (GtkAction *action,
4025 ModestWindow *window)
4027 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4028 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4030 /* not supported window for this action */
4031 g_return_if_reached ();
4036 modest_ui_actions_save_attachments (GtkAction *action,
4037 ModestWindow *window)
4039 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4040 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4042 /* not supported window for this action */
4043 g_return_if_reached ();
4048 modest_ui_actions_remove_attachments (GtkAction *action,
4049 ModestWindow *window)
4051 if (MODEST_IS_MAIN_WINDOW (window)) {
4052 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4053 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4054 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4056 /* not supported window for this action */
4057 g_return_if_reached ();
4062 modest_ui_actions_on_settings (GtkAction *action,
4067 dialog = modest_platform_get_global_settings_dialog ();
4068 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4069 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4070 gtk_widget_show_all (dialog);
4072 gtk_dialog_run (GTK_DIALOG (dialog));
4074 gtk_widget_destroy (dialog);
4078 modest_ui_actions_on_help (GtkAction *action,
4081 const gchar *help_id = NULL;
4083 if (MODEST_IS_MAIN_WINDOW (win)) {
4084 const gchar *action_name;
4085 action_name = gtk_action_get_name (action);
4087 if (!strcmp (action_name, "FolderViewCSMHelp") ||
4088 !strcmp (action_name, "HeaderViewCSMHelp")) {
4089 GtkWidget *folder_view;
4090 TnyFolderStore *folder_store;
4091 /* Get selected folder */
4092 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4093 MODEST_WIDGET_TYPE_FOLDER_VIEW);
4094 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4096 /* Switch help_id */
4097 if (TNY_IS_FOLDER (folder_store)) {
4098 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4099 case TNY_FOLDER_TYPE_NORMAL:
4100 help_id = "applications_email_managefolders";
4102 case TNY_FOLDER_TYPE_INBOX:
4103 help_id = "applications_email_inbox";
4105 case TNY_FOLDER_TYPE_OUTBOX:
4106 help_id = "applications_email_outbox";
4108 case TNY_FOLDER_TYPE_SENT:
4109 help_id = "applications_email_sent";
4111 case TNY_FOLDER_TYPE_DRAFTS:
4112 help_id = "applications_email_drafts";
4114 case TNY_FOLDER_TYPE_ARCHIVE:
4115 help_id = "applications_email_managefolders";
4118 help_id = "applications_email_managefolders";
4121 help_id = "applications_email_mainview";
4123 g_object_unref (folder_store);
4125 help_id = "applications_email_mainview";
4127 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4128 help_id = "applications_email_viewer";
4129 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4130 help_id = "applications_email_editor";
4132 modest_platform_show_help (GTK_WINDOW (win), help_id);
4136 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4137 ModestWindow *window)
4139 ModestMailOperation *mail_op;
4143 headers = get_selected_headers (window);
4147 /* Create mail operation */
4148 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4150 modest_ui_actions_get_msgs_full_error_handler,
4152 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4153 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4156 g_object_unref (headers);
4157 g_object_unref (mail_op);
4161 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4162 ModestWindow *window)
4164 g_return_if_fail (MODEST_IS_WINDOW (window));
4167 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4171 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4172 ModestWindow *window)
4174 g_return_if_fail (MODEST_IS_WINDOW (window));
4177 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4181 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4182 ModestWindow *window)
4184 g_return_if_fail (MODEST_IS_WINDOW (window));
4187 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4191 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4192 ModestWindow *window)
4194 g_return_if_fail (MODEST_IS_WINDOW (window));
4197 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4201 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4202 ModestWindow *window)
4204 g_return_if_fail (MODEST_IS_WINDOW (window));
4207 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4211 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4212 ModestWindow *window)
4214 g_return_if_fail (MODEST_IS_WINDOW (window));
4217 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4221 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4222 ModestWindow *window)
4224 g_return_if_fail (MODEST_IS_WINDOW (window));
4227 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4231 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4232 ModestWindow *window)
4234 g_return_if_fail (MODEST_IS_WINDOW (window));
4237 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4241 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4243 g_return_if_fail (MODEST_IS_WINDOW (window));
4246 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4250 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4252 g_return_if_fail (MODEST_IS_WINDOW (window));
4254 modest_platform_show_search_messages (GTK_WINDOW (window));
4258 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4260 g_return_if_fail (MODEST_IS_WINDOW (win));
4261 modest_platform_show_addressbook (GTK_WINDOW (win));
4266 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4267 ModestWindow *window)
4269 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4271 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4275 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
4276 ModestMailOperationState *state,
4279 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4281 /* Set send/receive operation finished */
4282 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4283 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));