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));
356 /* Update toolbar dimming state */
357 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (win));
363 g_object_unref (header_list);
368 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
370 #ifdef MODEST_PLATFORM_MAEMO
371 modest_osso_save_state();
372 #endif /* MODEST_PLATFORM_MAEMO */
374 g_debug ("closing down, clearing %d item(s) from operation queue",
375 modest_mail_operation_queue_num_elements
376 (modest_runtime_get_mail_operation_queue()));
378 /* cancel all outstanding operations */
379 modest_mail_operation_queue_cancel_all
380 (modest_runtime_get_mail_operation_queue());
382 g_debug ("queue has been cleared");
384 /* note: when modest-tny-account-store is finalized,
385 it will automatically set all network connections
392 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
395 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
397 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
398 /* gtk_widget_destroy (GTK_WIDGET (win)); */
399 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
400 /* gboolean ret_value; */
401 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
402 /* } else if (MODEST_IS_WINDOW (win)) { */
403 /* gtk_widget_destroy (GTK_WIDGET (win)); */
405 /* g_return_if_reached (); */
410 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
412 GtkClipboard *clipboard = NULL;
413 gchar *selection = NULL;
415 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
416 selection = gtk_clipboard_wait_for_text (clipboard);
418 /* Question: why is the clipboard being used here?
419 * It doesn't really make a lot of sense. */
423 modest_address_book_add_address (selection);
429 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
431 /* This is currently only implemented for Maemo */
432 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
433 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
434 run_account_setup_wizard (win);
437 /* Show the list of accounts: */
438 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
439 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
440 gtk_dialog_run (account_win);
441 gtk_widget_destroy (GTK_WIDGET(account_win));
444 GtkWidget *dialog, *label;
446 /* Create the widgets */
448 dialog = gtk_dialog_new_with_buttons ("Message",
450 GTK_DIALOG_DESTROY_WITH_PARENT,
454 label = gtk_label_new ("Hello World!");
456 /* Ensure that the dialog box is destroyed when the user responds. */
458 g_signal_connect_swapped (dialog, "response",
459 G_CALLBACK (gtk_widget_destroy),
462 /* Add the label, and show everything we've added to the dialog. */
464 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
466 gtk_widget_show_all (dialog);
467 #endif /* MODEST_PLATFORM_MAEMO */
471 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
473 ModestWindow *main_window = MODEST_WINDOW (user_data);
475 /* Save any changes. */
476 modest_connection_specific_smtp_window_save_server_accounts (
477 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
478 modest_window_get_active_account (main_window));
479 gtk_widget_destroy (GTK_WIDGET (window));
485 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
487 /* This is currently only implemented for Maemo,
488 * because it requires an API (libconic) to detect different connection
491 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
493 /* Create the window if necessary: */
494 const gchar *active_account_name = modest_window_get_active_account (win);
496 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
497 * or show the default account?
498 * If we show the default account then the account name should be shown in
499 * the window when we show it. */
500 if (!active_account_name) {
501 g_warning ("%s: No account is active.", __FUNCTION__);
505 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
506 modest_connection_specific_smtp_window_fill_with_connections (
507 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
508 modest_runtime_get_account_mgr(),
509 active_account_name);
511 /* Show the window: */
512 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
513 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
514 gtk_widget_show (specific_window);
516 /* Save changes when the window is hidden: */
517 g_signal_connect (specific_window, "hide",
518 G_CALLBACK (on_smtp_servers_window_hide), win);
519 #endif /* MODEST_PLATFORM_MAEMO */
523 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
525 ModestWindow *msg_win = NULL;
527 TnyFolder *folder = NULL;
528 gchar *account_name = NULL;
529 gchar *from_str = NULL;
530 /* GError *err = NULL; */
531 TnyAccount *account = NULL;
532 ModestWindowMgr *mgr;
533 gchar *signature = NULL, *blank_and_signature = NULL;
535 /* if there are no accounts yet, just show the wizard */
536 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
537 run_account_setup_wizard (win);
541 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
543 account_name = g_strdup (modest_window_get_active_account (win));
545 g_printerr ("modest: no account found\n");
549 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
551 TNY_ACCOUNT_TYPE_STORE);
553 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
557 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
559 g_printerr ("modest: failed get from string for '%s'\n", account_name);
563 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
564 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
565 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
566 MODEST_ACCOUNT_SIGNATURE, FALSE);
567 blank_and_signature = g_strconcat ("\n", signature, NULL);
570 blank_and_signature = g_strdup ("");
573 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
575 g_printerr ("modest: failed to create new msg\n");
579 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
581 g_printerr ("modest: failed to find Drafts folder\n");
586 /* Create and register edit window */
587 /* This is destroyed by TOOD. */
588 msg_win = modest_msg_edit_window_new (msg, account_name);
589 mgr = modest_runtime_get_window_mgr ();
590 modest_window_mgr_register_window (mgr, msg_win);
593 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
595 gtk_widget_show_all (GTK_WIDGET (msg_win));
598 g_free (account_name);
600 g_free (blank_and_signature);
602 g_object_unref (msg_win);
604 g_object_unref (G_OBJECT(account));
606 g_object_unref (G_OBJECT(msg));
608 g_object_unref (G_OBJECT(folder));
612 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
616 ModestMailOperationStatus status;
618 /* If there is no message or the operation was not successful */
619 status = modest_mail_operation_get_status (mail_op);
620 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
622 /* Remove the header from the preregistered uids */
623 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
633 open_msg_cb (ModestMailOperation *mail_op,
638 ModestWindowMgr *mgr = NULL;
639 ModestWindow *parent_win = NULL;
640 ModestWindow *win = NULL;
641 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
642 gchar *account = NULL;
645 /* Do nothing if there was any problem with the mail
646 operation. The error will be shown by the error_handler of
647 the mail operation */
648 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
649 printf ("DEBUG: %s: modest_ui_actions_msg_retrieval_check() failed.\n",
654 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
655 folder = tny_header_get_folder (header);
657 /* Mark header as read */
658 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
661 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
663 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
665 /* Gets folder type (OUTBOX headers will be opened in edit window */
666 if (modest_tny_folder_is_local_folder (folder))
667 folder_type = modest_tny_folder_get_local_folder_type (folder);
669 /* If the header is in the drafts folder then open the editor,
670 else the message view window */
671 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
672 /* we cannot edit without a valid account... */
673 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
674 run_account_setup_wizard(parent_win);
677 win = modest_msg_edit_window_new (msg, account);
679 gchar *uid = modest_tny_folder_get_header_unique_id (header);
681 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
682 GtkWidget *header_view;
683 GtkTreeSelection *sel;
684 GList *sel_list = NULL;
687 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
688 MODEST_WIDGET_TYPE_HEADER_VIEW);
690 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
691 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
693 if (sel_list != NULL) {
694 GtkTreeRowReference *row_reference;
696 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
697 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
698 g_list_free (sel_list);
700 win = modest_msg_view_window_new_with_header_model (msg,
705 gtk_tree_row_reference_free (row_reference);
707 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
710 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
715 /* Register and show new window */
717 mgr = modest_runtime_get_window_mgr ();
718 modest_window_mgr_register_window (mgr, win);
719 g_object_unref (win);
720 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
721 gtk_widget_show_all (GTK_WIDGET(win));
724 /* Update toolbar dimming state */
725 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
726 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
732 g_object_unref (parent_win);
733 /* g_object_unref (msg); */
734 g_object_unref (folder);
738 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
742 GObject *win = modest_mail_operation_get_source (mail_op);
744 error = modest_mail_operation_get_error (mail_op);
745 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, error->code, error->message);
747 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
749 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
752 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
753 _("mail_ni_ui_folder_get_msg_folder_error"));
757 g_object_unref (win);
761 * This function is used by both modest_ui_actions_on_open and
762 * modest_ui_actions_on_header_activated. This way we always do the
763 * same when trying to open messages.
766 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
768 ModestWindowMgr *mgr = NULL;
769 TnyIterator *iter = NULL;
770 ModestMailOperation *mail_op1 = NULL;
771 ModestMailOperation *mail_op2 = NULL;
772 TnyList *not_opened_headers = NULL;
773 TnyList *not_opened_cached_headers = NULL;
774 TnyHeaderFlags flags;
776 /* Look if we already have a message view for each header. If
777 true, then remove the header from the list of headers to
779 mgr = modest_runtime_get_window_mgr ();
780 iter = tny_list_create_iterator (headers);
781 not_opened_headers = tny_simple_list_new ();
782 not_opened_cached_headers = tny_simple_list_new ();
783 while (!tny_iterator_is_done (iter)) {
785 ModestWindow *window;
789 header = TNY_HEADER (tny_iterator_get_current (iter));
790 flags = tny_header_get_flags (header);
793 found = modest_window_mgr_find_registered_header (mgr, header, &window);
795 /* Do not open again the message and present the
796 window to the user */
799 gtk_window_present (GTK_WINDOW (window));
801 /* the header has been registered already, we don't do
802 * anything but wait for the window to come up*/
803 g_warning ("debug: header %p already registered, waiting for window",
806 if (!(flags & TNY_HEADER_FLAG_CACHED))
807 tny_list_append (not_opened_headers, G_OBJECT (header));
808 /* Check if msg has already been retreived */
810 tny_list_append (not_opened_cached_headers, G_OBJECT (header));
812 g_object_unref (header);
813 tny_iterator_next (iter);
815 g_object_unref (iter);
818 /* If some messages would have to be downloaded, ask the user to
819 * make a connection. It's generally easier to do this here (in the mainloop)
820 * than later in a thread:
822 if (tny_list_get_length (not_opened_cached_headers) > 0) {
823 gboolean connected = modest_platform_connect_and_wait (GTK_WINDOW (win));
825 /* Don't go further if a connection would be necessary but none is available: */
827 g_object_unref (not_opened_headers);
828 g_object_unref (not_opened_cached_headers);
833 /* Register the headers before actually creating the windows: */
834 TnyIterator *iter_not_opened = tny_list_create_iterator (not_opened_headers);
835 while (!tny_iterator_is_done (iter_not_opened)) {
836 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
837 modest_window_mgr_register_header (mgr, header);
838 g_object_unref (header);
840 tny_iterator_next (iter_not_opened);
842 g_object_unref (iter_not_opened);
843 iter_not_opened = NULL;
845 TnyIterator *iter_cached = tny_list_create_iterator (not_opened_cached_headers);
846 while (!tny_iterator_is_done (iter_cached)) {
847 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_cached));
848 modest_window_mgr_register_header (mgr, header);
849 g_object_unref (header);
851 tny_iterator_next (iter_cached);
853 g_object_unref (iter_cached);
857 /* Open each uncached message */
858 if (tny_list_get_length (not_opened_headers) > 0) {
859 mail_op1 = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
861 modest_ui_actions_get_msgs_full_error_handler,
863 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op1);
864 if (tny_list_get_length (not_opened_headers) > 1) {
865 modest_mail_operation_get_msgs_full (mail_op1,
871 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
872 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
873 modest_mail_operation_get_msg (mail_op1, header, open_msg_cb, NULL);
874 g_object_unref (header);
875 g_object_unref (iter);
879 /* Open each cached message */
880 if (tny_list_get_length (not_opened_cached_headers) > 0) {
881 mail_op2 = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
883 modest_ui_actions_get_msgs_full_error_handler,
885 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op2);
886 if (tny_list_get_length (not_opened_cached_headers) > 1) {
887 modest_mail_operation_get_msgs_full (mail_op2,
893 TnyIterator *iter = tny_list_create_iterator (not_opened_cached_headers);
894 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
895 modest_mail_operation_get_msg (mail_op2, header, open_msg_cb, NULL);
896 g_object_unref (header);
897 g_object_unref (iter);
902 if (not_opened_headers != NULL)
903 g_object_unref (not_opened_headers);
904 if (not_opened_cached_headers != NULL)
905 g_object_unref (not_opened_cached_headers);
907 g_object_unref (iter);
908 if (mail_op1 != NULL)
909 g_object_unref (mail_op1);
910 if (mail_op2 != NULL)
911 g_object_unref (mail_op2);
915 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
920 headers = get_selected_headers (win);
925 _modest_ui_actions_open (headers, win);
927 g_object_unref(headers);
932 free_reply_forward_helper (gpointer data)
934 ReplyForwardHelper *helper;
936 helper = (ReplyForwardHelper *) data;
937 g_free (helper->account_name);
938 g_slice_free (ReplyForwardHelper, helper);
942 reply_forward_cb (ModestMailOperation *mail_op,
948 ReplyForwardHelper *rf_helper;
949 ModestWindow *msg_win = NULL;
950 ModestEditType edit_type;
952 TnyAccount *account = NULL;
953 ModestWindowMgr *mgr = NULL;
954 gchar *signature = NULL;
956 /* If there was any error */
957 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
960 g_return_if_fail (user_data != NULL);
961 rf_helper = (ReplyForwardHelper *) user_data;
963 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
964 rf_helper->account_name);
965 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
966 rf_helper->account_name,
967 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
968 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
969 rf_helper->account_name,
970 MODEST_ACCOUNT_SIGNATURE, FALSE);
973 /* Create reply mail */
974 switch (rf_helper->action) {
977 modest_tny_msg_create_reply_msg (msg, from, signature,
978 rf_helper->reply_forward_type,
979 MODEST_TNY_MSG_REPLY_MODE_SENDER);
981 case ACTION_REPLY_TO_ALL:
983 modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type,
984 MODEST_TNY_MSG_REPLY_MODE_ALL);
985 edit_type = MODEST_EDIT_TYPE_REPLY;
989 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
990 edit_type = MODEST_EDIT_TYPE_FORWARD;
993 g_return_if_reached ();
1000 g_printerr ("modest: failed to create message\n");
1004 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1005 rf_helper->account_name,
1006 TNY_ACCOUNT_TYPE_STORE);
1008 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1012 /* Create and register the windows */
1013 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
1014 mgr = modest_runtime_get_window_mgr ();
1015 modest_window_mgr_register_window (mgr, msg_win);
1017 if (rf_helper->parent_window != NULL) {
1018 gdouble parent_zoom;
1020 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1021 modest_window_set_zoom (msg_win, parent_zoom);
1024 /* Show edit window */
1025 gtk_widget_show_all (GTK_WIDGET (msg_win));
1029 g_object_unref (msg_win);
1031 g_object_unref (G_OBJECT (new_msg));
1033 g_object_unref (G_OBJECT (account));
1034 /* g_object_unref (msg); */
1035 g_object_unref (header);
1036 free_reply_forward_helper (rf_helper);
1040 * Checks a list of headers. If any of them are not currently
1041 * downloaded (CACHED) then it asks the user for permission to
1044 * Returns FALSE if the user does not want to download the
1045 * messages. Returns TRUE if the user allowed the download or if all
1046 * of them are currently downloaded
1049 download_uncached_messages (TnyList *header_list, GtkWindow *win)
1053 gint uncached_messages = 0;
1055 iter = tny_list_create_iterator (header_list);
1056 while (!tny_iterator_is_done (iter)) {
1058 TnyHeaderFlags flags;
1060 header = TNY_HEADER (tny_iterator_get_current (iter));
1061 flags = tny_header_get_flags (header);
1062 /* TODO: is this the right flag?, it seems that some
1063 headers that have been previously downloaded do not
1065 if (! (flags & TNY_HEADER_FLAG_CACHED))
1066 uncached_messages ++;
1067 g_object_unref (header);
1068 tny_iterator_next (iter);
1070 g_object_unref (iter);
1072 /* Ask for user permission to download the messages */
1074 if (uncached_messages > 0) {
1075 GtkResponseType response;
1077 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1078 ngettext("mcen_nc_get_msg",
1080 uncached_messages));
1081 if (response == GTK_RESPONSE_CANCEL)
1084 /* If a download will be necessary, make sure that we have a connection: */
1085 retval = modest_platform_connect_and_wait(win);
1093 * Common code for the reply and forward actions
1096 reply_forward (ReplyForwardAction action, ModestWindow *win)
1098 ModestMailOperation *mail_op = NULL;
1099 TnyList *header_list = NULL;
1100 ReplyForwardHelper *rf_helper = NULL;
1101 guint reply_forward_type;
1102 gboolean continue_download;
1104 g_return_if_fail (MODEST_IS_WINDOW(win));
1106 /* we need an account when editing */
1107 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1108 run_account_setup_wizard (win);
1112 header_list = get_selected_headers (win);
1116 /* Check that the messages have been previously downloaded */
1117 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
1118 if (!continue_download) {
1119 g_object_unref (header_list);
1123 reply_forward_type =
1124 modest_conf_get_int (modest_runtime_get_conf (),
1125 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1127 /* We assume that we can only select messages of the
1128 same folder and that we reply all of them from the
1129 same account. In fact the interface currently only
1130 allows single selection */
1133 rf_helper = g_slice_new0 (ReplyForwardHelper);
1134 rf_helper->reply_forward_type = reply_forward_type;
1135 rf_helper->action = action;
1136 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1137 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1138 rf_helper->parent_window = GTK_WIDGET (win);
1139 if (!rf_helper->account_name)
1140 rf_helper->account_name =
1141 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1143 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1146 /* Get header and message. Do not free them here, the
1147 reply_forward_cb must do it */
1148 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1149 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1150 if (!msg || !header) {
1152 g_object_unref (msg);
1154 g_object_unref (header);
1155 g_printerr ("modest: no message found\n");
1158 reply_forward_cb (NULL, header, msg, rf_helper);
1164 /* Retrieve messages */
1165 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1167 modest_ui_actions_get_msgs_full_error_handler,
1169 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1171 /* Only reply/forward to one message */
1172 iter = tny_list_create_iterator (header_list);
1173 header = TNY_HEADER (tny_iterator_get_current (iter));
1174 g_object_unref (iter);
1176 modest_mail_operation_get_msg (mail_op,
1181 /* modest_mail_operation_get_msgs_full (mail_op, */
1183 /* reply_forward_cb, */
1185 /* free_reply_forward_helper); */
1188 g_object_unref(mail_op);
1192 g_object_unref (header_list);
1196 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1198 g_return_if_fail (MODEST_IS_WINDOW(win));
1200 reply_forward (ACTION_REPLY, win);
1204 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1206 g_return_if_fail (MODEST_IS_WINDOW(win));
1208 reply_forward (ACTION_FORWARD, win);
1212 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1214 g_return_if_fail (MODEST_IS_WINDOW(win));
1216 reply_forward (ACTION_REPLY_TO_ALL, win);
1220 modest_ui_actions_on_next (GtkAction *action,
1221 ModestWindow *window)
1223 if (MODEST_IS_MAIN_WINDOW (window)) {
1224 GtkWidget *header_view;
1226 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1227 MODEST_WIDGET_TYPE_HEADER_VIEW);
1231 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
1232 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1233 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
1235 g_return_if_reached ();
1240 modest_ui_actions_on_prev (GtkAction *action,
1241 ModestWindow *window)
1243 g_return_if_fail (MODEST_IS_WINDOW(window));
1245 if (MODEST_IS_MAIN_WINDOW (window)) {
1246 GtkWidget *header_view;
1247 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1248 MODEST_WIDGET_TYPE_HEADER_VIEW);
1252 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1253 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1254 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1256 g_return_if_reached ();
1261 modest_ui_actions_on_sort (GtkAction *action,
1262 ModestWindow *window)
1264 g_return_if_fail (MODEST_IS_WINDOW(window));
1266 if (MODEST_IS_MAIN_WINDOW (window)) {
1267 GtkWidget *header_view;
1268 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1269 MODEST_WIDGET_TYPE_HEADER_VIEW);
1273 /* Show sorting dialog */
1274 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1279 new_messages_arrived (ModestMailOperation *self,
1283 if (new_messages == 0)
1286 modest_platform_on_new_msg ();
1290 * This function performs the send & receive required actions. The
1291 * window is used to create the mail operation. Typically it should
1292 * always be the main window, but we pass it as argument in order to
1296 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1298 gchar *acc_name = NULL;
1299 ModestMailOperation *mail_op;
1301 /* If no account name was provided then get the current account, and if
1302 there is no current account then pick the default one: */
1303 if (!account_name) {
1304 acc_name = g_strdup (modest_window_get_active_account(win));
1306 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1308 g_printerr ("modest: cannot get default account\n");
1312 acc_name = g_strdup (account_name);
1315 /* Set send/receive operation in progress */
1316 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1318 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1320 modest_ui_actions_send_receive_error_handler,
1323 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1324 G_CALLBACK (_on_send_receive_progress_changed),
1327 /* Send & receive. */
1328 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1329 /* Receive and then send. The operation is tagged initially as
1330 a receive operation because the account update performs a
1331 receive and then a send. The operation changes its type
1332 internally, so the progress objects will receive the proper
1333 progress information */
1334 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1335 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, NULL);
1336 g_object_unref (G_OBJECT (mail_op));
1343 * Refreshes all accounts. This function will be used by automatic
1347 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1349 GSList *account_names, *iter;
1351 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1354 iter = account_names;
1356 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1357 iter = g_slist_next (iter);
1360 modest_account_mgr_free_account_names (account_names);
1361 account_names = NULL;
1365 * Handler of the click on Send&Receive button in the main toolbar
1368 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1370 /* Check if accounts exist */
1371 gboolean accounts_exist =
1372 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1374 /* If not, allow the user to create an account before trying to send/receive. */
1375 if (!accounts_exist)
1376 modest_ui_actions_on_accounts (NULL, win);
1378 /* Refresh the active account */
1379 modest_ui_actions_do_send_receive (NULL, win);
1384 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1387 GtkWidget *header_view;
1389 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1391 header_view = modest_main_window_get_child_widget (main_window,
1392 MODEST_WIDGET_TYPE_HEADER_VIEW);
1396 conf = modest_runtime_get_conf ();
1398 /* what is saved/restored is depending on the style; thus; we save with
1399 * old style, then update the style, and restore for this new style
1401 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1403 if (modest_header_view_get_style
1404 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1405 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1406 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1408 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1409 MODEST_HEADER_VIEW_STYLE_DETAILS);
1411 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1412 MODEST_CONF_HEADER_VIEW_KEY);
1417 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1419 ModestMainWindow *main_window)
1421 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1422 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1424 /* If no header has been selected then exit */
1429 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1430 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1432 /* Update Main window title */
1433 if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
1434 const gchar *subject = tny_header_get_subject (header);
1435 if (subject && strlen(subject) > 0)
1436 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1438 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1441 /* Update toolbar dimming state */
1442 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1446 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1448 ModestMainWindow *main_window)
1452 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1457 headers = tny_simple_list_new ();
1458 tny_list_prepend (headers, G_OBJECT (header));
1460 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1462 g_object_unref (headers);
1466 set_active_account_from_tny_account (TnyAccount *account,
1467 ModestWindow *window)
1469 const gchar *server_acc_name = tny_account_get_id (account);
1471 /* We need the TnyAccount provided by the
1472 account store because that is the one that
1473 knows the name of the Modest account */
1474 TnyAccount *modest_server_account = modest_server_account =
1475 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1476 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1479 const gchar *modest_acc_name =
1480 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1481 modest_window_set_active_account (window, modest_acc_name);
1482 g_object_unref (modest_server_account);
1487 folder_refreshed_cb (const GObject *obj,
1491 ModestMainWindow *win = NULL;
1492 GtkWidget *header_view;
1494 g_return_if_fail (TNY_IS_FOLDER (folder));
1496 win = MODEST_MAIN_WINDOW (user_data);
1498 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1500 /* Check if folder is empty and set headers view contents style */
1501 if (tny_folder_get_all_count (folder) == 0) {
1502 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1503 modest_main_window_set_contents_style (win,
1504 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1506 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1511 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1512 TnyFolderStore *folder_store,
1514 ModestMainWindow *main_window)
1517 GtkWidget *header_view;
1519 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1521 header_view = modest_main_window_get_child_widget(main_window,
1522 MODEST_WIDGET_TYPE_HEADER_VIEW);
1526 conf = modest_runtime_get_conf ();
1528 if (TNY_IS_ACCOUNT (folder_store)) {
1530 /* Update active account */
1531 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1532 /* Show account details */
1533 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1536 if (TNY_IS_FOLDER (folder_store) && selected) {
1538 /* Update the active account */
1539 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1541 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1542 g_object_unref (account);
1546 /* Set the header style by default, it could
1547 be changed later by the refresh callback to
1549 modest_main_window_set_contents_style (main_window,
1550 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1552 /* Set folder on header view. This function
1553 will call tny_folder_refresh_async so we
1554 pass a callback that will be called when
1555 finished. We use that callback to set the
1556 empty view if there are no messages */
1557 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1558 TNY_FOLDER (folder_store),
1559 folder_refreshed_cb,
1562 /* Restore configuration. We need to do this
1563 *after* the set_folder because the widget
1564 memory asks the header view about its
1566 modest_widget_memory_restore (modest_runtime_get_conf (),
1567 G_OBJECT(header_view),
1568 MODEST_CONF_HEADER_VIEW_KEY);
1570 /* Update the active account */
1571 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1572 /* Save only if we're seeing headers */
1573 if (modest_main_window_get_contents_style (main_window) ==
1574 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1575 modest_widget_memory_save (conf, G_OBJECT (header_view),
1576 MODEST_CONF_HEADER_VIEW_KEY);
1577 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1581 /* Update toolbar dimming state */
1582 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1586 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1593 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1595 online = tny_device_is_online (modest_runtime_get_device());
1598 /* already online -- the item is simply not there... */
1599 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1601 GTK_MESSAGE_WARNING,
1603 _("The %s you selected cannot be found"),
1605 gtk_dialog_run (GTK_DIALOG(dialog));
1607 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1611 GTK_RESPONSE_REJECT,
1613 GTK_RESPONSE_ACCEPT,
1615 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1616 "Do you want to get online?"), item);
1617 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1618 gtk_label_new (txt), FALSE, FALSE, 0);
1619 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1622 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1623 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1624 // modest_platform_connect_and_wait ();
1627 gtk_widget_destroy (dialog);
1631 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1634 /* g_message ("%s %s", __FUNCTION__, link); */
1639 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1642 modest_platform_activate_uri (link);
1646 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1649 modest_platform_show_uri_popup (link);
1653 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1656 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1660 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1661 const gchar *address,
1664 /* g_message ("%s %s", __FUNCTION__, address); */
1668 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1670 TnyTransportAccount *transport_account;
1671 ModestMailOperation *mail_operation;
1673 gchar *account_name, *from;
1674 ModestAccountMgr *account_mgr;
1675 gchar *info_text = NULL;
1677 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1679 data = modest_msg_edit_window_get_msg_data (edit_window);
1681 account_mgr = modest_runtime_get_account_mgr();
1682 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1684 account_name = modest_account_mgr_get_default_account (account_mgr);
1685 if (!account_name) {
1686 g_printerr ("modest: no account found\n");
1687 modest_msg_edit_window_free_msg_data (edit_window, data);
1691 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1692 account_name = g_strdup (data->account_name);
1696 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1697 (modest_runtime_get_account_store(),
1699 TNY_ACCOUNT_TYPE_TRANSPORT));
1700 if (!transport_account) {
1701 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1702 g_free (account_name);
1703 modest_msg_edit_window_free_msg_data (edit_window, data);
1706 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1708 /* Create the mail operation */
1709 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1710 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1712 modest_mail_operation_save_to_drafts (mail_operation,
1723 data->priority_flags);
1726 g_free (account_name);
1727 g_object_unref (G_OBJECT (transport_account));
1728 g_object_unref (G_OBJECT (mail_operation));
1730 modest_msg_edit_window_free_msg_data (edit_window, data);
1732 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
1733 modest_platform_information_banner (NULL, NULL, info_text);
1737 /* For instance, when clicking the Send toolbar button when editing a message: */
1739 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1741 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1743 if (!modest_msg_edit_window_check_names (edit_window))
1746 /* FIXME: Code added just for testing. The final version will
1747 use the send queue provided by tinymail and some
1749 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1750 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1752 account_name = modest_account_mgr_get_default_account (account_mgr);
1754 if (!account_name) {
1755 g_printerr ("modest: no account found\n");
1759 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1761 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1762 account_name = g_strdup (data->account_name);
1765 /* Get the currently-active transport account for this modest account: */
1766 TnyTransportAccount *transport_account =
1767 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1768 (modest_runtime_get_account_store(),
1770 if (!transport_account) {
1771 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1772 g_free (account_name);
1773 modest_msg_edit_window_free_msg_data (edit_window, data);
1777 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1779 /* mail content checks and dialogs */
1780 if (data->subject == NULL || data->subject[0] == '\0') {
1781 GtkResponseType response;
1782 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1783 _("mcen_nc_subject_is_empty_send"));
1784 if (response == GTK_RESPONSE_CANCEL) {
1785 g_free (account_name);
1790 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
1791 GtkResponseType response;
1792 gchar *note_message;
1793 gchar *note_subject = data->subject;
1794 if (note_subject == NULL || note_subject[0] == '\0')
1795 note_subject = _("mail_va_no_subject");
1796 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
1797 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1799 g_free (note_message);
1800 if (response == GTK_RESPONSE_CANCEL) {
1801 g_free (account_name);
1806 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
1808 /* Create the mail operation */
1809 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1810 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1812 modest_mail_operation_send_new_mail (mail_operation,
1823 data->priority_flags);
1827 g_free (account_name);
1828 g_object_unref (G_OBJECT (transport_account));
1829 g_object_unref (G_OBJECT (mail_operation));
1831 modest_msg_edit_window_free_msg_data (edit_window, data);
1832 modest_msg_edit_window_set_sent (edit_window, TRUE);
1834 /* Save settings and close the window: */
1835 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
1839 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1840 ModestMsgEditWindow *window)
1842 ModestMsgEditFormatState *format_state = NULL;
1844 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1845 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1847 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1850 format_state = modest_msg_edit_window_get_format_state (window);
1851 g_return_if_fail (format_state != NULL);
1853 format_state->bold = gtk_toggle_action_get_active (action);
1854 modest_msg_edit_window_set_format_state (window, format_state);
1855 g_free (format_state);
1860 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1861 ModestMsgEditWindow *window)
1863 ModestMsgEditFormatState *format_state = NULL;
1865 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1866 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1868 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1871 format_state = modest_msg_edit_window_get_format_state (window);
1872 g_return_if_fail (format_state != NULL);
1874 format_state->italics = gtk_toggle_action_get_active (action);
1875 modest_msg_edit_window_set_format_state (window, format_state);
1876 g_free (format_state);
1881 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1882 ModestMsgEditWindow *window)
1884 ModestMsgEditFormatState *format_state = NULL;
1886 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1887 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1889 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1892 format_state = modest_msg_edit_window_get_format_state (window);
1893 g_return_if_fail (format_state != NULL);
1895 format_state->bullet = gtk_toggle_action_get_active (action);
1896 modest_msg_edit_window_set_format_state (window, format_state);
1897 g_free (format_state);
1902 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1903 GtkRadioAction *selected,
1904 ModestMsgEditWindow *window)
1906 ModestMsgEditFormatState *format_state = NULL;
1907 GtkJustification value;
1909 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1911 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1914 value = gtk_radio_action_get_current_value (selected);
1916 format_state = modest_msg_edit_window_get_format_state (window);
1917 g_return_if_fail (format_state != NULL);
1919 format_state->justification = value;
1920 modest_msg_edit_window_set_format_state (window, format_state);
1921 g_free (format_state);
1925 modest_ui_actions_on_select_editor_color (GtkAction *action,
1926 ModestMsgEditWindow *window)
1928 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1929 g_return_if_fail (GTK_IS_ACTION (action));
1931 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1934 modest_msg_edit_window_select_color (window);
1938 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1939 ModestMsgEditWindow *window)
1941 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1942 g_return_if_fail (GTK_IS_ACTION (action));
1944 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1947 modest_msg_edit_window_select_background_color (window);
1951 modest_ui_actions_on_insert_image (GtkAction *action,
1952 ModestMsgEditWindow *window)
1954 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1955 g_return_if_fail (GTK_IS_ACTION (action));
1957 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1960 modest_msg_edit_window_insert_image (window);
1964 modest_ui_actions_on_attach_file (GtkAction *action,
1965 ModestMsgEditWindow *window)
1967 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1968 g_return_if_fail (GTK_IS_ACTION (action));
1970 modest_msg_edit_window_attach_file (window);
1974 modest_ui_actions_on_remove_attachments (GtkAction *action,
1975 ModestMsgEditWindow *window)
1977 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1978 g_return_if_fail (GTK_IS_ACTION (action));
1980 modest_msg_edit_window_remove_attachments (window, NULL);
1984 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1986 TnyFolderStore *parent_folder;
1987 GtkWidget *folder_view;
1989 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1991 folder_view = modest_main_window_get_child_widget (main_window,
1992 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1996 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1998 if (parent_folder) {
1999 gboolean finished = FALSE;
2001 gchar *folder_name = NULL, *suggested_name = NULL;
2003 /* Run the new folder dialog */
2005 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
2010 if (result == GTK_RESPONSE_REJECT) {
2013 ModestMailOperation *mail_op;
2014 TnyFolder *new_folder = NULL;
2016 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO,
2017 G_OBJECT(main_window));
2018 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2020 new_folder = modest_mail_operation_create_folder (mail_op,
2022 (const gchar *) folder_name);
2024 g_object_unref (new_folder);
2027 g_object_unref (mail_op);
2029 g_free (folder_name);
2033 g_object_unref (parent_folder);
2038 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2041 GObject *win = modest_mail_operation_get_source (mail_op);
2042 const GError *error = NULL;
2043 const gchar *message = NULL;
2045 /* Get error message */
2046 error = modest_mail_operation_get_error (mail_op);
2047 if (error != NULL && error->message != NULL) {
2048 message = error->message;
2050 message = _("!!! FIXME: Unable to rename");
2053 /* Show notification dialog */
2054 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
2055 g_object_unref (win);
2059 modest_ui_actions_on_rename_folder (GtkAction *action,
2060 ModestMainWindow *main_window)
2062 TnyFolderStore *folder;
2063 GtkWidget *folder_view;
2064 GtkWidget *header_view;
2066 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2068 folder_view = modest_main_window_get_child_widget (main_window,
2069 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2073 header_view = modest_main_window_get_child_widget (main_window,
2074 MODEST_WIDGET_TYPE_HEADER_VIEW);
2079 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2081 /* Offer the connection dialog if necessary: */
2082 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2083 g_object_unref (G_OBJECT (folder));
2088 if (folder && TNY_IS_FOLDER (folder)) {
2091 const gchar *current_name;
2093 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2094 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
2095 current_name, &folder_name);
2097 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
2098 ModestMailOperation *mail_op;
2101 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2102 G_OBJECT(main_window),
2103 modest_ui_actions_rename_folder_error_handler,
2107 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2110 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2112 modest_mail_operation_rename_folder (mail_op,
2113 TNY_FOLDER (folder),
2114 (const gchar *) folder_name);
2116 g_object_unref (mail_op);
2117 g_free (folder_name);
2119 g_object_unref (folder);
2124 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2127 GObject *win = modest_mail_operation_get_source (mail_op);
2129 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2130 _("mail_in_ui_folder_delete_error"));
2131 g_object_unref (win);
2135 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2137 TnyFolderStore *folder;
2138 GtkWidget *folder_view;
2142 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2144 folder_view = modest_main_window_get_child_widget (main_window,
2145 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2149 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2151 /* Show an error if it's an account */
2152 if (!TNY_IS_FOLDER (folder)) {
2153 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2154 _("mail_in_ui_folder_delete_error"));
2155 g_object_unref (G_OBJECT (folder));
2159 /* Offer the connection dialog if necessary: */
2160 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2161 g_object_unref (G_OBJECT (folder));
2166 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2167 tny_folder_get_name (TNY_FOLDER (folder)));
2168 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2169 (const gchar *) message);
2172 if (response == GTK_RESPONSE_OK) {
2173 ModestMailOperation *mail_op =
2174 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2175 G_OBJECT(main_window),
2176 modest_ui_actions_delete_folder_error_handler,
2179 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2181 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2182 g_object_unref (G_OBJECT (mail_op));
2185 g_object_unref (G_OBJECT (folder));
2189 modest_ui_actions_on_delete_folder (GtkAction *action,
2190 ModestMainWindow *main_window)
2192 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2194 delete_folder (main_window, FALSE);
2198 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2200 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2202 delete_folder (main_window, TRUE);
2206 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2207 const gchar* server_account_name,
2212 ModestMainWindow *main_window)
2214 g_return_if_fail(server_account_name);
2215 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2217 /* Initalize output parameters: */
2224 #ifdef MODEST_PLATFORM_MAEMO
2225 /* Maemo uses a different (awkward) button order,
2226 * It should probably just use gtk_alternative_dialog_button_order ().
2228 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2232 GTK_RESPONSE_ACCEPT,
2234 GTK_RESPONSE_REJECT,
2237 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2241 GTK_RESPONSE_REJECT,
2243 GTK_RESPONSE_ACCEPT,
2245 #endif /* MODEST_PLATFORM_MAEMO */
2247 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2249 gchar *server_name = modest_server_account_get_hostname (
2250 modest_runtime_get_account_mgr(), server_account_name);
2251 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2252 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2257 /* This causes a warning because the logical ID has no %s in it,
2258 * though the translation does, but there is not much we can do about that: */
2259 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2260 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2263 g_free (server_name);
2267 gchar *initial_username = modest_server_account_get_username (
2268 modest_runtime_get_account_mgr(), server_account_name);
2270 GtkWidget *entry_username = gtk_entry_new ();
2271 if (initial_username)
2272 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2273 /* Dim this if a connection has ever succeeded with this username,
2274 * as per the UI spec: */
2275 const gboolean username_known =
2276 modest_server_account_get_username_has_succeeded(
2277 modest_runtime_get_account_mgr(), server_account_name);
2278 gtk_widget_set_sensitive (entry_username, !username_known);
2280 #ifdef MODEST_PLATFORM_MAEMO
2281 /* Auto-capitalization is the default, so let's turn it off: */
2282 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2284 /* Create a size group to be used by all captions.
2285 * Note that HildonCaption does not create a default size group if we do not specify one.
2286 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2287 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2289 GtkWidget *caption = hildon_caption_new (sizegroup,
2290 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2291 gtk_widget_show (entry_username);
2292 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2293 FALSE, FALSE, MODEST_MARGIN_HALF);
2294 gtk_widget_show (caption);
2296 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2298 #endif /* MODEST_PLATFORM_MAEMO */
2301 GtkWidget *entry_password = gtk_entry_new ();
2302 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2303 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2305 #ifdef MODEST_PLATFORM_MAEMO
2306 /* Auto-capitalization is the default, so let's turn it off: */
2307 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2308 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2310 caption = hildon_caption_new (sizegroup,
2311 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2312 gtk_widget_show (entry_password);
2313 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2314 FALSE, FALSE, MODEST_MARGIN_HALF);
2315 gtk_widget_show (caption);
2316 g_object_unref (sizegroup);
2318 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2320 #endif /* MODEST_PLATFORM_MAEMO */
2322 /* This is not in the Maemo UI spec:
2323 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2324 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2328 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2330 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2332 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2334 modest_server_account_set_username (
2335 modest_runtime_get_account_mgr(), server_account_name,
2338 const gboolean username_was_changed =
2339 (strcmp (*username, initial_username) != 0);
2340 if (username_was_changed) {
2341 g_warning ("%s: tinymail does not yet support changing the "
2342 "username in the get_password() callback.\n", __FUNCTION__);
2347 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2349 /* We do not save the password in the configuration,
2350 * because this function is only called for passwords that should
2351 * not be remembered:
2352 modest_server_account_set_password (
2353 modest_runtime_get_account_mgr(), server_account_name,
2372 /* This is not in the Maemo UI spec:
2373 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2379 gtk_widget_destroy (dialog);
2381 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2385 modest_ui_actions_on_cut (GtkAction *action,
2386 ModestWindow *window)
2388 GtkWidget *focused_widget;
2390 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2391 if (GTK_IS_EDITABLE (focused_widget)) {
2392 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2393 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2394 GtkTextBuffer *buffer;
2395 GtkClipboard *clipboard;
2397 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2398 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2399 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2400 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2401 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2402 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2403 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2408 modest_ui_actions_on_copy (GtkAction *action,
2409 ModestWindow *window)
2411 GtkClipboard *clipboard;
2412 GtkWidget *focused_widget;
2414 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2415 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2417 if (GTK_IS_LABEL (focused_widget)) {
2418 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2419 } else if (GTK_IS_EDITABLE (focused_widget)) {
2420 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2421 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2422 GtkTextBuffer *buffer;
2423 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2424 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2425 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2426 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2427 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2428 TnyIterator *iter = tny_list_create_iterator (header_list);
2429 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2430 TnyFolder *folder = tny_header_get_folder (header);
2431 TnyAccount *account = tny_folder_get_account (folder);
2432 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2433 /* If it's POP then ask */
2434 gboolean ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2435 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2436 g_object_unref (account);
2437 g_object_unref (folder);
2438 g_object_unref (header);
2439 g_object_unref (iter);
2441 /* Check that the messages have been previously downloaded */
2442 gboolean continue_download = TRUE;
2444 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window));
2445 if (continue_download)
2446 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2447 g_object_unref (header_list);
2448 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2449 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2452 /* Show information banner */
2453 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2458 modest_ui_actions_on_undo (GtkAction *action,
2459 ModestWindow *window)
2461 ModestEmailClipboard *clipboard = NULL;
2463 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2464 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2465 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2466 /* Clear clipboard source */
2467 clipboard = modest_runtime_get_email_clipboard ();
2468 modest_email_clipboard_clear (clipboard);
2471 g_return_if_reached ();
2476 modest_ui_actions_on_redo (GtkAction *action,
2477 ModestWindow *window)
2479 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2480 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
2483 g_return_if_reached ();
2489 paste_msgs_cb (const GObject *object, gpointer user_data)
2491 g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2492 g_return_if_fail (GTK_IS_WIDGET (user_data));
2494 /* destroy information note */
2495 gtk_widget_destroy (GTK_WIDGET(user_data));
2499 modest_ui_actions_on_paste (GtkAction *action,
2500 ModestWindow *window)
2502 GtkWidget *focused_widget = NULL;
2503 GtkWidget *inf_note = NULL;
2504 ModestMailOperation *mail_op = NULL;
2506 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2507 if (GTK_IS_EDITABLE (focused_widget)) {
2508 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2509 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2510 GtkTextBuffer *buffer;
2511 GtkClipboard *clipboard;
2513 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2514 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2515 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2516 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2517 ModestEmailClipboard *clipboard = NULL;
2518 TnyFolder *src_folder = NULL;
2519 TnyFolderStore *folder_store = NULL;
2520 TnyList *data = NULL;
2521 gboolean delete = FALSE;
2523 /* Check clipboard source */
2524 clipboard = modest_runtime_get_email_clipboard ();
2525 if (modest_email_clipboard_cleared (clipboard))
2528 /* Get elements to paste */
2529 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2531 /* Create a new mail operation */
2532 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2533 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2536 /* Get destination folder */
2537 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2539 /* Launch notification */
2540 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2541 _CS("ckct_nw_pasting"));
2542 if (inf_note != NULL) {
2543 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
2544 gtk_widget_show (GTK_WIDGET(inf_note));
2547 /* transfer messages */
2549 modest_mail_operation_xfer_msgs (mail_op,
2551 TNY_FOLDER (folder_store),
2556 } else if (src_folder != NULL) {
2557 modest_mail_operation_xfer_folder (mail_op,
2567 g_object_unref (data);
2568 if (src_folder != NULL)
2569 g_object_unref (src_folder);
2570 if (folder_store != NULL)
2571 g_object_unref (folder_store);
2577 modest_ui_actions_on_select_all (GtkAction *action,
2578 ModestWindow *window)
2580 GtkWidget *focused_widget;
2582 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2583 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2584 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2585 } else if (GTK_IS_LABEL (focused_widget)) {
2586 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2587 } else if (GTK_IS_EDITABLE (focused_widget)) {
2588 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2589 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2590 GtkTextBuffer *buffer;
2591 GtkTextIter start, end;
2593 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2594 gtk_text_buffer_get_start_iter (buffer, &start);
2595 gtk_text_buffer_get_end_iter (buffer, &end);
2596 gtk_text_buffer_select_range (buffer, &start, &end);
2597 } else if (GTK_IS_HTML (focused_widget)) {
2598 gtk_html_select_all (GTK_HTML (focused_widget));
2599 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2600 GtkWidget *header_view = focused_widget;
2601 GtkTreeSelection *selection = NULL;
2603 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
2604 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2605 MODEST_WIDGET_TYPE_HEADER_VIEW);
2607 /* Select all messages */
2608 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2609 gtk_tree_selection_select_all (selection);
2611 /* Set focuse on header view */
2612 gtk_widget_grab_focus (header_view);
2618 modest_ui_actions_on_mark_as_read (GtkAction *action,
2619 ModestWindow *window)
2621 g_return_if_fail (MODEST_IS_WINDOW(window));
2623 /* Mark each header as read */
2624 do_headers_action (window, headers_action_mark_as_read, NULL);
2628 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2629 ModestWindow *window)
2631 g_return_if_fail (MODEST_IS_WINDOW(window));
2633 /* Mark each header as read */
2634 do_headers_action (window, headers_action_mark_as_unread, NULL);
2638 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2639 GtkRadioAction *selected,
2640 ModestWindow *window)
2644 value = gtk_radio_action_get_current_value (selected);
2645 if (MODEST_IS_WINDOW (window)) {
2646 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2650 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2651 GtkRadioAction *selected,
2652 ModestWindow *window)
2654 TnyHeaderFlags flags;
2655 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2657 flags = gtk_radio_action_get_current_value (selected);
2658 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2661 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2662 GtkRadioAction *selected,
2663 ModestWindow *window)
2667 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2669 file_format = gtk_radio_action_get_current_value (selected);
2670 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2675 modest_ui_actions_on_zoom_plus (GtkAction *action,
2676 ModestWindow *window)
2678 g_return_if_fail (MODEST_IS_WINDOW (window));
2680 modest_window_zoom_plus (MODEST_WINDOW (window));
2684 modest_ui_actions_on_zoom_minus (GtkAction *action,
2685 ModestWindow *window)
2687 g_return_if_fail (MODEST_IS_WINDOW (window));
2689 modest_window_zoom_minus (MODEST_WINDOW (window));
2693 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2694 ModestWindow *window)
2696 ModestWindowMgr *mgr;
2697 gboolean fullscreen, active;
2698 g_return_if_fail (MODEST_IS_WINDOW (window));
2700 mgr = modest_runtime_get_window_mgr ();
2702 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2703 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2705 if (active != fullscreen) {
2706 modest_window_mgr_set_fullscreen_mode (mgr, active);
2707 gtk_window_present (GTK_WINDOW (window));
2712 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2713 ModestWindow *window)
2715 ModestWindowMgr *mgr;
2716 gboolean fullscreen;
2718 g_return_if_fail (MODEST_IS_WINDOW (window));
2720 mgr = modest_runtime_get_window_mgr ();
2721 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2722 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2724 gtk_window_present (GTK_WINDOW (window));
2728 * Used by modest_ui_actions_on_details to call do_headers_action
2731 headers_action_show_details (TnyHeader *header,
2732 ModestWindow *window,
2739 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2742 gtk_widget_show_all (dialog);
2743 gtk_dialog_run (GTK_DIALOG (dialog));
2745 gtk_widget_destroy (dialog);
2749 * Show the folder details in a ModestDetailsDialog widget
2752 show_folder_details (TnyFolder *folder,
2758 dialog = modest_details_dialog_new_with_folder (window, folder);
2761 gtk_widget_show_all (dialog);
2762 gtk_dialog_run (GTK_DIALOG (dialog));
2764 gtk_widget_destroy (dialog);
2768 * Show the header details in a ModestDetailsDialog widget
2771 modest_ui_actions_on_details (GtkAction *action,
2774 TnyList * headers_list;
2778 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2781 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2784 g_object_unref (msg);
2786 headers_list = get_selected_headers (win);
2790 iter = tny_list_create_iterator (headers_list);
2792 header = TNY_HEADER (tny_iterator_get_current (iter));
2793 headers_action_show_details (header, win, NULL);
2794 g_object_unref (header);
2796 g_object_unref (iter);
2797 g_object_unref (headers_list);
2799 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2800 GtkWidget *folder_view, *header_view;
2802 /* Check which widget has the focus */
2803 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2804 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2805 if (gtk_widget_is_focus (folder_view)) {
2806 TnyFolderStore *folder_store
2807 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2808 if (!folder_store) {
2809 g_warning ("%s: No item was selected.\n", __FUNCTION__);
2812 /* Show only when it's a folder */
2813 /* This function should not be called for account items,
2814 * because we dim the menu item for them. */
2815 if (TNY_IS_FOLDER (folder_store)) {
2816 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
2819 g_object_unref (folder_store);
2822 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2823 MODEST_WIDGET_TYPE_HEADER_VIEW);
2824 /* Show details of each header */
2825 do_headers_action (win, headers_action_show_details, header_view);
2831 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2832 ModestMsgEditWindow *window)
2834 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2836 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2840 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2841 ModestMsgEditWindow *window)
2843 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2845 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2849 modest_ui_actions_toggle_folders_view (GtkAction *action,
2850 ModestMainWindow *main_window)
2854 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2856 conf = modest_runtime_get_conf ();
2858 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2859 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2861 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2865 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2866 ModestWindow *window)
2868 gboolean active, fullscreen = FALSE;
2869 ModestWindowMgr *mgr;
2871 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2873 /* Check if we want to toggle the toolbar vuew in fullscreen
2875 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2876 "ViewShowToolbarFullScreen")) {
2880 /* Toggle toolbar */
2881 mgr = modest_runtime_get_window_mgr ();
2882 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2886 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2887 ModestMsgEditWindow *window)
2889 modest_msg_edit_window_select_font (window);
2893 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2894 const gchar *display_name,
2897 /* Do not change the application name if the widget has not
2898 the focus. This callback could be called even if the folder
2899 view has not the focus, because the handled signal could be
2900 emitted when the folder view is redrawn */
2901 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2903 gtk_window_set_title (window, display_name);
2905 gtk_window_set_title (window, " ");
2910 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2912 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2913 modest_msg_edit_window_select_contacts (window);
2917 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2919 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2920 modest_msg_edit_window_check_names (window);
2925 create_move_to_dialog (ModestWindow *win,
2926 GtkWidget *folder_view,
2927 GtkWidget **tree_view)
2929 GtkWidget *dialog, *scroll;
2931 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2933 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2935 GTK_RESPONSE_ACCEPT,
2937 GTK_RESPONSE_REJECT,
2940 /* Create scrolled window */
2941 scroll = gtk_scrolled_window_new (NULL, NULL);
2942 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2943 GTK_POLICY_AUTOMATIC,
2944 GTK_POLICY_AUTOMATIC);
2946 /* Create folder view */
2947 *tree_view = modest_platform_create_folder_view (NULL);
2949 /* It could happen that we're trying to move a message from a
2950 window (msg window for example) after the main window was
2951 closed, so we can not just get the model of the folder
2953 if (MODEST_IS_FOLDER_VIEW (folder_view))
2954 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2955 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2957 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
2958 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
2960 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2962 /* Add scroll to dialog */
2963 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2964 scroll, FALSE, FALSE, 0);
2966 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2968 /* Select INBOX or local account */
2969 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (*tree_view));
2975 * Returns TRUE if at least one of the headers of the list belongs to
2976 * a message that has been fully retrieved.
2979 has_retrieved_msgs (TnyList *list)
2982 gboolean found = FALSE;
2984 iter = tny_list_create_iterator (list);
2985 while (tny_iterator_is_done (iter) && !found) {
2987 TnyHeaderFlags flags;
2989 header = TNY_HEADER (tny_iterator_get_current (iter));
2990 flags = tny_header_get_flags (header);
2991 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2995 tny_iterator_next (iter);
2997 g_object_unref (iter);
3003 * Shows a confirmation dialog to the user when we're moving messages
3004 * from a remote server to the local storage. Returns the dialog
3005 * response. If it's other kind of movement the it always returns
3009 msgs_move_to_confirmation (GtkWindow *win,
3010 TnyFolder *dest_folder,
3013 gint response = GTK_RESPONSE_OK;
3015 /* If the destination is a local folder */
3016 if (modest_tny_folder_is_local_folder (dest_folder)) {
3017 TnyFolder *src_folder;
3021 /* Get source folder */
3022 iter = tny_list_create_iterator (headers);
3023 header = TNY_HEADER (tny_iterator_get_current (iter));
3024 src_folder = tny_header_get_folder (header);
3025 g_object_unref (header);
3026 g_object_unref (iter);
3028 /* if no src_folder, message may be an attahcment */
3029 if (src_folder == NULL)
3030 return GTK_RESPONSE_CANCEL;
3032 /* If the source is a remote folder */
3033 if (!modest_tny_folder_is_local_folder (src_folder)) {
3034 const gchar *message;
3036 if (has_retrieved_msgs (headers))
3037 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
3038 tny_list_get_length (headers));
3040 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
3041 tny_list_get_length (headers));
3043 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
3044 (const gchar *) message);
3046 g_object_unref (src_folder);
3054 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
3056 ModestMsgViewWindow *self = NULL;
3057 gboolean last, first;
3059 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
3060 self = MODEST_MSG_VIEW_WINDOW (object);
3062 last = modest_msg_view_window_last_message_selected (self);
3063 first = modest_msg_view_window_first_message_selected (self);
3065 /* No more messages to view, so close this window */
3066 /* gboolean ret_value; */
3067 /* g_signal_emit_by_name (G_OBJECT (self), "delete-event", NULL, &ret_value); */
3068 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3070 modest_msg_view_window_select_previous_message (self);
3072 modest_msg_view_window_select_next_message (self);
3076 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3079 GObject *win = modest_mail_operation_get_source (mail_op);
3080 const GError *error = NULL;
3081 const gchar *message = NULL;
3083 /* Get error message */
3084 error = modest_mail_operation_get_error (mail_op);
3085 if (error != NULL && error->message != NULL) {
3086 message = error->message;
3088 message = _("mail_in_ui_folder_move_target_error");
3091 /* Show notification dialog */
3092 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3093 g_object_unref (win);
3097 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3100 GObject *win = modest_mail_operation_get_source (mail_op);
3101 const GError *error = modest_mail_operation_get_error (mail_op);
3103 g_return_if_fail (error != NULL);
3104 if (error->message != NULL)
3105 g_printerr ("modest: %s\n", error->message);
3107 g_printerr ("modest: unkonw error on send&receive operation");
3109 /* Show error message */
3110 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3111 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3112 /* _CS("sfil_ib_unable_to_receive")); */
3114 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3115 /* _CS("sfil_ib_unable_to_send")); */
3116 g_object_unref (win);
3120 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3127 gint pending_purges = 0;
3128 gboolean some_purged = FALSE;
3129 ModestWindow *win = MODEST_WINDOW (user_data);
3131 /* If there was any error */
3132 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
3135 /* Once the message has been retrieved for purging, we check if
3136 * it's all ok for purging */
3138 parts = tny_simple_list_new ();
3139 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3140 iter = tny_list_create_iterator (parts);
3142 while (!tny_iterator_is_done (iter)) {
3144 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3145 if (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)) {
3146 if (tny_mime_part_is_purged (part))
3151 tny_iterator_next (iter);
3154 if (pending_purges>0) {
3156 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3158 if (response == GTK_RESPONSE_OK) {
3159 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3160 tny_iterator_first (iter);
3161 while (!tny_iterator_is_done (iter)) {
3164 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3165 if (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))
3166 tny_mime_part_set_purged (part);
3167 tny_iterator_next (iter);
3170 tny_msg_rewrite_cache (msg);
3173 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3176 /* remove attachments */
3177 tny_iterator_first (iter);
3178 while (!tny_iterator_is_done (iter)) {
3181 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3182 g_object_unref (part);
3183 tny_iterator_next (iter);
3186 g_object_unref (iter);
3187 g_object_unref (parts);
3191 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3192 ModestMainWindow *win)
3194 GtkWidget *header_view;
3195 TnyList *header_list;
3198 TnyHeaderFlags flags;
3199 ModestWindow *msg_view_window = NULL;
3202 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3204 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3205 MODEST_WIDGET_TYPE_HEADER_VIEW);
3207 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3209 if (tny_list_get_length (header_list) == 1) {
3210 iter = tny_list_create_iterator (header_list);
3211 header = TNY_HEADER (tny_iterator_get_current (iter));
3212 g_object_unref (iter);
3217 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3218 header, &msg_view_window);
3219 flags = tny_header_get_flags (header);
3220 if (!(flags & TNY_HEADER_FLAG_CACHED))
3223 if (msg_view_window != NULL)
3224 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3226 /* do nothing; uid was registered before, so window is probably on it's way */
3227 g_warning ("debug: header %p has already been registered", header);
3230 ModestMailOperation *mail_op = NULL;
3231 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3232 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3234 modest_ui_actions_get_msgs_full_error_handler,
3236 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3237 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3239 g_object_unref (mail_op);
3242 g_object_unref (header);
3244 g_object_unref (header_list);
3248 * UI handler for the "Move to" action when invoked from the
3252 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3253 ModestMainWindow *win)
3255 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3256 GtkWidget *header_view = NULL;
3258 TnyFolderStore *folder_store = NULL;
3259 ModestMailOperation *mail_op = NULL;
3261 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3263 /* Get the folder view */
3264 folder_view = modest_main_window_get_child_widget (win,
3265 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3267 /* Get header view */
3268 header_view = modest_main_window_get_child_widget (win,
3269 MODEST_WIDGET_TYPE_HEADER_VIEW);
3271 /* Create and run the dialog */
3272 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
3273 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3274 result = gtk_dialog_run (GTK_DIALOG(dialog));
3275 g_object_ref (tree_view);
3277 /* We do this to save an indentation level ;-) */
3278 if (result != GTK_RESPONSE_ACCEPT)
3281 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3283 if (TNY_IS_ACCOUNT (folder_store) &&
3284 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (folder_store))
3287 /* Offer the connection dialog if necessary: */
3288 if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win), folder_store)) {
3292 /* Get folder or messages to transfer */
3293 if (gtk_widget_is_focus (folder_view)) {
3294 TnyFolderStore *src_folder;
3295 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3297 /* Offer the connection dialog if necessary: */
3298 if (modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win), src_folder)) {
3300 /* Clean folder on header view before moving it */
3301 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3303 if (TNY_IS_FOLDER (src_folder)) {
3305 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3307 modest_ui_actions_move_folder_error_handler,
3309 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3311 modest_mail_operation_xfer_folder (mail_op,
3312 TNY_FOLDER (src_folder),
3315 /* Unref mail operation */
3316 g_object_unref (G_OBJECT (mail_op));
3320 g_object_unref (G_OBJECT (src_folder));
3323 if (gtk_widget_is_focus (header_view)) {
3324 TnyList *headers = NULL;
3327 /* TODO: Check for connection if the headers are on a network account. */
3328 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3330 /* Ask for user confirmation */
3331 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3332 TNY_FOLDER (folder_store),
3335 /* Transfer messages */
3336 if (response == GTK_RESPONSE_OK) {
3338 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3340 modest_ui_actions_move_folder_error_handler,
3342 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3345 modest_mail_operation_xfer_msgs (mail_op,
3347 TNY_FOLDER (folder_store),
3352 g_object_unref (G_OBJECT (mail_op));
3354 g_object_unref (headers);
3359 if (folder_store != NULL)
3360 g_object_unref (folder_store);
3362 gtk_widget_destroy (dialog);
3367 * UI handler for the "Move to" action when invoked from the
3368 * ModestMsgViewWindow
3371 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3372 ModestMsgViewWindow *win)
3374 GtkWidget *dialog, *folder_view, *tree_view = NULL;
3376 ModestMainWindow *main_window = NULL;
3377 TnyHeader *header = NULL;
3378 TnyList *headers = NULL;
3380 /* Get the folder view */
3381 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3383 folder_view = modest_main_window_get_child_widget (main_window,
3384 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3388 /* Create and run the dialog */
3389 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
3390 result = gtk_dialog_run (GTK_DIALOG(dialog));
3392 if (result == GTK_RESPONSE_ACCEPT) {
3393 TnyFolderStore *folder_store;
3396 /* Create header list */
3397 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3398 g_return_if_fail (header != NULL);
3400 /* Offer the connection dialog if necessary: */
3401 /* TODO: What's the extra g_object_ref() for? Isn't this leaking a ref? */
3402 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (g_object_ref (tree_view)));
3403 TnyFolder *header_folder = tny_header_get_folder(header);
3404 if (modest_platform_connect_and_wait_if_network_folderstore (NULL, folder_store) &&
3405 modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (header_folder))) {
3407 headers = tny_simple_list_new ();
3408 tny_list_prepend (headers, G_OBJECT (header));
3409 g_object_unref (header);
3411 /* Ask user for confirmation. MSG-NOT404 */
3412 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3413 TNY_FOLDER (folder_store),
3416 /* Transfer current msg */
3417 if (response == GTK_RESPONSE_OK) {
3418 ModestMailOperation *mail_op;
3420 /* Create mail op */
3421 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
3422 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3425 /* Transfer messages */
3426 modest_mail_operation_xfer_msgs (mail_op,
3428 TNY_FOLDER (folder_store),
3430 transfer_msgs_from_viewer_cb,
3432 g_object_unref (G_OBJECT (mail_op));
3437 g_object_unref (header_folder);
3440 g_object_unref (headers);
3443 g_object_unref (folder_store);
3446 gtk_widget_destroy (dialog);
3450 modest_ui_actions_on_move_to (GtkAction *action,
3453 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3454 MODEST_IS_MSG_VIEW_WINDOW (win));
3456 if (MODEST_IS_MAIN_WINDOW (win))
3457 modest_ui_actions_on_main_window_move_to (action,
3458 MODEST_MAIN_WINDOW (win));
3460 modest_ui_actions_on_msg_view_window_move_to (action,
3461 MODEST_MSG_VIEW_WINDOW (win));
3465 * Calls #HeadersFunc for each header already selected in the main
3466 * window or the message currently being shown in the msg view window
3469 do_headers_action (ModestWindow *win,
3473 TnyList *headers_list;
3479 headers_list = get_selected_headers (win);
3483 /* Get the folder */
3484 iter = tny_list_create_iterator (headers_list);
3485 header = TNY_HEADER (tny_iterator_get_current (iter));
3486 folder = tny_header_get_folder (header);
3487 g_object_unref (header);
3489 /* Call the function for each header */
3490 while (!tny_iterator_is_done (iter)) {
3491 header = TNY_HEADER (tny_iterator_get_current (iter));
3492 func (header, win, user_data);
3493 g_object_unref (header);
3494 tny_iterator_next (iter);
3497 /* Trick: do a poke status in order to speed up the signaling
3499 tny_folder_poke_status (folder);
3502 g_object_unref (folder);
3503 g_object_unref (iter);
3504 g_object_unref (headers_list);
3508 modest_ui_actions_view_attachment (GtkAction *action,
3509 ModestWindow *window)
3511 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3512 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
3514 /* not supported window for this action */
3515 g_return_if_reached ();
3520 modest_ui_actions_save_attachments (GtkAction *action,
3521 ModestWindow *window)
3523 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3524 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
3526 /* not supported window for this action */
3527 g_return_if_reached ();
3532 modest_ui_actions_remove_attachments (GtkAction *action,
3533 ModestWindow *window)
3535 if (MODEST_IS_MAIN_WINDOW (window)) {
3536 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
3537 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3538 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
3540 /* not supported window for this action */
3541 g_return_if_reached ();
3546 modest_ui_actions_on_settings (GtkAction *action,
3551 dialog = modest_platform_get_global_settings_dialog ();
3552 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
3553 gtk_widget_show_all (dialog);
3555 gtk_dialog_run (GTK_DIALOG (dialog));
3557 gtk_widget_destroy (dialog);
3561 modest_ui_actions_on_help (GtkAction *action,
3564 const gchar *help_id = NULL;
3566 if (MODEST_IS_MAIN_WINDOW (win)) {
3567 const gchar *action_name;
3568 action_name = gtk_action_get_name (action);
3570 if (!strcmp (action_name, "FolderViewCSMHelp") ||
3571 !strcmp (action_name, "HeaderViewCSMHelp")) {
3572 GtkWidget *folder_view;
3573 TnyFolderStore *folder_store;
3574 /* Get selected folder */
3575 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3576 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3577 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3579 /* Switch help_id */
3580 if (TNY_IS_FOLDER (folder_store)) {
3581 switch (tny_folder_get_folder_type (TNY_FOLDER (folder_store))) {
3582 case TNY_FOLDER_TYPE_NORMAL:
3583 help_id = "applications_email_userfolder";
3585 case TNY_FOLDER_TYPE_INBOX:
3586 help_id = "applications_email_inbox";
3588 case TNY_FOLDER_TYPE_OUTBOX:
3589 help_id = "applications_email_outbox";
3591 case TNY_FOLDER_TYPE_SENT:
3592 help_id = "applications_email_sent";
3594 case TNY_FOLDER_TYPE_DRAFTS:
3595 help_id = "applications_email_drafts";
3597 case TNY_FOLDER_TYPE_ARCHIVE:
3598 help_id = "applications_email_archive";
3604 g_object_unref (folder_store);
3606 help_id = "applications_email_mainview";
3608 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3609 help_id = "applications_email_viewer";
3610 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
3611 help_id = "applications_email_editor";
3613 modest_platform_show_help (GTK_WINDOW (win), help_id);
3617 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
3618 ModestWindow *window)
3620 ModestMailOperation *mail_op;
3624 headers = get_selected_headers (window);
3628 /* Create mail operation */
3629 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3631 modest_ui_actions_get_msgs_full_error_handler,
3633 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3634 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
3637 g_object_unref (headers);
3638 g_object_unref (mail_op);
3642 modest_ui_actions_on_email_menu_activated (GtkAction *action,
3643 ModestWindow *window)
3645 g_return_if_fail (MODEST_IS_WINDOW (window));
3648 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3652 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
3653 ModestWindow *window)
3655 g_return_if_fail (MODEST_IS_WINDOW (window));
3658 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3662 modest_ui_actions_on_view_menu_activated (GtkAction *action,
3663 ModestWindow *window)
3665 g_return_if_fail (MODEST_IS_WINDOW (window));
3668 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3672 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
3673 ModestWindow *window)
3675 g_return_if_fail (MODEST_IS_WINDOW (window));
3678 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3682 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
3683 ModestWindow *window)
3685 g_return_if_fail (MODEST_IS_WINDOW (window));
3688 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3692 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
3693 ModestWindow *window)
3695 g_return_if_fail (MODEST_IS_WINDOW (window));
3698 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3702 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
3703 ModestWindow *window)
3705 g_return_if_fail (MODEST_IS_WINDOW (window));
3708 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3712 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
3713 ModestWindow *window)
3715 g_return_if_fail (MODEST_IS_WINDOW (window));
3718 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3722 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
3724 g_return_if_fail (MODEST_IS_WINDOW (window));
3727 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
3731 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
3733 g_return_if_fail (MODEST_IS_WINDOW (window));
3735 modest_platform_show_search_messages (GTK_WINDOW (window));
3739 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
3741 g_return_if_fail (MODEST_IS_WINDOW (win));
3742 modest_platform_show_addressbook (GTK_WINDOW (win));
3747 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
3748 ModestWindow *window)
3750 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3752 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
3756 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
3757 ModestMailOperationState *state,
3760 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
3762 /* Set send/receive operation finished */
3763 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3764 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));