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"
48 #ifdef MODEST_PLATFORM_MAEMO
49 #include "maemo/modest-osso-state-saving.h"
50 #endif /* MODEST_PLATFORM_MAEMO */
52 #include "widgets/modest-ui-constants.h"
53 #include <widgets/modest-main-window.h>
54 #include <widgets/modest-msg-view-window.h>
55 #include <widgets/modest-account-view-window.h>
56 #include <widgets/modest-details-dialog.h>
57 #include <widgets/modest-attachments-view.h>
58 #include "widgets/modest-folder-view.h"
59 #include "widgets/modest-global-settings-dialog.h"
60 #include "modest-connection-specific-smtp-window.h"
61 #include "modest-account-mgr-helpers.h"
62 #include "modest-mail-operation.h"
63 #include "modest-text-utils.h"
65 #ifdef MODEST_HAVE_EASYSETUP
66 #include "easysetup/modest-easysetup-wizard.h"
67 #endif /* MODEST_HAVE_EASYSETUP */
69 #include <modest-widget-memory.h>
70 #include <tny-error.h>
71 #include <tny-simple-list.h>
72 #include <tny-msg-view.h>
73 #include <tny-device.h>
74 #include <tny-merge-folder.h>
76 typedef struct _GetMsgAsyncHelper {
78 ModestMailOperation *mail_op;
85 typedef enum _ReplyForwardAction {
91 typedef struct _ReplyForwardHelper {
92 guint reply_forward_type;
93 ReplyForwardAction action;
95 GtkWidget *parent_window;
99 * The do_headers_action uses this kind of functions to perform some
100 * action to each member of a list of headers
102 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
105 do_headers_action (ModestWindow *win,
110 static void open_msg_cb (ModestMailOperation *mail_op,
115 static void reply_forward_cb (ModestMailOperation *mail_op,
120 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
122 static gchar* ask_for_folder_name (GtkWindow *parent_window, const gchar *title);
125 static void _on_send_receive_progress_changed (ModestMailOperation *mail_op,
126 ModestMailOperationState *state,
132 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
135 const gchar *authors[] = {
136 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
139 about = gtk_about_dialog_new ();
140 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
141 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
142 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
143 _("Copyright (c) 2006, Nokia Corporation\n"
144 "All rights reserved."));
145 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
146 _("a modest e-mail client\n\n"
147 "design and implementation: Dirk-Jan C. Binnema\n"
148 "contributions from the fine people at KC and Ig\n"
149 "uses the tinymail email framework written by Philip van Hoof"));
150 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
151 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
153 gtk_dialog_run (GTK_DIALOG (about));
154 gtk_widget_destroy(about);
158 * Gets the list of currently selected messages. If the win is the
159 * main window, then it returns a newly allocated list of the headers
160 * selected in the header view. If win is the msg view window, then
161 * the value returned is a list with just a single header.
163 * The caller of this funcion must free the list.
166 get_selected_headers (ModestWindow *win)
168 if (MODEST_IS_MAIN_WINDOW(win)) {
169 GtkWidget *header_view;
171 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
172 MODEST_WIDGET_TYPE_HEADER_VIEW);
173 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
175 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
176 /* for MsgViewWindows, we simply return a list with one element */
178 TnyList *list = NULL;
180 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
181 if (header != NULL) {
182 list = tny_simple_list_new ();
183 tny_list_prepend (list, G_OBJECT(header));
184 g_object_unref (G_OBJECT(header));
194 headers_action_mark_as_read (TnyHeader *header,
198 TnyHeaderFlags flags;
200 g_return_if_fail (TNY_IS_HEADER(header));
202 flags = tny_header_get_flags (header);
203 if (flags & TNY_HEADER_FLAG_SEEN) return;
204 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
208 headers_action_mark_as_unread (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) {
218 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
224 headers_action_delete (TnyHeader *header,
228 ModestMailOperation *mail_op = NULL;
230 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE, G_OBJECT(win));
231 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
234 /* Always delete. TODO: Move to trash still not supported */
235 modest_mail_operation_remove_msg (mail_op, header, FALSE);
236 g_object_unref (G_OBJECT (mail_op));
240 modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
242 TnyList *header_list = NULL;
243 TnyIterator *iter = NULL;
244 TnyHeader *header = NULL;
245 gchar *message = NULL;
249 ModestWindowMgr *mgr;
251 g_return_if_fail (MODEST_IS_WINDOW(win));
253 header_list = get_selected_headers (win);
254 if (!header_list) return;
256 /* Check if any of the headers is already opened */
257 iter = tny_list_create_iterator (header_list);
259 mgr = modest_runtime_get_window_mgr ();
260 while (!tny_iterator_is_done (iter) && !found) {
261 header = TNY_HEADER (tny_iterator_get_current (iter));
262 if (modest_window_mgr_find_window_by_header (mgr, header))
264 g_object_unref (header);
265 tny_iterator_next (iter);
267 g_object_unref (iter);
272 num = g_strdup_printf ("%d", tny_list_get_length (header_list));
273 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
275 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
279 g_object_unref (header_list);
284 if (tny_list_get_length(header_list) > 1)
285 message = g_strdup(_("emev_nc_delete_messages"));
287 iter = tny_list_create_iterator (header_list);
288 header = TNY_HEADER (tny_iterator_get_current (iter));
289 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
290 message = g_strdup_printf(_("emev_nc_delete_message"), desc);
291 g_object_unref (header);
292 g_object_unref (iter);
295 /* Confirmation dialog */
296 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
300 if (response == GTK_RESPONSE_OK) {
301 if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
303 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
307 /* Remove each header */
308 do_headers_action (win, headers_action_delete, NULL);
310 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
311 gtk_widget_destroy (GTK_WIDGET(win));
318 g_object_unref (header_list);
323 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
325 #ifdef MODEST_PLATFORM_MAEMO
326 modest_osso_save_state();
327 #endif /* MODEST_PLATFORM_MAEMO */
333 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
335 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
336 gtk_widget_destroy (GTK_WIDGET (win));
337 } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
339 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
340 } else if (MODEST_IS_WINDOW (win)) {
341 gtk_widget_destroy (GTK_WIDGET (win));
343 g_return_if_reached ();
348 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
350 GtkClipboard *clipboard = NULL;
351 gchar *selection = NULL;
353 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
354 selection = gtk_clipboard_wait_for_text (clipboard);
356 /* Question: why is the clipboard being used here?
357 * It doesn't really make a lot of sense. */
361 modest_address_book_add_address (selection);
367 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
369 /* This is currently only implemented for Maemo,
370 * because it requires a providers preset file which is not publically available.
372 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
373 gboolean accounts_exist = modest_account_mgr_has_accounts(
374 modest_runtime_get_account_mgr(), TRUE);
376 if (!accounts_exist) {
377 /* If there are no accounts yet, just show the easy-setup wizard, as per the UI spec: */
378 ModestEasysetupWizardDialog *wizard = modest_easysetup_wizard_dialog_new ();
379 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
380 gtk_dialog_run (GTK_DIALOG (wizard));
381 gtk_widget_destroy (GTK_WIDGET (wizard));
383 /* Show the list of accounts: */
384 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
385 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
386 gtk_dialog_run (account_win);
387 gtk_widget_destroy (GTK_WIDGET(account_win));
390 GtkWidget *dialog, *label;
392 /* Create the widgets */
394 dialog = gtk_dialog_new_with_buttons ("Message",
396 GTK_DIALOG_DESTROY_WITH_PARENT,
400 label = gtk_label_new ("Hello World!");
402 /* Ensure that the dialog box is destroyed when the user responds. */
404 g_signal_connect_swapped (dialog, "response",
405 G_CALLBACK (gtk_widget_destroy),
408 /* Add the label, and show everything we've added to the dialog. */
410 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
412 gtk_widget_show_all (dialog);
413 #endif /* MODEST_PLATFORM_MAEMO */
417 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
419 ModestWindow *main_window = MODEST_WINDOW (user_data);
421 /* Save any changes. */
422 modest_connection_specific_smtp_window_save_server_accounts (
423 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
424 modest_window_get_active_account (main_window));
425 gtk_widget_destroy (GTK_WIDGET (window));
429 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
431 /* This is currently only implemented for Maemo,
432 * because it requires an API (libconic) to detect different connection
435 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
437 /* Create the window if necessary: */
438 const gchar *active_account_name = modest_window_get_active_account (win);
440 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
441 * or show the default account?
442 * If we show the default account then the account name should be shown in
443 * the window when we show it. */
444 if (!active_account_name) {
445 g_warning ("%s: No account is active.", __FUNCTION__);
449 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
450 modest_connection_specific_smtp_window_fill_with_connections (
451 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
452 modest_runtime_get_account_mgr(),
453 active_account_name);
455 /* Show the window: */
456 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
457 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
458 gtk_widget_show (specific_window);
460 /* Save changes when the window is hidden: */
461 g_signal_connect (specific_window, "hide",
462 G_CALLBACK (on_smtp_servers_window_hide), win);
463 #endif /* MODEST_PLATFORM_MAEMO */
467 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
469 ModestWindow *msg_win;
471 TnyFolder *folder = NULL;
472 gchar *account_name = NULL;
473 gchar *from_str = NULL;
474 /* GError *err = NULL; */
475 TnyAccount *account = NULL;
476 ModestWindowMgr *mgr;
477 gchar *signature = NULL, *blank_and_signature = NULL;
479 account_name = g_strdup(modest_window_get_active_account (win));
481 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
483 g_printerr ("modest: no account found\n");
487 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
489 TNY_ACCOUNT_TYPE_STORE);
491 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
495 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
497 g_printerr ("modest: failed get from string for '%s'\n", account_name);
501 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
502 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
503 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
504 MODEST_ACCOUNT_SIGNATURE, FALSE);
505 blank_and_signature = g_strconcat ("\n", signature, NULL);
508 blank_and_signature = g_strdup ("");
511 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
513 g_printerr ("modest: failed to create new msg\n");
517 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
519 g_printerr ("modest: failed to find Drafts folder\n");
523 /* tny_folder_add_msg (folder, msg, &err); */
525 /* g_printerr ("modest: error adding msg to Drafts folder: %s", */
527 /* g_error_free (err); */
531 /* Create and register edit window */
532 /* This is destroyed by TOOD. */
533 msg_win = modest_msg_edit_window_new (msg, account_name);
534 mgr = modest_runtime_get_window_mgr ();
535 modest_window_mgr_register_window (mgr, msg_win);
538 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
540 gtk_widget_show_all (GTK_WIDGET (msg_win));
543 g_free (account_name);
545 g_free (blank_and_signature);
547 g_object_unref (G_OBJECT(account));
549 g_object_unref (G_OBJECT(msg));
551 g_object_unref (G_OBJECT(folder));
555 open_msg_cb (ModestMailOperation *mail_op,
560 ModestWindowMgr *mgr = NULL;
561 ModestWindow *parent_win = NULL;
562 ModestWindow *win = NULL;
563 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
564 gchar *account = NULL;
567 /* TODO: Show an error? (review the specs) */
571 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
572 folder = tny_header_get_folder (header);
574 /* Mark header as read */
575 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
578 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
580 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
582 /* Gets folder type (OUTBOX headers will be opened in edit window */
583 if (modest_tny_folder_is_local_folder (folder))
584 folder_type = modest_tny_folder_get_local_folder_type (folder);
586 /* If the header is in the drafts folder then open the editor,
587 else the message view window */
588 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
589 win = modest_msg_edit_window_new (msg, account);
591 gchar *uid = modest_tny_folder_get_header_unique_id (header);
593 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
594 GtkWidget *header_view;
595 GtkTreeSelection *sel;
596 GList *sel_list = NULL;
599 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
600 MODEST_WIDGET_TYPE_HEADER_VIEW);
602 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
603 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
605 if (sel_list != NULL) {
606 GtkTreeRowReference *row_reference;
608 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
609 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
610 g_list_free (sel_list);
612 win = modest_msg_view_window_new_with_header_model (msg,
617 gtk_tree_row_reference_free (row_reference);
619 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
622 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
627 /* Register and show new window */
629 mgr = modest_runtime_get_window_mgr ();
630 modest_window_mgr_register_window (mgr, win);
631 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
632 gtk_widget_show_all (GTK_WIDGET(win));
637 g_object_unref (msg);
638 g_object_unref (folder);
639 g_object_unref (header);
643 * This function is the error handler of the
644 * modest_mail_operation_get_msgs_full operation
647 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
652 error = modest_mail_operation_get_error (mail_op);
653 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
654 GObject *win = modest_mail_operation_get_source (mail_op);
656 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
662 * This function is used by both modest_ui_actions_on_open and
663 * modest_ui_actions_on_header_activated. This way we always do the
664 * same when trying to open messages.
667 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
669 ModestWindowMgr *mgr;
671 ModestMailOperation *mail_op;
673 /* Look if we already have a message view for each header. If
674 true, then remove the header from the list of headers to
676 mgr = modest_runtime_get_window_mgr ();
677 iter = tny_list_create_iterator (headers);
678 while (!tny_iterator_is_done (iter)) {
679 ModestWindow *window;
682 header = TNY_HEADER (tny_iterator_get_current (iter));
683 window = modest_window_mgr_find_window_by_header (mgr, header);
685 /* Do not open again the message and present
686 the window to the user */
687 tny_list_remove (headers, G_OBJECT (header));
688 gtk_window_present (GTK_WINDOW (window));
691 g_object_unref (header);
692 tny_iterator_next (iter);
696 /* Open each message */
697 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
699 modest_ui_actions_get_msgs_full_error_handler,
701 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
702 modest_mail_operation_get_msgs_full (mail_op,
708 g_object_unref (iter);
709 g_object_unref(mail_op);
713 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
718 headers = get_selected_headers (win);
723 _modest_ui_actions_open (headers, win);
725 g_object_unref(headers);
730 free_reply_forward_helper (gpointer data)
732 ReplyForwardHelper *helper;
734 helper = (ReplyForwardHelper *) data;
735 g_free (helper->account_name);
736 g_slice_free (ReplyForwardHelper, helper);
740 reply_forward_cb (ModestMailOperation *mail_op,
746 ReplyForwardHelper *rf_helper;
747 ModestWindow *msg_win;
748 ModestEditType edit_type;
750 TnyAccount *account = NULL;
751 ModestWindowMgr *mgr;
752 gchar *signature = NULL;
754 g_return_if_fail (user_data != NULL);
755 rf_helper = (ReplyForwardHelper *) user_data;
757 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
758 rf_helper->account_name);
759 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
760 rf_helper->account_name,
761 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
762 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
763 rf_helper->account_name,
764 MODEST_ACCOUNT_SIGNATURE, FALSE);
767 /* Create reply mail */
768 switch (rf_helper->action) {
771 modest_tny_msg_create_reply_msg (msg, from, signature,
772 rf_helper->reply_forward_type,
773 MODEST_TNY_MSG_REPLY_MODE_SENDER);
775 case ACTION_REPLY_TO_ALL:
777 modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type,
778 MODEST_TNY_MSG_REPLY_MODE_ALL);
779 edit_type = MODEST_EDIT_TYPE_REPLY;
783 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
784 edit_type = MODEST_EDIT_TYPE_FORWARD;
787 g_return_if_reached ();
794 g_printerr ("modest: failed to create message\n");
798 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
799 rf_helper->account_name,
800 TNY_ACCOUNT_TYPE_STORE);
802 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
806 /* Create and register the windows */
807 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
808 mgr = modest_runtime_get_window_mgr ();
809 modest_window_mgr_register_window (mgr, msg_win);
811 if (rf_helper->parent_window != NULL) {
814 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
815 modest_window_set_zoom (msg_win, parent_zoom);
818 /* Show edit window */
819 gtk_widget_show_all (GTK_WIDGET (msg_win));
823 g_object_unref (G_OBJECT (new_msg));
825 g_object_unref (G_OBJECT (account));
826 g_object_unref (msg);
827 g_object_unref (header);
831 * Checks a list of headers. If any of them are not currently
832 * downloaded (CACHED) then it asks the user for permission to
835 * Returns FALSE if the user does not want to download the
836 * messages. Returns TRUE if the user allowed the download or if all
837 * of them are currently downloaded
840 download_uncached_messages (TnyList *header_list, GtkWindow *win)
843 gboolean found, retval;
845 iter = tny_list_create_iterator (header_list);
847 while (!tny_iterator_is_done (iter) && !found) {
849 TnyHeaderFlags flags;
851 header = TNY_HEADER (tny_iterator_get_current (iter));
852 flags = tny_header_get_flags (header);
853 /* TODO: is this the right flag?, it seems that some
854 headers that have been previously downloaded do not
856 found = !(flags & TNY_HEADER_FLAG_CACHED);
857 g_object_unref (header);
858 tny_iterator_next (iter);
860 g_object_unref (iter);
862 /* Ask for user permission to download the messages */
865 GtkResponseType response;
867 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
868 _("mcen_nc_get_multi_msg_txt"));
869 if (response == GTK_RESPONSE_CANCEL)
877 * Common code for the reply and forward actions
880 reply_forward (ReplyForwardAction action, ModestWindow *win)
882 ModestMailOperation *mail_op = NULL;
883 TnyList *header_list = NULL;
884 ReplyForwardHelper *rf_helper = NULL;
885 guint reply_forward_type;
886 gboolean continue_download;
888 g_return_if_fail (MODEST_IS_WINDOW(win));
890 header_list = get_selected_headers (win);
894 /* Check that the messages have been previously downloaded */
895 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
896 if (!continue_download) {
897 g_object_unref (header_list);
902 modest_conf_get_int (modest_runtime_get_conf (),
903 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
905 /* We assume that we can only select messages of the
906 same folder and that we reply all of them from the
907 same account. In fact the interface currently only
908 allows single selection */
911 rf_helper = g_slice_new0 (ReplyForwardHelper);
912 rf_helper->reply_forward_type = reply_forward_type;
913 rf_helper->action = action;
914 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
915 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
916 rf_helper->parent_window = GTK_WIDGET (win);
917 if (!rf_helper->account_name)
918 rf_helper->account_name =
919 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
921 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
924 /* Get header and message. Do not free them here, the
925 reply_forward_cb must do it */
926 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
927 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
928 if (!msg || !header) {
930 g_object_unref (msg);
932 g_object_unref (header);
933 g_printerr ("modest: no message found\n");
936 reply_forward_cb (NULL, header, msg, rf_helper);
938 /* Retrieve messages */
939 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
941 modest_ui_actions_get_msgs_full_error_handler,
943 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
944 modest_mail_operation_get_msgs_full (mail_op,
948 free_reply_forward_helper);
951 g_object_unref(mail_op);
955 g_object_unref (header_list);
959 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
961 g_return_if_fail (MODEST_IS_WINDOW(win));
963 reply_forward (ACTION_REPLY, win);
967 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
969 g_return_if_fail (MODEST_IS_WINDOW(win));
971 reply_forward (ACTION_FORWARD, win);
975 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
977 g_return_if_fail (MODEST_IS_WINDOW(win));
979 reply_forward (ACTION_REPLY_TO_ALL, win);
983 modest_ui_actions_on_next (GtkAction *action,
984 ModestWindow *window)
986 if (MODEST_IS_MAIN_WINDOW (window)) {
987 GtkWidget *header_view;
989 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
990 MODEST_WIDGET_TYPE_HEADER_VIEW);
994 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
995 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
996 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
998 g_return_if_reached ();
1003 modest_ui_actions_on_prev (GtkAction *action,
1004 ModestWindow *window)
1006 g_return_if_fail (MODEST_IS_WINDOW(window));
1008 if (MODEST_IS_MAIN_WINDOW (window)) {
1009 GtkWidget *header_view;
1010 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1011 MODEST_WIDGET_TYPE_HEADER_VIEW);
1015 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1016 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1017 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1019 g_return_if_reached ();
1024 modest_ui_actions_on_sort (GtkAction *action,
1025 ModestWindow *window)
1027 g_return_if_fail (MODEST_IS_WINDOW(window));
1029 if (MODEST_IS_MAIN_WINDOW (window)) {
1030 GtkWidget *header_view;
1031 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1032 MODEST_WIDGET_TYPE_HEADER_VIEW);
1036 /* Show sorting dialog */
1037 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1042 * This function performs the send & receive required actions. The
1043 * window is used to create the mail operation. Typically it should
1044 * always be the main window, but we pass it as argument in order to
1048 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1050 gchar *acc_name = NULL;
1051 ModestMailOperation *mail_op;
1053 /* If no account name was provided then get the current account, and if
1054 there is no current account then pick the default one: */
1055 if (!account_name) {
1056 acc_name = g_strdup (modest_window_get_active_account(win));
1058 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1060 g_printerr ("modest: cannot get default account\n");
1064 acc_name = g_strdup (account_name);
1067 /* Set send/receive operation in progress */
1068 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1070 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
1071 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1072 G_CALLBACK (_on_send_receive_progress_changed),
1075 /* Send & receive. */
1076 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1077 /* Receive and then send. The operation is tagged initially as
1078 a receive operation because the account update performs a
1079 receive and then a send. The operation changes its type
1080 internally, so the progress objects will receive the proper
1081 progress information */
1082 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1083 modest_mail_operation_update_account (mail_op, acc_name);
1084 g_object_unref (G_OBJECT (mail_op));
1091 * Refreshes all accounts. This function will be used by automatic
1095 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1097 GSList *account_names, *iter;
1099 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1102 iter = account_names;
1104 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1105 iter = g_slist_next (iter);
1108 g_slist_foreach (account_names, (GFunc) g_free, NULL);
1109 g_slist_free (account_names);
1113 * Handler of the click on Send&Receive button in the main toolbar
1116 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1118 /* Check if accounts exist */
1119 gboolean accounts_exist =
1120 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1122 /* If not, allow the user to create an account before trying to send/receive. */
1123 if (!accounts_exist)
1124 modest_ui_actions_on_accounts (NULL, win);
1126 /* Refresh the active account */
1127 modest_ui_actions_do_send_receive (NULL, win);
1132 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1135 GtkWidget *header_view;
1137 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1139 header_view = modest_main_window_get_child_widget (main_window,
1140 MODEST_WIDGET_TYPE_HEADER_VIEW);
1144 conf = modest_runtime_get_conf ();
1146 /* what is saved/restored is depending on the style; thus; we save with
1147 * old style, then update the style, and restore for this new style
1149 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1151 if (modest_header_view_get_style
1152 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1153 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1154 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1156 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1157 MODEST_HEADER_VIEW_STYLE_DETAILS);
1159 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1160 MODEST_CONF_HEADER_VIEW_KEY);
1165 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1167 ModestMainWindow *main_window)
1169 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1170 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1172 /* If no header has been selected then exit */
1176 /* Update Main window title */
1177 if (GTK_WIDGET_HAS_FOCUS (header_view)) {
1178 const gchar *subject = tny_header_get_subject (header);
1179 if (subject && strlen(subject) > 0)
1180 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1182 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1185 /* Update toolbar dimming state */
1186 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1190 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1192 ModestMainWindow *main_window)
1196 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1201 headers = tny_simple_list_new ();
1202 tny_list_prepend (headers, G_OBJECT (header));
1204 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1206 g_object_unref (headers);
1210 set_active_account_from_tny_account (TnyAccount *account,
1211 ModestWindow *window)
1213 const gchar *server_acc_name = tny_account_get_id (account);
1215 /* We need the TnyAccount provided by the
1216 account store because that is the one that
1217 knows the name of the Modest account */
1218 TnyAccount *modest_server_account = modest_server_account =
1219 modest_tny_account_store_get_tny_account_by_id (modest_runtime_get_account_store (),
1222 const gchar *modest_acc_name =
1223 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1224 modest_window_set_active_account (window, modest_acc_name);
1225 g_object_unref (modest_server_account);
1229 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1230 TnyFolderStore *folder_store,
1232 ModestMainWindow *main_window)
1235 GtkWidget *header_view;
1236 gboolean folder_empty = FALSE;
1238 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1240 header_view = modest_main_window_get_child_widget(main_window,
1241 MODEST_WIDGET_TYPE_HEADER_VIEW);
1245 conf = modest_runtime_get_conf ();
1247 if (TNY_IS_ACCOUNT (folder_store)) {
1248 /* Update active account */
1249 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1250 /* Show account details */
1251 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1253 if (TNY_IS_FOLDER (folder_store) && selected) {
1255 if (!TNY_IS_MERGE_FOLDER (folder_store)) { /* TnyMergeFolder can have no get_account() implementation. */
1256 /* Update the active account */
1257 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1258 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1259 g_object_unref (account);
1263 /* Set folder on header view */
1264 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1265 TNY_FOLDER (folder_store));
1267 /* Set main view style */
1268 folder_empty = tny_folder_get_all_count (TNY_FOLDER (folder_store)) == 0;
1270 modest_main_window_set_contents_style (main_window,
1271 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1274 modest_main_window_set_contents_style (main_window,
1275 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1276 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1277 MODEST_CONF_HEADER_VIEW_KEY);
1280 /* Update the active account */
1281 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1282 /* Do not show folder */
1283 modest_widget_memory_save (conf, G_OBJECT (header_view), MODEST_CONF_HEADER_VIEW_KEY);
1284 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
1288 /* Update toolbar dimming state */
1289 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1293 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1300 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1302 if (g_main_depth > 0)
1303 gdk_threads_enter ();
1304 online = tny_device_is_online (modest_runtime_get_device());
1307 /* already online -- the item is simply not there... */
1308 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1310 GTK_MESSAGE_WARNING,
1312 _("The %s you selected cannot be found"),
1314 gtk_dialog_run (GTK_DIALOG(dialog));
1316 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1320 GTK_RESPONSE_REJECT,
1322 GTK_RESPONSE_ACCEPT,
1324 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1325 "Do you want to get online?"), item);
1326 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1327 gtk_label_new (txt), FALSE, FALSE, 0);
1328 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1331 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1332 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1333 // modest_platform_connect_and_wait ();;
1336 gtk_widget_destroy (dialog);
1337 if (g_main_depth > 0)
1338 gdk_threads_leave ();
1342 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1345 /* g_message ("%s %s", __FUNCTION__, link); */
1350 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1353 modest_platform_activate_uri (link);
1357 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1360 modest_platform_show_uri_popup (link);
1364 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1367 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1371 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1372 const gchar *address,
1375 /* g_message ("%s %s", __FUNCTION__, address); */
1379 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1381 TnyTransportAccount *transport_account;
1382 ModestMailOperation *mail_operation;
1384 gchar *account_name, *from;
1385 ModestAccountMgr *account_mgr;
1387 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1389 data = modest_msg_edit_window_get_msg_data (edit_window);
1391 account_mgr = modest_runtime_get_account_mgr();
1392 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1394 account_name = modest_account_mgr_get_default_account (account_mgr);
1395 if (!account_name) {
1396 g_printerr ("modest: no account found\n");
1397 modest_msg_edit_window_free_msg_data (edit_window, data);
1401 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1402 account_name = g_strdup (data->account_name);
1406 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1407 (modest_runtime_get_account_store(),
1409 TNY_ACCOUNT_TYPE_TRANSPORT));
1410 if (!transport_account) {
1411 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1412 g_free (account_name);
1413 modest_msg_edit_window_free_msg_data (edit_window, data);
1416 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1418 /* Create the mail operation */
1419 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1420 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1422 modest_mail_operation_save_to_drafts (mail_operation,
1433 data->priority_flags);
1436 g_free (account_name);
1437 g_object_unref (G_OBJECT (transport_account));
1438 g_object_unref (G_OBJECT (mail_operation));
1440 modest_msg_edit_window_free_msg_data (edit_window, data);
1442 /* Save settings and close the window */
1443 gtk_widget_destroy (GTK_WIDGET (edit_window));
1446 /* For instance, when clicking the Send toolbar button when editing a message: */
1448 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1450 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1452 if (!modest_msg_edit_window_check_names (edit_window))
1455 /* FIXME: Code added just for testing. The final version will
1456 use the send queue provided by tinymail and some
1458 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1459 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1461 account_name = modest_account_mgr_get_default_account (account_mgr);
1463 if (!account_name) {
1464 g_printerr ("modest: no account found\n");
1468 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1470 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1471 account_name = g_strdup (data->account_name);
1474 /* Get the currently-active transport account for this modest account: */
1475 TnyTransportAccount *transport_account =
1476 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1477 (modest_runtime_get_account_store(),
1479 if (!transport_account) {
1480 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1481 g_free (account_name);
1482 modest_msg_edit_window_free_msg_data (edit_window, data);
1486 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1488 /* mail content checks and dialogs */
1489 if (data->subject == NULL || data->subject[0] == '\0') {
1490 GtkResponseType response;
1491 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1492 _("mcen_nc_subject_is_empty_send"));
1493 if (response == GTK_RESPONSE_CANCEL) {
1494 g_free (account_name);
1499 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
1500 GtkResponseType response;
1501 gchar *note_message;
1502 gchar *note_subject = data->subject;
1503 if (note_subject == NULL || note_subject[0] == '\0')
1504 note_subject = _("mail_va_no_subject");
1505 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
1506 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1508 g_free (note_message);
1509 if (response == GTK_RESPONSE_CANCEL) {
1510 g_free (account_name);
1515 /* Create the mail operation */
1516 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1517 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1519 modest_mail_operation_send_new_mail (mail_operation,
1530 data->priority_flags);
1534 g_free (account_name);
1535 g_object_unref (G_OBJECT (transport_account));
1536 g_object_unref (G_OBJECT (mail_operation));
1538 modest_msg_edit_window_free_msg_data (edit_window, data);
1540 /* Save settings and close the window: */
1541 gtk_widget_destroy (GTK_WIDGET (edit_window));
1545 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1546 ModestMsgEditWindow *window)
1548 ModestMsgEditFormatState *format_state = NULL;
1550 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1551 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1553 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1556 format_state = modest_msg_edit_window_get_format_state (window);
1557 g_return_if_fail (format_state != NULL);
1559 format_state->bold = gtk_toggle_action_get_active (action);
1560 modest_msg_edit_window_set_format_state (window, format_state);
1561 g_free (format_state);
1566 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1567 ModestMsgEditWindow *window)
1569 ModestMsgEditFormatState *format_state = NULL;
1571 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1572 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1574 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1577 format_state = modest_msg_edit_window_get_format_state (window);
1578 g_return_if_fail (format_state != NULL);
1580 format_state->italics = gtk_toggle_action_get_active (action);
1581 modest_msg_edit_window_set_format_state (window, format_state);
1582 g_free (format_state);
1587 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1588 ModestMsgEditWindow *window)
1590 ModestMsgEditFormatState *format_state = NULL;
1592 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1593 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1595 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1598 format_state = modest_msg_edit_window_get_format_state (window);
1599 g_return_if_fail (format_state != NULL);
1601 format_state->bullet = gtk_toggle_action_get_active (action);
1602 modest_msg_edit_window_set_format_state (window, format_state);
1603 g_free (format_state);
1608 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1609 GtkRadioAction *selected,
1610 ModestMsgEditWindow *window)
1612 ModestMsgEditFormatState *format_state = NULL;
1613 GtkJustification value;
1615 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1617 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1620 value = gtk_radio_action_get_current_value (selected);
1622 format_state = modest_msg_edit_window_get_format_state (window);
1623 g_return_if_fail (format_state != NULL);
1625 format_state->justification = value;
1626 modest_msg_edit_window_set_format_state (window, format_state);
1627 g_free (format_state);
1631 modest_ui_actions_on_select_editor_color (GtkAction *action,
1632 ModestMsgEditWindow *window)
1634 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1635 g_return_if_fail (GTK_IS_ACTION (action));
1637 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1640 modest_msg_edit_window_select_color (window);
1644 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1645 ModestMsgEditWindow *window)
1647 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1648 g_return_if_fail (GTK_IS_ACTION (action));
1650 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1653 modest_msg_edit_window_select_background_color (window);
1657 modest_ui_actions_on_insert_image (GtkAction *action,
1658 ModestMsgEditWindow *window)
1660 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1661 g_return_if_fail (GTK_IS_ACTION (action));
1663 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1666 modest_msg_edit_window_insert_image (window);
1670 modest_ui_actions_on_attach_file (GtkAction *action,
1671 ModestMsgEditWindow *window)
1673 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1674 g_return_if_fail (GTK_IS_ACTION (action));
1676 modest_msg_edit_window_attach_file (window);
1680 modest_ui_actions_on_remove_attachments (GtkAction *action,
1681 ModestMsgEditWindow *window)
1683 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1684 g_return_if_fail (GTK_IS_ACTION (action));
1686 modest_msg_edit_window_remove_attachments (window, NULL);
1690 * Shows a dialog with an entry that asks for some text. The returned
1691 * value must be freed by the caller. The dialog window title will be
1695 ask_for_folder_name (GtkWindow *parent_window,
1698 GtkWidget *dialog, *entry;
1699 gchar *folder_name = NULL;
1701 /* Ask for folder name */
1702 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1706 GTK_RESPONSE_REJECT,
1708 GTK_RESPONSE_ACCEPT,
1710 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1711 gtk_label_new(title),
1714 entry = gtk_entry_new_with_max_length (40);
1715 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1719 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1721 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1722 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1724 gtk_widget_destroy (dialog);
1730 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1732 TnyFolderStore *parent_folder;
1733 GtkWidget *folder_view;
1735 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1737 folder_view = modest_main_window_get_child_widget (main_window,
1738 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1742 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1744 if (parent_folder) {
1745 gboolean finished = FALSE;
1747 gchar *folder_name = NULL, *suggested_name = NULL;
1749 /* Run the new folder dialog */
1751 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1756 if (result == GTK_RESPONSE_REJECT) {
1759 ModestMailOperation *mail_op;
1760 TnyFolder *new_folder = NULL;
1762 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO,
1763 G_OBJECT(main_window));
1764 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1766 new_folder = modest_mail_operation_create_folder (mail_op,
1768 (const gchar *) folder_name);
1770 g_object_unref (new_folder);
1773 g_object_unref (mail_op);
1775 g_free (folder_name);
1779 g_object_unref (parent_folder);
1784 modest_ui_actions_on_rename_folder (GtkAction *action,
1785 ModestMainWindow *main_window)
1787 TnyFolderStore *folder;
1788 GtkWidget *folder_view;
1789 GtkWidget *header_view;
1791 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1793 folder_view = modest_main_window_get_child_widget (main_window,
1794 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1798 header_view = modest_main_window_get_child_widget (main_window,
1799 MODEST_WIDGET_TYPE_HEADER_VIEW);
1804 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1806 if (folder && TNY_IS_FOLDER (folder)) {
1808 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1809 _("Please enter a new name for the folder"));
1811 if (folder_name != NULL && strlen (folder_name) > 0) {
1812 ModestMailOperation *mail_op;
1814 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(main_window));
1815 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1818 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
1820 modest_mail_operation_rename_folder (mail_op,
1821 TNY_FOLDER (folder),
1822 (const gchar *) folder_name);
1824 g_object_unref (mail_op);
1825 g_free (folder_name);
1827 g_object_unref (folder);
1832 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
1835 GObject *win = modest_mail_operation_get_source (mail_op);
1837 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1838 _("mail_in_ui_folder_delete_error"));
1842 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1844 TnyFolderStore *folder;
1845 GtkWidget *folder_view;
1849 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1851 folder_view = modest_main_window_get_child_widget (main_window,
1852 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1856 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1858 /* Show an error if it's an account */
1859 if (!TNY_IS_FOLDER (folder)) {
1860 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1861 _("mail_in_ui_folder_delete_error"));
1866 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
1867 tny_folder_get_name (TNY_FOLDER (folder)));
1868 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
1869 (const gchar *) message);
1872 if (response == GTK_RESPONSE_OK) {
1873 ModestMailOperation *mail_op =
1874 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
1875 G_OBJECT(main_window),
1876 modest_ui_actions_delete_folder_error_handler,
1879 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1881 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1882 g_object_unref (G_OBJECT (mail_op));
1885 g_object_unref (G_OBJECT (folder));
1889 modest_ui_actions_on_delete_folder (GtkAction *action,
1890 ModestMainWindow *main_window)
1892 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1894 delete_folder (main_window, FALSE);
1898 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1900 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1902 delete_folder (main_window, TRUE);
1906 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1907 const gchar* server_account_name,
1912 ModestMainWindow *main_window)
1914 g_return_if_fail(server_account_name);
1915 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
1917 /* Initalize output parameters: */
1924 #ifdef MODEST_PLATFORM_MAEMO
1925 /* Maemo uses a different (awkward) button order,
1926 * It should probably just use gtk_alternative_dialog_button_order ().
1928 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1932 GTK_RESPONSE_ACCEPT,
1934 GTK_RESPONSE_REJECT,
1937 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
1941 GTK_RESPONSE_REJECT,
1943 GTK_RESPONSE_ACCEPT,
1945 #endif /* MODEST_PLATFORM_MAEMO */
1947 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1949 gchar *server_name = modest_server_account_get_hostname (
1950 modest_runtime_get_account_mgr(), server_account_name);
1951 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
1952 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
1957 /* This causes a warning because the logical ID has no %s in it,
1958 * though the translation does, but there is not much we can do about that: */
1959 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
1960 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1963 g_free (server_name);
1967 gchar *initial_username = modest_server_account_get_username (
1968 modest_runtime_get_account_mgr(), server_account_name);
1970 GtkWidget *entry_username = gtk_entry_new ();
1971 if (initial_username)
1972 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
1973 /* Dim this if a connection has ever succeeded with this username,
1974 * as per the UI spec: */
1975 const gboolean username_known =
1976 modest_server_account_get_username_has_succeeded(
1977 modest_runtime_get_account_mgr(), server_account_name);
1978 gtk_widget_set_sensitive (entry_username, !username_known);
1980 #ifdef MODEST_PLATFORM_MAEMO
1981 /* Auto-capitalization is the default, so let's turn it off: */
1982 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
1984 /* Create a size group to be used by all captions.
1985 * Note that HildonCaption does not create a default size group if we do not specify one.
1986 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
1987 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
1989 GtkWidget *caption = hildon_caption_new (sizegroup,
1990 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
1991 gtk_widget_show (entry_username);
1992 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
1993 FALSE, FALSE, MODEST_MARGIN_HALF);
1994 gtk_widget_show (caption);
1996 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
1998 #endif /* MODEST_PLATFORM_MAEMO */
2001 GtkWidget *entry_password = gtk_entry_new ();
2002 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2003 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2005 #ifdef MODEST_PLATFORM_MAEMO
2006 /* Auto-capitalization is the default, so let's turn it off: */
2007 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2008 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2010 caption = hildon_caption_new (sizegroup,
2011 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2012 gtk_widget_show (entry_password);
2013 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2014 FALSE, FALSE, MODEST_MARGIN_HALF);
2015 gtk_widget_show (caption);
2016 g_object_unref (sizegroup);
2018 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2020 #endif /* MODEST_PLATFORM_MAEMO */
2022 /* This is not in the Maemo UI spec:
2023 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2024 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2028 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2030 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2032 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2034 modest_server_account_set_username (
2035 modest_runtime_get_account_mgr(), server_account_name,
2038 const gboolean username_was_changed =
2039 (strcmp (*username, initial_username) != 0);
2040 if (username_was_changed) {
2041 /* To actually use a changed username,
2042 * we must reset the connection, according to pvanhoof.
2043 * This _might_ be a sensible way to do that: */
2044 TnyDevice *device = modest_runtime_get_device();
2045 tny_device_force_offline (device);
2046 tny_device_force_online (device);
2051 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2053 /* We do not save the password in the configuration,
2054 * because this function is only called for passwords that should
2055 * not be remembered:
2056 modest_server_account_set_password (
2057 modest_runtime_get_account_mgr(), server_account_name,
2076 /* This is not in the Maemo UI spec:
2077 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2083 gtk_widget_destroy (dialog);
2085 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2089 modest_ui_actions_on_cut (GtkAction *action,
2090 ModestWindow *window)
2092 GtkWidget *focused_widget;
2094 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2095 if (GTK_IS_EDITABLE (focused_widget)) {
2096 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2097 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2098 GtkTextBuffer *buffer;
2099 GtkClipboard *clipboard;
2101 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2102 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2103 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2108 modest_ui_actions_on_copy (GtkAction *action,
2109 ModestWindow *window)
2111 GtkClipboard *clipboard;
2112 GtkWidget *focused_widget;
2114 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2115 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2116 if (GTK_IS_LABEL (focused_widget)) {
2117 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2118 } else if (GTK_IS_EDITABLE (focused_widget)) {
2119 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2120 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2121 GtkTextBuffer *buffer;
2123 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2124 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2129 modest_ui_actions_on_undo (GtkAction *action,
2130 ModestWindow *window)
2132 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2133 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2135 g_return_if_reached ();
2140 modest_ui_actions_on_paste (GtkAction *action,
2141 ModestWindow *window)
2143 GtkWidget *focused_widget;
2145 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2146 if (GTK_IS_EDITABLE (focused_widget)) {
2147 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2148 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2149 GtkTextBuffer *buffer;
2150 GtkClipboard *clipboard;
2152 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2153 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2154 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2159 modest_ui_actions_on_select_all (GtkAction *action,
2160 ModestWindow *window)
2162 GtkWidget *focused_widget;
2164 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2165 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2166 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2167 } else if (GTK_IS_LABEL (focused_widget)) {
2168 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2169 } else if (GTK_IS_EDITABLE (focused_widget)) {
2170 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2171 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2172 GtkTextBuffer *buffer;
2173 GtkTextIter start, end;
2175 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2176 gtk_text_buffer_get_start_iter (buffer, &start);
2177 gtk_text_buffer_get_end_iter (buffer, &end);
2178 gtk_text_buffer_select_range (buffer, &start, &end);
2180 else if ((MODEST_IS_FOLDER_VIEW (focused_widget)) ||
2181 (MODEST_IS_HEADER_VIEW (focused_widget))) {
2183 GtkTreeSelection *selection = NULL;
2185 /* Get header view */
2186 GtkWidget *header_view = focused_widget;
2187 if (MODEST_IS_FOLDER_VIEW (focused_widget))
2188 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2189 MODEST_WIDGET_TYPE_HEADER_VIEW);
2191 /* Select all messages */
2192 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2193 gtk_tree_selection_select_all (selection);
2198 modest_ui_actions_on_mark_as_read (GtkAction *action,
2199 ModestWindow *window)
2201 g_return_if_fail (MODEST_IS_WINDOW(window));
2203 /* Mark each header as read */
2204 do_headers_action (window, headers_action_mark_as_read, NULL);
2208 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2209 ModestWindow *window)
2211 g_return_if_fail (MODEST_IS_WINDOW(window));
2213 /* Mark each header as read */
2214 do_headers_action (window, headers_action_mark_as_unread, NULL);
2218 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2219 GtkRadioAction *selected,
2220 ModestWindow *window)
2224 value = gtk_radio_action_get_current_value (selected);
2225 if (MODEST_IS_WINDOW (window)) {
2226 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2230 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2231 GtkRadioAction *selected,
2232 ModestWindow *window)
2234 TnyHeaderFlags flags;
2235 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2237 flags = gtk_radio_action_get_current_value (selected);
2238 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2241 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2242 GtkRadioAction *selected,
2243 ModestWindow *window)
2247 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2249 file_format = gtk_radio_action_get_current_value (selected);
2250 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2255 modest_ui_actions_on_zoom_plus (GtkAction *action,
2256 ModestWindow *window)
2258 g_return_if_fail (MODEST_IS_WINDOW (window));
2260 modest_window_zoom_plus (MODEST_WINDOW (window));
2264 modest_ui_actions_on_zoom_minus (GtkAction *action,
2265 ModestWindow *window)
2267 g_return_if_fail (MODEST_IS_WINDOW (window));
2269 modest_window_zoom_minus (MODEST_WINDOW (window));
2273 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2274 ModestWindow *window)
2276 ModestWindowMgr *mgr;
2277 gboolean fullscreen, active;
2278 g_return_if_fail (MODEST_IS_WINDOW (window));
2280 mgr = modest_runtime_get_window_mgr ();
2282 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2283 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2285 if (active != fullscreen) {
2286 modest_window_mgr_set_fullscreen_mode (mgr, active);
2287 gtk_window_present (GTK_WINDOW (window));
2292 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2293 ModestWindow *window)
2295 ModestWindowMgr *mgr;
2296 gboolean fullscreen;
2298 g_return_if_fail (MODEST_IS_WINDOW (window));
2300 mgr = modest_runtime_get_window_mgr ();
2301 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2302 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2304 gtk_window_present (GTK_WINDOW (window));
2308 * Used by modest_ui_actions_on_details to call do_headers_action
2311 headers_action_show_details (TnyHeader *header,
2312 ModestWindow *window,
2319 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2322 gtk_widget_show_all (dialog);
2323 gtk_dialog_run (GTK_DIALOG (dialog));
2325 gtk_widget_destroy (dialog);
2329 * Show the folder details in a ModestDetailsDialog widget
2332 show_folder_details (TnyFolder *folder,
2338 dialog = modest_details_dialog_new_with_folder (window, folder);
2341 gtk_widget_show_all (dialog);
2342 gtk_dialog_run (GTK_DIALOG (dialog));
2344 gtk_widget_destroy (dialog);
2348 * Show the header details in a ModestDetailsDialog widget
2351 modest_ui_actions_on_details (GtkAction *action,
2354 TnyList * headers_list;
2358 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2361 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2364 g_object_unref (msg);
2366 headers_list = get_selected_headers (win);
2370 iter = tny_list_create_iterator (headers_list);
2372 header = TNY_HEADER (tny_iterator_get_current (iter));
2373 headers_action_show_details (header, win, NULL);
2374 g_object_unref (header);
2376 g_object_unref (iter);
2377 g_object_unref (headers_list);
2379 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2380 GtkWidget *folder_view, *header_view;
2382 /* Check which widget has the focus */
2383 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2384 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2385 if (gtk_widget_is_focus (folder_view)) {
2388 folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2390 /* Show only when it's a folder */
2391 if (!folder || !TNY_IS_FOLDER (folder))
2394 show_folder_details (folder, GTK_WINDOW (win));
2397 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2398 MODEST_WIDGET_TYPE_HEADER_VIEW);
2399 /* Show details of each header */
2400 do_headers_action (win, headers_action_show_details, header_view);
2406 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2407 ModestMsgEditWindow *window)
2409 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2411 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2415 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2416 ModestMsgEditWindow *window)
2418 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2420 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2424 modest_ui_actions_toggle_folders_view (GtkAction *action,
2425 ModestMainWindow *main_window)
2429 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2431 conf = modest_runtime_get_conf ();
2433 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2434 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2436 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2440 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2441 ModestWindow *window)
2443 gboolean active, fullscreen = FALSE;
2444 ModestWindowMgr *mgr;
2446 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2448 /* Check if we want to toggle the toolbar vuew in fullscreen
2450 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2451 "ViewShowToolbarFullScreen")) {
2455 /* Toggle toolbar */
2456 mgr = modest_runtime_get_window_mgr ();
2457 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2461 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2462 ModestMsgEditWindow *window)
2464 modest_msg_edit_window_select_font (window);
2468 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2469 const gchar *display_name,
2472 /* Do not change the application name if the widget has not
2473 the focus. This callback could be called even if the folder
2474 view has not the focus, because the handled signal could be
2475 emitted when the folder view is redrawn */
2476 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2478 gtk_window_set_title (window, display_name);
2480 gtk_window_set_title (window, " ");
2485 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2487 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2488 modest_msg_edit_window_select_contacts (window);
2492 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2494 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2495 modest_msg_edit_window_check_names (window);
2500 create_move_to_dialog (ModestWindow *win,
2501 GtkWidget *folder_view,
2502 GtkWidget **tree_view)
2504 GtkWidget *dialog, *scroll;
2506 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2508 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2510 GTK_RESPONSE_ACCEPT,
2512 GTK_RESPONSE_REJECT,
2515 /* Create scrolled window */
2516 scroll = gtk_scrolled_window_new (NULL, NULL);
2517 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2518 GTK_POLICY_AUTOMATIC,
2519 GTK_POLICY_AUTOMATIC);
2521 /* Create folder view */
2522 *tree_view = modest_folder_view_new (NULL);
2524 /* It could happen that we're trying to move a message from a
2525 window (msg window for example) after the main window was
2526 closed, so we can not just get the model of the folder
2528 if (MODEST_IS_FOLDER_VIEW (folder_view))
2529 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2530 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2532 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
2533 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
2535 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2537 /* Add scroll to dialog */
2538 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2539 scroll, FALSE, FALSE, 0);
2541 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2547 * Returns TRUE if at least one of the headers of the list belongs to
2548 * a message that has been fully retrieved.
2551 has_retrieved_msgs (TnyList *list)
2554 gboolean found = FALSE;
2556 iter = tny_list_create_iterator (list);
2557 while (tny_iterator_is_done (iter) && !found) {
2559 TnyHeaderFlags flags;
2561 header = TNY_HEADER (tny_iterator_get_current (iter));
2562 flags = tny_header_get_flags (header);
2563 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2567 tny_iterator_next (iter);
2569 g_object_unref (iter);
2575 * Shows a confirmation dialog to the user when we're moving messages
2576 * from a remote server to the local storage. Returns the dialog
2577 * response. If it's other kind of movement the it always returns
2581 msgs_move_to_confirmation (GtkWindow *win,
2582 TnyFolder *dest_folder,
2585 gint response = GTK_RESPONSE_OK;
2587 /* If the destination is a local folder */
2588 if (modest_tny_folder_is_local_folder (dest_folder)) {
2589 TnyFolder *src_folder;
2593 /* Get source folder */
2594 iter = tny_list_create_iterator (headers);
2595 header = TNY_HEADER (tny_iterator_get_current (iter));
2596 src_folder = tny_header_get_folder (header);
2597 g_object_unref (header);
2598 g_object_unref (iter);
2600 /* If the source is a remote folder */
2601 if (!modest_tny_folder_is_local_folder (src_folder)) {
2602 const gchar *message;
2604 if (tny_list_get_length (headers) == 1)
2605 if (has_retrieved_msgs (headers))
2606 message = _("mcen_nc_move_retrieve");
2608 message = _("mcen_nc_move_header");
2610 if (has_retrieved_msgs (headers))
2611 message = _("mcen_nc_move_retrieves");
2613 message = _("mcen_nc_move_headers");
2615 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2616 (const gchar *) message);
2618 g_object_unref (src_folder);
2625 tranasfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
2627 ModestMsgViewWindow *self = NULL;
2628 gboolean found = FALSE;
2630 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
2631 self = MODEST_MSG_VIEW_WINDOW (object);
2633 found = modest_msg_view_window_select_first_message (self);
2634 g_return_if_fail (found);
2638 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
2641 GObject *win = modest_mail_operation_get_source (mail_op);
2643 /* TODO: show error message */
2644 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2645 _("mail_in_ui_folder_move_target_error"));
2649 * UI handler for the "Move to" action when invoked from the
2653 modest_ui_actions_on_main_window_move_to (GtkAction *action,
2654 ModestMainWindow *win)
2656 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
2657 GtkWidget *header_view = NULL;
2659 TnyFolderStore *folder_store = NULL;
2660 ModestMailOperation *mail_op = NULL;
2662 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2664 /* Get the folder view */
2665 folder_view = modest_main_window_get_child_widget (win,
2666 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2668 /* Get header view */
2669 header_view = modest_main_window_get_child_widget (win,
2670 MODEST_WIDGET_TYPE_HEADER_VIEW);
2672 /* Create and run the dialog */
2673 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2674 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
2675 result = gtk_dialog_run (GTK_DIALOG(dialog));
2676 g_object_ref (tree_view);
2678 /* We do this to save an indentation level ;-) */
2679 if (result != GTK_RESPONSE_ACCEPT)
2682 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2684 if (TNY_IS_ACCOUNT (folder_store))
2687 /* Get folder or messages to transfer */
2688 if (gtk_widget_is_focus (folder_view)) {
2689 TnyFolderStore *src_folder;
2690 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2692 /* Clean folder on header view before moving it */
2693 modest_header_view_set_folder (MODEST_HEADER_VIEW (header_view), NULL);
2695 if (TNY_IS_FOLDER (src_folder)) {
2697 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2699 modest_ui_actions_move_folder_error_handler,
2701 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2703 modest_mail_operation_xfer_folder (mail_op,
2704 TNY_FOLDER (src_folder),
2707 /* Unref mail operation */
2708 g_object_unref (G_OBJECT (mail_op));
2712 g_object_unref (G_OBJECT (src_folder));
2714 if (gtk_widget_is_focus (header_view)) {
2718 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2720 /* Ask for user confirmation */
2721 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2722 TNY_FOLDER (folder_store),
2725 /* Transfer messages */
2726 if (response == GTK_RESPONSE_OK) {
2727 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2728 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2731 modest_mail_operation_xfer_msgs (mail_op,
2733 TNY_FOLDER (folder_store),
2738 g_object_unref (G_OBJECT (mail_op));
2740 g_object_unref (headers);
2743 g_object_unref (folder_store);
2745 gtk_widget_destroy (dialog);
2750 * UI handler for the "Move to" action when invoked from the
2751 * ModestMsgViewWindow
2754 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
2755 ModestMsgViewWindow *win)
2757 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2759 ModestMainWindow *main_window;
2763 /* Get the folder view */
2764 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2766 folder_view = modest_main_window_get_child_widget (main_window,
2767 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2771 /* Create and run the dialog */
2772 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2773 result = gtk_dialog_run (GTK_DIALOG(dialog));
2774 g_object_ref (tree_view);
2776 if (result == GTK_RESPONSE_ACCEPT) {
2777 TnyFolderStore *folder_store;
2780 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2782 /* Create header list */
2783 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
2784 headers = tny_simple_list_new ();
2785 tny_list_prepend (headers, G_OBJECT (header));
2786 g_object_unref (header);
2788 /* Ask user for confirmation. MSG-NOT404 */
2789 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2790 TNY_FOLDER (folder_store),
2793 /* Transfer current msg */
2794 if (response == GTK_RESPONSE_OK) {
2795 ModestMailOperation *mail_op;
2797 /* Create mail op */
2798 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
2799 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2802 /* Transfer messages */
2803 modest_mail_operation_xfer_msgs (mail_op,
2805 TNY_FOLDER (folder_store),
2807 tranasfer_msgs_from_viewer_cb,
2809 g_object_unref (G_OBJECT (mail_op));
2811 g_object_unref (headers);
2812 g_object_unref (folder_store);
2814 gtk_widget_destroy (dialog);
2818 modest_ui_actions_on_move_to (GtkAction *action,
2821 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
2822 MODEST_IS_MSG_VIEW_WINDOW (win));
2824 if (MODEST_IS_MAIN_WINDOW (win))
2825 modest_ui_actions_on_main_window_move_to (action,
2826 MODEST_MAIN_WINDOW (win));
2828 modest_ui_actions_on_msg_view_window_move_to (action,
2829 MODEST_MSG_VIEW_WINDOW (win));
2833 * Calls #HeadersFunc for each header already selected in the main
2834 * window or the message currently being shown in the msg view window
2837 do_headers_action (ModestWindow *win,
2841 TnyList *headers_list;
2845 headers_list = get_selected_headers (win);
2849 /* Call the function for each header */
2850 iter = tny_list_create_iterator (headers_list);
2851 while (!tny_iterator_is_done (iter)) {
2854 header = TNY_HEADER (tny_iterator_get_current (iter));
2855 func (header, win, user_data);
2856 g_object_unref (header);
2857 tny_iterator_next (iter);
2859 g_object_unref (iter);
2860 g_object_unref (headers_list);
2864 modest_ui_actions_view_attachment (GtkAction *action,
2865 ModestWindow *window)
2867 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2868 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
2870 /* not supported window for this action */
2871 g_return_if_reached ();
2876 modest_ui_actions_save_attachments (GtkAction *action,
2877 ModestWindow *window)
2879 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2880 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2882 /* not supported window for this action */
2883 g_return_if_reached ();
2888 modest_ui_actions_remove_attachments (GtkAction *action,
2889 ModestWindow *window)
2891 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2892 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
2894 /* not supported window for this action */
2895 g_return_if_reached ();
2900 modest_ui_actions_on_settings (GtkAction *action,
2905 dialog = modest_platform_get_global_settings_dialog ();
2906 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
2907 gtk_widget_show (dialog);
2909 gtk_dialog_run (GTK_DIALOG (dialog));
2911 gtk_widget_destroy (dialog);
2915 modest_ui_actions_on_help (GtkAction *action,
2918 const gchar *help_id = NULL;
2920 if (MODEST_IS_MAIN_WINDOW (win)) {
2921 const gchar *action_name;
2922 action_name = gtk_action_get_name (action);
2924 if (!strcmp (action_name, "FolderViewCSMHelp") ||
2925 !strcmp (action_name, "HeaderViewCSMHelp")) {
2926 GtkWidget *folder_view;
2927 TnyFolderStore *folder_store;
2928 /* Get selected folder */
2929 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2930 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2931 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2933 /* Switch help_id */
2934 if (TNY_IS_FOLDER (folder_store)) {
2935 switch (tny_folder_get_folder_type (TNY_FOLDER (folder_store))) {
2936 case TNY_FOLDER_TYPE_NORMAL:
2937 help_id = "applications_email_userfolder";
2939 case TNY_FOLDER_TYPE_INBOX:
2940 help_id = "applications_email_inbox";
2942 case TNY_FOLDER_TYPE_OUTBOX:
2943 help_id = "applications_email_outbox";
2945 case TNY_FOLDER_TYPE_SENT:
2946 help_id = "applications_email_sent";
2948 case TNY_FOLDER_TYPE_DRAFTS:
2949 help_id = "applications_email_drafts";
2951 case TNY_FOLDER_TYPE_ARCHIVE:
2952 help_id = "applications_email_archive";
2959 help_id = "applications_email_mainview";
2961 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2962 help_id = "applications_email_viewer";
2963 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
2964 help_id = "applications_email_editor";
2966 modest_platform_show_help (GTK_WINDOW (win), help_id);
2970 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
2971 ModestWindow *window)
2973 ModestMailOperation *mail_op;
2977 headers = get_selected_headers (window);
2981 /* Create mail operation */
2982 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
2984 modest_ui_actions_get_msgs_full_error_handler,
2986 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2987 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
2990 g_object_unref (headers);
2991 g_object_unref (mail_op);
2995 modest_ui_actions_on_email_menu_activated (GtkAction *action,
2996 ModestWindow *window)
2998 g_return_if_fail (MODEST_IS_WINDOW (window));
3001 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3005 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
3006 ModestWindow *window)
3008 g_return_if_fail (MODEST_IS_WINDOW (window));
3011 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3015 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
3016 ModestWindow *window)
3018 g_return_if_fail (MODEST_IS_WINDOW (window));
3021 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3025 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
3026 ModestWindow *window)
3028 g_return_if_fail (MODEST_IS_WINDOW (window));
3031 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3035 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
3036 ModestWindow *window)
3038 g_return_if_fail (MODEST_IS_WINDOW (window));
3041 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3045 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
3047 g_return_if_fail (MODEST_IS_WINDOW (window));
3050 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
3054 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
3056 g_return_if_fail (MODEST_IS_WINDOW (window));
3058 modest_platform_show_search_messages (GTK_WINDOW (window));
3062 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
3064 g_return_if_fail (MODEST_IS_WINDOW (win));
3065 modest_platform_show_addressbook (GTK_WINDOW (win));
3070 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
3071 ModestWindow *window)
3073 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3075 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
3079 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
3080 ModestMailOperationState *state,
3083 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
3085 /* Set send/receive operation finished */
3086 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3087 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));