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>
49 #ifdef MODEST_PLATFORM_MAEMO
50 #include "maemo/modest-osso-state-saving.h"
51 #endif /* MODEST_PLATFORM_MAEMO */
53 #include "widgets/modest-ui-constants.h"
54 #include <widgets/modest-main-window.h>
55 #include <widgets/modest-msg-view-window.h>
56 #include <widgets/modest-account-view-window.h>
57 #include <widgets/modest-details-dialog.h>
58 #include <widgets/modest-attachments-view.h>
59 #include "widgets/modest-folder-view.h"
60 #include "widgets/modest-global-settings-dialog.h"
61 #include "modest-connection-specific-smtp-window.h"
62 #include "modest-account-mgr-helpers.h"
63 #include "modest-mail-operation.h"
64 #include "modest-text-utils.h"
66 #ifdef MODEST_HAVE_EASYSETUP
67 #include "easysetup/modest-easysetup-wizard.h"
68 #endif /* MODEST_HAVE_EASYSETUP */
70 #include <modest-widget-memory.h>
71 #include <tny-error.h>
72 #include <tny-simple-list.h>
73 #include <tny-msg-view.h>
74 #include <tny-device.h>
75 #include <tny-merge-folder.h>
77 #include <gtkhtml/gtkhtml.h>
79 typedef struct _GetMsgAsyncHelper {
81 ModestMailOperation *mail_op;
88 typedef enum _ReplyForwardAction {
94 typedef struct _ReplyForwardHelper {
95 guint reply_forward_type;
96 ReplyForwardAction action;
98 GtkWidget *parent_window;
103 * The do_headers_action uses this kind of functions to perform some
104 * action to each member of a list of headers
106 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
108 static void do_headers_action (ModestWindow *win,
112 static void open_msg_cb (ModestMailOperation *mail_op,
117 static void reply_forward_cb (ModestMailOperation *mail_op,
122 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
125 static void _on_send_receive_progress_changed (ModestMailOperation *mail_op,
126 ModestMailOperationState *state,
132 run_account_setup_wizard (ModestWindow *win)
134 ModestEasysetupWizardDialog *wizard;
136 g_return_if_fail (MODEST_IS_WINDOW(win));
138 wizard = modest_easysetup_wizard_dialog_new ();
139 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
140 gtk_dialog_run (GTK_DIALOG (wizard));
141 gtk_widget_destroy (GTK_WIDGET (wizard));
146 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
149 const gchar *authors[] = {
150 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
153 about = gtk_about_dialog_new ();
154 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
155 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
156 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
157 _("Copyright (c) 2006, Nokia Corporation\n"
158 "All rights reserved."));
159 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
160 _("a modest e-mail client\n\n"
161 "design and implementation: Dirk-Jan C. Binnema\n"
162 "contributions from the fine people at KC and Ig\n"
163 "uses the tinymail email framework written by Philip van Hoof"));
164 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
165 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
167 gtk_dialog_run (GTK_DIALOG (about));
168 gtk_widget_destroy(about);
172 * Gets the list of currently selected messages. If the win is the
173 * main window, then it returns a newly allocated list of the headers
174 * selected in the header view. If win is the msg view window, then
175 * the value returned is a list with just a single header.
177 * The caller of this funcion must free the list.
180 get_selected_headers (ModestWindow *win)
182 if (MODEST_IS_MAIN_WINDOW(win)) {
183 GtkWidget *header_view;
185 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
186 MODEST_WIDGET_TYPE_HEADER_VIEW);
187 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
189 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
190 /* for MsgViewWindows, we simply return a list with one element */
192 TnyList *list = NULL;
194 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
195 if (header != NULL) {
196 list = tny_simple_list_new ();
197 tny_list_prepend (list, G_OBJECT(header));
198 g_object_unref (G_OBJECT(header));
208 headers_action_mark_as_read (TnyHeader *header,
212 TnyHeaderFlags flags;
214 g_return_if_fail (TNY_IS_HEADER(header));
216 flags = tny_header_get_flags (header);
217 if (flags & TNY_HEADER_FLAG_SEEN) return;
218 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
222 headers_action_mark_as_unread (TnyHeader *header,
226 TnyHeaderFlags flags;
228 g_return_if_fail (TNY_IS_HEADER(header));
230 flags = tny_header_get_flags (header);
231 if (flags & TNY_HEADER_FLAG_SEEN) {
232 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
238 headers_action_delete (TnyHeader *header,
242 ModestMailOperation *mail_op = NULL;
244 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE, G_OBJECT(win));
245 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
248 /* Always delete. TODO: Move to trash still not supported */
249 modest_mail_operation_remove_msg (mail_op, header, FALSE);
250 g_object_unref (G_OBJECT (mail_op));
252 /* refilter treemodel to hide marked-as-deleted rows */
253 if (MODEST_IS_HEADER_VIEW (user_data))
254 modest_header_view_refilter (MODEST_HEADER_VIEW (user_data));
258 modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
260 TnyList *header_list = NULL;
261 TnyIterator *iter = NULL;
262 TnyHeader *header = NULL;
263 gchar *message = NULL;
266 ModestWindowMgr *mgr;
267 GtkWidget *header_view = NULL;
269 g_return_if_fail (MODEST_IS_WINDOW(win));
271 /* Check first if the header view has the focus */
272 if (MODEST_IS_MAIN_WINDOW (win)) {
274 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
275 MODEST_WIDGET_TYPE_HEADER_VIEW);
276 if (!gtk_widget_is_focus (header_view))
280 header_list = get_selected_headers (win);
281 if (!header_list) return;
283 /* Check if any of the headers is already opened, or in the process of being opened */
284 if (MODEST_IS_MAIN_WINDOW (win)) {
286 iter = tny_list_create_iterator (header_list);
288 mgr = modest_runtime_get_window_mgr ();
289 while (!tny_iterator_is_done (iter) && !found) {
290 header = TNY_HEADER (tny_iterator_get_current (iter));
291 found = modest_window_mgr_find_registered_header (mgr, header, NULL);
292 g_object_unref (header);
293 tny_iterator_next (iter);
295 g_object_unref (iter);
300 num = g_strdup_printf ("%d", tny_list_get_length (header_list));
301 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
303 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
307 g_object_unref (header_list);
313 if (tny_list_get_length(header_list) == 1) {
314 iter = tny_list_create_iterator (header_list);
315 header = TNY_HEADER (tny_iterator_get_current (iter));
316 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
317 g_object_unref (header);
318 g_object_unref (iter);
320 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
321 tny_list_get_length(header_list)), desc);
323 /* Confirmation dialog */
324 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
328 if (response == GTK_RESPONSE_OK) {
329 ModestMainWindow *main_window;
330 ModestWindowMgr *mgr;
332 /* Remove each header. If it's a view window header_view == NULL */
333 do_headers_action (win, headers_action_delete, header_view);
335 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
336 /* Close msg view window or select next */
337 if (modest_msg_view_window_last_message_selected (MODEST_MSG_VIEW_WINDOW (win)) &&
338 modest_msg_view_window_first_message_selected (MODEST_MSG_VIEW_WINDOW (win))) {
339 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
341 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (win));
345 /* Refilter header view model, if main window still exists */
346 mgr = modest_runtime_get_window_mgr ();
347 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr));
351 widget = modest_main_window_get_child_widget (main_window,
352 MODEST_WIDGET_TYPE_HEADER_VIEW);
353 modest_header_view_refilter (MODEST_HEADER_VIEW (widget));
355 /* Update toolbar dimming state */
356 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
363 g_object_unref (header_list);
368 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
370 #ifdef MODEST_PLATFORM_MAEMO
371 modest_osso_save_state();
372 #endif /* MODEST_PLATFORM_MAEMO */
374 g_debug ("closing down, clearing %d item(s) from operation queue",
375 modest_mail_operation_queue_num_elements
376 (modest_runtime_get_mail_operation_queue()));
378 /* cancel all outstanding operations */
379 modest_mail_operation_queue_cancel_all
380 (modest_runtime_get_mail_operation_queue());
382 g_debug ("queue has been cleared");
384 /* note: when modest-tny-account-store is finalized,
385 it will automatically set all network connections
392 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
395 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
397 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
398 /* gtk_widget_destroy (GTK_WIDGET (win)); */
399 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
400 /* gboolean ret_value; */
401 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
402 /* } else if (MODEST_IS_WINDOW (win)) { */
403 /* gtk_widget_destroy (GTK_WIDGET (win)); */
405 /* g_return_if_reached (); */
410 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
412 GtkClipboard *clipboard = NULL;
413 gchar *selection = NULL;
415 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
416 selection = gtk_clipboard_wait_for_text (clipboard);
418 /* Question: why is the clipboard being used here?
419 * It doesn't really make a lot of sense. */
423 modest_address_book_add_address (selection);
429 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
431 /* This is currently only implemented for Maemo */
432 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
433 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
434 run_account_setup_wizard (win);
437 /* Show the list of accounts: */
438 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
439 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
440 gtk_dialog_run (account_win);
441 gtk_widget_destroy (GTK_WIDGET(account_win));
444 GtkWidget *dialog, *label;
446 /* Create the widgets */
448 dialog = gtk_dialog_new_with_buttons ("Message",
450 GTK_DIALOG_DESTROY_WITH_PARENT,
454 label = gtk_label_new ("Hello World!");
456 /* Ensure that the dialog box is destroyed when the user responds. */
458 g_signal_connect_swapped (dialog, "response",
459 G_CALLBACK (gtk_widget_destroy),
462 /* Add the label, and show everything we've added to the dialog. */
464 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
466 gtk_widget_show_all (dialog);
467 #endif /* MODEST_PLATFORM_MAEMO */
471 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
473 ModestWindow *main_window = MODEST_WINDOW (user_data);
475 /* Save any changes. */
476 modest_connection_specific_smtp_window_save_server_accounts (
477 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
478 modest_window_get_active_account (main_window));
479 gtk_widget_destroy (GTK_WIDGET (window));
485 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
487 /* This is currently only implemented for Maemo,
488 * because it requires an API (libconic) to detect different connection
491 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
493 /* Create the window if necessary: */
494 const gchar *active_account_name = modest_window_get_active_account (win);
496 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
497 * or show the default account?
498 * If we show the default account then the account name should be shown in
499 * the window when we show it. */
500 if (!active_account_name) {
501 g_warning ("%s: No account is active.", __FUNCTION__);
505 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
506 modest_connection_specific_smtp_window_fill_with_connections (
507 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
508 modest_runtime_get_account_mgr(),
509 active_account_name);
511 /* Show the window: */
512 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
513 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
514 gtk_widget_show (specific_window);
516 /* Save changes when the window is hidden: */
517 g_signal_connect (specific_window, "hide",
518 G_CALLBACK (on_smtp_servers_window_hide), win);
519 #endif /* MODEST_PLATFORM_MAEMO */
523 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
525 ModestWindow *msg_win = NULL;
527 TnyFolder *folder = NULL;
528 gchar *account_name = NULL;
529 gchar *from_str = NULL;
530 /* GError *err = NULL; */
531 TnyAccount *account = NULL;
532 ModestWindowMgr *mgr;
533 gchar *signature = NULL, *blank_and_signature = NULL;
535 /* if there are no accounts yet, just show the wizard */
536 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
537 run_account_setup_wizard (win);
541 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
543 account_name = g_strdup (modest_window_get_active_account (win));
545 g_printerr ("modest: no account found\n");
549 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
551 TNY_ACCOUNT_TYPE_STORE);
553 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
557 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
559 g_printerr ("modest: failed get from string for '%s'\n", account_name);
563 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
564 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
565 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
566 MODEST_ACCOUNT_SIGNATURE, FALSE);
567 blank_and_signature = g_strconcat ("\n", signature, NULL);
570 blank_and_signature = g_strdup ("");
573 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
575 g_printerr ("modest: failed to create new msg\n");
579 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
581 g_printerr ("modest: failed to find Drafts folder\n");
586 /* Create and register edit window */
587 /* This is destroyed by TOOD. */
588 msg_win = modest_msg_edit_window_new (msg, account_name);
589 mgr = modest_runtime_get_window_mgr ();
590 modest_window_mgr_register_window (mgr, msg_win);
593 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
595 gtk_widget_show_all (GTK_WIDGET (msg_win));
598 g_free (account_name);
600 g_free (blank_and_signature);
602 g_object_unref (msg_win);
604 g_object_unref (G_OBJECT(account));
606 g_object_unref (G_OBJECT(msg));
608 g_object_unref (G_OBJECT(folder));
612 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
616 ModestMailOperationStatus status;
618 /* If there is no message or the operation was not successful */
619 status = modest_mail_operation_get_status (mail_op);
620 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
622 /* Remove the header from the preregistered uids */
623 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
633 open_msg_cb (ModestMailOperation *mail_op,
638 ModestWindowMgr *mgr = NULL;
639 ModestWindow *parent_win = NULL;
640 ModestWindow *win = NULL;
641 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
642 gchar *account = NULL;
645 /* Do nothing if there was any problem with the mail
646 operation. The error will be shown by the error_handler of
647 the mail operation */
648 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
649 printf ("DEBUG: %s: modest_ui_actions_msg_retrieval_check() failed.\n",
654 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
655 folder = tny_header_get_folder (header);
657 /* Mark header as read */
658 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
661 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
663 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
665 /* Gets folder type (OUTBOX headers will be opened in edit window */
666 if (modest_tny_folder_is_local_folder (folder))
667 folder_type = modest_tny_folder_get_local_folder_type (folder);
669 /* If the header is in the drafts folder then open the editor,
670 else the message view window */
671 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
672 /* we cannot edit without a valid account... */
673 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
674 run_account_setup_wizard(parent_win);
677 win = modest_msg_edit_window_new (msg, account);
679 gchar *uid = modest_tny_folder_get_header_unique_id (header);
681 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
682 GtkWidget *header_view;
683 GtkTreeSelection *sel;
684 GList *sel_list = NULL;
687 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
688 MODEST_WIDGET_TYPE_HEADER_VIEW);
690 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
691 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
693 if (sel_list != NULL) {
694 GtkTreeRowReference *row_reference;
696 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
697 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
698 g_list_free (sel_list);
700 win = modest_msg_view_window_new_with_header_model (msg,
705 gtk_tree_row_reference_free (row_reference);
707 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
710 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
715 /* Register and show new window */
717 mgr = modest_runtime_get_window_mgr ();
718 modest_window_mgr_register_window (mgr, win);
719 g_object_unref (win);
720 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
721 gtk_widget_show_all (GTK_WIDGET(win));
724 /* Update toolbar dimming state */
725 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
726 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
732 g_object_unref (parent_win);
733 /* g_object_unref (msg); */
734 g_object_unref (folder);
738 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
742 GObject *win = modest_mail_operation_get_source (mail_op);
744 error = modest_mail_operation_get_error (mail_op);
745 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, error->code, error->message);
747 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
749 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
752 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
753 _("mail_ni_ui_folder_get_msg_folder_error"));
757 g_object_unref (win);
761 * This function is used by both modest_ui_actions_on_open and
762 * modest_ui_actions_on_header_activated. This way we always do the
763 * same when trying to open messages.
766 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
768 ModestWindowMgr *mgr = NULL;
769 TnyIterator *iter = NULL;
770 ModestMailOperation *mail_op1 = NULL;
771 ModestMailOperation *mail_op2 = NULL;
772 TnyList *not_opened_headers = NULL;
773 TnyList *not_opened_cached_headers = NULL;
774 TnyHeaderFlags flags;
776 /* Look if we already have a message view for each header. If
777 true, then remove the header from the list of headers to
779 mgr = modest_runtime_get_window_mgr ();
780 iter = tny_list_create_iterator (headers);
781 not_opened_headers = tny_simple_list_new ();
782 not_opened_cached_headers = tny_simple_list_new ();
783 while (!tny_iterator_is_done (iter)) {
785 ModestWindow *window;
789 header = TNY_HEADER (tny_iterator_get_current (iter));
790 flags = tny_header_get_flags (header);
793 found = modest_window_mgr_find_registered_header (mgr, header, &window);
795 /* Do not open again the message and present the
796 window to the user */
799 gtk_window_present (GTK_WINDOW (window));
801 /* the header has been registered already, we don't do
802 * anything but wait for the window to come up*/
803 g_warning ("debug: header %p already registered, waiting for window",
806 if (!(flags & TNY_HEADER_FLAG_CACHED))
807 tny_list_append (not_opened_headers, G_OBJECT (header));
808 /* Check if msg has already been retreived */
810 tny_list_append (not_opened_cached_headers, G_OBJECT (header));
812 g_object_unref (header);
813 tny_iterator_next (iter);
815 g_object_unref (iter);
818 /* If some messages would have to be downloaded, ask the user to
819 * make a connection. It's generally easier to do this here (in the mainloop)
820 * than later in a thread:
822 if (tny_list_get_length (not_opened_cached_headers) > 0) {
823 gboolean connected = modest_platform_connect_and_wait (GTK_WINDOW (win));
825 /* Don't go further if a connection would be necessary but none is available: */
827 g_object_unref (not_opened_headers);
828 g_object_unref (not_opened_cached_headers);
833 /* Register the headers before actually creating the windows: */
834 TnyIterator *iter_not_opened = tny_list_create_iterator (not_opened_headers);
835 while (!tny_iterator_is_done (iter_not_opened)) {
836 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
837 modest_window_mgr_register_header (mgr, header);
838 g_object_unref (header);
840 tny_iterator_next (iter_not_opened);
842 g_object_unref (iter_not_opened);
843 iter_not_opened = NULL;
845 TnyIterator *iter_cached = tny_list_create_iterator (not_opened_cached_headers);
846 while (!tny_iterator_is_done (iter_cached)) {
847 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_cached));
848 modest_window_mgr_register_header (mgr, header);
849 g_object_unref (header);
851 tny_iterator_next (iter_cached);
853 g_object_unref (iter_cached);
857 /* Open each uncached message */
858 if (tny_list_get_length (not_opened_headers) > 0) {
859 mail_op1 = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
861 modest_ui_actions_get_msgs_full_error_handler,
863 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op1);
864 if (tny_list_get_length (not_opened_headers) > 1) {
865 modest_mail_operation_get_msgs_full (mail_op1,
871 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
872 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
873 modest_mail_operation_get_msg (mail_op1, header, open_msg_cb, NULL);
874 g_object_unref (header);
875 g_object_unref (iter);
879 /* Open each cached message */
880 if (tny_list_get_length (not_opened_cached_headers) > 0) {
881 mail_op2 = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
883 modest_ui_actions_get_msgs_full_error_handler,
885 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op2);
886 if (tny_list_get_length (not_opened_cached_headers) > 1) {
887 modest_mail_operation_get_msgs_full (mail_op2,
893 TnyIterator *iter = tny_list_create_iterator (not_opened_cached_headers);
894 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
895 modest_mail_operation_get_msg (mail_op2, header, open_msg_cb, NULL);
896 g_object_unref (header);
897 g_object_unref (iter);
902 if (not_opened_headers != NULL)
903 g_object_unref (not_opened_headers);
904 if (not_opened_cached_headers != NULL)
905 g_object_unref (not_opened_cached_headers);
907 g_object_unref (iter);
908 if (mail_op1 != NULL)
909 g_object_unref (mail_op1);
910 if (mail_op2 != NULL)
911 g_object_unref (mail_op2);
915 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
920 headers = get_selected_headers (win);
925 _modest_ui_actions_open (headers, win);
927 g_object_unref(headers);
932 free_reply_forward_helper (gpointer data)
934 ReplyForwardHelper *helper;
936 helper = (ReplyForwardHelper *) data;
937 g_free (helper->account_name);
938 g_slice_free (ReplyForwardHelper, helper);
942 reply_forward_cb (ModestMailOperation *mail_op,
948 ReplyForwardHelper *rf_helper;
949 ModestWindow *msg_win = NULL;
950 ModestEditType edit_type;
952 TnyAccount *account = NULL;
953 ModestWindowMgr *mgr = NULL;
954 gchar *signature = NULL;
956 /* If there was any error */
957 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
960 g_return_if_fail (user_data != NULL);
961 rf_helper = (ReplyForwardHelper *) user_data;
963 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
964 rf_helper->account_name);
965 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
966 rf_helper->account_name,
967 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
968 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
969 rf_helper->account_name,
970 MODEST_ACCOUNT_SIGNATURE, FALSE);
973 /* Create reply mail */
974 switch (rf_helper->action) {
977 modest_tny_msg_create_reply_msg (msg, from, signature,
978 rf_helper->reply_forward_type,
979 MODEST_TNY_MSG_REPLY_MODE_SENDER);
981 case ACTION_REPLY_TO_ALL:
983 modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type,
984 MODEST_TNY_MSG_REPLY_MODE_ALL);
985 edit_type = MODEST_EDIT_TYPE_REPLY;
989 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
990 edit_type = MODEST_EDIT_TYPE_FORWARD;
993 g_return_if_reached ();
1000 g_printerr ("modest: failed to create message\n");
1004 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1005 rf_helper->account_name,
1006 TNY_ACCOUNT_TYPE_STORE);
1008 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1012 /* Create and register the windows */
1013 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
1014 mgr = modest_runtime_get_window_mgr ();
1015 modest_window_mgr_register_window (mgr, msg_win);
1017 if (rf_helper->parent_window != NULL) {
1018 gdouble parent_zoom;
1020 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1021 modest_window_set_zoom (msg_win, parent_zoom);
1024 /* Show edit window */
1025 gtk_widget_show_all (GTK_WIDGET (msg_win));
1029 g_object_unref (msg_win);
1031 g_object_unref (G_OBJECT (new_msg));
1033 g_object_unref (G_OBJECT (account));
1034 /* g_object_unref (msg); */
1035 g_object_unref (header);
1036 free_reply_forward_helper (rf_helper);
1040 * Checks a list of headers. If any of them are not currently
1041 * downloaded (CACHED) then it asks the user for permission to
1044 * Returns FALSE if the user does not want to download the
1045 * messages. Returns TRUE if the user allowed the download or if all
1046 * of them are currently downloaded
1049 download_uncached_messages (TnyList *header_list, GtkWindow *win)
1053 gint uncached_messages = 0;
1055 iter = tny_list_create_iterator (header_list);
1056 while (!tny_iterator_is_done (iter)) {
1058 TnyHeaderFlags flags;
1060 header = TNY_HEADER (tny_iterator_get_current (iter));
1061 flags = tny_header_get_flags (header);
1062 /* TODO: is this the right flag?, it seems that some
1063 headers that have been previously downloaded do not
1065 if (! (flags & TNY_HEADER_FLAG_CACHED))
1066 uncached_messages ++;
1067 g_object_unref (header);
1068 tny_iterator_next (iter);
1070 g_object_unref (iter);
1072 /* Ask for user permission to download the messages */
1074 if (uncached_messages > 0) {
1075 GtkResponseType response;
1077 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1078 ngettext("mcen_nc_get_msg",
1080 uncached_messages));
1081 if (response == GTK_RESPONSE_CANCEL)
1084 /* If a download will be necessary, make sure that we have a connection: */
1085 retval = modest_platform_connect_and_wait(win);
1093 * Common code for the reply and forward actions
1096 reply_forward (ReplyForwardAction action, ModestWindow *win)
1098 ModestMailOperation *mail_op = NULL;
1099 TnyList *header_list = NULL;
1100 ReplyForwardHelper *rf_helper = NULL;
1101 guint reply_forward_type;
1102 gboolean continue_download;
1104 g_return_if_fail (MODEST_IS_WINDOW(win));
1106 /* we need an account when editing */
1107 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1108 run_account_setup_wizard (win);
1112 header_list = get_selected_headers (win);
1116 /* Check that the messages have been previously downloaded */
1117 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
1118 if (!continue_download) {
1119 g_object_unref (header_list);
1123 reply_forward_type =
1124 modest_conf_get_int (modest_runtime_get_conf (),
1125 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1127 /* We assume that we can only select messages of the
1128 same folder and that we reply all of them from the
1129 same account. In fact the interface currently only
1130 allows single selection */
1133 rf_helper = g_slice_new0 (ReplyForwardHelper);
1134 rf_helper->reply_forward_type = reply_forward_type;
1135 rf_helper->action = action;
1136 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1137 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1138 rf_helper->parent_window = GTK_WIDGET (win);
1139 if (!rf_helper->account_name)
1140 rf_helper->account_name =
1141 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1143 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1146 /* Get header and message. Do not free them here, the
1147 reply_forward_cb must do it */
1148 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1149 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1150 if (!msg || !header) {
1152 g_object_unref (msg);
1154 g_object_unref (header);
1155 g_printerr ("modest: no message found\n");
1158 reply_forward_cb (NULL, header, msg, rf_helper);
1164 /* Retrieve messages */
1165 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1167 modest_ui_actions_get_msgs_full_error_handler,
1169 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1171 /* Only reply/forward to one message */
1172 iter = tny_list_create_iterator (header_list);
1173 header = TNY_HEADER (tny_iterator_get_current (iter));
1174 g_object_unref (iter);
1176 modest_mail_operation_get_msg (mail_op,
1181 /* modest_mail_operation_get_msgs_full (mail_op, */
1183 /* reply_forward_cb, */
1185 /* free_reply_forward_helper); */
1188 g_object_unref(mail_op);
1192 g_object_unref (header_list);
1196 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1198 g_return_if_fail (MODEST_IS_WINDOW(win));
1200 reply_forward (ACTION_REPLY, win);
1204 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1206 g_return_if_fail (MODEST_IS_WINDOW(win));
1208 reply_forward (ACTION_FORWARD, win);
1212 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1214 g_return_if_fail (MODEST_IS_WINDOW(win));
1216 reply_forward (ACTION_REPLY_TO_ALL, win);
1220 modest_ui_actions_on_next (GtkAction *action,
1221 ModestWindow *window)
1223 if (MODEST_IS_MAIN_WINDOW (window)) {
1224 GtkWidget *header_view;
1226 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1227 MODEST_WIDGET_TYPE_HEADER_VIEW);
1231 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
1232 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1233 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
1235 g_return_if_reached ();
1240 modest_ui_actions_on_prev (GtkAction *action,
1241 ModestWindow *window)
1243 g_return_if_fail (MODEST_IS_WINDOW(window));
1245 if (MODEST_IS_MAIN_WINDOW (window)) {
1246 GtkWidget *header_view;
1247 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1248 MODEST_WIDGET_TYPE_HEADER_VIEW);
1252 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1253 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1254 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1256 g_return_if_reached ();
1261 modest_ui_actions_on_sort (GtkAction *action,
1262 ModestWindow *window)
1264 g_return_if_fail (MODEST_IS_WINDOW(window));
1266 if (MODEST_IS_MAIN_WINDOW (window)) {
1267 GtkWidget *header_view;
1268 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1269 MODEST_WIDGET_TYPE_HEADER_VIEW);
1273 /* Show sorting dialog */
1274 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1279 new_messages_arrived (ModestMailOperation *self,
1283 if (new_messages == 0)
1286 modest_platform_on_new_msg ();
1290 * This function performs the send & receive required actions. The
1291 * window is used to create the mail operation. Typically it should
1292 * always be the main window, but we pass it as argument in order to
1296 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1298 gchar *acc_name = NULL;
1299 ModestMailOperation *mail_op;
1301 /* If no account name was provided then get the current account, and if
1302 there is no current account then pick the default one: */
1303 if (!account_name) {
1304 acc_name = g_strdup (modest_window_get_active_account(win));
1306 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1308 g_printerr ("modest: cannot get default account\n");
1312 acc_name = g_strdup (account_name);
1315 /* Set send/receive operation in progress */
1316 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1318 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1320 modest_ui_actions_send_receive_error_handler,
1323 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1324 G_CALLBACK (_on_send_receive_progress_changed),
1327 /* Send & receive. */
1328 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1329 /* Receive and then send. The operation is tagged initially as
1330 a receive operation because the account update performs a
1331 receive and then a send. The operation changes its type
1332 internally, so the progress objects will receive the proper
1333 progress information */
1334 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1335 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, NULL);
1336 g_object_unref (G_OBJECT (mail_op));
1343 * Refreshes all accounts. This function will be used by automatic
1347 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1349 GSList *account_names, *iter;
1351 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1354 iter = account_names;
1356 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1357 iter = g_slist_next (iter);
1360 modest_account_mgr_free_account_names (account_names);
1361 account_names = NULL;
1365 * Handler of the click on Send&Receive button in the main toolbar
1368 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1370 /* Check if accounts exist */
1371 gboolean accounts_exist =
1372 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1374 /* If not, allow the user to create an account before trying to send/receive. */
1375 if (!accounts_exist)
1376 modest_ui_actions_on_accounts (NULL, win);
1378 /* Refresh the active account */
1379 modest_ui_actions_do_send_receive (NULL, win);
1384 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1387 GtkWidget *header_view;
1389 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1391 header_view = modest_main_window_get_child_widget (main_window,
1392 MODEST_WIDGET_TYPE_HEADER_VIEW);
1396 conf = modest_runtime_get_conf ();
1398 /* what is saved/restored is depending on the style; thus; we save with
1399 * old style, then update the style, and restore for this new style
1401 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1403 if (modest_header_view_get_style
1404 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1405 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1406 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1408 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1409 MODEST_HEADER_VIEW_STYLE_DETAILS);
1411 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1412 MODEST_CONF_HEADER_VIEW_KEY);
1417 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1419 ModestMainWindow *main_window)
1421 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1422 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1424 /* If no header has been selected then exit */
1429 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1430 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1432 /* Update Main window title */
1433 if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
1434 const gchar *subject = tny_header_get_subject (header);
1435 if (subject && strlen(subject) > 0)
1436 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1438 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1441 /* Update toolbar dimming state */
1442 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1446 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1448 ModestMainWindow *main_window)
1452 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1457 headers = tny_simple_list_new ();
1458 tny_list_prepend (headers, G_OBJECT (header));
1460 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1462 g_object_unref (headers);
1466 set_active_account_from_tny_account (TnyAccount *account,
1467 ModestWindow *window)
1469 const gchar *server_acc_name = tny_account_get_id (account);
1471 /* We need the TnyAccount provided by the
1472 account store because that is the one that
1473 knows the name of the Modest account */
1474 TnyAccount *modest_server_account = modest_server_account =
1475 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1476 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1479 const gchar *modest_acc_name =
1480 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1481 modest_window_set_active_account (window, modest_acc_name);
1482 g_object_unref (modest_server_account);
1487 folder_refreshed_cb (const GObject *obj,
1491 ModestMainWindow *win = NULL;
1492 GtkWidget *header_view;
1494 g_return_if_fail (TNY_IS_FOLDER (folder));
1496 win = MODEST_MAIN_WINDOW (user_data);
1498 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1500 /* Check if folder is empty and set headers view contents style */
1501 if (tny_folder_get_all_count (folder) == 0) {
1502 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1503 modest_main_window_set_contents_style (win,
1504 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1506 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1511 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1512 TnyFolderStore *folder_store,
1514 ModestMainWindow *main_window)
1517 GtkWidget *header_view;
1519 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1521 header_view = modest_main_window_get_child_widget(main_window,
1522 MODEST_WIDGET_TYPE_HEADER_VIEW);
1526 conf = modest_runtime_get_conf ();
1528 if (TNY_IS_ACCOUNT (folder_store)) {
1530 /* Update active account */
1531 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1532 /* Show account details */
1533 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1536 if (TNY_IS_FOLDER (folder_store) && selected) {
1538 /* Update the active account */
1539 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1541 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1542 g_object_unref (account);
1546 /* Set the header style by default, it could
1547 be changed later by the refresh callback to
1549 modest_main_window_set_contents_style (main_window,
1550 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1552 /* Set folder on header view. This function
1553 will call tny_folder_refresh_async so we
1554 pass a callback that will be called when
1555 finished. We use that callback to set the
1556 empty view if there are no messages */
1557 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1558 TNY_FOLDER (folder_store),
1559 folder_refreshed_cb,
1562 /* Restore configuration. We need to do this
1563 *after* the set_folder because the widget
1564 memory asks the header view about its
1566 modest_widget_memory_restore (modest_runtime_get_conf (),
1567 G_OBJECT(header_view),
1568 MODEST_CONF_HEADER_VIEW_KEY);
1570 /* Update the active account */
1571 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1572 /* Save only if we're seeing headers */
1573 if (modest_main_window_get_contents_style (main_window) ==
1574 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1575 modest_widget_memory_save (conf, G_OBJECT (header_view),
1576 MODEST_CONF_HEADER_VIEW_KEY);
1577 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1581 /* Update toolbar dimming state */
1582 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1586 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1593 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1595 online = tny_device_is_online (modest_runtime_get_device());
1598 /* already online -- the item is simply not there... */
1599 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1601 GTK_MESSAGE_WARNING,
1603 _("The %s you selected cannot be found"),
1605 gtk_dialog_run (GTK_DIALOG(dialog));
1607 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1611 GTK_RESPONSE_REJECT,
1613 GTK_RESPONSE_ACCEPT,
1615 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1616 "Do you want to get online?"), item);
1617 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1618 gtk_label_new (txt), FALSE, FALSE, 0);
1619 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1622 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1623 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1624 // modest_platform_connect_and_wait ();
1627 gtk_widget_destroy (dialog);
1631 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1634 /* g_message ("%s %s", __FUNCTION__, link); */
1639 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1642 modest_platform_activate_uri (link);
1646 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1649 modest_platform_show_uri_popup (link);
1653 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1656 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1660 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1661 const gchar *address,
1664 /* g_message ("%s %s", __FUNCTION__, address); */
1668 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1670 TnyTransportAccount *transport_account;
1671 ModestMailOperation *mail_operation;
1673 gchar *account_name, *from;
1674 ModestAccountMgr *account_mgr;
1675 gchar *info_text = NULL;
1677 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1679 data = modest_msg_edit_window_get_msg_data (edit_window);
1681 account_mgr = modest_runtime_get_account_mgr();
1682 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1684 account_name = modest_account_mgr_get_default_account (account_mgr);
1685 if (!account_name) {
1686 g_printerr ("modest: no account found\n");
1687 modest_msg_edit_window_free_msg_data (edit_window, data);
1691 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1692 account_name = g_strdup (data->account_name);
1696 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1697 (modest_runtime_get_account_store(),
1699 TNY_ACCOUNT_TYPE_TRANSPORT));
1700 if (!transport_account) {
1701 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1702 g_free (account_name);
1703 modest_msg_edit_window_free_msg_data (edit_window, data);
1706 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1708 /* Create the mail operation */
1709 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1710 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1712 modest_mail_operation_save_to_drafts (mail_operation,
1723 data->priority_flags);
1726 g_free (account_name);
1727 g_object_unref (G_OBJECT (transport_account));
1728 g_object_unref (G_OBJECT (mail_operation));
1730 modest_msg_edit_window_free_msg_data (edit_window, data);
1732 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
1733 modest_platform_information_banner (NULL, NULL, info_text);
1737 /* For instance, when clicking the Send toolbar button when editing a message: */
1739 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1741 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1743 if (!modest_msg_edit_window_check_names (edit_window))
1746 /* Offer the connection dialog, if necessary: */
1747 if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window)))
1750 /* FIXME: Code added just for testing. The final version will
1751 use the send queue provided by tinymail and some
1753 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1754 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1756 account_name = modest_account_mgr_get_default_account (account_mgr);
1758 if (!account_name) {
1759 g_printerr ("modest: no account found\n");
1763 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1765 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1766 account_name = g_strdup (data->account_name);
1769 /* Get the currently-active transport account for this modest account: */
1770 TnyTransportAccount *transport_account =
1771 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1772 (modest_runtime_get_account_store(),
1774 if (!transport_account) {
1775 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1776 g_free (account_name);
1777 modest_msg_edit_window_free_msg_data (edit_window, data);
1781 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1783 /* mail content checks and dialogs */
1784 if (data->subject == NULL || data->subject[0] == '\0') {
1785 GtkResponseType response;
1786 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1787 _("mcen_nc_subject_is_empty_send"));
1788 if (response == GTK_RESPONSE_CANCEL) {
1789 g_free (account_name);
1794 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
1795 GtkResponseType response;
1796 gchar *note_message;
1797 gchar *note_subject = data->subject;
1798 if (note_subject == NULL || note_subject[0] == '\0')
1799 note_subject = _("mail_va_no_subject");
1800 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
1801 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1803 g_free (note_message);
1804 if (response == GTK_RESPONSE_CANCEL) {
1805 g_free (account_name);
1810 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
1812 /* Create the mail operation */
1813 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1814 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1816 modest_mail_operation_send_new_mail (mail_operation,
1827 data->priority_flags);
1831 g_free (account_name);
1832 g_object_unref (G_OBJECT (transport_account));
1833 g_object_unref (G_OBJECT (mail_operation));
1835 modest_msg_edit_window_free_msg_data (edit_window, data);
1836 modest_msg_edit_window_set_sent (edit_window, TRUE);
1838 /* Save settings and close the window: */
1839 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
1843 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1844 ModestMsgEditWindow *window)
1846 ModestMsgEditFormatState *format_state = NULL;
1848 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1849 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1851 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1854 format_state = modest_msg_edit_window_get_format_state (window);
1855 g_return_if_fail (format_state != NULL);
1857 format_state->bold = gtk_toggle_action_get_active (action);
1858 modest_msg_edit_window_set_format_state (window, format_state);
1859 g_free (format_state);
1864 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1865 ModestMsgEditWindow *window)
1867 ModestMsgEditFormatState *format_state = NULL;
1869 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1870 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1872 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1875 format_state = modest_msg_edit_window_get_format_state (window);
1876 g_return_if_fail (format_state != NULL);
1878 format_state->italics = gtk_toggle_action_get_active (action);
1879 modest_msg_edit_window_set_format_state (window, format_state);
1880 g_free (format_state);
1885 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1886 ModestMsgEditWindow *window)
1888 ModestMsgEditFormatState *format_state = NULL;
1890 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1891 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1893 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1896 format_state = modest_msg_edit_window_get_format_state (window);
1897 g_return_if_fail (format_state != NULL);
1899 format_state->bullet = gtk_toggle_action_get_active (action);
1900 modest_msg_edit_window_set_format_state (window, format_state);
1901 g_free (format_state);
1906 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1907 GtkRadioAction *selected,
1908 ModestMsgEditWindow *window)
1910 ModestMsgEditFormatState *format_state = NULL;
1911 GtkJustification value;
1913 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1915 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1918 value = gtk_radio_action_get_current_value (selected);
1920 format_state = modest_msg_edit_window_get_format_state (window);
1921 g_return_if_fail (format_state != NULL);
1923 format_state->justification = value;
1924 modest_msg_edit_window_set_format_state (window, format_state);
1925 g_free (format_state);
1929 modest_ui_actions_on_select_editor_color (GtkAction *action,
1930 ModestMsgEditWindow *window)
1932 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1933 g_return_if_fail (GTK_IS_ACTION (action));
1935 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1938 modest_msg_edit_window_select_color (window);
1942 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1943 ModestMsgEditWindow *window)
1945 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1946 g_return_if_fail (GTK_IS_ACTION (action));
1948 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1951 modest_msg_edit_window_select_background_color (window);
1955 modest_ui_actions_on_insert_image (GtkAction *action,
1956 ModestMsgEditWindow *window)
1958 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1959 g_return_if_fail (GTK_IS_ACTION (action));
1961 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1964 modest_msg_edit_window_insert_image (window);
1968 modest_ui_actions_on_attach_file (GtkAction *action,
1969 ModestMsgEditWindow *window)
1971 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1972 g_return_if_fail (GTK_IS_ACTION (action));
1974 modest_msg_edit_window_attach_file (window);
1978 modest_ui_actions_on_remove_attachments (GtkAction *action,
1979 ModestMsgEditWindow *window)
1981 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1982 g_return_if_fail (GTK_IS_ACTION (action));
1984 modest_msg_edit_window_remove_attachments (window, NULL);
1988 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1990 TnyFolderStore *parent_folder;
1991 GtkWidget *folder_view;
1993 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1995 folder_view = modest_main_window_get_child_widget (main_window,
1996 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2000 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2002 if (parent_folder) {
2003 gboolean finished = FALSE;
2005 gchar *folder_name = NULL, *suggested_name = NULL;
2007 /* Run the new folder dialog */
2009 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
2014 if (result == GTK_RESPONSE_REJECT) {
2017 ModestMailOperation *mail_op;
2018 TnyFolder *new_folder = NULL;
2020 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO,
2021 G_OBJECT(main_window));
2022 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2024 new_folder = modest_mail_operation_create_folder (mail_op,
2026 (const gchar *) folder_name);
2028 g_object_unref (new_folder);
2031 g_object_unref (mail_op);
2033 g_free (folder_name);
2037 g_object_unref (parent_folder);
2042 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2045 GObject *win = modest_mail_operation_get_source (mail_op);
2046 const GError *error = NULL;
2047 const gchar *message = NULL;
2049 /* Get error message */
2050 error = modest_mail_operation_get_error (mail_op);
2051 if (error != NULL && error->message != NULL) {
2052 message = error->message;
2054 message = _("!!! FIXME: Unable to rename");
2057 /* Show notification dialog */
2058 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
2059 g_object_unref (win);
2063 modest_ui_actions_on_rename_folder (GtkAction *action,
2064 ModestMainWindow *main_window)
2066 TnyFolderStore *folder;
2067 GtkWidget *folder_view;
2068 GtkWidget *header_view;
2070 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2072 folder_view = modest_main_window_get_child_widget (main_window,
2073 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2077 header_view = modest_main_window_get_child_widget (main_window,
2078 MODEST_WIDGET_TYPE_HEADER_VIEW);
2083 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2085 /* Offer the connection dialog if necessary: */
2086 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2087 g_object_unref (G_OBJECT (folder));
2092 if (folder && TNY_IS_FOLDER (folder)) {
2095 const gchar *current_name;
2097 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2098 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
2099 current_name, &folder_name);
2101 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
2102 ModestMailOperation *mail_op;
2105 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2106 G_OBJECT(main_window),
2107 modest_ui_actions_rename_folder_error_handler,
2111 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2114 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2116 modest_mail_operation_rename_folder (mail_op,
2117 TNY_FOLDER (folder),
2118 (const gchar *) folder_name);
2120 g_object_unref (mail_op);
2121 g_free (folder_name);
2123 g_object_unref (folder);
2128 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2131 GObject *win = modest_mail_operation_get_source (mail_op);
2133 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2134 _("mail_in_ui_folder_delete_error"));
2135 g_object_unref (win);
2139 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2141 TnyFolderStore *folder;
2142 GtkWidget *folder_view;
2146 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2148 folder_view = modest_main_window_get_child_widget (main_window,
2149 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2153 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2155 /* Show an error if it's an account */
2156 if (!TNY_IS_FOLDER (folder)) {
2157 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2158 _("mail_in_ui_folder_delete_error"));
2159 g_object_unref (G_OBJECT (folder));
2163 /* Offer the connection dialog if necessary: */
2164 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2165 g_object_unref (G_OBJECT (folder));
2170 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2171 tny_folder_get_name (TNY_FOLDER (folder)));
2172 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2173 (const gchar *) message);
2176 if (response == GTK_RESPONSE_OK) {
2177 ModestMailOperation *mail_op =
2178 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2179 G_OBJECT(main_window),
2180 modest_ui_actions_delete_folder_error_handler,
2183 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2185 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2186 g_object_unref (G_OBJECT (mail_op));
2189 g_object_unref (G_OBJECT (folder));
2193 modest_ui_actions_on_delete_folder (GtkAction *action,
2194 ModestMainWindow *main_window)
2196 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2198 delete_folder (main_window, FALSE);
2202 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2204 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2206 delete_folder (main_window, TRUE);
2210 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2211 const gchar* server_account_name,
2216 ModestMainWindow *main_window)
2218 g_return_if_fail(server_account_name);
2219 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2221 /* Initalize output parameters: */
2228 #ifdef MODEST_PLATFORM_MAEMO
2229 /* Maemo uses a different (awkward) button order,
2230 * It should probably just use gtk_alternative_dialog_button_order ().
2232 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2236 GTK_RESPONSE_ACCEPT,
2238 GTK_RESPONSE_REJECT,
2241 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2245 GTK_RESPONSE_REJECT,
2247 GTK_RESPONSE_ACCEPT,
2249 #endif /* MODEST_PLATFORM_MAEMO */
2251 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2253 gchar *server_name = modest_server_account_get_hostname (
2254 modest_runtime_get_account_mgr(), server_account_name);
2255 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2256 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2261 /* This causes a warning because the logical ID has no %s in it,
2262 * though the translation does, but there is not much we can do about that: */
2263 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2264 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2267 g_free (server_name);
2271 gchar *initial_username = modest_server_account_get_username (
2272 modest_runtime_get_account_mgr(), server_account_name);
2274 GtkWidget *entry_username = gtk_entry_new ();
2275 if (initial_username)
2276 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2277 /* Dim this if a connection has ever succeeded with this username,
2278 * as per the UI spec: */
2279 const gboolean username_known =
2280 modest_server_account_get_username_has_succeeded(
2281 modest_runtime_get_account_mgr(), server_account_name);
2282 gtk_widget_set_sensitive (entry_username, !username_known);
2284 #ifdef MODEST_PLATFORM_MAEMO
2285 /* Auto-capitalization is the default, so let's turn it off: */
2286 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2288 /* Create a size group to be used by all captions.
2289 * Note that HildonCaption does not create a default size group if we do not specify one.
2290 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2291 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2293 GtkWidget *caption = hildon_caption_new (sizegroup,
2294 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2295 gtk_widget_show (entry_username);
2296 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2297 FALSE, FALSE, MODEST_MARGIN_HALF);
2298 gtk_widget_show (caption);
2300 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2302 #endif /* MODEST_PLATFORM_MAEMO */
2305 GtkWidget *entry_password = gtk_entry_new ();
2306 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2307 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2309 #ifdef MODEST_PLATFORM_MAEMO
2310 /* Auto-capitalization is the default, so let's turn it off: */
2311 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2312 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2314 caption = hildon_caption_new (sizegroup,
2315 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2316 gtk_widget_show (entry_password);
2317 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2318 FALSE, FALSE, MODEST_MARGIN_HALF);
2319 gtk_widget_show (caption);
2320 g_object_unref (sizegroup);
2322 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2324 #endif /* MODEST_PLATFORM_MAEMO */
2326 /* This is not in the Maemo UI spec:
2327 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2328 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2332 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2334 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2336 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2338 modest_server_account_set_username (
2339 modest_runtime_get_account_mgr(), server_account_name,
2342 const gboolean username_was_changed =
2343 (strcmp (*username, initial_username) != 0);
2344 if (username_was_changed) {
2345 g_warning ("%s: tinymail does not yet support changing the "
2346 "username in the get_password() callback.\n", __FUNCTION__);
2351 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2353 /* We do not save the password in the configuration,
2354 * because this function is only called for passwords that should
2355 * not be remembered:
2356 modest_server_account_set_password (
2357 modest_runtime_get_account_mgr(), server_account_name,
2376 /* This is not in the Maemo UI spec:
2377 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2383 gtk_widget_destroy (dialog);
2385 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2389 modest_ui_actions_on_cut (GtkAction *action,
2390 ModestWindow *window)
2392 GtkWidget *focused_widget;
2394 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2395 if (GTK_IS_EDITABLE (focused_widget)) {
2396 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2397 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2398 GtkTextBuffer *buffer;
2399 GtkClipboard *clipboard;
2401 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2402 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2403 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2404 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2405 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2406 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2407 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2412 modest_ui_actions_on_copy (GtkAction *action,
2413 ModestWindow *window)
2415 GtkClipboard *clipboard;
2416 GtkWidget *focused_widget;
2418 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2419 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2421 if (GTK_IS_LABEL (focused_widget)) {
2422 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2423 } else if (GTK_IS_EDITABLE (focused_widget)) {
2424 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2425 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2426 GtkTextBuffer *buffer;
2427 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2428 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2429 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2430 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2431 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2432 TnyIterator *iter = tny_list_create_iterator (header_list);
2433 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2434 TnyFolder *folder = tny_header_get_folder (header);
2435 TnyAccount *account = tny_folder_get_account (folder);
2436 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2437 /* If it's POP then ask */
2438 gboolean ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2439 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2440 g_object_unref (account);
2441 g_object_unref (folder);
2442 g_object_unref (header);
2443 g_object_unref (iter);
2445 /* Check that the messages have been previously downloaded */
2446 gboolean continue_download = TRUE;
2448 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window));
2449 if (continue_download)
2450 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2451 g_object_unref (header_list);
2452 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2453 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2456 /* Show information banner */
2457 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2462 modest_ui_actions_on_undo (GtkAction *action,
2463 ModestWindow *window)
2465 ModestEmailClipboard *clipboard = NULL;
2467 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2468 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2469 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2470 /* Clear clipboard source */
2471 clipboard = modest_runtime_get_email_clipboard ();
2472 modest_email_clipboard_clear (clipboard);
2475 g_return_if_reached ();
2480 modest_ui_actions_on_redo (GtkAction *action,
2481 ModestWindow *window)
2483 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2484 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
2487 g_return_if_reached ();
2493 paste_msgs_cb (const GObject *object, gpointer user_data)
2495 g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2496 g_return_if_fail (GTK_IS_WIDGET (user_data));
2498 /* destroy information note */
2499 gtk_widget_destroy (GTK_WIDGET(user_data));
2503 modest_ui_actions_on_paste (GtkAction *action,
2504 ModestWindow *window)
2506 GtkWidget *focused_widget = NULL;
2507 GtkWidget *inf_note = NULL;
2508 ModestMailOperation *mail_op = NULL;
2510 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2511 if (GTK_IS_EDITABLE (focused_widget)) {
2512 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2513 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2514 GtkTextBuffer *buffer;
2515 GtkClipboard *clipboard;
2517 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2518 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2519 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2520 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2521 ModestEmailClipboard *clipboard = NULL;
2522 TnyFolder *src_folder = NULL;
2523 TnyFolderStore *folder_store = NULL;
2524 TnyList *data = NULL;
2525 gboolean delete = FALSE;
2527 /* Check clipboard source */
2528 clipboard = modest_runtime_get_email_clipboard ();
2529 if (modest_email_clipboard_cleared (clipboard))
2532 /* Get elements to paste */
2533 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2535 /* Create a new mail operation */
2536 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2537 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2540 /* Get destination folder */
2541 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2543 /* Launch notification */
2544 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2545 _CS("ckct_nw_pasting"));
2546 if (inf_note != NULL) {
2547 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
2548 gtk_widget_show (GTK_WIDGET(inf_note));
2551 /* transfer messages */
2553 modest_mail_operation_xfer_msgs (mail_op,
2555 TNY_FOLDER (folder_store),
2560 } else if (src_folder != NULL) {
2561 modest_mail_operation_xfer_folder (mail_op,
2571 g_object_unref (data);
2572 if (src_folder != NULL)
2573 g_object_unref (src_folder);
2574 if (folder_store != NULL)
2575 g_object_unref (folder_store);
2581 modest_ui_actions_on_select_all (GtkAction *action,
2582 ModestWindow *window)
2584 GtkWidget *focused_widget;
2586 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2587 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2588 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2589 } else if (GTK_IS_LABEL (focused_widget)) {
2590 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2591 } else if (GTK_IS_EDITABLE (focused_widget)) {
2592 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2593 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2594 GtkTextBuffer *buffer;
2595 GtkTextIter start, end;
2597 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2598 gtk_text_buffer_get_start_iter (buffer, &start);
2599 gtk_text_buffer_get_end_iter (buffer, &end);
2600 gtk_text_buffer_select_range (buffer, &start, &end);
2601 } else if (GTK_IS_HTML (focused_widget)) {
2602 gtk_html_select_all (GTK_HTML (focused_widget));
2603 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2604 GtkWidget *header_view = focused_widget;
2605 GtkTreeSelection *selection = NULL;
2607 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
2608 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2609 MODEST_WIDGET_TYPE_HEADER_VIEW);
2611 /* Select all messages */
2612 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2613 gtk_tree_selection_select_all (selection);
2615 /* Set focuse on header view */
2616 gtk_widget_grab_focus (header_view);
2622 modest_ui_actions_on_mark_as_read (GtkAction *action,
2623 ModestWindow *window)
2625 g_return_if_fail (MODEST_IS_WINDOW(window));
2627 /* Mark each header as read */
2628 do_headers_action (window, headers_action_mark_as_read, NULL);
2632 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2633 ModestWindow *window)
2635 g_return_if_fail (MODEST_IS_WINDOW(window));
2637 /* Mark each header as read */
2638 do_headers_action (window, headers_action_mark_as_unread, NULL);
2642 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2643 GtkRadioAction *selected,
2644 ModestWindow *window)
2648 value = gtk_radio_action_get_current_value (selected);
2649 if (MODEST_IS_WINDOW (window)) {
2650 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2654 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2655 GtkRadioAction *selected,
2656 ModestWindow *window)
2658 TnyHeaderFlags flags;
2659 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2661 flags = gtk_radio_action_get_current_value (selected);
2662 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2665 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2666 GtkRadioAction *selected,
2667 ModestWindow *window)
2671 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2673 file_format = gtk_radio_action_get_current_value (selected);
2674 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2679 modest_ui_actions_on_zoom_plus (GtkAction *action,
2680 ModestWindow *window)
2682 g_return_if_fail (MODEST_IS_WINDOW (window));
2684 modest_window_zoom_plus (MODEST_WINDOW (window));
2688 modest_ui_actions_on_zoom_minus (GtkAction *action,
2689 ModestWindow *window)
2691 g_return_if_fail (MODEST_IS_WINDOW (window));
2693 modest_window_zoom_minus (MODEST_WINDOW (window));
2697 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2698 ModestWindow *window)
2700 ModestWindowMgr *mgr;
2701 gboolean fullscreen, active;
2702 g_return_if_fail (MODEST_IS_WINDOW (window));
2704 mgr = modest_runtime_get_window_mgr ();
2706 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2707 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2709 if (active != fullscreen) {
2710 modest_window_mgr_set_fullscreen_mode (mgr, active);
2711 gtk_window_present (GTK_WINDOW (window));
2716 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2717 ModestWindow *window)
2719 ModestWindowMgr *mgr;
2720 gboolean fullscreen;
2722 g_return_if_fail (MODEST_IS_WINDOW (window));
2724 mgr = modest_runtime_get_window_mgr ();
2725 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2726 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2728 gtk_window_present (GTK_WINDOW (window));
2732 * Used by modest_ui_actions_on_details to call do_headers_action
2735 headers_action_show_details (TnyHeader *header,
2736 ModestWindow *window,
2743 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2746 gtk_widget_show_all (dialog);
2747 gtk_dialog_run (GTK_DIALOG (dialog));
2749 gtk_widget_destroy (dialog);
2753 * Show the folder details in a ModestDetailsDialog widget
2756 show_folder_details (TnyFolder *folder,
2762 dialog = modest_details_dialog_new_with_folder (window, folder);
2765 gtk_widget_show_all (dialog);
2766 gtk_dialog_run (GTK_DIALOG (dialog));
2768 gtk_widget_destroy (dialog);
2772 * Show the header details in a ModestDetailsDialog widget
2775 modest_ui_actions_on_details (GtkAction *action,
2778 TnyList * headers_list;
2782 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2785 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2788 g_object_unref (msg);
2790 headers_list = get_selected_headers (win);
2794 iter = tny_list_create_iterator (headers_list);
2796 header = TNY_HEADER (tny_iterator_get_current (iter));
2797 headers_action_show_details (header, win, NULL);
2798 g_object_unref (header);
2800 g_object_unref (iter);
2801 g_object_unref (headers_list);
2803 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2804 GtkWidget *folder_view, *header_view;
2806 /* Check which widget has the focus */
2807 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2808 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2809 if (gtk_widget_is_focus (folder_view)) {
2810 TnyFolderStore *folder_store
2811 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2812 if (!folder_store) {
2813 g_warning ("%s: No item was selected.\n", __FUNCTION__);
2816 /* Show only when it's a folder */
2817 /* This function should not be called for account items,
2818 * because we dim the menu item for them. */
2819 if (TNY_IS_FOLDER (folder_store)) {
2820 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
2823 g_object_unref (folder_store);
2826 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2827 MODEST_WIDGET_TYPE_HEADER_VIEW);
2828 /* Show details of each header */
2829 do_headers_action (win, headers_action_show_details, header_view);
2835 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2836 ModestMsgEditWindow *window)
2838 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2840 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2844 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2845 ModestMsgEditWindow *window)
2847 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2849 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2853 modest_ui_actions_toggle_folders_view (GtkAction *action,
2854 ModestMainWindow *main_window)
2858 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2860 conf = modest_runtime_get_conf ();
2862 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2863 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2865 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2869 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2870 ModestWindow *window)
2872 gboolean active, fullscreen = FALSE;
2873 ModestWindowMgr *mgr;
2875 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2877 /* Check if we want to toggle the toolbar vuew in fullscreen
2879 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2880 "ViewShowToolbarFullScreen")) {
2884 /* Toggle toolbar */
2885 mgr = modest_runtime_get_window_mgr ();
2886 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2890 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2891 ModestMsgEditWindow *window)
2893 modest_msg_edit_window_select_font (window);
2897 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2898 const gchar *display_name,
2901 /* Do not change the application name if the widget has not
2902 the focus. This callback could be called even if the folder
2903 view has not the focus, because the handled signal could be
2904 emitted when the folder view is redrawn */
2905 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2907 gtk_window_set_title (window, display_name);
2909 gtk_window_set_title (window, " ");
2914 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2916 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2917 modest_msg_edit_window_select_contacts (window);
2921 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2923 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2924 modest_msg_edit_window_check_names (window);
2929 create_move_to_dialog (ModestWindow *win,
2930 GtkWidget *folder_view,
2931 GtkWidget **tree_view)
2933 GtkWidget *dialog, *scroll;
2935 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2937 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2939 GTK_RESPONSE_ACCEPT,
2941 GTK_RESPONSE_REJECT,
2944 /* Create scrolled window */
2945 scroll = gtk_scrolled_window_new (NULL, NULL);
2946 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2947 GTK_POLICY_AUTOMATIC,
2948 GTK_POLICY_AUTOMATIC);
2950 /* Create folder view */
2951 *tree_view = modest_platform_create_folder_view (NULL);
2953 /* It could happen that we're trying to move a message from a
2954 window (msg window for example) after the main window was
2955 closed, so we can not just get the model of the folder
2957 if (MODEST_IS_FOLDER_VIEW (folder_view))
2958 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2959 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2961 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
2962 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
2964 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2966 /* Add scroll to dialog */
2967 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2968 scroll, FALSE, FALSE, 0);
2970 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2972 /* Select INBOX or local account */
2973 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (*tree_view));
2979 * Returns TRUE if at least one of the headers of the list belongs to
2980 * a message that has been fully retrieved.
2983 has_retrieved_msgs (TnyList *list)
2986 gboolean found = FALSE;
2988 iter = tny_list_create_iterator (list);
2989 while (tny_iterator_is_done (iter) && !found) {
2991 TnyHeaderFlags flags;
2993 header = TNY_HEADER (tny_iterator_get_current (iter));
2994 flags = tny_header_get_flags (header);
2995 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2999 tny_iterator_next (iter);
3001 g_object_unref (iter);
3007 * Shows a confirmation dialog to the user when we're moving messages
3008 * from a remote server to the local storage. Returns the dialog
3009 * response. If it's other kind of movement the it always returns
3013 msgs_move_to_confirmation (GtkWindow *win,
3014 TnyFolder *dest_folder,
3017 gint response = GTK_RESPONSE_OK;
3019 /* If the destination is a local folder */
3020 if (modest_tny_folder_is_local_folder (dest_folder)) {
3021 TnyFolder *src_folder;
3025 /* Get source folder */
3026 iter = tny_list_create_iterator (headers);
3027 header = TNY_HEADER (tny_iterator_get_current (iter));
3028 src_folder = tny_header_get_folder (header);
3029 g_object_unref (header);
3030 g_object_unref (iter);
3032 /* if no src_folder, message may be an attahcment */
3033 if (src_folder == NULL)
3034 return GTK_RESPONSE_CANCEL;
3036 /* If the source is a remote folder */
3037 if (!modest_tny_folder_is_local_folder (src_folder)) {
3038 const gchar *message;
3040 if (has_retrieved_msgs (headers))
3041 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
3042 tny_list_get_length (headers));
3044 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
3045 tny_list_get_length (headers));
3047 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
3048 (const gchar *) message);
3050 g_object_unref (src_folder);
3058 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
3060 ModestMsgViewWindow *self = NULL;
3061 gboolean last, first;
3063 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
3064 self = MODEST_MSG_VIEW_WINDOW (object);
3066 last = modest_msg_view_window_last_message_selected (self);
3067 first = modest_msg_view_window_first_message_selected (self);
3069 /* No more messages to view, so close this window */
3070 /* gboolean ret_value; */
3071 /* g_signal_emit_by_name (G_OBJECT (self), "delete-event", NULL, &ret_value); */
3072 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3074 modest_msg_view_window_select_previous_message (self);
3076 modest_msg_view_window_select_next_message (self);
3080 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3083 GObject *win = modest_mail_operation_get_source (mail_op);
3084 const GError *error = NULL;
3085 const gchar *message = NULL;
3087 /* Get error message */
3088 error = modest_mail_operation_get_error (mail_op);
3089 if (error != NULL && error->message != NULL) {
3090 message = error->message;
3092 message = _("mail_in_ui_folder_move_target_error");
3095 /* Show notification dialog */
3096 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3097 g_object_unref (win);
3101 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3104 GObject *win = modest_mail_operation_get_source (mail_op);
3105 const GError *error = modest_mail_operation_get_error (mail_op);
3107 g_return_if_fail (error != NULL);
3108 if (error->message != NULL)
3109 g_printerr ("modest: %s\n", error->message);
3111 g_printerr ("modest: unkonw error on send&receive operation");
3113 /* Show error message */
3114 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3115 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3116 /* _CS("sfil_ib_unable_to_receive")); */
3118 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3119 /* _CS("sfil_ib_unable_to_send")); */
3120 g_object_unref (win);
3124 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3131 gint pending_purges = 0;
3132 gboolean some_purged = FALSE;
3133 ModestWindow *win = MODEST_WINDOW (user_data);
3135 /* If there was any error */
3136 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
3139 /* Once the message has been retrieved for purging, we check if
3140 * it's all ok for purging */
3142 parts = tny_simple_list_new ();
3143 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3144 iter = tny_list_create_iterator (parts);
3146 while (!tny_iterator_is_done (iter)) {
3148 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3149 if (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)) {
3150 if (tny_mime_part_is_purged (part))
3155 tny_iterator_next (iter);
3158 if (pending_purges>0) {
3160 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3162 if (response == GTK_RESPONSE_OK) {
3163 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3164 tny_iterator_first (iter);
3165 while (!tny_iterator_is_done (iter)) {
3168 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3169 if (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))
3170 tny_mime_part_set_purged (part);
3171 tny_iterator_next (iter);
3174 tny_msg_rewrite_cache (msg);
3177 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3180 /* remove attachments */
3181 tny_iterator_first (iter);
3182 while (!tny_iterator_is_done (iter)) {
3185 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3186 g_object_unref (part);
3187 tny_iterator_next (iter);
3190 g_object_unref (iter);
3191 g_object_unref (parts);
3195 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3196 ModestMainWindow *win)
3198 GtkWidget *header_view;
3199 TnyList *header_list;
3202 TnyHeaderFlags flags;
3203 ModestWindow *msg_view_window = NULL;
3206 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3208 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3209 MODEST_WIDGET_TYPE_HEADER_VIEW);
3211 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3213 if (tny_list_get_length (header_list) == 1) {
3214 iter = tny_list_create_iterator (header_list);
3215 header = TNY_HEADER (tny_iterator_get_current (iter));
3216 g_object_unref (iter);
3221 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3222 header, &msg_view_window);
3223 flags = tny_header_get_flags (header);
3224 if (!(flags & TNY_HEADER_FLAG_CACHED))
3227 if (msg_view_window != NULL)
3228 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3230 /* do nothing; uid was registered before, so window is probably on it's way */
3231 g_warning ("debug: header %p has already been registered", header);
3234 ModestMailOperation *mail_op = NULL;
3235 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3236 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3238 modest_ui_actions_get_msgs_full_error_handler,
3240 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3241 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3243 g_object_unref (mail_op);
3246 g_object_unref (header);
3248 g_object_unref (header_list);
3252 * UI handler for the "Move to" action when invoked from the
3256 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3257 ModestMainWindow *win)
3259 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3260 GtkWidget *header_view = NULL;
3262 TnyFolderStore *folder_store = NULL;
3263 ModestMailOperation *mail_op = NULL;
3265 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3267 /* Get the folder view */
3268 folder_view = modest_main_window_get_child_widget (win,
3269 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3271 TnyFolderStore *src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3273 /* Offer the connection dialog if necessary, if the source folder is in a networked account: */
3274 if (!modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win), src_folder)) {
3276 g_object_unref (src_folder);
3282 /* Get header view */
3283 header_view = modest_main_window_get_child_widget (win,
3284 MODEST_WIDGET_TYPE_HEADER_VIEW);
3286 /* Create and run the dialog */
3287 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
3288 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3289 result = gtk_dialog_run (GTK_DIALOG(dialog));
3290 g_object_ref (tree_view);
3292 /* We do this to save an indentation level ;-) */
3293 if (result != GTK_RESPONSE_ACCEPT)
3296 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3298 if (TNY_IS_ACCOUNT (folder_store) &&
3299 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (folder_store))
3302 /* Offer the connection dialog if necessary: */
3303 if (!modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win), folder_store)) {
3307 /* Get folder or messages to transfer */
3308 if (gtk_widget_is_focus (folder_view)) {
3310 /* Clean folder on header view before moving it */
3311 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3313 if (TNY_IS_FOLDER (src_folder)) {
3315 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3317 modest_ui_actions_move_folder_error_handler,
3319 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3321 modest_mail_operation_xfer_folder (mail_op,
3322 TNY_FOLDER (src_folder),
3325 /* Unref mail operation */
3326 g_object_unref (G_OBJECT (mail_op));
3328 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
3331 if (gtk_widget_is_focus (header_view)) {
3332 TnyList *headers = NULL;
3335 /* TODO: Check for connection if the headers are on a network account. */
3336 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3338 /* Ask for user confirmation */
3339 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3340 TNY_FOLDER (folder_store),
3343 /* Transfer messages */
3344 if (response == GTK_RESPONSE_OK) {
3346 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3348 modest_ui_actions_move_folder_error_handler,
3350 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3353 modest_mail_operation_xfer_msgs (mail_op,
3355 TNY_FOLDER (folder_store),
3360 g_object_unref (G_OBJECT (mail_op));
3362 g_object_unref (headers);
3368 g_object_unref (src_folder);
3371 g_object_unref (folder_store);
3373 gtk_widget_destroy (dialog);
3378 * UI handler for the "Move to" action when invoked from the
3379 * ModestMsgViewWindow
3382 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3383 ModestMsgViewWindow *win)
3385 GtkWidget *dialog, *folder_view, *tree_view = NULL;
3387 ModestMainWindow *main_window = NULL;
3388 TnyHeader *header = NULL;
3389 TnyList *headers = NULL;
3391 /* Get the folder view */
3392 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3394 folder_view = modest_main_window_get_child_widget (main_window,
3395 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3399 /* Create and run the dialog */
3400 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
3401 result = gtk_dialog_run (GTK_DIALOG(dialog));
3403 if (result == GTK_RESPONSE_ACCEPT) {
3404 TnyFolderStore *folder_store;
3407 /* Create header list */
3408 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3409 g_return_if_fail (header != NULL);
3411 /* Offer the connection dialog if necessary: */
3412 /* TODO: What's the extra g_object_ref() for? Isn't this leaking a ref? */
3413 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (g_object_ref (tree_view)));
3414 TnyFolder *header_folder = tny_header_get_folder(header);
3415 if (modest_platform_connect_and_wait_if_network_folderstore (NULL, folder_store) &&
3416 modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (header_folder))) {
3418 headers = tny_simple_list_new ();
3419 tny_list_prepend (headers, G_OBJECT (header));
3420 g_object_unref (header);
3422 /* Ask user for confirmation. MSG-NOT404 */
3423 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3424 TNY_FOLDER (folder_store),
3427 /* Transfer current msg */
3428 if (response == GTK_RESPONSE_OK) {
3429 ModestMailOperation *mail_op;
3431 /* Create mail op */
3432 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
3433 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3436 /* Transfer messages */
3437 modest_mail_operation_xfer_msgs (mail_op,
3439 TNY_FOLDER (folder_store),
3441 transfer_msgs_from_viewer_cb,
3443 g_object_unref (G_OBJECT (mail_op));
3448 g_object_unref (header_folder);
3451 g_object_unref (headers);
3454 g_object_unref (folder_store);
3457 gtk_widget_destroy (dialog);
3461 modest_ui_actions_on_move_to (GtkAction *action,
3464 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3465 MODEST_IS_MSG_VIEW_WINDOW (win));
3467 if (MODEST_IS_MAIN_WINDOW (win))
3468 modest_ui_actions_on_main_window_move_to (action,
3469 MODEST_MAIN_WINDOW (win));
3471 modest_ui_actions_on_msg_view_window_move_to (action,
3472 MODEST_MSG_VIEW_WINDOW (win));
3476 * Calls #HeadersFunc for each header already selected in the main
3477 * window or the message currently being shown in the msg view window
3480 do_headers_action (ModestWindow *win,
3484 TnyList *headers_list;
3490 headers_list = get_selected_headers (win);
3494 /* Get the folder */
3495 iter = tny_list_create_iterator (headers_list);
3496 header = TNY_HEADER (tny_iterator_get_current (iter));
3497 folder = tny_header_get_folder (header);
3498 g_object_unref (header);
3500 /* Call the function for each header */
3501 while (!tny_iterator_is_done (iter)) {
3502 header = TNY_HEADER (tny_iterator_get_current (iter));
3503 func (header, win, user_data);
3504 g_object_unref (header);
3505 tny_iterator_next (iter);
3508 /* Trick: do a poke status in order to speed up the signaling
3510 tny_folder_poke_status (folder);
3513 g_object_unref (folder);
3514 g_object_unref (iter);
3515 g_object_unref (headers_list);
3519 modest_ui_actions_view_attachment (GtkAction *action,
3520 ModestWindow *window)
3522 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3523 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
3525 /* not supported window for this action */
3526 g_return_if_reached ();
3531 modest_ui_actions_save_attachments (GtkAction *action,
3532 ModestWindow *window)
3534 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3535 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
3537 /* not supported window for this action */
3538 g_return_if_reached ();
3543 modest_ui_actions_remove_attachments (GtkAction *action,
3544 ModestWindow *window)
3546 if (MODEST_IS_MAIN_WINDOW (window)) {
3547 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
3548 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3549 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
3551 /* not supported window for this action */
3552 g_return_if_reached ();
3557 modest_ui_actions_on_settings (GtkAction *action,
3562 dialog = modest_platform_get_global_settings_dialog ();
3563 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
3564 gtk_widget_show_all (dialog);
3566 gtk_dialog_run (GTK_DIALOG (dialog));
3568 gtk_widget_destroy (dialog);
3572 modest_ui_actions_on_help (GtkAction *action,
3575 const gchar *help_id = NULL;
3577 if (MODEST_IS_MAIN_WINDOW (win)) {
3578 const gchar *action_name;
3579 action_name = gtk_action_get_name (action);
3581 if (!strcmp (action_name, "FolderViewCSMHelp") ||
3582 !strcmp (action_name, "HeaderViewCSMHelp")) {
3583 GtkWidget *folder_view;
3584 TnyFolderStore *folder_store;
3585 /* Get selected folder */
3586 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3587 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3588 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3590 /* Switch help_id */
3591 if (TNY_IS_FOLDER (folder_store)) {
3592 switch (tny_folder_get_folder_type (TNY_FOLDER (folder_store))) {
3593 case TNY_FOLDER_TYPE_NORMAL:
3594 help_id = "applications_email_userfolder";
3596 case TNY_FOLDER_TYPE_INBOX:
3597 help_id = "applications_email_inbox";
3599 case TNY_FOLDER_TYPE_OUTBOX:
3600 help_id = "applications_email_outbox";
3602 case TNY_FOLDER_TYPE_SENT:
3603 help_id = "applications_email_sent";
3605 case TNY_FOLDER_TYPE_DRAFTS:
3606 help_id = "applications_email_drafts";
3608 case TNY_FOLDER_TYPE_ARCHIVE:
3609 help_id = "applications_email_archive";
3615 g_object_unref (folder_store);
3617 help_id = "applications_email_mainview";
3619 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3620 help_id = "applications_email_viewer";
3621 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
3622 help_id = "applications_email_editor";
3624 modest_platform_show_help (GTK_WINDOW (win), help_id);
3628 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
3629 ModestWindow *window)
3631 ModestMailOperation *mail_op;
3635 headers = get_selected_headers (window);
3639 /* Create mail operation */
3640 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3642 modest_ui_actions_get_msgs_full_error_handler,
3644 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3645 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
3648 g_object_unref (headers);
3649 g_object_unref (mail_op);
3653 modest_ui_actions_on_email_menu_activated (GtkAction *action,
3654 ModestWindow *window)
3656 g_return_if_fail (MODEST_IS_WINDOW (window));
3659 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3663 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
3664 ModestWindow *window)
3666 g_return_if_fail (MODEST_IS_WINDOW (window));
3669 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3673 modest_ui_actions_on_view_menu_activated (GtkAction *action,
3674 ModestWindow *window)
3676 g_return_if_fail (MODEST_IS_WINDOW (window));
3679 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3683 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
3684 ModestWindow *window)
3686 g_return_if_fail (MODEST_IS_WINDOW (window));
3689 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3693 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
3694 ModestWindow *window)
3696 g_return_if_fail (MODEST_IS_WINDOW (window));
3699 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3703 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
3704 ModestWindow *window)
3706 g_return_if_fail (MODEST_IS_WINDOW (window));
3709 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3713 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
3714 ModestWindow *window)
3716 g_return_if_fail (MODEST_IS_WINDOW (window));
3719 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3723 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
3724 ModestWindow *window)
3726 g_return_if_fail (MODEST_IS_WINDOW (window));
3729 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3733 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
3735 g_return_if_fail (MODEST_IS_WINDOW (window));
3738 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
3742 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
3744 g_return_if_fail (MODEST_IS_WINDOW (window));
3746 modest_platform_show_search_messages (GTK_WINDOW (window));
3750 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
3752 g_return_if_fail (MODEST_IS_WINDOW (win));
3753 modest_platform_show_addressbook (GTK_WINDOW (win));
3758 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
3759 ModestWindow *window)
3761 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3763 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
3767 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
3768 ModestMailOperationState *state,
3771 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
3773 /* Set send/receive operation finished */
3774 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3775 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));