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 (ModestMailOperation *mail_op,
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 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2405 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2406 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2407 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2408 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2413 modest_ui_actions_on_copy (GtkAction *action,
2414 ModestWindow *window)
2416 GtkClipboard *clipboard;
2417 GtkWidget *focused_widget;
2419 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2420 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2422 if (GTK_IS_LABEL (focused_widget)) {
2423 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2424 } else if (GTK_IS_EDITABLE (focused_widget)) {
2425 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2426 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2427 GtkTextBuffer *buffer;
2428 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2429 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2430 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2431 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2432 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2433 TnyIterator *iter = tny_list_create_iterator (header_list);
2434 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2435 TnyFolder *folder = tny_header_get_folder (header);
2436 TnyAccount *account = tny_folder_get_account (folder);
2437 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2438 /* If it's POP then ask */
2439 gboolean ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2440 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2441 g_object_unref (account);
2442 g_object_unref (folder);
2443 g_object_unref (header);
2444 g_object_unref (iter);
2446 /* Check that the messages have been previously downloaded */
2447 gboolean continue_download = TRUE;
2449 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window));
2450 if (continue_download)
2451 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2452 g_object_unref (header_list);
2453 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2454 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2457 /* Show information banner */
2458 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2463 modest_ui_actions_on_undo (GtkAction *action,
2464 ModestWindow *window)
2466 ModestEmailClipboard *clipboard = NULL;
2468 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2469 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2470 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2471 /* Clear clipboard source */
2472 clipboard = modest_runtime_get_email_clipboard ();
2473 modest_email_clipboard_clear (clipboard);
2476 g_return_if_reached ();
2481 modest_ui_actions_on_redo (GtkAction *action,
2482 ModestWindow *window)
2484 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2485 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
2488 g_return_if_reached ();
2494 paste_msgs_cb (const GObject *object, gpointer user_data)
2496 g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2497 g_return_if_fail (GTK_IS_WIDGET (user_data));
2499 /* destroy information note */
2500 gtk_widget_destroy (GTK_WIDGET(user_data));
2504 modest_ui_actions_on_paste (GtkAction *action,
2505 ModestWindow *window)
2507 GtkWidget *focused_widget = NULL;
2508 GtkWidget *inf_note = NULL;
2509 ModestMailOperation *mail_op = NULL;
2511 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2512 if (GTK_IS_EDITABLE (focused_widget)) {
2513 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2514 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2515 GtkTextBuffer *buffer;
2516 GtkClipboard *clipboard;
2518 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2519 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2520 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2521 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2522 ModestEmailClipboard *clipboard = NULL;
2523 TnyFolder *src_folder = NULL;
2524 TnyFolderStore *folder_store = NULL;
2525 TnyList *data = NULL;
2526 gboolean delete = FALSE;
2528 /* Check clipboard source */
2529 clipboard = modest_runtime_get_email_clipboard ();
2530 if (modest_email_clipboard_cleared (clipboard))
2533 /* Get elements to paste */
2534 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2536 /* Create a new mail operation */
2537 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2538 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2541 /* Get destination folder */
2542 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2544 /* Launch notification */
2545 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2546 _CS("ckct_nw_pasting"));
2547 if (inf_note != NULL) {
2548 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
2549 gtk_widget_show (GTK_WIDGET(inf_note));
2552 /* transfer messages */
2554 modest_mail_operation_xfer_msgs (mail_op,
2556 TNY_FOLDER (folder_store),
2561 } else if (src_folder != NULL) {
2562 modest_mail_operation_xfer_folder (mail_op,
2572 g_object_unref (data);
2573 if (src_folder != NULL)
2574 g_object_unref (src_folder);
2575 if (folder_store != NULL)
2576 g_object_unref (folder_store);
2582 modest_ui_actions_on_select_all (GtkAction *action,
2583 ModestWindow *window)
2585 GtkWidget *focused_widget;
2587 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2588 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2589 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2590 } else if (GTK_IS_LABEL (focused_widget)) {
2591 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2592 } else if (GTK_IS_EDITABLE (focused_widget)) {
2593 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2594 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2595 GtkTextBuffer *buffer;
2596 GtkTextIter start, end;
2598 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2599 gtk_text_buffer_get_start_iter (buffer, &start);
2600 gtk_text_buffer_get_end_iter (buffer, &end);
2601 gtk_text_buffer_select_range (buffer, &start, &end);
2602 } else if (GTK_IS_HTML (focused_widget)) {
2603 gtk_html_select_all (GTK_HTML (focused_widget));
2604 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2605 GtkWidget *header_view = focused_widget;
2606 GtkTreeSelection *selection = NULL;
2608 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
2609 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2610 MODEST_WIDGET_TYPE_HEADER_VIEW);
2612 /* Select all messages */
2613 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2614 gtk_tree_selection_select_all (selection);
2616 /* Set focuse on header view */
2617 gtk_widget_grab_focus (header_view);
2623 modest_ui_actions_on_mark_as_read (GtkAction *action,
2624 ModestWindow *window)
2626 g_return_if_fail (MODEST_IS_WINDOW(window));
2628 /* Mark each header as read */
2629 do_headers_action (window, headers_action_mark_as_read, NULL);
2633 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2634 ModestWindow *window)
2636 g_return_if_fail (MODEST_IS_WINDOW(window));
2638 /* Mark each header as read */
2639 do_headers_action (window, headers_action_mark_as_unread, NULL);
2643 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2644 GtkRadioAction *selected,
2645 ModestWindow *window)
2649 value = gtk_radio_action_get_current_value (selected);
2650 if (MODEST_IS_WINDOW (window)) {
2651 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2655 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2656 GtkRadioAction *selected,
2657 ModestWindow *window)
2659 TnyHeaderFlags flags;
2660 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2662 flags = gtk_radio_action_get_current_value (selected);
2663 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2666 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2667 GtkRadioAction *selected,
2668 ModestWindow *window)
2672 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2674 file_format = gtk_radio_action_get_current_value (selected);
2675 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2680 modest_ui_actions_on_zoom_plus (GtkAction *action,
2681 ModestWindow *window)
2683 g_return_if_fail (MODEST_IS_WINDOW (window));
2685 modest_window_zoom_plus (MODEST_WINDOW (window));
2689 modest_ui_actions_on_zoom_minus (GtkAction *action,
2690 ModestWindow *window)
2692 g_return_if_fail (MODEST_IS_WINDOW (window));
2694 modest_window_zoom_minus (MODEST_WINDOW (window));
2698 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2699 ModestWindow *window)
2701 ModestWindowMgr *mgr;
2702 gboolean fullscreen, active;
2703 g_return_if_fail (MODEST_IS_WINDOW (window));
2705 mgr = modest_runtime_get_window_mgr ();
2707 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2708 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2710 if (active != fullscreen) {
2711 modest_window_mgr_set_fullscreen_mode (mgr, active);
2712 gtk_window_present (GTK_WINDOW (window));
2717 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2718 ModestWindow *window)
2720 ModestWindowMgr *mgr;
2721 gboolean fullscreen;
2723 g_return_if_fail (MODEST_IS_WINDOW (window));
2725 mgr = modest_runtime_get_window_mgr ();
2726 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2727 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2729 gtk_window_present (GTK_WINDOW (window));
2733 * Used by modest_ui_actions_on_details to call do_headers_action
2736 headers_action_show_details (TnyHeader *header,
2737 ModestWindow *window,
2744 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2747 gtk_widget_show_all (dialog);
2748 gtk_dialog_run (GTK_DIALOG (dialog));
2750 gtk_widget_destroy (dialog);
2754 * Show the folder details in a ModestDetailsDialog widget
2757 show_folder_details (TnyFolder *folder,
2763 dialog = modest_details_dialog_new_with_folder (window, folder);
2766 gtk_widget_show_all (dialog);
2767 gtk_dialog_run (GTK_DIALOG (dialog));
2769 gtk_widget_destroy (dialog);
2773 * Show the header details in a ModestDetailsDialog widget
2776 modest_ui_actions_on_details (GtkAction *action,
2779 TnyList * headers_list;
2783 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2786 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2789 g_object_unref (msg);
2791 headers_list = get_selected_headers (win);
2795 iter = tny_list_create_iterator (headers_list);
2797 header = TNY_HEADER (tny_iterator_get_current (iter));
2798 headers_action_show_details (header, win, NULL);
2799 g_object_unref (header);
2801 g_object_unref (iter);
2802 g_object_unref (headers_list);
2804 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2805 GtkWidget *folder_view, *header_view;
2807 /* Check which widget has the focus */
2808 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2809 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2810 if (gtk_widget_is_focus (folder_view)) {
2811 TnyFolderStore *folder_store
2812 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2813 if (!folder_store) {
2814 g_warning ("%s: No item was selected.\n", __FUNCTION__);
2817 /* Show only when it's a folder */
2818 /* This function should not be called for account items,
2819 * because we dim the menu item for them. */
2820 if (TNY_IS_FOLDER (folder_store)) {
2821 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
2824 g_object_unref (folder_store);
2827 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2828 MODEST_WIDGET_TYPE_HEADER_VIEW);
2829 /* Show details of each header */
2830 do_headers_action (win, headers_action_show_details, header_view);
2836 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2837 ModestMsgEditWindow *window)
2839 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2841 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2845 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2846 ModestMsgEditWindow *window)
2848 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2850 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2854 modest_ui_actions_toggle_folders_view (GtkAction *action,
2855 ModestMainWindow *main_window)
2859 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2861 conf = modest_runtime_get_conf ();
2863 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2864 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2866 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2870 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2871 ModestWindow *window)
2873 gboolean active, fullscreen = FALSE;
2874 ModestWindowMgr *mgr;
2876 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2878 /* Check if we want to toggle the toolbar vuew in fullscreen
2880 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2881 "ViewShowToolbarFullScreen")) {
2885 /* Toggle toolbar */
2886 mgr = modest_runtime_get_window_mgr ();
2887 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2891 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2892 ModestMsgEditWindow *window)
2894 modest_msg_edit_window_select_font (window);
2898 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2899 const gchar *display_name,
2902 /* Do not change the application name if the widget has not
2903 the focus. This callback could be called even if the folder
2904 view has not the focus, because the handled signal could be
2905 emitted when the folder view is redrawn */
2906 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2908 gtk_window_set_title (window, display_name);
2910 gtk_window_set_title (window, " ");
2915 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2917 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2918 modest_msg_edit_window_select_contacts (window);
2922 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2924 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2925 modest_msg_edit_window_check_names (window);
2930 create_move_to_dialog (ModestWindow *win,
2931 GtkWidget *folder_view,
2932 GtkWidget **tree_view)
2934 GtkWidget *dialog, *scroll;
2936 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2938 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2940 GTK_RESPONSE_ACCEPT,
2942 GTK_RESPONSE_REJECT,
2945 /* Create scrolled window */
2946 scroll = gtk_scrolled_window_new (NULL, NULL);
2947 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2948 GTK_POLICY_AUTOMATIC,
2949 GTK_POLICY_AUTOMATIC);
2951 /* Create folder view */
2952 *tree_view = modest_platform_create_folder_view (NULL);
2954 /* It could happen that we're trying to move a message from a
2955 window (msg window for example) after the main window was
2956 closed, so we can not just get the model of the folder
2958 if (MODEST_IS_FOLDER_VIEW (folder_view))
2959 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2960 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2962 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
2963 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
2965 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2967 /* Add scroll to dialog */
2968 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2969 scroll, FALSE, FALSE, 0);
2971 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2973 /* Select INBOX or local account */
2974 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (*tree_view));
2980 * Returns TRUE if at least one of the headers of the list belongs to
2981 * a message that has been fully retrieved.
2984 has_retrieved_msgs (TnyList *list)
2987 gboolean found = FALSE;
2989 iter = tny_list_create_iterator (list);
2990 while (tny_iterator_is_done (iter) && !found) {
2992 TnyHeaderFlags flags;
2994 header = TNY_HEADER (tny_iterator_get_current (iter));
2995 flags = tny_header_get_flags (header);
2996 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
3000 tny_iterator_next (iter);
3002 g_object_unref (iter);
3008 * Shows a confirmation dialog to the user when we're moving messages
3009 * from a remote server to the local storage. Returns the dialog
3010 * response. If it's other kind of movement the it always returns
3014 msgs_move_to_confirmation (GtkWindow *win,
3015 TnyFolder *dest_folder,
3018 gint response = GTK_RESPONSE_OK;
3020 /* If the destination is a local folder */
3021 if (modest_tny_folder_is_local_folder (dest_folder)) {
3022 TnyFolder *src_folder;
3026 /* Get source folder */
3027 iter = tny_list_create_iterator (headers);
3028 header = TNY_HEADER (tny_iterator_get_current (iter));
3029 src_folder = tny_header_get_folder (header);
3030 g_object_unref (header);
3031 g_object_unref (iter);
3033 /* if no src_folder, message may be an attahcment */
3034 if (src_folder == NULL)
3035 return GTK_RESPONSE_CANCEL;
3037 /* If the source is a remote folder */
3038 if (!modest_tny_folder_is_local_folder (src_folder)) {
3039 const gchar *message;
3041 if (has_retrieved_msgs (headers))
3042 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
3043 tny_list_get_length (headers));
3045 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
3046 tny_list_get_length (headers));
3048 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
3049 (const gchar *) message);
3051 g_object_unref (src_folder);
3059 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
3061 ModestMsgViewWindow *self = NULL;
3062 gboolean last, first;
3064 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
3065 self = MODEST_MSG_VIEW_WINDOW (object);
3067 last = modest_msg_view_window_last_message_selected (self);
3068 first = modest_msg_view_window_first_message_selected (self);
3070 /* No more messages to view, so close this window */
3071 /* gboolean ret_value; */
3072 /* g_signal_emit_by_name (G_OBJECT (self), "delete-event", NULL, &ret_value); */
3073 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3075 modest_msg_view_window_select_previous_message (self);
3077 modest_msg_view_window_select_next_message (self);
3081 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3084 GObject *win = modest_mail_operation_get_source (mail_op);
3085 const GError *error = NULL;
3086 const gchar *message = NULL;
3088 /* Get error message */
3089 error = modest_mail_operation_get_error (mail_op);
3090 if (error != NULL && error->message != NULL) {
3091 message = error->message;
3093 message = _("mail_in_ui_folder_move_target_error");
3096 /* Show notification dialog */
3097 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3098 g_object_unref (win);
3102 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3105 GObject *win = modest_mail_operation_get_source (mail_op);
3106 const GError *error = modest_mail_operation_get_error (mail_op);
3108 g_return_if_fail (error != NULL);
3109 if (error->message != NULL)
3110 g_printerr ("modest: %s\n", error->message);
3112 g_printerr ("modest: unkonw error on send&receive operation");
3114 /* Show error message */
3115 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3116 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3117 /* _CS("sfil_ib_unable_to_receive")); */
3119 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3120 /* _CS("sfil_ib_unable_to_send")); */
3121 g_object_unref (win);
3125 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3132 gint pending_purges = 0;
3133 gboolean some_purged = FALSE;
3134 ModestWindow *win = MODEST_WINDOW (user_data);
3136 /* If there was any error */
3137 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
3140 /* Once the message has been retrieved for purging, we check if
3141 * it's all ok for purging */
3143 parts = tny_simple_list_new ();
3144 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3145 iter = tny_list_create_iterator (parts);
3147 while (!tny_iterator_is_done (iter)) {
3149 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3150 if (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)) {
3151 if (tny_mime_part_is_purged (part))
3156 tny_iterator_next (iter);
3159 if (pending_purges>0) {
3161 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3163 if (response == GTK_RESPONSE_OK) {
3164 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3165 tny_iterator_first (iter);
3166 while (!tny_iterator_is_done (iter)) {
3169 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3170 if (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))
3171 tny_mime_part_set_purged (part);
3172 tny_iterator_next (iter);
3175 tny_msg_rewrite_cache (msg);
3178 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3181 /* remove attachments */
3182 tny_iterator_first (iter);
3183 while (!tny_iterator_is_done (iter)) {
3186 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3187 g_object_unref (part);
3188 tny_iterator_next (iter);
3191 g_object_unref (iter);
3192 g_object_unref (parts);
3196 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3197 ModestMainWindow *win)
3199 GtkWidget *header_view;
3200 TnyList *header_list;
3203 TnyHeaderFlags flags;
3204 ModestWindow *msg_view_window = NULL;
3207 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3209 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3210 MODEST_WIDGET_TYPE_HEADER_VIEW);
3212 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3214 if (tny_list_get_length (header_list) == 1) {
3215 iter = tny_list_create_iterator (header_list);
3216 header = TNY_HEADER (tny_iterator_get_current (iter));
3217 g_object_unref (iter);
3222 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3223 header, &msg_view_window);
3224 flags = tny_header_get_flags (header);
3225 if (!(flags & TNY_HEADER_FLAG_CACHED))
3228 if (msg_view_window != NULL)
3229 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3231 /* do nothing; uid was registered before, so window is probably on it's way */
3232 g_warning ("debug: header %p has already been registered", header);
3235 ModestMailOperation *mail_op = NULL;
3236 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3237 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3239 modest_ui_actions_get_msgs_full_error_handler,
3241 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3242 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3244 g_object_unref (mail_op);
3247 g_object_unref (header);
3249 g_object_unref (header_list);
3253 * UI handler for the "Move to" action when invoked from the
3257 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3258 ModestMainWindow *win)
3260 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3261 GtkWidget *header_view = NULL;
3263 TnyFolderStore *folder_store = NULL;
3264 ModestMailOperation *mail_op = NULL;
3266 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3268 /* Get the folder view */
3269 folder_view = modest_main_window_get_child_widget (win,
3270 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3272 TnyFolderStore *src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3274 /* Offer the connection dialog if necessary, if the source folder is in a networked account: */
3275 if (!modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win), src_folder)) {
3277 g_object_unref (src_folder);
3283 /* Get header view */
3284 header_view = modest_main_window_get_child_widget (win,
3285 MODEST_WIDGET_TYPE_HEADER_VIEW);
3287 /* Create and run the dialog */
3288 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
3289 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3290 result = gtk_dialog_run (GTK_DIALOG(dialog));
3291 g_object_ref (tree_view);
3293 /* We do this to save an indentation level ;-) */
3294 if (result != GTK_RESPONSE_ACCEPT)
3297 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3299 if (TNY_IS_ACCOUNT (folder_store) &&
3300 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (folder_store))
3303 /* Offer the connection dialog if necessary: */
3304 if (!modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win), folder_store)) {
3308 /* Get folder or messages to transfer */
3309 if (gtk_widget_is_focus (folder_view)) {
3311 /* Clean folder on header view before moving it */
3312 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3314 if (TNY_IS_FOLDER (src_folder)) {
3316 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3318 modest_ui_actions_move_folder_error_handler,
3320 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3322 modest_mail_operation_xfer_folder (mail_op,
3323 TNY_FOLDER (src_folder),
3326 /* Unref mail operation */
3327 g_object_unref (G_OBJECT (mail_op));
3329 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
3332 if (gtk_widget_is_focus (header_view)) {
3333 TnyList *headers = NULL;
3336 /* TODO: Check for connection if the headers are on a network account. */
3337 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3339 /* Ask for user confirmation */
3340 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3341 TNY_FOLDER (folder_store),
3344 /* Transfer messages */
3345 if (response == GTK_RESPONSE_OK) {
3347 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3349 modest_ui_actions_move_folder_error_handler,
3351 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3354 modest_mail_operation_xfer_msgs (mail_op,
3356 TNY_FOLDER (folder_store),
3361 g_object_unref (G_OBJECT (mail_op));
3363 g_object_unref (headers);
3369 g_object_unref (src_folder);
3372 g_object_unref (folder_store);
3374 gtk_widget_destroy (dialog);
3379 * UI handler for the "Move to" action when invoked from the
3380 * ModestMsgViewWindow
3383 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3384 ModestMsgViewWindow *win)
3386 GtkWidget *dialog, *folder_view, *tree_view = NULL;
3388 ModestMainWindow *main_window = NULL;
3389 TnyHeader *header = NULL;
3390 TnyList *headers = NULL;
3392 /* Get the folder view */
3393 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3395 folder_view = modest_main_window_get_child_widget (main_window,
3396 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3400 /* Create and run the dialog */
3401 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
3402 result = gtk_dialog_run (GTK_DIALOG(dialog));
3404 if (result == GTK_RESPONSE_ACCEPT) {
3405 TnyFolderStore *folder_store;
3408 /* Create header list */
3409 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3410 g_return_if_fail (header != NULL);
3412 /* Offer the connection dialog if necessary: */
3413 /* TODO: What's the extra g_object_ref() for? Isn't this leaking a ref? */
3414 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (g_object_ref (tree_view)));
3415 TnyFolder *header_folder = tny_header_get_folder(header);
3416 if (modest_platform_connect_and_wait_if_network_folderstore (NULL, folder_store) &&
3417 modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (header_folder))) {
3419 headers = tny_simple_list_new ();
3420 tny_list_prepend (headers, G_OBJECT (header));
3421 g_object_unref (header);
3423 /* Ask user for confirmation. MSG-NOT404 */
3424 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3425 TNY_FOLDER (folder_store),
3428 /* Transfer current msg */
3429 if (response == GTK_RESPONSE_OK) {
3430 ModestMailOperation *mail_op;
3432 /* Create mail op */
3433 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
3434 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3437 /* Transfer messages */
3438 modest_mail_operation_xfer_msgs (mail_op,
3440 TNY_FOLDER (folder_store),
3442 transfer_msgs_from_viewer_cb,
3444 g_object_unref (G_OBJECT (mail_op));
3449 g_object_unref (header_folder);
3452 g_object_unref (headers);
3455 g_object_unref (folder_store);
3458 gtk_widget_destroy (dialog);
3462 modest_ui_actions_on_move_to (GtkAction *action,
3465 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3466 MODEST_IS_MSG_VIEW_WINDOW (win));
3468 if (MODEST_IS_MAIN_WINDOW (win))
3469 modest_ui_actions_on_main_window_move_to (action,
3470 MODEST_MAIN_WINDOW (win));
3472 modest_ui_actions_on_msg_view_window_move_to (action,
3473 MODEST_MSG_VIEW_WINDOW (win));
3477 * Calls #HeadersFunc for each header already selected in the main
3478 * window or the message currently being shown in the msg view window
3481 do_headers_action (ModestWindow *win,
3485 TnyList *headers_list;
3491 headers_list = get_selected_headers (win);
3495 /* Get the folder */
3496 iter = tny_list_create_iterator (headers_list);
3497 header = TNY_HEADER (tny_iterator_get_current (iter));
3498 folder = tny_header_get_folder (header);
3499 g_object_unref (header);
3501 /* Call the function for each header */
3502 while (!tny_iterator_is_done (iter)) {
3503 header = TNY_HEADER (tny_iterator_get_current (iter));
3504 func (header, win, user_data);
3505 g_object_unref (header);
3506 tny_iterator_next (iter);
3509 /* Trick: do a poke status in order to speed up the signaling
3511 tny_folder_poke_status (folder);
3514 g_object_unref (folder);
3515 g_object_unref (iter);
3516 g_object_unref (headers_list);
3520 modest_ui_actions_view_attachment (GtkAction *action,
3521 ModestWindow *window)
3523 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3524 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
3526 /* not supported window for this action */
3527 g_return_if_reached ();
3532 modest_ui_actions_save_attachments (GtkAction *action,
3533 ModestWindow *window)
3535 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3536 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
3538 /* not supported window for this action */
3539 g_return_if_reached ();
3544 modest_ui_actions_remove_attachments (GtkAction *action,
3545 ModestWindow *window)
3547 if (MODEST_IS_MAIN_WINDOW (window)) {
3548 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
3549 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3550 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
3552 /* not supported window for this action */
3553 g_return_if_reached ();
3558 modest_ui_actions_on_settings (GtkAction *action,
3563 dialog = modest_platform_get_global_settings_dialog ();
3564 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
3565 gtk_widget_show_all (dialog);
3567 gtk_dialog_run (GTK_DIALOG (dialog));
3569 gtk_widget_destroy (dialog);
3573 modest_ui_actions_on_help (GtkAction *action,
3576 const gchar *help_id = NULL;
3578 if (MODEST_IS_MAIN_WINDOW (win)) {
3579 const gchar *action_name;
3580 action_name = gtk_action_get_name (action);
3582 if (!strcmp (action_name, "FolderViewCSMHelp") ||
3583 !strcmp (action_name, "HeaderViewCSMHelp")) {
3584 GtkWidget *folder_view;
3585 TnyFolderStore *folder_store;
3586 /* Get selected folder */
3587 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3588 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3589 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3591 /* Switch help_id */
3592 if (TNY_IS_FOLDER (folder_store)) {
3593 switch (tny_folder_get_folder_type (TNY_FOLDER (folder_store))) {
3594 case TNY_FOLDER_TYPE_NORMAL:
3595 help_id = "applications_email_userfolder";
3597 case TNY_FOLDER_TYPE_INBOX:
3598 help_id = "applications_email_inbox";
3600 case TNY_FOLDER_TYPE_OUTBOX:
3601 help_id = "applications_email_outbox";
3603 case TNY_FOLDER_TYPE_SENT:
3604 help_id = "applications_email_sent";
3606 case TNY_FOLDER_TYPE_DRAFTS:
3607 help_id = "applications_email_drafts";
3609 case TNY_FOLDER_TYPE_ARCHIVE:
3610 help_id = "applications_email_archive";
3616 g_object_unref (folder_store);
3618 help_id = "applications_email_mainview";
3620 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3621 help_id = "applications_email_viewer";
3622 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
3623 help_id = "applications_email_editor";
3625 modest_platform_show_help (GTK_WINDOW (win), help_id);
3629 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
3630 ModestWindow *window)
3632 ModestMailOperation *mail_op;
3636 headers = get_selected_headers (window);
3640 /* Create mail operation */
3641 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3643 modest_ui_actions_get_msgs_full_error_handler,
3645 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3646 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
3649 g_object_unref (headers);
3650 g_object_unref (mail_op);
3654 modest_ui_actions_on_email_menu_activated (GtkAction *action,
3655 ModestWindow *window)
3657 g_return_if_fail (MODEST_IS_WINDOW (window));
3660 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3664 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
3665 ModestWindow *window)
3667 g_return_if_fail (MODEST_IS_WINDOW (window));
3670 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3674 modest_ui_actions_on_view_menu_activated (GtkAction *action,
3675 ModestWindow *window)
3677 g_return_if_fail (MODEST_IS_WINDOW (window));
3680 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3684 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
3685 ModestWindow *window)
3687 g_return_if_fail (MODEST_IS_WINDOW (window));
3690 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3694 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
3695 ModestWindow *window)
3697 g_return_if_fail (MODEST_IS_WINDOW (window));
3700 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3704 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
3705 ModestWindow *window)
3707 g_return_if_fail (MODEST_IS_WINDOW (window));
3710 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3714 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
3715 ModestWindow *window)
3717 g_return_if_fail (MODEST_IS_WINDOW (window));
3720 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3724 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
3725 ModestWindow *window)
3727 g_return_if_fail (MODEST_IS_WINDOW (window));
3730 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3734 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
3736 g_return_if_fail (MODEST_IS_WINDOW (window));
3739 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
3743 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
3745 g_return_if_fail (MODEST_IS_WINDOW (window));
3747 modest_platform_show_search_messages (GTK_WINDOW (window));
3751 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
3753 g_return_if_fail (MODEST_IS_WINDOW (win));
3754 modest_platform_show_addressbook (GTK_WINDOW (win));
3759 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
3760 ModestWindow *window)
3762 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3764 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
3768 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
3769 ModestMailOperationState *state,
3772 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
3774 /* Set send/receive operation finished */
3775 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3776 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));