1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #endif /*HAVE_CONFIG_H*/
34 #include <glib/gi18n.h>
35 #include <glib/gprintf.h>
37 #include <modest-runtime.h>
38 #include <modest-tny-folder.h>
39 #include <modest-tny-msg.h>
40 #include <modest-tny-account.h>
41 #include <modest-address-book.h>
42 #include "modest-error.h"
43 #include "modest-ui-actions.h"
45 #include "modest-tny-platform-factory.h"
46 #include "modest-platform.h"
47 #include <tny-mime-part.h>
48 #include <tny-camel-folder.h>
49 #include <tny-camel-imap-folder.h>
50 #include <tny-camel-pop-folder.h>
52 #ifdef MODEST_PLATFORM_MAEMO
53 #include "maemo/modest-osso-state-saving.h"
54 #include "maemo/modest-maemo-utils.h"
55 #include "maemo/modest-hildon-includes.h"
56 #endif /* MODEST_PLATFORM_MAEMO */
58 #include "widgets/modest-ui-constants.h"
59 #include <widgets/modest-main-window.h>
60 #include <widgets/modest-msg-view-window.h>
61 #include <widgets/modest-account-view-window.h>
62 #include <widgets/modest-details-dialog.h>
63 #include <widgets/modest-attachments-view.h>
64 #include "widgets/modest-folder-view.h"
65 #include "widgets/modest-global-settings-dialog.h"
66 #include "modest-connection-specific-smtp-window.h"
67 #include "modest-account-mgr-helpers.h"
68 #include "modest-mail-operation.h"
69 #include "modest-text-utils.h"
71 #ifdef MODEST_HAVE_EASYSETUP
72 #include "easysetup/modest-easysetup-wizard.h"
73 #endif /* MODEST_HAVE_EASYSETUP */
75 #include <modest-widget-memory.h>
76 #include <tny-error.h>
77 #include <tny-simple-list.h>
78 #include <tny-msg-view.h>
79 #include <tny-device.h>
80 #include <tny-merge-folder.h>
82 #include <gtkhtml/gtkhtml.h>
84 typedef struct _GetMsgAsyncHelper {
86 ModestMailOperation *mail_op;
93 typedef enum _ReplyForwardAction {
99 typedef struct _ReplyForwardHelper {
100 guint reply_forward_type;
101 ReplyForwardAction action;
103 GtkWidget *parent_window;
104 } ReplyForwardHelper;
106 typedef struct _PasteAsAttachmentHelper {
107 ModestMsgEditWindow *window;
109 } PasteAsAttachmentHelper;
113 * The do_headers_action uses this kind of functions to perform some
114 * action to each member of a list of headers
116 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
118 static void do_headers_action (ModestWindow *win,
122 static void open_msg_cb (ModestMailOperation *mail_op,
127 static void reply_forward_cb (ModestMailOperation *mail_op,
132 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
134 static void folder_refreshed_cb (ModestMailOperation *mail_op,
138 static void _on_send_receive_progress_changed (ModestMailOperation *mail_op,
139 ModestMailOperationState *state,
143 download_uncached_messages (TnyList *header_list, GtkWindow *win);
147 msgs_move_to_confirmation (GtkWindow *win,
148 TnyFolder *dest_folder,
153 /* Show the account creation wizard dialog.
154 * returns: TRUE if an account was created. FALSE if the user cancelled.
157 modest_run_account_setup_wizard (ModestWindow *win)
159 gboolean result = FALSE;
160 ModestEasysetupWizardDialog *wizard;
163 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ());
165 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
167 wizard = modest_easysetup_wizard_dialog_new_or_present ();
169 /* if wizard == NULL it means there is already a easy setup thingy running;
170 * in that case, don't do anything here; the call above will present it instead */
172 g_message ("%s: easysetup wizard already running", __FUNCTION__);
176 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
178 /* Don't make this a modal window, because secondary windows will then
179 * be unusable, freezing the UI: */
180 /* gtk_window_set_modal (GTK_WINDOW (wizard), TRUE); */
182 gint dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
183 if (dialog_response == GTK_RESPONSE_CANCEL)
186 /* Check whether an account was created: */
187 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
190 gtk_widget_destroy (GTK_WIDGET (wizard));
197 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
200 const gchar *authors[] = {
201 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
204 about = gtk_about_dialog_new ();
205 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
206 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
207 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
208 _("Copyright (c) 2006, Nokia Corporation\n"
209 "All rights reserved."));
210 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
211 _("a modest e-mail client\n\n"
212 "design and implementation: Dirk-Jan C. Binnema\n"
213 "contributions from the fine people at KC and Ig\n"
214 "uses the tinymail email framework written by Philip van Hoof"));
215 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
216 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
217 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
218 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
220 gtk_dialog_run (GTK_DIALOG (about));
221 gtk_widget_destroy(about);
225 * Gets the list of currently selected messages. If the win is the
226 * main window, then it returns a newly allocated list of the headers
227 * selected in the header view. If win is the msg view window, then
228 * the value returned is a list with just a single header.
230 * The caller of this funcion must free the list.
233 get_selected_headers (ModestWindow *win)
235 if (MODEST_IS_MAIN_WINDOW(win)) {
236 GtkWidget *header_view;
238 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
239 MODEST_WIDGET_TYPE_HEADER_VIEW);
240 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
242 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
243 /* for MsgViewWindows, we simply return a list with one element */
245 TnyList *list = NULL;
247 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
248 if (header != NULL) {
249 list = tny_simple_list_new ();
250 tny_list_prepend (list, G_OBJECT(header));
251 g_object_unref (G_OBJECT(header));
261 headers_action_mark_as_read (TnyHeader *header,
265 TnyHeaderFlags flags;
267 g_return_if_fail (TNY_IS_HEADER(header));
269 flags = tny_header_get_flags (header);
270 if (flags & TNY_HEADER_FLAG_SEEN) return;
271 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
275 headers_action_mark_as_unread (TnyHeader *header,
279 TnyHeaderFlags flags;
281 g_return_if_fail (TNY_IS_HEADER(header));
283 flags = tny_header_get_flags (header);
284 if (flags & TNY_HEADER_FLAG_SEEN) {
285 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
289 /** A convenience method, because deleting a message is
290 * otherwise complicated, and it's best to change it in one place
293 void modest_do_message_delete (TnyHeader *header, ModestWindow *win)
295 ModestMailOperation *mail_op = NULL;
296 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE,
297 win ? G_OBJECT(win) : NULL);
298 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
301 /* Always delete. TODO: Move to trash still not supported */
302 modest_mail_operation_remove_msg (mail_op, header, FALSE);
303 g_object_unref (G_OBJECT (mail_op));
307 headers_action_delete (TnyHeader *header,
311 modest_do_message_delete (header, win);
314 /** After deleing a message that is currently visible in a window,
315 * show the next message from the list, or close the window if there are no more messages.
317 void modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
319 /* Close msg view window or select next */
320 if (modest_msg_view_window_last_message_selected (win) &&
321 modest_msg_view_window_first_message_selected (win)) {
322 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
324 if (!modest_msg_view_window_select_next_message (win)) {
326 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
332 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
334 TnyList *header_list = NULL;
335 TnyIterator *iter = NULL;
336 TnyHeader *header = NULL;
337 gchar *message = NULL;
340 ModestWindowMgr *mgr;
341 GtkWidget *header_view = NULL;
343 g_return_if_fail (MODEST_IS_WINDOW(win));
345 /* Check first if the header view has the focus */
346 if (MODEST_IS_MAIN_WINDOW (win)) {
348 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
349 MODEST_WIDGET_TYPE_HEADER_VIEW);
350 if (!gtk_widget_is_focus (header_view))
354 /* Get the headers, either from the header view (if win is the main window),
355 * or from the message view window: */
356 header_list = get_selected_headers (win);
357 if (!header_list) return;
359 /* Check if any of the headers are already opened, or in the process of being opened */
360 if (MODEST_IS_MAIN_WINDOW (win)) {
362 iter = tny_list_create_iterator (header_list);
364 mgr = modest_runtime_get_window_mgr ();
365 while (!tny_iterator_is_done (iter) && !found) {
366 header = TNY_HEADER (tny_iterator_get_current (iter));
368 found = modest_window_mgr_find_registered_header (mgr, header, NULL);
369 g_object_unref (header);
372 tny_iterator_next (iter);
374 g_object_unref (iter);
379 num = g_strdup_printf ("%d", tny_list_get_length (header_list));
380 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
382 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
386 g_object_unref (header_list);
392 if (tny_list_get_length(header_list) == 1) {
393 iter = tny_list_create_iterator (header_list);
394 header = TNY_HEADER (tny_iterator_get_current (iter));
396 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
397 g_object_unref (header);
400 g_object_unref (iter);
402 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
403 tny_list_get_length(header_list)), desc);
405 /* Confirmation dialog */
406 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
410 if (response == GTK_RESPONSE_OK) {
411 ModestWindow *main_window = NULL;
412 ModestWindowMgr *mgr = NULL;
413 GtkTreeModel *model = NULL;
414 GtkTreeSelection *sel = NULL;
415 GList *sel_list = NULL, *tmp = NULL;
416 GtkTreeRowReference *row_reference = NULL;
417 GtkTreePath *next_path = NULL;
418 TnyFolder *folder = NULL;
421 /* Find last selected row */
422 if (MODEST_IS_MAIN_WINDOW (win)) {
423 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
424 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
425 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
426 for (tmp=sel_list; tmp; tmp=tmp->next) {
427 if (tmp->next == NULL) {
428 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
429 gtk_tree_path_next (next_path);
430 row_reference = gtk_tree_row_reference_new (model, next_path);
431 gtk_tree_path_free (next_path);
436 /* Remove each header. If it's a view window header_view == NULL */
437 do_headers_action (win, headers_action_delete, header_view);
439 /* refresh the header view (removing marked-as-deleted)*/
440 modest_header_view_refilter (MODEST_HEADER_VIEW(header_view));
442 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
443 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
445 /* Get main window */
446 mgr = modest_runtime_get_window_mgr ();
447 main_window = modest_window_mgr_get_main_window (mgr);
450 /* Move cursor to next row */
453 /* Select next row */
454 if (gtk_tree_row_reference_valid (row_reference)) {
455 next_path = gtk_tree_row_reference_get_path (row_reference);
456 gtk_tree_selection_select_path (sel, next_path);
457 gtk_tree_path_free (next_path);
459 if (row_reference != NULL)
460 gtk_tree_row_reference_free (row_reference);
463 /* Get folder from first header and sync it */
464 iter = tny_list_create_iterator (header_list);
465 header = TNY_HEADER (tny_iterator_get_current (iter));
466 folder = tny_header_get_folder (header);
467 if (TNY_IS_CAMEL_IMAP_FOLDER (folder))
468 /* tny_folder_sync_async(folder, FALSE, NULL, NULL, NULL); /\* FALSE --> don't expunge *\/ */
469 tny_folder_sync (folder, FALSE, &err); /* FALSE --> don't expunge */
470 else if (TNY_IS_CAMEL_POP_FOLDER (folder))
471 /* tny_folder_sync_async(folder, FALSE, NULL, NULL, NULL); /\* TRUE --> dont expunge *\/ */
472 tny_folder_sync (folder, TRUE, &err); /* TRUE --> expunge */
475 /* tny_folder_sync_async(folder, TRUE, NULL, NULL, NULL); /\* TRUE --> expunge *\/ */
476 tny_folder_sync (folder, TRUE, &err); /* TRUE --> expunge */
479 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, err->code, err->message);
483 g_object_unref (header);
484 g_object_unref (iter);
485 g_object_unref (folder);
487 /* Update toolbar dimming state */
488 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
491 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
492 g_list_free (sel_list);
498 g_object_unref (header_list);
504 /* delete either message or folder, based on where we are */
506 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
508 g_return_if_fail (MODEST_IS_WINDOW(win));
510 /* Check first if the header view has the focus */
511 if (MODEST_IS_MAIN_WINDOW (win)) {
513 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
514 MODEST_WIDGET_TYPE_FOLDER_VIEW);
515 if (gtk_widget_is_focus (w)) {
516 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
520 modest_ui_actions_on_delete_message (action, win);
526 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
528 #ifdef MODEST_PLATFORM_MAEMO
529 modest_osso_save_state();
530 #endif /* MODEST_PLATFORM_MAEMO */
532 g_debug ("closing down, clearing %d item(s) from operation queue",
533 modest_mail_operation_queue_num_elements
534 (modest_runtime_get_mail_operation_queue()));
536 /* cancel all outstanding operations */
537 modest_mail_operation_queue_cancel_all
538 (modest_runtime_get_mail_operation_queue());
540 g_debug ("queue has been cleared");
542 /* note: when modest-tny-account-store is finalized,
543 it will automatically set all network connections
550 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
554 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
556 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
557 /* gtk_widget_destroy (GTK_WIDGET (win)); */
558 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
559 /* gboolean ret_value; */
560 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
561 /* } else if (MODEST_IS_WINDOW (win)) { */
562 /* gtk_widget_destroy (GTK_WIDGET (win)); */
564 /* g_return_if_reached (); */
569 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
571 GtkClipboard *clipboard = NULL;
572 gchar *selection = NULL;
574 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
575 selection = gtk_clipboard_wait_for_text (clipboard);
577 /* Question: why is the clipboard being used here?
578 * It doesn't really make a lot of sense. */
582 modest_address_book_add_address (selection);
588 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
590 /* This is currently only implemented for Maemo */
591 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
592 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
593 modest_run_account_setup_wizard (win);
596 /* Show the list of accounts: */
597 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
598 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW (win));
600 /* Don't make this a modal window, because secondary windows will then
601 * be unusable, freezing the UI: */
602 /* gtk_window_set_modal (GTK_WINDOW (account_win), TRUE); */
603 modest_maemo_show_dialog_and_forget (GTK_WINDOW (win), account_win);
606 GtkWidget *dialog, *label;
608 /* Create the widgets */
610 dialog = gtk_dialog_new_with_buttons ("Message",
612 GTK_DIALOG_DESTROY_WITH_PARENT,
616 label = gtk_label_new ("Hello World!");
618 /* Ensure that the dialog box is destroyed when the user responds. */
620 g_signal_connect_swapped (dialog, "response",
621 G_CALLBACK (gtk_widget_destroy),
624 /* Add the label, and show everything we've added to the dialog. */
626 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
628 gtk_widget_show_all (dialog);
629 #endif /* MODEST_PLATFORM_MAEMO */
633 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
635 ModestWindow *main_window = MODEST_WINDOW (user_data);
637 /* Save any changes. */
638 modest_connection_specific_smtp_window_save_server_accounts (
639 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
640 modest_window_get_active_account (main_window));
641 gtk_widget_destroy (GTK_WIDGET (window));
647 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
649 /* This is currently only implemented for Maemo,
650 * because it requires an API (libconic) to detect different connection
653 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
655 /* Create the window if necessary: */
656 const gchar *active_account_name = modest_window_get_active_account (win);
658 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
659 * or show the default account?
660 * If we show the default account then the account name should be shown in
661 * the window when we show it. */
662 if (!active_account_name) {
663 g_warning ("%s: No account is active.", __FUNCTION__);
667 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
668 modest_connection_specific_smtp_window_fill_with_connections (
669 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
670 modest_runtime_get_account_mgr(),
671 active_account_name);
673 /* Show the window: */
674 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
675 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
676 gtk_widget_show (specific_window);
678 /* Save changes when the window is hidden: */
679 g_signal_connect (specific_window, "hide",
680 G_CALLBACK (on_smtp_servers_window_hide), win);
681 #endif /* MODEST_PLATFORM_MAEMO */
685 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
687 ModestWindow *msg_win = NULL;
689 TnyFolder *folder = NULL;
690 gchar *account_name = NULL;
691 gchar *from_str = NULL;
692 /* GError *err = NULL; */
693 TnyAccount *account = NULL;
694 ModestWindowMgr *mgr;
695 gchar *signature = NULL, *blank_and_signature = NULL;
697 /* if there are no accounts yet, just show the wizard */
698 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
699 const gboolean created = modest_run_account_setup_wizard (win);
704 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
706 account_name = g_strdup (modest_window_get_active_account (win));
708 g_printerr ("modest: no account found\n");
712 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
714 TNY_ACCOUNT_TYPE_STORE);
716 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
720 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
722 g_printerr ("modest: failed get from string for '%s'\n", account_name);
726 gboolean use_signature = FALSE;
727 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr (), account_name, &use_signature);
730 blank_and_signature = g_strconcat ("\n", signature, NULL);
732 blank_and_signature = g_strdup ("");
737 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
739 g_printerr ("modest: failed to create new msg\n");
743 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
745 g_printerr ("modest: failed to find Drafts folder\n");
750 /* Create and register edit window */
751 /* This is destroyed by TODO. */
752 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
753 mgr = modest_runtime_get_window_mgr ();
754 modest_window_mgr_register_window (mgr, msg_win);
757 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
759 gtk_widget_show_all (GTK_WIDGET (msg_win));
762 g_free (account_name);
764 g_free (blank_and_signature);
766 g_object_unref (msg_win);
768 g_object_unref (G_OBJECT(account));
770 g_object_unref (G_OBJECT(msg));
772 g_object_unref (G_OBJECT(folder));
776 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
780 ModestMailOperationStatus status;
782 /* If there is no message or the operation was not successful */
783 status = modest_mail_operation_get_status (mail_op);
784 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
786 /* Remove the header from the preregistered uids */
787 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
797 open_msg_cb (ModestMailOperation *mail_op,
802 ModestWindowMgr *mgr = NULL;
803 ModestWindow *parent_win = NULL;
804 ModestWindow *win = NULL;
805 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
806 gchar *account = NULL;
809 /* Do nothing if there was any problem with the mail
810 operation. The error will be shown by the error_handler of
811 the mail operation */
812 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
816 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
817 folder = tny_header_get_folder (header);
819 /* Mark header as read */
820 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
823 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
825 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
827 /* Gets folder type (OUTBOX headers will be opened in edit window */
828 if (modest_tny_folder_is_local_folder (folder))
829 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
831 /* If the header is in the drafts folder then open the editor,
832 else the message view window */
833 if ((folder_type == TNY_FOLDER_TYPE_DRAFTS) ||
834 (folder_type == TNY_FOLDER_TYPE_OUTBOX)) {
835 /* we cannot edit without a valid account... */
836 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
837 const gboolean created = modest_run_account_setup_wizard(parent_win);
841 win = modest_msg_edit_window_new (msg, account, TRUE);
844 gchar *uid = modest_tny_folder_get_header_unique_id (header);
846 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
847 GtkWidget *header_view;
848 GtkTreeSelection *sel;
849 GList *sel_list = NULL;
852 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
853 MODEST_WIDGET_TYPE_HEADER_VIEW);
855 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
856 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
858 if (sel_list != NULL) {
859 GtkTreeRowReference *row_reference;
861 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
862 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
863 g_list_free (sel_list);
865 win = modest_msg_view_window_new_with_header_model (
866 msg, account, (const gchar*) uid,
867 model, row_reference);
868 gtk_tree_row_reference_free (row_reference);
870 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
873 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
878 /* Register and show new window */
880 mgr = modest_runtime_get_window_mgr ();
881 modest_window_mgr_register_window (mgr, win);
882 g_object_unref (win);
883 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
884 gtk_widget_show_all (GTK_WIDGET(win));
887 /* Update toolbar dimming state */
888 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
889 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
895 g_object_unref (parent_win);
896 g_object_unref (folder);
900 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
904 GObject *win = modest_mail_operation_get_source (mail_op);
906 error = modest_mail_operation_get_error (mail_op);
907 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, error->code, error->message);
909 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
911 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
914 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
915 _("mail_ni_ui_folder_get_msg_folder_error"));
919 g_object_unref (win);
923 * This function is used by both modest_ui_actions_on_open and
924 * modest_ui_actions_on_header_activated. This way we always do the
925 * same when trying to open messages.
928 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
930 ModestWindowMgr *mgr = NULL;
931 TnyIterator *iter = NULL;
932 ModestMailOperation *mail_op = NULL;
933 TnyList *not_opened_headers = NULL;
934 TnyHeaderFlags flags = 0;
936 /* Look if we already have a message view for each header. If
937 true, then remove the header from the list of headers to
939 mgr = modest_runtime_get_window_mgr ();
940 iter = tny_list_create_iterator (headers);
941 not_opened_headers = tny_simple_list_new ();
943 while (!tny_iterator_is_done (iter)) {
945 ModestWindow *window = NULL;
946 TnyHeader *header = NULL;
947 gboolean found = FALSE;
949 header = TNY_HEADER (tny_iterator_get_current (iter));
951 flags = tny_header_get_flags (header);
954 found = modest_window_mgr_find_registered_header (mgr, header, &window);
956 /* Do not open again the message and present the
957 window to the user */
960 gtk_window_present (GTK_WINDOW (window));
962 /* the header has been registered already, we don't do
963 * anything but wait for the window to come up*/
964 g_debug ("header %p already registered, waiting for window", header);
966 tny_list_append (not_opened_headers, G_OBJECT (header));
970 g_object_unref (header);
972 tny_iterator_next (iter);
974 g_object_unref (iter);
977 /* If some messages would have to be downloaded, ask the user to
978 * make a connection. It's generally easier to do this here (in the mainloop)
979 * than later in a thread:
981 if (tny_list_get_length (not_opened_headers) > 0) {
983 gboolean found = FALSE;
985 iter = tny_list_create_iterator (not_opened_headers);
986 while (!tny_iterator_is_done (iter) && !found) {
987 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
988 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
991 tny_iterator_next (iter);
993 g_object_unref (header);
995 g_object_unref (iter);
997 if (found && !modest_platform_connect_and_wait (GTK_WINDOW (win), NULL)) {
998 g_object_unref (not_opened_headers);
1003 /* Register the headers before actually creating the windows: */
1004 TnyIterator *iter_not_opened = tny_list_create_iterator (not_opened_headers);
1005 while (!tny_iterator_is_done (iter_not_opened)) {
1006 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1008 modest_window_mgr_register_header (mgr, header);
1009 g_object_unref (header);
1012 tny_iterator_next (iter_not_opened);
1014 g_object_unref (iter_not_opened);
1015 iter_not_opened = NULL;
1017 /* Open each message */
1018 if (tny_list_get_length (not_opened_headers) > 0) {
1019 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1021 modest_ui_actions_get_msgs_full_error_handler,
1023 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1024 if (tny_list_get_length (not_opened_headers) > 1) {
1025 modest_mail_operation_get_msgs_full (mail_op,
1031 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1032 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1033 modest_mail_operation_get_msg (mail_op, header, open_msg_cb, NULL);
1034 g_object_unref (header);
1035 g_object_unref (iter);
1037 g_object_unref (mail_op);
1041 if (not_opened_headers != NULL)
1042 g_object_unref (not_opened_headers);
1046 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1051 headers = get_selected_headers (win);
1056 _modest_ui_actions_open (headers, win);
1058 g_object_unref(headers);
1063 free_reply_forward_helper (gpointer data)
1065 ReplyForwardHelper *helper;
1067 helper = (ReplyForwardHelper *) data;
1068 g_free (helper->account_name);
1069 g_slice_free (ReplyForwardHelper, helper);
1073 reply_forward_cb (ModestMailOperation *mail_op,
1079 ReplyForwardHelper *rf_helper;
1080 ModestWindow *msg_win = NULL;
1081 ModestEditType edit_type;
1083 TnyAccount *account = NULL;
1084 ModestWindowMgr *mgr = NULL;
1085 gchar *signature = NULL;
1087 /* If there was any error. The mail operation could be NULL,
1088 this means that we already have the message downloaded and
1089 that we didn't do a mail operation to retrieve it */
1090 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1093 g_return_if_fail (user_data != NULL);
1094 rf_helper = (ReplyForwardHelper *) user_data;
1096 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1097 rf_helper->account_name);
1098 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
1099 rf_helper->account_name,
1100 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
1101 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
1102 rf_helper->account_name,
1103 MODEST_ACCOUNT_SIGNATURE, FALSE);
1106 /* Create reply mail */
1107 switch (rf_helper->action) {
1110 modest_tny_msg_create_reply_msg (msg, header, from, signature,
1111 rf_helper->reply_forward_type,
1112 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1114 case ACTION_REPLY_TO_ALL:
1116 modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1117 MODEST_TNY_MSG_REPLY_MODE_ALL);
1118 edit_type = MODEST_EDIT_TYPE_REPLY;
1120 case ACTION_FORWARD:
1122 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1123 edit_type = MODEST_EDIT_TYPE_FORWARD;
1126 g_return_if_reached ();
1133 g_printerr ("modest: failed to create message\n");
1137 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1138 rf_helper->account_name,
1139 TNY_ACCOUNT_TYPE_STORE);
1141 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1145 /* Create and register the windows */
1146 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1147 mgr = modest_runtime_get_window_mgr ();
1148 modest_window_mgr_register_window (mgr, msg_win);
1150 if (rf_helper->parent_window != NULL) {
1151 gdouble parent_zoom;
1153 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1154 modest_window_set_zoom (msg_win, parent_zoom);
1157 /* Show edit window */
1158 gtk_widget_show_all (GTK_WIDGET (msg_win));
1162 g_object_unref (msg_win);
1164 g_object_unref (G_OBJECT (new_msg));
1166 g_object_unref (G_OBJECT (account));
1167 /* g_object_unref (msg); */
1168 free_reply_forward_helper (rf_helper);
1172 * Checks a list of headers. If any of them are not currently
1173 * downloaded (CACHED) then it asks the user for permission to
1176 * Returns FALSE if the user does not want to download the
1177 * messages. Returns TRUE if the user allowed the download or if all
1178 * of them are currently downloaded
1181 download_uncached_messages (TnyList *header_list,
1186 gint uncached_messages = 0;
1188 iter = tny_list_create_iterator (header_list);
1189 while (!tny_iterator_is_done (iter)) {
1192 header = TNY_HEADER (tny_iterator_get_current (iter));
1194 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1195 uncached_messages ++;
1196 g_object_unref (header);
1199 tny_iterator_next (iter);
1201 g_object_unref (iter);
1203 /* Ask for user permission to download the messages */
1205 if (uncached_messages > 0) {
1206 gboolean download = TRUE;
1207 if (!tny_device_is_online (modest_runtime_get_device())) {
1208 GtkResponseType response =
1209 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1210 ngettext("mcen_nc_get_msg",
1212 uncached_messages));
1213 if (response == GTK_RESPONSE_CANCEL) download = FALSE;
1216 /* If a download will be necessary, make sure that we have a connection: */
1217 retval = modest_platform_connect_and_wait(win, NULL);
1227 * Common code for the reply and forward actions
1230 reply_forward (ReplyForwardAction action, ModestWindow *win)
1232 ModestMailOperation *mail_op = NULL;
1233 TnyList *header_list = NULL;
1234 ReplyForwardHelper *rf_helper = NULL;
1235 guint reply_forward_type;
1236 gboolean continue_download = TRUE;
1237 gboolean do_retrieve = TRUE;
1239 g_return_if_fail (MODEST_IS_WINDOW(win));
1241 /* we need an account when editing */
1242 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1243 const gboolean created = modest_run_account_setup_wizard (win);
1248 header_list = get_selected_headers (win);
1252 reply_forward_type =
1253 modest_conf_get_int (modest_runtime_get_conf (),
1254 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1257 /* Check that the messages have been previously downloaded */
1258 do_retrieve = (action == ACTION_FORWARD) || (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1260 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
1261 if (!continue_download) {
1262 g_object_unref (header_list);
1266 /* We assume that we can only select messages of the
1267 same folder and that we reply all of them from the
1268 same account. In fact the interface currently only
1269 allows single selection */
1272 rf_helper = g_slice_new0 (ReplyForwardHelper);
1273 rf_helper->reply_forward_type = reply_forward_type;
1274 rf_helper->action = action;
1275 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1277 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1278 rf_helper->parent_window = GTK_WIDGET (win);
1279 if (!rf_helper->account_name)
1280 rf_helper->account_name =
1281 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1283 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1286 /* Get header and message. Do not free them here, the
1287 reply_forward_cb must do it */
1288 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1289 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1290 if (!msg || !header) {
1292 g_object_unref (msg);
1293 g_printerr ("modest: no message found\n");
1296 reply_forward_cb (NULL, header, msg, rf_helper);
1299 g_object_unref (header);
1304 /* Only reply/forward to one message */
1305 iter = tny_list_create_iterator (header_list);
1306 header = TNY_HEADER (tny_iterator_get_current (iter));
1307 g_object_unref (iter);
1310 /* Retrieve messages */
1312 mail_op = modest_mail_operation_new_with_error_handling (
1313 MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1315 modest_ui_actions_get_msgs_full_error_handler,
1317 modest_mail_operation_queue_add (
1318 modest_runtime_get_mail_operation_queue (), mail_op);
1320 modest_mail_operation_get_msg (mail_op,
1325 g_object_unref(mail_op);
1327 /* we put a ref here to prevent double unref as the reply
1328 * forward callback unrefs the header at its end */
1329 reply_forward_cb (NULL, header, NULL, rf_helper);
1333 g_object_unref (header);
1339 g_object_unref (header_list);
1343 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1345 g_return_if_fail (MODEST_IS_WINDOW(win));
1347 reply_forward (ACTION_REPLY, win);
1351 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1353 g_return_if_fail (MODEST_IS_WINDOW(win));
1355 reply_forward (ACTION_FORWARD, win);
1359 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1361 g_return_if_fail (MODEST_IS_WINDOW(win));
1363 reply_forward (ACTION_REPLY_TO_ALL, win);
1367 modest_ui_actions_on_next (GtkAction *action,
1368 ModestWindow *window)
1370 if (MODEST_IS_MAIN_WINDOW (window)) {
1371 GtkWidget *header_view;
1373 header_view = modest_main_window_get_child_widget (
1374 MODEST_MAIN_WINDOW(window),
1375 MODEST_WIDGET_TYPE_HEADER_VIEW);
1379 modest_header_view_select_next (
1380 MODEST_HEADER_VIEW(header_view));
1381 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1382 modest_msg_view_window_select_next_message (
1383 MODEST_MSG_VIEW_WINDOW (window));
1385 g_return_if_reached ();
1390 modest_ui_actions_on_prev (GtkAction *action,
1391 ModestWindow *window)
1393 g_return_if_fail (MODEST_IS_WINDOW(window));
1395 if (MODEST_IS_MAIN_WINDOW (window)) {
1396 GtkWidget *header_view;
1397 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1398 MODEST_WIDGET_TYPE_HEADER_VIEW);
1402 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1403 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1404 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1406 g_return_if_reached ();
1411 modest_ui_actions_on_sort (GtkAction *action,
1412 ModestWindow *window)
1414 g_return_if_fail (MODEST_IS_WINDOW(window));
1416 if (MODEST_IS_MAIN_WINDOW (window)) {
1417 GtkWidget *header_view;
1418 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1419 MODEST_WIDGET_TYPE_HEADER_VIEW);
1421 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1426 /* Show sorting dialog */
1427 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1432 new_messages_arrived (ModestMailOperation *self,
1436 ModestMainWindow *win = NULL;
1437 GtkWidget *folder_view = NULL;
1438 TnyFolderStore *folder = NULL;
1439 gboolean folder_empty = FALSE;
1441 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
1442 win = MODEST_MAIN_WINDOW (user_data);
1444 /* Set contents style of headers view */
1445 if (modest_main_window_get_contents_style (win) == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1446 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1447 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1448 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1451 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1454 modest_main_window_set_contents_style (win,
1455 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1458 /* Notify new messages have been downloaded */
1459 if (new_messages > 0)
1460 modest_platform_on_new_msg ();
1464 * This function performs the send & receive required actions. The
1465 * window is used to create the mail operation. Typically it should
1466 * always be the main window, but we pass it as argument in order to
1470 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1472 gchar *acc_name = NULL;
1473 ModestMailOperation *mail_op;
1475 /* If no account name was provided then get the current account, and if
1476 there is no current account then pick the default one: */
1477 if (!account_name) {
1478 acc_name = g_strdup (modest_window_get_active_account(win));
1480 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1482 g_printerr ("modest: cannot get default account\n");
1486 acc_name = g_strdup (account_name);
1489 /* Set send/receive operation in progress */
1490 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1492 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1494 modest_ui_actions_send_receive_error_handler,
1497 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1498 G_CALLBACK (_on_send_receive_progress_changed),
1501 /* Send & receive. */
1502 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1503 /* Receive and then send. The operation is tagged initially as
1504 a receive operation because the account update performs a
1505 receive and then a send. The operation changes its type
1506 internally, so the progress objects will receive the proper
1507 progress information */
1508 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1509 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, win);
1510 g_object_unref (G_OBJECT (mail_op));
1518 modest_ui_actions_do_cancel_send (const gchar *account_name,
1521 TnyTransportAccount *transport_account;
1522 TnySendQueue *send_queue = NULL;
1523 GError *error = NULL;
1525 /* Get transport account */
1527 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1528 (modest_runtime_get_account_store(),
1530 TNY_ACCOUNT_TYPE_TRANSPORT));
1531 if (!transport_account) {
1532 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1537 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1538 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1539 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1540 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1541 "modest: could not find send queue for account\n");
1543 /* Keeep messages in outbox folder */
1544 tny_send_queue_cancel (send_queue, FALSE, &error);
1548 if (transport_account != NULL)
1549 g_object_unref (G_OBJECT (transport_account));
1553 modest_ui_actions_cancel_send_all (ModestWindow *win)
1555 GSList *account_names, *iter;
1557 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1560 iter = account_names;
1562 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1563 iter = g_slist_next (iter);
1566 modest_account_mgr_free_account_names (account_names);
1567 account_names = NULL;
1571 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1574 /* Check if accounts exist */
1575 gboolean accounts_exist =
1576 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1578 /* If not, allow the user to create an account before trying to send/receive. */
1579 if (!accounts_exist)
1580 modest_ui_actions_on_accounts (NULL, win);
1582 /* Cancel all sending operaitons */
1583 modest_ui_actions_cancel_send_all (win);
1587 * Refreshes all accounts. This function will be used by automatic
1591 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1593 GSList *account_names, *iter;
1595 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1598 iter = account_names;
1600 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1601 iter = g_slist_next (iter);
1604 modest_account_mgr_free_account_names (account_names);
1605 account_names = NULL;
1609 modest_do_refresh_current_folder(ModestWindow *win)
1611 /* Refresh currently selected folder. Note that if we only
1612 want to retreive the headers, then the refresh only will
1613 invoke a poke_status over all folders, i.e., only the
1614 total/unread count will be updated */
1615 if (MODEST_IS_MAIN_WINDOW (win)) {
1616 GtkWidget *header_view, *folder_view;
1617 TnyFolderStore *folder_store;
1619 /* Get folder and header view */
1621 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1622 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1624 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1626 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1628 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1629 MODEST_WIDGET_TYPE_HEADER_VIEW);
1631 /* We do not need to set the contents style
1632 because it hasn't changed. We also do not
1633 need to save the widget status. Just force
1635 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1636 TNY_FOLDER (folder_store),
1637 folder_refreshed_cb,
1638 MODEST_MAIN_WINDOW (win));
1642 g_object_unref (folder_store);
1648 * Handler of the click on Send&Receive button in the main toolbar
1651 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1653 /* Check if accounts exist */
1654 gboolean accounts_exist =
1655 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1657 /* If not, allow the user to create an account before trying to send/receive. */
1658 if (!accounts_exist)
1659 modest_ui_actions_on_accounts (NULL, win);
1661 modest_do_refresh_current_folder (win);
1663 /* Refresh the active account */
1664 modest_ui_actions_do_send_receive (NULL, win);
1669 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1672 GtkWidget *header_view;
1674 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1676 header_view = modest_main_window_get_child_widget (main_window,
1677 MODEST_WIDGET_TYPE_HEADER_VIEW);
1681 conf = modest_runtime_get_conf ();
1683 /* what is saved/restored is depending on the style; thus; we save with
1684 * old style, then update the style, and restore for this new style
1686 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1688 if (modest_header_view_get_style
1689 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1690 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1691 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1693 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1694 MODEST_HEADER_VIEW_STYLE_DETAILS);
1696 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1697 MODEST_CONF_HEADER_VIEW_KEY);
1702 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1704 ModestMainWindow *main_window)
1706 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1707 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1709 /* in the case the folder is empty, show the empty folder message and focus
1711 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1712 if (modest_header_view_is_empty (header_view)) {
1713 TnyFolder *folder = modest_header_view_get_folder (header_view);
1714 GtkWidget *folder_view =
1715 modest_main_window_get_child_widget (main_window,
1716 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1718 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1719 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1723 /* If no header has been selected then exit */
1728 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1729 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1731 /* Update toolbar dimming state */
1732 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1736 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1738 ModestMainWindow *main_window)
1742 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1747 headers = tny_simple_list_new ();
1748 tny_list_prepend (headers, G_OBJECT (header));
1750 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1752 g_object_unref (headers);
1756 set_active_account_from_tny_account (TnyAccount *account,
1757 ModestWindow *window)
1759 const gchar *server_acc_name = tny_account_get_id (account);
1761 /* We need the TnyAccount provided by the
1762 account store because that is the one that
1763 knows the name of the Modest account */
1764 TnyAccount *modest_server_account = modest_server_account =
1765 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1766 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1769 const gchar *modest_acc_name =
1770 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1771 modest_window_set_active_account (window, modest_acc_name);
1772 g_object_unref (modest_server_account);
1777 folder_refreshed_cb (ModestMailOperation *mail_op,
1781 ModestMainWindow *win = NULL;
1782 GtkWidget *header_view;
1783 TnyFolder *current_folder;
1784 gboolean folder_empty = FALSE;
1785 gboolean all_marked_as_deleted = FALSE;
1787 g_return_if_fail (TNY_IS_FOLDER (folder));
1789 win = MODEST_MAIN_WINDOW (user_data);
1791 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1794 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1795 if (current_folder != NULL && folder != current_folder) {
1800 /* Check if folder is empty and set headers view contents style */
1801 folder_empty = (tny_folder_get_all_count (folder) == 0);
1802 all_marked_as_deleted = modest_header_view_is_empty (MODEST_HEADER_VIEW(header_view));
1803 folder_empty = folder_empty || all_marked_as_deleted ;
1806 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1807 modest_main_window_set_contents_style (win,
1808 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1810 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1815 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1816 TnyFolderStore *folder_store,
1818 ModestMainWindow *main_window)
1821 GtkWidget *header_view;
1823 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1825 header_view = modest_main_window_get_child_widget(main_window,
1826 MODEST_WIDGET_TYPE_HEADER_VIEW);
1830 conf = modest_runtime_get_conf ();
1832 if (TNY_IS_ACCOUNT (folder_store)) {
1834 /* Update active account */
1835 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1836 /* Show account details */
1837 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1840 if (TNY_IS_FOLDER (folder_store) && selected) {
1842 /* Update the active account */
1843 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1845 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1846 g_object_unref (account);
1850 /* Set the header style by default, it could
1851 be changed later by the refresh callback to
1853 modest_main_window_set_contents_style (main_window,
1854 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1856 /* Set folder on header view. This function
1857 will call tny_folder_refresh_async so we
1858 pass a callback that will be called when
1859 finished. We use that callback to set the
1860 empty view if there are no messages */
1861 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1862 TNY_FOLDER (folder_store),
1863 folder_refreshed_cb,
1866 /* Restore configuration. We need to do this
1867 *after* the set_folder because the widget
1868 memory asks the header view about its
1870 modest_widget_memory_restore (modest_runtime_get_conf (),
1871 G_OBJECT(header_view),
1872 MODEST_CONF_HEADER_VIEW_KEY);
1874 /* Update the active account */
1875 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1876 /* Save only if we're seeing headers */
1877 if (modest_main_window_get_contents_style (main_window) ==
1878 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1879 modest_widget_memory_save (conf, G_OBJECT (header_view),
1880 MODEST_CONF_HEADER_VIEW_KEY);
1881 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1885 /* Update toolbar dimming state */
1886 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1890 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1897 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1899 online = tny_device_is_online (modest_runtime_get_device());
1902 /* already online -- the item is simply not there... */
1903 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1905 GTK_MESSAGE_WARNING,
1907 _("The %s you selected cannot be found"),
1909 gtk_dialog_run (GTK_DIALOG(dialog));
1911 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1915 GTK_RESPONSE_REJECT,
1917 GTK_RESPONSE_ACCEPT,
1919 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1920 "Do you want to get online?"), item);
1921 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1922 gtk_label_new (txt), FALSE, FALSE, 0);
1923 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1926 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1927 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1928 /* TODO: Comment about why is this commented out: */
1929 /* modest_platform_connect_and_wait (); */
1932 gtk_widget_destroy (dialog);
1936 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1939 /* g_message ("%s %s", __FUNCTION__, link); */
1944 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1947 modest_platform_activate_uri (link);
1951 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1954 modest_platform_show_uri_popup (link);
1958 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1961 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1965 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1966 const gchar *address,
1969 /* g_message ("%s %s", __FUNCTION__, address); */
1973 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1975 TnyTransportAccount *transport_account;
1976 ModestMailOperation *mail_operation;
1978 gchar *account_name, *from;
1979 ModestAccountMgr *account_mgr;
1980 gchar *info_text = NULL;
1982 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1984 data = modest_msg_edit_window_get_msg_data (edit_window);
1986 account_mgr = modest_runtime_get_account_mgr();
1987 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1989 account_name = modest_account_mgr_get_default_account (account_mgr);
1990 if (!account_name) {
1991 g_printerr ("modest: no account found\n");
1992 modest_msg_edit_window_free_msg_data (edit_window, data);
1996 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1997 account_name = g_strdup (data->account_name);
2001 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2002 (modest_runtime_get_account_store(),
2004 TNY_ACCOUNT_TYPE_TRANSPORT));
2005 if (!transport_account) {
2006 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2007 g_free (account_name);
2008 modest_msg_edit_window_free_msg_data (edit_window, data);
2011 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2013 /* Create the mail operation */
2014 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
2015 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2017 modest_mail_operation_save_to_drafts (mail_operation,
2029 data->priority_flags);
2032 g_free (account_name);
2033 g_object_unref (G_OBJECT (transport_account));
2034 g_object_unref (G_OBJECT (mail_operation));
2036 modest_msg_edit_window_free_msg_data (edit_window, data);
2038 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2039 modest_platform_information_banner (NULL, NULL, info_text);
2043 /* For instance, when clicking the Send toolbar button when editing a message: */
2045 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2047 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2049 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2052 /* Offer the connection dialog, if necessary: */
2053 if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
2056 /* FIXME: Code added just for testing. The final version will
2057 use the send queue provided by tinymail and some
2059 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2060 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2062 account_name = modest_account_mgr_get_default_account (account_mgr);
2064 if (!account_name) {
2065 /* Run account setup wizard */
2066 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2071 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2073 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2074 account_name = g_strdup (data->account_name);
2077 /* Get the currently-active transport account for this modest account: */
2078 TnyTransportAccount *transport_account =
2079 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2080 (modest_runtime_get_account_store(),
2082 if (!transport_account) {
2083 /* Run account setup wizard */
2084 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2089 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2091 /* modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent")); */
2093 /* Create the mail operation */
2094 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
2095 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2097 modest_mail_operation_send_new_mail (mail_operation,
2108 data->priority_flags);
2112 g_free (account_name);
2113 g_object_unref (G_OBJECT (transport_account));
2114 g_object_unref (G_OBJECT (mail_operation));
2116 modest_msg_edit_window_free_msg_data (edit_window, data);
2117 modest_msg_edit_window_set_sent (edit_window, TRUE);
2119 /* Save settings and close the window: */
2120 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2124 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2125 ModestMsgEditWindow *window)
2127 ModestMsgEditFormatState *format_state = NULL;
2129 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2130 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2132 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2135 format_state = modest_msg_edit_window_get_format_state (window);
2136 g_return_if_fail (format_state != NULL);
2138 format_state->bold = gtk_toggle_action_get_active (action);
2139 modest_msg_edit_window_set_format_state (window, format_state);
2140 g_free (format_state);
2145 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2146 ModestMsgEditWindow *window)
2148 ModestMsgEditFormatState *format_state = NULL;
2150 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2151 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2153 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2156 format_state = modest_msg_edit_window_get_format_state (window);
2157 g_return_if_fail (format_state != NULL);
2159 format_state->italics = gtk_toggle_action_get_active (action);
2160 modest_msg_edit_window_set_format_state (window, format_state);
2161 g_free (format_state);
2166 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2167 ModestMsgEditWindow *window)
2169 ModestMsgEditFormatState *format_state = NULL;
2171 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2172 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2174 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2177 format_state = modest_msg_edit_window_get_format_state (window);
2178 g_return_if_fail (format_state != NULL);
2180 format_state->bullet = gtk_toggle_action_get_active (action);
2181 modest_msg_edit_window_set_format_state (window, format_state);
2182 g_free (format_state);
2187 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2188 GtkRadioAction *selected,
2189 ModestMsgEditWindow *window)
2191 ModestMsgEditFormatState *format_state = NULL;
2192 GtkJustification value;
2194 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2196 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2199 value = gtk_radio_action_get_current_value (selected);
2201 format_state = modest_msg_edit_window_get_format_state (window);
2202 g_return_if_fail (format_state != NULL);
2204 format_state->justification = value;
2205 modest_msg_edit_window_set_format_state (window, format_state);
2206 g_free (format_state);
2210 modest_ui_actions_on_select_editor_color (GtkAction *action,
2211 ModestMsgEditWindow *window)
2213 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2214 g_return_if_fail (GTK_IS_ACTION (action));
2216 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2219 modest_msg_edit_window_select_color (window);
2223 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2224 ModestMsgEditWindow *window)
2226 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2227 g_return_if_fail (GTK_IS_ACTION (action));
2229 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2232 modest_msg_edit_window_select_background_color (window);
2236 modest_ui_actions_on_insert_image (GtkAction *action,
2237 ModestMsgEditWindow *window)
2239 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2240 g_return_if_fail (GTK_IS_ACTION (action));
2242 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2245 modest_msg_edit_window_insert_image (window);
2249 modest_ui_actions_on_attach_file (GtkAction *action,
2250 ModestMsgEditWindow *window)
2252 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2253 g_return_if_fail (GTK_IS_ACTION (action));
2255 modest_msg_edit_window_offer_attach_file (window);
2259 modest_ui_actions_on_remove_attachments (GtkAction *action,
2260 ModestMsgEditWindow *window)
2262 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2263 g_return_if_fail (GTK_IS_ACTION (action));
2265 modest_msg_edit_window_remove_attachments (window, NULL);
2269 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2272 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2273 const GError *error = modest_mail_operation_get_error (mail_op);
2277 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2278 modest_mail_operation_get_error (mail_op)->message);
2283 modest_ui_actions_create_folder(GtkWidget *parent_window,
2284 GtkWidget *folder_view)
2286 TnyFolderStore *parent_folder;
2288 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2290 if (parent_folder) {
2291 gboolean finished = FALSE;
2293 gchar *folder_name = NULL, *suggested_name = NULL;
2294 const gchar *proto_str = NULL;
2295 TnyAccount *account;
2297 if (TNY_IS_ACCOUNT (parent_folder))
2298 account = g_object_ref (parent_folder);
2300 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2301 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2303 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2304 MODEST_PROTOCOL_STORE_POP) {
2306 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2308 g_object_unref (account);
2310 /* Run the new folder dialog */
2312 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2317 g_free (suggested_name);
2318 suggested_name = NULL;
2320 if (result == GTK_RESPONSE_REJECT) {
2323 ModestMailOperation *mail_op;
2324 TnyFolder *new_folder = NULL;
2326 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2327 G_OBJECT(parent_window),
2328 modest_ui_actions_new_folder_error_handler,
2331 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2333 new_folder = modest_mail_operation_create_folder (mail_op,
2335 (const gchar *) folder_name);
2337 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2340 g_object_unref (new_folder);
2343 g_object_unref (mail_op);
2346 suggested_name = folder_name;
2350 g_object_unref (parent_folder);
2355 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2357 GtkWidget *folder_view;
2359 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2361 folder_view = modest_main_window_get_child_widget (main_window,
2362 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2366 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2370 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2373 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2374 const GError *error = NULL;
2375 const gchar *message = NULL;
2377 /* Get error message */
2378 error = modest_mail_operation_get_error (mail_op);
2379 if (error != NULL && error->message != NULL) {
2380 message = error->message;
2382 message = _("!!! FIXME: Unable to rename");
2385 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2390 modest_ui_actions_on_rename_folder (GtkAction *action,
2391 ModestMainWindow *main_window)
2393 TnyFolderStore *folder;
2394 GtkWidget *folder_view;
2395 GtkWidget *header_view;
2397 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2399 folder_view = modest_main_window_get_child_widget (main_window,
2400 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2404 header_view = modest_main_window_get_child_widget (main_window,
2405 MODEST_WIDGET_TYPE_HEADER_VIEW);
2410 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2414 /* Offer the connection dialog if necessary: */
2415 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2416 g_object_unref (G_OBJECT (folder));
2421 if (TNY_IS_FOLDER (folder)) {
2424 const gchar *current_name;
2425 TnyFolderStore *parent;
2427 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2428 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
2429 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
2430 parent, current_name,
2432 g_object_unref (parent);
2434 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
2435 ModestMailOperation *mail_op;
2438 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2439 G_OBJECT(main_window),
2440 modest_ui_actions_rename_folder_error_handler,
2444 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2447 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2449 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2450 TNY_FOLDER(folder), TRUE);
2452 modest_header_view_clear ((ModestHeaderView *) header_view);
2454 modest_mail_operation_rename_folder (mail_op,
2455 TNY_FOLDER (folder),
2456 (const gchar *) folder_name);
2458 g_object_unref (mail_op);
2459 g_free (folder_name);
2462 g_object_unref (folder);
2466 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2469 GObject *win = modest_mail_operation_get_source (mail_op);
2471 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2472 _("mail_in_ui_folder_delete_error"));
2473 g_object_unref (win);
2477 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2479 TnyFolderStore *folder;
2480 GtkWidget *folder_view;
2484 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
2486 folder_view = modest_main_window_get_child_widget (main_window,
2487 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2491 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2493 /* Show an error if it's an account */
2494 if (!TNY_IS_FOLDER (folder)) {
2495 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2496 _("mail_in_ui_folder_delete_error"));
2497 g_object_unref (G_OBJECT (folder));
2501 /* Offer the connection dialog if necessary: */
2502 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2503 g_object_unref (G_OBJECT (folder));
2508 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2509 tny_folder_get_name (TNY_FOLDER (folder)));
2510 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2511 (const gchar *) message);
2514 if (response == GTK_RESPONSE_OK) {
2515 ModestMailOperation *mail_op =
2516 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2517 G_OBJECT(main_window),
2518 modest_ui_actions_delete_folder_error_handler,
2521 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2523 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2524 g_object_unref (G_OBJECT (mail_op));
2527 g_object_unref (G_OBJECT (folder));
2531 modest_ui_actions_on_delete_folder (GtkAction *action,
2532 ModestMainWindow *main_window)
2534 GtkWidget *folder_view;
2535 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2537 delete_folder (main_window, FALSE);
2538 folder_view = modest_main_window_get_child_widget (main_window,
2539 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2542 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2546 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2548 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2550 delete_folder (main_window, TRUE);
2555 show_error (GtkWidget *parent_widget, const gchar* text)
2557 hildon_banner_show_information(parent_widget, NULL, text);
2560 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2562 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2569 gtk_dialog_run (dialog);
2570 gtk_widget_destroy (GTK_WIDGET (dialog));
2575 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2576 const gchar* server_account_name,
2581 ModestMainWindow *main_window)
2583 g_return_if_fail(server_account_name);
2584 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2586 /* Initalize output parameters: */
2593 #ifdef MODEST_PLATFORM_MAEMO
2594 /* Maemo uses a different (awkward) button order,
2595 * It should probably just use gtk_alternative_dialog_button_order ().
2597 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2601 GTK_RESPONSE_ACCEPT,
2603 GTK_RESPONSE_REJECT,
2606 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2610 GTK_RESPONSE_REJECT,
2612 GTK_RESPONSE_ACCEPT,
2614 #endif /* MODEST_PLATFORM_MAEMO */
2616 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2618 gchar *server_name = modest_server_account_get_hostname (
2619 modest_runtime_get_account_mgr(), server_account_name);
2620 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2621 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2626 /* This causes a warning because the logical ID has no %s in it,
2627 * though the translation does, but there is not much we can do about that: */
2628 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2629 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2632 g_free (server_name);
2636 gchar *initial_username = modest_server_account_get_username (
2637 modest_runtime_get_account_mgr(), server_account_name);
2639 GtkWidget *entry_username = gtk_entry_new ();
2640 if (initial_username)
2641 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2642 /* Dim this if a connection has ever succeeded with this username,
2643 * as per the UI spec: */
2644 const gboolean username_known =
2645 modest_server_account_get_username_has_succeeded(
2646 modest_runtime_get_account_mgr(), server_account_name);
2647 gtk_widget_set_sensitive (entry_username, !username_known);
2649 #ifdef MODEST_PLATFORM_MAEMO
2650 /* Auto-capitalization is the default, so let's turn it off: */
2651 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2653 /* Create a size group to be used by all captions.
2654 * Note that HildonCaption does not create a default size group if we do not specify one.
2655 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2656 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2658 GtkWidget *caption = hildon_caption_new (sizegroup,
2659 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2660 gtk_widget_show (entry_username);
2661 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2662 FALSE, FALSE, MODEST_MARGIN_HALF);
2663 gtk_widget_show (caption);
2665 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2667 #endif /* MODEST_PLATFORM_MAEMO */
2670 GtkWidget *entry_password = gtk_entry_new ();
2671 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2672 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2674 #ifdef MODEST_PLATFORM_MAEMO
2675 /* Auto-capitalization is the default, so let's turn it off: */
2676 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2677 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2679 caption = hildon_caption_new (sizegroup,
2680 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2681 gtk_widget_show (entry_password);
2682 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2683 FALSE, FALSE, MODEST_MARGIN_HALF);
2684 gtk_widget_show (caption);
2685 g_object_unref (sizegroup);
2687 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2689 #endif /* MODEST_PLATFORM_MAEMO */
2691 /* This is not in the Maemo UI spec:
2692 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2693 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2697 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2699 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2701 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2703 modest_server_account_set_username (
2704 modest_runtime_get_account_mgr(), server_account_name,
2707 const gboolean username_was_changed =
2708 (strcmp (*username, initial_username) != 0);
2709 if (username_was_changed) {
2710 g_warning ("%s: tinymail does not yet support changing the "
2711 "username in the get_password() callback.\n", __FUNCTION__);
2716 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2718 /* We do not save the password in the configuration,
2719 * because this function is only called for passwords that should
2720 * not be remembered:
2721 modest_server_account_set_password (
2722 modest_runtime_get_account_mgr(), server_account_name,
2731 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2743 /* This is not in the Maemo UI spec:
2744 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2750 gtk_widget_destroy (dialog);
2752 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2756 modest_ui_actions_on_cut (GtkAction *action,
2757 ModestWindow *window)
2759 GtkWidget *focused_widget;
2760 GtkClipboard *clipboard;
2762 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2763 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2764 if (GTK_IS_EDITABLE (focused_widget)) {
2765 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2766 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2767 gtk_clipboard_store (clipboard);
2768 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2769 GtkTextBuffer *buffer;
2771 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2772 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2773 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2774 gtk_clipboard_store (clipboard);
2775 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2776 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2777 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2778 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2783 modest_ui_actions_on_copy (GtkAction *action,
2784 ModestWindow *window)
2786 GtkClipboard *clipboard;
2787 GtkWidget *focused_widget;
2789 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2790 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2792 if (GTK_IS_LABEL (focused_widget)) {
2793 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2794 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2795 gtk_clipboard_store (clipboard);
2796 } else if (GTK_IS_EDITABLE (focused_widget)) {
2797 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2798 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2799 gtk_clipboard_store (clipboard);
2800 } else if (GTK_IS_HTML (focused_widget)) {
2801 gtk_html_copy (GTK_HTML (focused_widget));
2802 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2803 gtk_clipboard_store (clipboard);
2804 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2805 GtkTextBuffer *buffer;
2806 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2807 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2808 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2809 gtk_clipboard_store (clipboard);
2810 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2811 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2812 TnyIterator *iter = tny_list_create_iterator (header_list);
2813 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2815 gboolean ask = FALSE;
2817 TnyFolder *folder = tny_header_get_folder (header);
2818 TnyAccount *account = tny_folder_get_account (folder);
2819 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2820 /* If it's POP then ask */
2821 ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2822 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2823 g_object_unref (account);
2824 g_object_unref (folder);
2825 g_object_unref (header);
2828 g_object_unref (iter);
2830 /* Check that the messages have been previously downloaded */
2831 gboolean continue_download = TRUE;
2833 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window));
2834 if (continue_download)
2835 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2836 g_object_unref (header_list);
2837 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2838 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2841 /* Show information banner */
2842 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2847 modest_ui_actions_on_undo (GtkAction *action,
2848 ModestWindow *window)
2850 ModestEmailClipboard *clipboard = NULL;
2852 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2853 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2854 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2855 /* Clear clipboard source */
2856 clipboard = modest_runtime_get_email_clipboard ();
2857 modest_email_clipboard_clear (clipboard);
2860 g_return_if_reached ();
2865 modest_ui_actions_on_redo (GtkAction *action,
2866 ModestWindow *window)
2868 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2869 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
2872 g_return_if_reached ();
2878 paste_msgs_cb (const GObject *object, gpointer user_data)
2880 g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2881 g_return_if_fail (GTK_IS_WIDGET (user_data));
2883 /* destroy information note */
2884 gtk_widget_destroy (GTK_WIDGET(user_data));
2888 paste_as_attachment_free (gpointer data)
2890 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
2892 gtk_widget_destroy (helper->banner);
2893 g_object_unref (helper->banner);
2898 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
2903 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
2904 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
2909 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
2914 modest_ui_actions_on_paste (GtkAction *action,
2915 ModestWindow *window)
2917 GtkWidget *focused_widget = NULL;
2918 GtkWidget *inf_note = NULL;
2919 ModestMailOperation *mail_op = NULL;
2921 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2922 if (GTK_IS_EDITABLE (focused_widget)) {
2923 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2924 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2925 ModestEmailClipboard *e_clipboard = NULL;
2926 e_clipboard = modest_runtime_get_email_clipboard ();
2927 if (modest_email_clipboard_cleared (e_clipboard)) {
2928 GtkTextBuffer *buffer;
2929 GtkClipboard *clipboard;
2931 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2932 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2933 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2934 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2935 ModestMailOperation *mail_op;
2936 TnyFolder *src_folder;
2939 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
2940 helper->window = MODEST_MSG_EDIT_WINDOW (window);
2941 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2942 _CS("ckct_nw_pasting"));
2943 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
2944 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2946 if (helper->banner != NULL) {
2947 g_object_ref (G_OBJECT (helper->banner));
2948 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
2949 gtk_widget_show (GTK_WIDGET (helper->banner));
2953 modest_mail_operation_get_msgs_full (mail_op,
2955 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
2957 paste_as_attachment_free);
2960 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2961 ModestEmailClipboard *clipboard = NULL;
2962 TnyFolder *src_folder = NULL;
2963 TnyFolderStore *folder_store = NULL;
2964 TnyList *data = NULL;
2965 gboolean delete = FALSE;
2967 /* Check clipboard source */
2968 clipboard = modest_runtime_get_email_clipboard ();
2969 if (modest_email_clipboard_cleared (clipboard))
2972 /* Get elements to paste */
2973 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2975 /* Create a new mail operation */
2976 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2978 /* Get destination folder */
2979 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2981 /* transfer messages */
2985 /* Ask for user confirmation */
2986 response = msgs_move_to_confirmation (GTK_WINDOW (window),
2987 TNY_FOLDER (folder_store),
2991 if (response == GTK_RESPONSE_OK) {
2992 /* Launch notification */
2993 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2994 _CS("ckct_nw_pasting"));
2995 if (inf_note != NULL) {
2996 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
2997 gtk_widget_show (GTK_WIDGET(inf_note));
3000 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3001 modest_mail_operation_xfer_msgs (mail_op,
3003 TNY_FOLDER (folder_store),
3008 g_object_unref (mail_op);
3011 } else if (src_folder != NULL) {
3012 /* Launch notification */
3013 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3014 _CS("ckct_nw_pasting"));
3015 if (inf_note != NULL) {
3016 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3017 gtk_widget_show (GTK_WIDGET(inf_note));
3020 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3021 modest_mail_operation_xfer_folder (mail_op,
3031 g_object_unref (data);
3032 if (src_folder != NULL)
3033 g_object_unref (src_folder);
3034 if (folder_store != NULL)
3035 g_object_unref (folder_store);
3041 modest_ui_actions_on_select_all (GtkAction *action,
3042 ModestWindow *window)
3044 GtkWidget *focused_widget;
3046 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3047 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3048 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3049 } else if (GTK_IS_LABEL (focused_widget)) {
3050 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3051 } else if (GTK_IS_EDITABLE (focused_widget)) {
3052 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3053 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3054 GtkTextBuffer *buffer;
3055 GtkTextIter start, end;
3057 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3058 gtk_text_buffer_get_start_iter (buffer, &start);
3059 gtk_text_buffer_get_end_iter (buffer, &end);
3060 gtk_text_buffer_select_range (buffer, &start, &end);
3061 } else if (GTK_IS_HTML (focused_widget)) {
3062 gtk_html_select_all (GTK_HTML (focused_widget));
3063 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3064 GtkWidget *header_view = focused_widget;
3065 GtkTreeSelection *selection = NULL;
3067 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
3068 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3069 MODEST_WIDGET_TYPE_HEADER_VIEW);
3071 /* Select all messages */
3072 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3073 gtk_tree_selection_select_all (selection);
3075 /* Set focuse on header view */
3076 gtk_widget_grab_focus (header_view);
3082 modest_ui_actions_on_mark_as_read (GtkAction *action,
3083 ModestWindow *window)
3085 g_return_if_fail (MODEST_IS_WINDOW(window));
3087 /* Mark each header as read */
3088 do_headers_action (window, headers_action_mark_as_read, NULL);
3092 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3093 ModestWindow *window)
3095 g_return_if_fail (MODEST_IS_WINDOW(window));
3097 /* Mark each header as read */
3098 do_headers_action (window, headers_action_mark_as_unread, NULL);
3102 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3103 GtkRadioAction *selected,
3104 ModestWindow *window)
3108 value = gtk_radio_action_get_current_value (selected);
3109 if (MODEST_IS_WINDOW (window)) {
3110 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3114 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3115 GtkRadioAction *selected,
3116 ModestWindow *window)
3118 TnyHeaderFlags flags;
3119 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3121 flags = gtk_radio_action_get_current_value (selected);
3122 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3125 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3126 GtkRadioAction *selected,
3127 ModestWindow *window)
3131 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3133 file_format = gtk_radio_action_get_current_value (selected);
3134 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3139 modest_ui_actions_on_zoom_plus (GtkAction *action,
3140 ModestWindow *window)
3142 g_return_if_fail (MODEST_IS_WINDOW (window));
3144 modest_window_zoom_plus (MODEST_WINDOW (window));
3148 modest_ui_actions_on_zoom_minus (GtkAction *action,
3149 ModestWindow *window)
3151 g_return_if_fail (MODEST_IS_WINDOW (window));
3153 modest_window_zoom_minus (MODEST_WINDOW (window));
3157 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3158 ModestWindow *window)
3160 ModestWindowMgr *mgr;
3161 gboolean fullscreen, active;
3162 g_return_if_fail (MODEST_IS_WINDOW (window));
3164 mgr = modest_runtime_get_window_mgr ();
3166 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3167 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3169 if (active != fullscreen) {
3170 modest_window_mgr_set_fullscreen_mode (mgr, active);
3171 gtk_window_present (GTK_WINDOW (window));
3176 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3177 ModestWindow *window)
3179 ModestWindowMgr *mgr;
3180 gboolean fullscreen;
3182 g_return_if_fail (MODEST_IS_WINDOW (window));
3184 mgr = modest_runtime_get_window_mgr ();
3185 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3186 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3188 gtk_window_present (GTK_WINDOW (window));
3192 * Used by modest_ui_actions_on_details to call do_headers_action
3195 headers_action_show_details (TnyHeader *header,
3196 ModestWindow *window,
3203 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3206 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3207 gtk_widget_show_all (dialog);
3208 gtk_dialog_run (GTK_DIALOG (dialog));
3210 gtk_widget_destroy (dialog);
3214 * Show the folder details in a ModestDetailsDialog widget
3217 show_folder_details (TnyFolder *folder,
3223 dialog = modest_details_dialog_new_with_folder (window, folder);
3226 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3227 gtk_widget_show_all (dialog);
3228 gtk_dialog_run (GTK_DIALOG (dialog));
3230 gtk_widget_destroy (dialog);
3234 * Show the header details in a ModestDetailsDialog widget
3237 modest_ui_actions_on_details (GtkAction *action,
3240 TnyList * headers_list;
3244 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3247 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3250 g_object_unref (msg);
3252 headers_list = get_selected_headers (win);
3256 iter = tny_list_create_iterator (headers_list);
3258 header = TNY_HEADER (tny_iterator_get_current (iter));
3260 headers_action_show_details (header, win, NULL);
3261 g_object_unref (header);
3264 g_object_unref (iter);
3265 g_object_unref (headers_list);
3267 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3268 GtkWidget *folder_view, *header_view;
3270 /* Check which widget has the focus */
3271 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3272 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3273 if (gtk_widget_is_focus (folder_view)) {
3274 TnyFolderStore *folder_store
3275 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3276 if (!folder_store) {
3277 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3280 /* Show only when it's a folder */
3281 /* This function should not be called for account items,
3282 * because we dim the menu item for them. */
3283 if (TNY_IS_FOLDER (folder_store)) {
3284 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3287 g_object_unref (folder_store);
3290 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3291 MODEST_WIDGET_TYPE_HEADER_VIEW);
3292 /* Show details of each header */
3293 do_headers_action (win, headers_action_show_details, header_view);
3299 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3300 ModestMsgEditWindow *window)
3302 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3304 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3308 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3309 ModestMsgEditWindow *window)
3311 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3313 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3317 modest_ui_actions_toggle_folders_view (GtkAction *action,
3318 ModestMainWindow *main_window)
3320 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3322 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3323 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3325 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3329 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3330 ModestWindow *window)
3332 gboolean active, fullscreen = FALSE;
3333 ModestWindowMgr *mgr;
3335 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3337 /* Check if we want to toggle the toolbar vuew in fullscreen
3339 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3340 "ViewShowToolbarFullScreen")) {
3344 /* Toggle toolbar */
3345 mgr = modest_runtime_get_window_mgr ();
3346 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
3350 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3351 ModestMsgEditWindow *window)
3353 modest_msg_edit_window_select_font (window);
3357 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3358 const gchar *display_name,
3361 /* Do not change the application name if the widget has not
3362 the focus. This callback could be called even if the folder
3363 view has not the focus, because the handled signal could be
3364 emitted when the folder view is redrawn */
3365 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3367 gtk_window_set_title (window, display_name);
3369 gtk_window_set_title (window, " ");
3374 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3376 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3377 modest_msg_edit_window_select_contacts (window);
3381 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3383 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3384 modest_msg_edit_window_check_names (window, FALSE);
3388 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3390 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3391 GTK_WIDGET (user_data));
3395 create_move_to_dialog (GtkWindow *win,
3396 GtkWidget *folder_view,
3397 GtkWidget **tree_view)
3399 GtkWidget *dialog, *scroll;
3400 GtkWidget *new_button;
3402 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3404 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3407 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
3408 /* We do this manually so GTK+ does not associate a response ID for
3410 new_button = gtk_button_new_from_stock (GTK_STOCK_NEW);
3411 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3412 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
3414 /* Create scrolled window */
3415 scroll = gtk_scrolled_window_new (NULL, NULL);
3416 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3417 GTK_POLICY_AUTOMATIC,
3418 GTK_POLICY_AUTOMATIC);
3420 /* Create folder view */
3421 *tree_view = modest_platform_create_folder_view (NULL);
3422 /* *tree_view = modest_folder_view_new (NULL); */
3424 g_signal_connect (G_OBJECT (new_button), "clicked", G_CALLBACK(create_move_to_dialog_on_new_folder), *tree_view);
3426 /* It could happen that we're trying to move a message from a
3427 window (msg window for example) after the main window was
3428 closed, so we can not just get the model of the folder
3430 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
3431 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
3432 MODEST_FOLDER_VIEW(*tree_view));
3434 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3435 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3437 /* Hide special folders */
3438 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3440 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3442 /* Add scroll to dialog */
3443 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3444 scroll, TRUE, TRUE, 0);
3446 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3447 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3453 * Returns TRUE if at least one of the headers of the list belongs to
3454 * a message that has been fully retrieved.
3456 #if 0 /* no longer in use. delete in 2007.10 */
3458 has_retrieved_msgs (TnyList *list)
3461 gboolean found = FALSE;
3463 iter = tny_list_create_iterator (list);
3464 while (!tny_iterator_is_done (iter) && !found) {
3466 TnyHeaderFlags flags = 0;
3468 header = TNY_HEADER (tny_iterator_get_current (iter));
3470 flags = tny_header_get_flags (header);
3471 if (flags & TNY_HEADER_FLAG_CACHED)
3472 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3475 g_object_unref (header);
3479 tny_iterator_next (iter);
3481 g_object_unref (iter);
3489 * Shows a confirmation dialog to the user when we're moving messages
3490 * from a remote server to the local storage. Returns the dialog
3491 * response. If it's other kind of movement the it always returns
3495 msgs_move_to_confirmation (GtkWindow *win,
3496 TnyFolder *dest_folder,
3500 gint response = GTK_RESPONSE_OK;
3502 /* If the destination is a local folder (or MMC folder )*/
3503 if (!modest_tny_folder_is_remote_folder (dest_folder)) {
3508 TnyFolder *src_folder = NULL;
3509 TnyIterator *iter = NULL;
3510 TnyHeader *header = NULL;
3512 /* get the device */
3514 device = modest_runtime_get_device ();
3516 is_online = tny_device_is_online (device);
3518 g_warning ("failed to get tny device"); /* should not happend */
3522 /* Get source folder */
3523 iter = tny_list_create_iterator (headers);
3524 header = TNY_HEADER (tny_iterator_get_current (iter));
3526 src_folder = tny_header_get_folder (header);
3527 g_object_unref (header);
3530 g_object_unref (iter);
3532 /* if no src_folder, message may be an attahcment */
3533 if (src_folder == NULL)
3534 return GTK_RESPONSE_CANCEL;
3536 /* If the source is a remote folder */
3537 if (!is_online && modest_tny_folder_is_remote_folder (src_folder)) {
3539 const gchar *message = NULL;
3540 message = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs",
3541 tny_list_get_length (headers));
3542 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
3543 (const gchar *) message);
3545 response = GTK_RESPONSE_OK;
3547 g_object_unref (src_folder);
3556 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
3558 ModestMsgViewWindow *self = NULL;
3560 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
3561 self = MODEST_MSG_VIEW_WINDOW (object);
3563 if (!modest_msg_view_window_select_next_message (self))
3564 if (!modest_msg_view_window_select_previous_message (self))
3565 /* No more messages to view, so close this window */
3566 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3570 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3573 GObject *win = modest_mail_operation_get_source (mail_op);
3574 const GError *error = NULL;
3575 const gchar *message = NULL;
3577 /* Get error message */
3578 error = modest_mail_operation_get_error (mail_op);
3579 if (error != NULL && error->message != NULL) {
3580 message = error->message;
3582 message = _("mail_in_ui_folder_move_target_error");
3585 /* Show notification dialog */
3586 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3587 g_object_unref (win);
3591 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3594 GObject *win = modest_mail_operation_get_source (mail_op);
3595 const GError *error = modest_mail_operation_get_error (mail_op);
3597 g_return_if_fail (error != NULL);
3598 if (error->message != NULL)
3599 g_printerr ("modest: %s\n", error->message);
3601 g_printerr ("modest: unkonw error on send&receive operation");
3603 /* Show error message */
3604 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3605 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3606 /* _CS("sfil_ib_unable_to_receive")); */
3608 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3609 /* _CS("sfil_ib_unable_to_send")); */
3610 g_object_unref (win);
3614 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3621 gint pending_purges = 0;
3622 gboolean some_purged = FALSE;
3623 ModestWindow *win = MODEST_WINDOW (user_data);
3624 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3626 /* If there was any error */
3627 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
3628 modest_window_mgr_unregister_header (mgr, header);
3632 /* Once the message has been retrieved for purging, we check if
3633 * it's all ok for purging */
3635 parts = tny_simple_list_new ();
3636 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3637 iter = tny_list_create_iterator (parts);
3639 while (!tny_iterator_is_done (iter)) {
3641 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3642 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
3643 if (tny_mime_part_is_purged (part))
3650 g_object_unref (part);
3652 tny_iterator_next (iter);
3655 if (pending_purges>0) {
3657 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3659 if (response == GTK_RESPONSE_OK) {
3660 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3661 tny_iterator_first (iter);
3662 while (!tny_iterator_is_done (iter)) {
3665 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3666 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
3667 tny_mime_part_set_purged (part);
3670 g_object_unref (part);
3672 tny_iterator_next (iter);
3675 tny_msg_rewrite_cache (msg);
3678 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3681 /* remove attachments */
3682 tny_iterator_first (iter);
3683 while (!tny_iterator_is_done (iter)) {
3686 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3688 /* One for the reference given by tny_iterator_get_current(): */
3689 g_object_unref (part);
3691 /* TODO: Is this meant to remove the attachment by doing another unref()?
3692 * Otherwise, this seems useless. */
3695 tny_iterator_next (iter);
3697 modest_window_mgr_unregister_header (mgr, header);
3699 g_object_unref (iter);
3700 g_object_unref (parts);
3704 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3705 ModestMainWindow *win)
3707 GtkWidget *header_view;
3708 TnyList *header_list;
3711 TnyHeaderFlags flags;
3712 ModestWindow *msg_view_window = NULL;
3715 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3717 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3718 MODEST_WIDGET_TYPE_HEADER_VIEW);
3720 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3722 if (tny_list_get_length (header_list) == 1) {
3723 iter = tny_list_create_iterator (header_list);
3724 header = TNY_HEADER (tny_iterator_get_current (iter));
3725 g_object_unref (iter);
3730 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3731 header, &msg_view_window);
3732 flags = tny_header_get_flags (header);
3733 if (!(flags & TNY_HEADER_FLAG_CACHED))
3736 if (msg_view_window != NULL)
3737 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3739 /* do nothing; uid was registered before, so window is probably on it's way */
3740 g_warning ("debug: header %p has already been registered", header);
3743 ModestMailOperation *mail_op = NULL;
3744 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3745 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3747 modest_ui_actions_get_msgs_full_error_handler,
3749 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3750 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3752 g_object_unref (mail_op);
3755 g_object_unref (header);
3757 g_object_unref (header_list);
3761 * Utility function that transfer messages from both the main window
3762 * and the msg view window when using the "Move to" dialog
3765 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
3768 TnyList *headers = NULL;
3770 TnyAccount *dst_account = NULL;
3771 const gchar *proto_str = NULL;
3772 gboolean dst_is_pop = FALSE;
3774 if (!TNY_IS_FOLDER (dst_folder)) {
3775 modest_platform_information_banner (GTK_WIDGET (win),
3777 _CS("ckdg_ib_unable_to_move_to_current_location"));
3781 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
3782 proto_str = tny_account_get_proto (dst_account);
3784 /* tinymail will return NULL for local folders it seems */
3785 dst_is_pop = proto_str &&
3786 (modest_protocol_info_get_transport_store_protocol (proto_str) ==
3787 MODEST_PROTOCOL_STORE_POP);
3789 g_object_unref (dst_account);
3791 /* Get selected headers */
3792 headers = get_selected_headers (MODEST_WINDOW (win));
3795 modest_platform_information_banner (GTK_WIDGET (win),
3797 ngettext("mail_in_ui_folder_move_target_error",
3798 "mail_in_ui_folder_move_targets_error",
3799 tny_list_get_length (headers)));
3800 g_object_unref (headers);
3804 /* Ask for user confirmation */
3805 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3806 TNY_FOLDER (dst_folder),
3810 /* Transfer messages */
3811 if (response == GTK_RESPONSE_OK) {
3812 ModestMailOperation *mail_op =
3813 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3815 modest_ui_actions_move_folder_error_handler,
3817 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3820 modest_mail_operation_xfer_msgs (mail_op,
3822 TNY_FOLDER (dst_folder),
3824 (MODEST_IS_MSG_VIEW_WINDOW (win)) ? transfer_msgs_from_viewer_cb : NULL,
3827 g_object_unref (G_OBJECT (mail_op));
3829 g_object_unref (headers);
3833 * UI handler for the "Move to" action when invoked from the
3837 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3838 GtkWidget *folder_view,
3839 TnyFolderStore *dst_folder,
3840 ModestMainWindow *win)
3842 GtkWidget *header_view = NULL;
3843 ModestMailOperation *mail_op = NULL;
3844 TnyFolderStore *src_folder;
3846 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3848 /* Get the source folder */
3849 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3851 /* Offer the connection dialog if necessary, if the source folder is in a networked account: */
3852 if (!modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3856 /* Get header view */
3858 modest_main_window_get_child_widget (win, MODEST_WIDGET_TYPE_HEADER_VIEW);
3860 /* Get folder or messages to transfer */
3861 if (gtk_widget_is_focus (folder_view)) {
3863 /* Allow only to transfer folders to the local root folder */
3864 if (TNY_IS_ACCOUNT (dst_folder) &&
3865 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder))
3868 /* Clean folder on header view before moving it */
3869 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3871 if (TNY_IS_FOLDER (src_folder)) {
3873 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3875 modest_ui_actions_move_folder_error_handler,
3877 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3880 modest_mail_operation_xfer_folder (mail_op,
3881 TNY_FOLDER (src_folder),
3884 /* Unref mail operation */
3885 g_object_unref (G_OBJECT (mail_op));
3887 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
3889 } else if (gtk_widget_is_focus (header_view)) {
3890 /* Transfer messages */
3891 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3896 g_object_unref (src_folder);
3901 * UI handler for the "Move to" action when invoked from the
3902 * ModestMsgViewWindow
3905 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3906 TnyFolderStore *dst_folder,
3907 ModestMsgViewWindow *win)
3909 TnyHeader *header = NULL;
3910 TnyFolder *src_folder;
3912 /* Create header list */
3913 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3914 src_folder = tny_header_get_folder(header);
3915 g_object_unref (header);
3917 /* Transfer the message */
3918 if (modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (src_folder)))
3919 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
3921 g_object_unref (src_folder);
3925 modest_ui_actions_on_move_to (GtkAction *action,
3928 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3930 TnyFolderStore *dst_folder = NULL;
3931 ModestMainWindow *main_window;
3933 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3934 MODEST_IS_MSG_VIEW_WINDOW (win));
3936 /* Get the main window if exists */
3937 if (MODEST_IS_MAIN_WINDOW (win))
3938 main_window = MODEST_MAIN_WINDOW (win);
3941 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3943 /* Get the folder view widget if exists */
3945 folder_view = modest_main_window_get_child_widget (main_window,
3946 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3950 /* Create and run the dialog */
3951 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
3952 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3953 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3954 result = gtk_dialog_run (GTK_DIALOG(dialog));
3955 g_object_ref (tree_view);
3956 gtk_widget_destroy (dialog);
3958 if (result != GTK_RESPONSE_ACCEPT)
3961 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3962 /* Offer the connection dialog if necessary: */
3963 if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win),
3966 /* Do window specific stuff */
3967 if (MODEST_IS_MAIN_WINDOW (win))
3968 modest_ui_actions_on_main_window_move_to (action,
3971 MODEST_MAIN_WINDOW (win));
3973 modest_ui_actions_on_msg_view_window_move_to (action,
3975 MODEST_MSG_VIEW_WINDOW (win));
3978 g_object_unref (dst_folder);
3982 * Calls #HeadersFunc for each header already selected in the main
3983 * window or the message currently being shown in the msg view window
3986 do_headers_action (ModestWindow *win,
3990 TnyList *headers_list = NULL;
3991 TnyIterator *iter = NULL;
3992 TnyHeader *header = NULL;
3993 TnyFolder *folder = NULL;
3996 headers_list = get_selected_headers (win);
4000 /* Get the folder */
4001 iter = tny_list_create_iterator (headers_list);
4002 header = TNY_HEADER (tny_iterator_get_current (iter));
4004 folder = tny_header_get_folder (header);
4005 g_object_unref (header);
4008 /* Call the function for each header */
4009 while (!tny_iterator_is_done (iter)) {
4010 header = TNY_HEADER (tny_iterator_get_current (iter));
4011 func (header, win, user_data);
4012 g_object_unref (header);
4013 tny_iterator_next (iter);
4016 /* Trick: do a poke status in order to speed up the signaling
4018 tny_folder_poke_status (folder);
4021 g_object_unref (folder);
4022 g_object_unref (iter);
4023 g_object_unref (headers_list);
4027 modest_ui_actions_view_attachment (GtkAction *action,
4028 ModestWindow *window)
4030 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4031 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4033 /* not supported window for this action */
4034 g_return_if_reached ();
4039 modest_ui_actions_save_attachments (GtkAction *action,
4040 ModestWindow *window)
4042 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4043 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4045 /* not supported window for this action */
4046 g_return_if_reached ();
4051 modest_ui_actions_remove_attachments (GtkAction *action,
4052 ModestWindow *window)
4054 if (MODEST_IS_MAIN_WINDOW (window)) {
4055 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4056 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4057 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4059 /* not supported window for this action */
4060 g_return_if_reached ();
4065 modest_ui_actions_on_settings (GtkAction *action,
4070 dialog = modest_platform_get_global_settings_dialog ();
4071 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4072 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4073 gtk_widget_show_all (dialog);
4075 gtk_dialog_run (GTK_DIALOG (dialog));
4077 gtk_widget_destroy (dialog);
4081 modest_ui_actions_on_help (GtkAction *action,
4084 const gchar *help_id = NULL;
4086 if (MODEST_IS_MAIN_WINDOW (win)) {
4087 const gchar *action_name;
4088 action_name = gtk_action_get_name (action);
4090 if (!strcmp (action_name, "FolderViewCSMHelp") ||
4091 !strcmp (action_name, "HeaderViewCSMHelp")) {
4092 GtkWidget *folder_view;
4093 TnyFolderStore *folder_store;
4094 /* Get selected folder */
4095 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4096 MODEST_WIDGET_TYPE_FOLDER_VIEW);
4097 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4099 /* Switch help_id */
4100 if (TNY_IS_FOLDER (folder_store)) {
4101 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4102 case TNY_FOLDER_TYPE_NORMAL:
4103 help_id = "applications_email_managefolders";
4105 case TNY_FOLDER_TYPE_INBOX:
4106 help_id = "applications_email_inbox";
4108 case TNY_FOLDER_TYPE_OUTBOX:
4109 help_id = "applications_email_outbox";
4111 case TNY_FOLDER_TYPE_SENT:
4112 help_id = "applications_email_sent";
4114 case TNY_FOLDER_TYPE_DRAFTS:
4115 help_id = "applications_email_drafts";
4117 case TNY_FOLDER_TYPE_ARCHIVE:
4118 help_id = "applications_email_managefolders";
4121 help_id = "applications_email_managefolders";
4124 help_id = "applications_email_mainview";
4126 g_object_unref (folder_store);
4128 help_id = "applications_email_mainview";
4130 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4131 help_id = "applications_email_viewer";
4132 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4133 help_id = "applications_email_editor";
4135 modest_platform_show_help (GTK_WINDOW (win), help_id);
4139 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4140 ModestWindow *window)
4142 ModestMailOperation *mail_op;
4146 headers = get_selected_headers (window);
4150 /* Create mail operation */
4151 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4153 modest_ui_actions_get_msgs_full_error_handler,
4155 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4156 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4159 g_object_unref (headers);
4160 g_object_unref (mail_op);
4164 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4165 ModestWindow *window)
4167 g_return_if_fail (MODEST_IS_WINDOW (window));
4170 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4174 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4175 ModestWindow *window)
4177 g_return_if_fail (MODEST_IS_WINDOW (window));
4180 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4184 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4185 ModestWindow *window)
4187 g_return_if_fail (MODEST_IS_WINDOW (window));
4190 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4194 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4195 ModestWindow *window)
4197 g_return_if_fail (MODEST_IS_WINDOW (window));
4200 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4204 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4205 ModestWindow *window)
4207 g_return_if_fail (MODEST_IS_WINDOW (window));
4210 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4214 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4215 ModestWindow *window)
4217 g_return_if_fail (MODEST_IS_WINDOW (window));
4220 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4224 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4225 ModestWindow *window)
4227 g_return_if_fail (MODEST_IS_WINDOW (window));
4230 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4234 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4235 ModestWindow *window)
4237 g_return_if_fail (MODEST_IS_WINDOW (window));
4240 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4244 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4246 g_return_if_fail (MODEST_IS_WINDOW (window));
4249 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4253 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4255 g_return_if_fail (MODEST_IS_WINDOW (window));
4257 modest_platform_show_search_messages (GTK_WINDOW (window));
4261 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4263 g_return_if_fail (MODEST_IS_WINDOW (win));
4264 modest_platform_show_addressbook (GTK_WINDOW (win));
4269 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4270 ModestWindow *window)
4272 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4274 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4278 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
4279 ModestMailOperationState *state,
4282 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4284 /* Set send/receive operation finished */
4285 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4286 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));