1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #endif /*HAVE_CONFIG_H*/
34 #include <glib/gi18n.h>
35 #include <glib/gprintf.h>
37 #include <modest-runtime.h>
38 #include <modest-tny-folder.h>
39 #include <modest-tny-msg.h>
40 #include <modest-tny-account.h>
41 #include <modest-address-book.h>
42 #include "modest-error.h"
43 #include "modest-ui-actions.h"
45 #include "modest-tny-platform-factory.h"
46 #include "modest-platform.h"
47 #include <tny-mime-part.h>
49 #ifdef MODEST_PLATFORM_MAEMO
50 #include "maemo/modest-osso-state-saving.h"
51 #endif /* MODEST_PLATFORM_MAEMO */
53 #include "widgets/modest-ui-constants.h"
54 #include <widgets/modest-main-window.h>
55 #include <widgets/modest-msg-view-window.h>
56 #include <widgets/modest-account-view-window.h>
57 #include <widgets/modest-details-dialog.h>
58 #include <widgets/modest-attachments-view.h>
59 #include "widgets/modest-folder-view.h"
60 #include "widgets/modest-global-settings-dialog.h"
61 #include "modest-connection-specific-smtp-window.h"
62 #include "modest-account-mgr-helpers.h"
63 #include "modest-mail-operation.h"
64 #include "modest-text-utils.h"
66 #ifdef MODEST_HAVE_EASYSETUP
67 #include "easysetup/modest-easysetup-wizard.h"
68 #endif /* MODEST_HAVE_EASYSETUP */
70 #include <modest-widget-memory.h>
71 #include <tny-error.h>
72 #include <tny-simple-list.h>
73 #include <tny-msg-view.h>
74 #include <tny-device.h>
75 #include <tny-merge-folder.h>
77 #include <gtkhtml/gtkhtml.h>
79 typedef struct _GetMsgAsyncHelper {
81 ModestMailOperation *mail_op;
88 typedef enum _ReplyForwardAction {
94 typedef struct _ReplyForwardHelper {
95 guint reply_forward_type;
96 ReplyForwardAction action;
98 GtkWidget *parent_window;
103 * The do_headers_action uses this kind of functions to perform some
104 * action to each member of a list of headers
106 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
108 static void do_headers_action (ModestWindow *win,
112 static void open_msg_cb (ModestMailOperation *mail_op,
117 static void reply_forward_cb (ModestMailOperation *mail_op,
122 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
125 static void _on_send_receive_progress_changed (ModestMailOperation *mail_op,
126 ModestMailOperationState *state,
132 run_account_setup_wizard (ModestWindow *win)
134 ModestEasysetupWizardDialog *wizard;
136 g_return_if_fail (MODEST_IS_WINDOW(win));
138 wizard = modest_easysetup_wizard_dialog_new ();
139 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
140 gtk_dialog_run (GTK_DIALOG (wizard));
141 gtk_widget_destroy (GTK_WIDGET (wizard));
146 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
149 const gchar *authors[] = {
150 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
153 about = gtk_about_dialog_new ();
154 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
155 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
156 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
157 _("Copyright (c) 2006, Nokia Corporation\n"
158 "All rights reserved."));
159 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
160 _("a modest e-mail client\n\n"
161 "design and implementation: Dirk-Jan C. Binnema\n"
162 "contributions from the fine people at KC and Ig\n"
163 "uses the tinymail email framework written by Philip van Hoof"));
164 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
165 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
167 gtk_dialog_run (GTK_DIALOG (about));
168 gtk_widget_destroy(about);
172 * Gets the list of currently selected messages. If the win is the
173 * main window, then it returns a newly allocated list of the headers
174 * selected in the header view. If win is the msg view window, then
175 * the value returned is a list with just a single header.
177 * The caller of this funcion must free the list.
180 get_selected_headers (ModestWindow *win)
182 if (MODEST_IS_MAIN_WINDOW(win)) {
183 GtkWidget *header_view;
185 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
186 MODEST_WIDGET_TYPE_HEADER_VIEW);
187 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
189 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
190 /* for MsgViewWindows, we simply return a list with one element */
192 TnyList *list = NULL;
194 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
195 if (header != NULL) {
196 list = tny_simple_list_new ();
197 tny_list_prepend (list, G_OBJECT(header));
198 g_object_unref (G_OBJECT(header));
208 headers_action_mark_as_read (TnyHeader *header,
212 TnyHeaderFlags flags;
214 g_return_if_fail (TNY_IS_HEADER(header));
216 flags = tny_header_get_flags (header);
217 if (flags & TNY_HEADER_FLAG_SEEN) return;
218 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
222 headers_action_mark_as_unread (TnyHeader *header,
226 TnyHeaderFlags flags;
228 g_return_if_fail (TNY_IS_HEADER(header));
230 flags = tny_header_get_flags (header);
231 if (flags & TNY_HEADER_FLAG_SEEN) {
232 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
238 headers_action_delete (TnyHeader *header,
242 ModestMailOperation *mail_op = NULL;
244 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE, G_OBJECT(win));
245 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
248 /* Always delete. TODO: Move to trash still not supported */
249 modest_mail_operation_remove_msg (mail_op, header, FALSE);
250 g_object_unref (G_OBJECT (mail_op));
252 /* refilter treemodel to hide marked-as-deleted rows */
253 if (MODEST_IS_HEADER_VIEW (user_data))
254 modest_header_view_refilter (MODEST_HEADER_VIEW (user_data));
258 modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
260 TnyList *header_list = NULL;
261 TnyIterator *iter = NULL;
262 TnyHeader *header = NULL;
263 gchar *message = NULL;
266 ModestWindowMgr *mgr;
267 GtkWidget *header_view = NULL;
269 g_return_if_fail (MODEST_IS_WINDOW(win));
271 /* Check first if the header view has the focus */
272 if (MODEST_IS_MAIN_WINDOW (win)) {
274 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
275 MODEST_WIDGET_TYPE_HEADER_VIEW);
276 if (!gtk_widget_is_focus (header_view))
280 header_list = get_selected_headers (win);
281 if (!header_list) return;
283 /* Check if any of the headers is already opened, or in the process of being opened */
284 if (MODEST_IS_MAIN_WINDOW (win)) {
286 iter = tny_list_create_iterator (header_list);
288 mgr = modest_runtime_get_window_mgr ();
289 while (!tny_iterator_is_done (iter) && !found) {
290 header = TNY_HEADER (tny_iterator_get_current (iter));
291 found = modest_window_mgr_find_registered_header (mgr, header, NULL);
292 g_object_unref (header);
293 tny_iterator_next (iter);
295 g_object_unref (iter);
300 num = g_strdup_printf ("%d", tny_list_get_length (header_list));
301 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
303 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
307 g_object_unref (header_list);
313 if (tny_list_get_length(header_list) == 1) {
314 iter = tny_list_create_iterator (header_list);
315 header = TNY_HEADER (tny_iterator_get_current (iter));
316 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
317 g_object_unref (header);
318 g_object_unref (iter);
320 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
321 tny_list_get_length(header_list)), desc);
323 /* Confirmation dialog */
324 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
328 if (response == GTK_RESPONSE_OK) {
329 ModestMainWindow *main_window;
330 ModestWindowMgr *mgr;
332 /* Remove each header. If it's a view window header_view == NULL */
333 do_headers_action (win, headers_action_delete, header_view);
335 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
336 /* Close msg view window or select next */
337 if (modest_msg_view_window_last_message_selected (MODEST_MSG_VIEW_WINDOW (win)) &&
338 modest_msg_view_window_first_message_selected (MODEST_MSG_VIEW_WINDOW (win))) {
339 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
341 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (win));
345 /* Refilter header view model, if main window still exists */
346 mgr = modest_runtime_get_window_mgr ();
347 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr));
351 widget = modest_main_window_get_child_widget (main_window,
352 MODEST_WIDGET_TYPE_HEADER_VIEW);
353 modest_header_view_refilter (MODEST_HEADER_VIEW (widget));
355 /* Update toolbar dimming state */
356 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
363 g_object_unref (header_list);
368 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
370 #ifdef MODEST_PLATFORM_MAEMO
371 modest_osso_save_state();
372 #endif /* MODEST_PLATFORM_MAEMO */
374 g_debug ("closing down, clearing %d item(s) from operation queue",
375 modest_mail_operation_queue_num_elements
376 (modest_runtime_get_mail_operation_queue()));
378 /* cancel all outstanding operations */
379 modest_mail_operation_queue_cancel_all
380 (modest_runtime_get_mail_operation_queue());
382 g_debug ("queue has been cleared");
384 /* note: when modest-tny-account-store is finalized,
385 it will automatically set all network connections
392 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
395 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
397 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
398 /* gtk_widget_destroy (GTK_WIDGET (win)); */
399 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
400 /* gboolean ret_value; */
401 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
402 /* } else if (MODEST_IS_WINDOW (win)) { */
403 /* gtk_widget_destroy (GTK_WIDGET (win)); */
405 /* g_return_if_reached (); */
410 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
412 GtkClipboard *clipboard = NULL;
413 gchar *selection = NULL;
415 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
416 selection = gtk_clipboard_wait_for_text (clipboard);
418 /* Question: why is the clipboard being used here?
419 * It doesn't really make a lot of sense. */
423 modest_address_book_add_address (selection);
429 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
431 /* This is currently only implemented for Maemo */
432 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
433 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
434 run_account_setup_wizard (win);
437 /* Show the list of accounts: */
438 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
439 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
440 gtk_dialog_run (account_win);
441 gtk_widget_destroy (GTK_WIDGET(account_win));
444 GtkWidget *dialog, *label;
446 /* Create the widgets */
448 dialog = gtk_dialog_new_with_buttons ("Message",
450 GTK_DIALOG_DESTROY_WITH_PARENT,
454 label = gtk_label_new ("Hello World!");
456 /* Ensure that the dialog box is destroyed when the user responds. */
458 g_signal_connect_swapped (dialog, "response",
459 G_CALLBACK (gtk_widget_destroy),
462 /* Add the label, and show everything we've added to the dialog. */
464 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
466 gtk_widget_show_all (dialog);
467 #endif /* MODEST_PLATFORM_MAEMO */
471 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
473 ModestWindow *main_window = MODEST_WINDOW (user_data);
475 /* Save any changes. */
476 modest_connection_specific_smtp_window_save_server_accounts (
477 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window),
478 modest_window_get_active_account (main_window));
479 gtk_widget_destroy (GTK_WIDGET (window));
485 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
487 /* This is currently only implemented for Maemo,
488 * because it requires an API (libconic) to detect different connection
491 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
493 /* Create the window if necessary: */
494 const gchar *active_account_name = modest_window_get_active_account (win);
496 /* TODO: Dim the menu item (not in the UI spec)? or show a warning,
497 * or show the default account?
498 * If we show the default account then the account name should be shown in
499 * the window when we show it. */
500 if (!active_account_name) {
501 g_warning ("%s: No account is active.", __FUNCTION__);
505 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
506 modest_connection_specific_smtp_window_fill_with_connections (
507 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
508 modest_runtime_get_account_mgr(),
509 active_account_name);
511 /* Show the window: */
512 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
513 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
514 gtk_widget_show (specific_window);
516 /* Save changes when the window is hidden: */
517 g_signal_connect (specific_window, "hide",
518 G_CALLBACK (on_smtp_servers_window_hide), win);
519 #endif /* MODEST_PLATFORM_MAEMO */
523 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
525 ModestWindow *msg_win = NULL;
527 TnyFolder *folder = NULL;
528 gchar *account_name = NULL;
529 gchar *from_str = NULL;
530 /* GError *err = NULL; */
531 TnyAccount *account = NULL;
532 ModestWindowMgr *mgr;
533 gchar *signature = NULL, *blank_and_signature = NULL;
535 /* if there are no accounts yet, just show the wizard */
536 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
537 run_account_setup_wizard (win);
541 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
543 account_name = g_strdup (modest_window_get_active_account (win));
545 g_printerr ("modest: no account found\n");
549 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
551 TNY_ACCOUNT_TYPE_STORE);
553 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
557 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
559 g_printerr ("modest: failed get from string for '%s'\n", account_name);
563 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
564 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
565 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
566 MODEST_ACCOUNT_SIGNATURE, FALSE);
567 blank_and_signature = g_strconcat ("\n", signature, NULL);
570 blank_and_signature = g_strdup ("");
573 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
575 g_printerr ("modest: failed to create new msg\n");
579 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
581 g_printerr ("modest: failed to find Drafts folder\n");
586 /* Create and register edit window */
587 /* This is destroyed by TOOD. */
588 msg_win = modest_msg_edit_window_new (msg, account_name);
589 mgr = modest_runtime_get_window_mgr ();
590 modest_window_mgr_register_window (mgr, msg_win);
593 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
595 gtk_widget_show_all (GTK_WIDGET (msg_win));
598 g_free (account_name);
600 g_free (blank_and_signature);
602 g_object_unref (msg_win);
604 g_object_unref (G_OBJECT(account));
606 g_object_unref (G_OBJECT(msg));
608 g_object_unref (G_OBJECT(folder));
612 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
616 ModestMailOperationStatus status;
618 /* If there is no message or the operation was not successful */
619 status = modest_mail_operation_get_status (mail_op);
620 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
622 /* Remove the header from the preregistered uids */
623 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
633 open_msg_cb (ModestMailOperation *mail_op,
638 ModestWindowMgr *mgr = NULL;
639 ModestWindow *parent_win = NULL;
640 ModestWindow *win = NULL;
641 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
642 gchar *account = NULL;
645 /* Do nothing if there was any problem with the mail
646 operation. The error will be shown by the error_handler of
647 the mail operation */
648 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
649 printf ("DEBUG: %s: modest_ui_actions_msg_retrieval_check() failed.\n",
654 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
655 folder = tny_header_get_folder (header);
657 /* Mark header as read */
658 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
661 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
663 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
665 /* Gets folder type (OUTBOX headers will be opened in edit window */
666 if (modest_tny_folder_is_local_folder (folder))
667 folder_type = modest_tny_folder_get_local_folder_type (folder);
669 /* If the header is in the drafts folder then open the editor,
670 else the message view window */
671 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
672 /* we cannot edit without a valid account... */
673 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
674 run_account_setup_wizard(parent_win);
677 win = modest_msg_edit_window_new (msg, account);
679 gchar *uid = modest_tny_folder_get_header_unique_id (header);
681 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
682 GtkWidget *header_view;
683 GtkTreeSelection *sel;
684 GList *sel_list = NULL;
687 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
688 MODEST_WIDGET_TYPE_HEADER_VIEW);
690 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
691 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
693 if (sel_list != NULL) {
694 GtkTreeRowReference *row_reference;
696 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
697 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
698 g_list_free (sel_list);
700 win = modest_msg_view_window_new_with_header_model (msg,
705 gtk_tree_row_reference_free (row_reference);
707 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
710 win = modest_msg_view_window_new (msg, account, (const gchar*) uid);
715 /* Register and show new window */
717 mgr = modest_runtime_get_window_mgr ();
718 modest_window_mgr_register_window (mgr, win);
719 g_object_unref (win);
720 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
721 gtk_widget_show_all (GTK_WIDGET(win));
724 /* Update toolbar dimming state */
725 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
726 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
732 g_object_unref (parent_win);
733 /* g_object_unref (msg); */
734 g_object_unref (folder);
738 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
742 GObject *win = modest_mail_operation_get_source (mail_op);
744 error = modest_mail_operation_get_error (mail_op);
745 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, error->code, error->message);
747 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
749 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
752 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
753 _("mail_ni_ui_folder_get_msg_folder_error"));
757 g_object_unref (win);
761 * This function is used by both modest_ui_actions_on_open and
762 * modest_ui_actions_on_header_activated. This way we always do the
763 * same when trying to open messages.
766 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
768 ModestWindowMgr *mgr = NULL;
769 TnyIterator *iter = NULL;
770 ModestMailOperation *mail_op1 = NULL;
771 ModestMailOperation *mail_op2 = NULL;
772 TnyList *not_opened_headers = NULL;
773 TnyList *not_opened_cached_headers = NULL;
774 TnyHeaderFlags flags;
776 /* Look if we already have a message view for each header. If
777 true, then remove the header from the list of headers to
779 mgr = modest_runtime_get_window_mgr ();
780 iter = tny_list_create_iterator (headers);
781 not_opened_headers = tny_simple_list_new ();
782 not_opened_cached_headers = tny_simple_list_new ();
783 while (!tny_iterator_is_done (iter)) {
785 ModestWindow *window;
789 header = TNY_HEADER (tny_iterator_get_current (iter));
790 flags = tny_header_get_flags (header);
793 found = modest_window_mgr_find_registered_header (mgr, header, &window);
795 /* Do not open again the message and present the
796 window to the user */
799 gtk_window_present (GTK_WINDOW (window));
801 /* the header has been registered already, we don't do
802 * anything but wait for the window to come up*/
803 g_warning ("debug: header %p already registered, waiting for window",
806 if (!(flags & TNY_HEADER_FLAG_CACHED))
807 tny_list_append (not_opened_headers, G_OBJECT (header));
808 /* Check if msg has already been retreived */
810 tny_list_append (not_opened_cached_headers, G_OBJECT (header));
812 g_object_unref (header);
813 tny_iterator_next (iter);
815 g_object_unref (iter);
818 /* If some messages would have to be downloaded, ask the user to
819 * make a connection. It's generally easier to do this here (in the mainloop)
820 * than later in a thread:
822 if (tny_list_get_length (not_opened_cached_headers) > 0) {
823 gboolean connected = modest_platform_connect_and_wait (GTK_WINDOW (win));
825 /* Don't go further if a connection would be necessary but none is available: */
827 g_object_unref (not_opened_headers);
828 g_object_unref (not_opened_cached_headers);
833 /* Register the headers before actually creating the windows: */
834 TnyIterator *iter_not_opened = tny_list_create_iterator (not_opened_headers);
835 while (!tny_iterator_is_done (iter_not_opened)) {
836 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
837 modest_window_mgr_register_header (mgr, header);
838 g_object_unref (header);
840 tny_iterator_next (iter_not_opened);
842 g_object_unref (iter_not_opened);
843 iter_not_opened = NULL;
845 TnyIterator *iter_cached = tny_list_create_iterator (not_opened_cached_headers);
846 while (!tny_iterator_is_done (iter_cached)) {
847 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_cached));
848 modest_window_mgr_register_header (mgr, header);
849 g_object_unref (header);
851 tny_iterator_next (iter_cached);
853 g_object_unref (iter_cached);
857 /* Open each uncached message */
858 if (tny_list_get_length (not_opened_headers) > 0) {
859 mail_op1 = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
861 modest_ui_actions_get_msgs_full_error_handler,
863 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op1);
864 if (tny_list_get_length (not_opened_headers) > 1) {
865 modest_mail_operation_get_msgs_full (mail_op1,
871 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
872 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
873 modest_mail_operation_get_msg (mail_op1, header, open_msg_cb, NULL);
874 g_object_unref (header);
875 g_object_unref (iter);
879 /* Open each cached message */
880 if (tny_list_get_length (not_opened_cached_headers) > 0) {
881 mail_op2 = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
883 modest_ui_actions_get_msgs_full_error_handler,
885 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op2);
886 if (tny_list_get_length (not_opened_cached_headers) > 1) {
887 modest_mail_operation_get_msgs_full (mail_op2,
893 TnyIterator *iter = tny_list_create_iterator (not_opened_cached_headers);
894 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
895 modest_mail_operation_get_msg (mail_op2, header, open_msg_cb, NULL);
896 g_object_unref (header);
897 g_object_unref (iter);
902 if (not_opened_headers != NULL)
903 g_object_unref (not_opened_headers);
904 if (not_opened_cached_headers != NULL)
905 g_object_unref (not_opened_cached_headers);
907 g_object_unref (iter);
908 if (mail_op1 != NULL)
909 g_object_unref (mail_op1);
910 if (mail_op2 != NULL)
911 g_object_unref (mail_op2);
915 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
920 headers = get_selected_headers (win);
925 _modest_ui_actions_open (headers, win);
927 g_object_unref(headers);
932 free_reply_forward_helper (gpointer data)
934 ReplyForwardHelper *helper;
936 helper = (ReplyForwardHelper *) data;
937 g_free (helper->account_name);
938 g_slice_free (ReplyForwardHelper, helper);
942 reply_forward_cb (ModestMailOperation *mail_op,
948 ReplyForwardHelper *rf_helper;
949 ModestWindow *msg_win = NULL;
950 ModestEditType edit_type;
952 TnyAccount *account = NULL;
953 ModestWindowMgr *mgr = NULL;
954 gchar *signature = NULL;
956 /* If there was any error */
957 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
960 g_return_if_fail (user_data != NULL);
961 rf_helper = (ReplyForwardHelper *) user_data;
963 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
964 rf_helper->account_name);
965 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
966 rf_helper->account_name,
967 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
968 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
969 rf_helper->account_name,
970 MODEST_ACCOUNT_SIGNATURE, FALSE);
973 /* Create reply mail */
974 switch (rf_helper->action) {
977 modest_tny_msg_create_reply_msg (msg, from, signature,
978 rf_helper->reply_forward_type,
979 MODEST_TNY_MSG_REPLY_MODE_SENDER);
981 case ACTION_REPLY_TO_ALL:
983 modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type,
984 MODEST_TNY_MSG_REPLY_MODE_ALL);
985 edit_type = MODEST_EDIT_TYPE_REPLY;
989 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
990 edit_type = MODEST_EDIT_TYPE_FORWARD;
993 g_return_if_reached ();
1000 g_printerr ("modest: failed to create message\n");
1004 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1005 rf_helper->account_name,
1006 TNY_ACCOUNT_TYPE_STORE);
1008 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1012 /* Create and register the windows */
1013 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
1014 mgr = modest_runtime_get_window_mgr ();
1015 modest_window_mgr_register_window (mgr, msg_win);
1017 if (rf_helper->parent_window != NULL) {
1018 gdouble parent_zoom;
1020 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1021 modest_window_set_zoom (msg_win, parent_zoom);
1024 /* Show edit window */
1025 gtk_widget_show_all (GTK_WIDGET (msg_win));
1029 g_object_unref (msg_win);
1031 g_object_unref (G_OBJECT (new_msg));
1033 g_object_unref (G_OBJECT (account));
1034 /* g_object_unref (msg); */
1035 g_object_unref (header);
1036 free_reply_forward_helper (rf_helper);
1040 * Checks a list of headers. If any of them are not currently
1041 * downloaded (CACHED) then it asks the user for permission to
1044 * Returns FALSE if the user does not want to download the
1045 * messages. Returns TRUE if the user allowed the download or if all
1046 * of them are currently downloaded
1049 download_uncached_messages (TnyList *header_list, GtkWindow *win)
1053 gint uncached_messages = 0;
1055 iter = tny_list_create_iterator (header_list);
1056 while (!tny_iterator_is_done (iter)) {
1058 TnyHeaderFlags flags;
1060 header = TNY_HEADER (tny_iterator_get_current (iter));
1061 flags = tny_header_get_flags (header);
1062 /* TODO: is this the right flag?, it seems that some
1063 headers that have been previously downloaded do not
1065 if (! (flags & TNY_HEADER_FLAG_CACHED))
1066 uncached_messages ++;
1067 g_object_unref (header);
1068 tny_iterator_next (iter);
1070 g_object_unref (iter);
1072 /* Ask for user permission to download the messages */
1074 if (uncached_messages > 0) {
1075 GtkResponseType response;
1077 modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1078 ngettext("mcen_nc_get_msg",
1080 uncached_messages));
1081 if (response == GTK_RESPONSE_CANCEL)
1084 /* If a download will be necessary, make sure that we have a connection: */
1085 retval = modest_platform_connect_and_wait(win);
1093 * Common code for the reply and forward actions
1096 reply_forward (ReplyForwardAction action, ModestWindow *win)
1098 ModestMailOperation *mail_op = NULL;
1099 TnyList *header_list = NULL;
1100 ReplyForwardHelper *rf_helper = NULL;
1101 guint reply_forward_type;
1102 gboolean continue_download;
1104 g_return_if_fail (MODEST_IS_WINDOW(win));
1106 /* we need an account when editing */
1107 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1108 run_account_setup_wizard (win);
1112 header_list = get_selected_headers (win);
1116 /* Check that the messages have been previously downloaded */
1117 continue_download = download_uncached_messages (header_list, GTK_WINDOW (win));
1118 if (!continue_download) {
1119 g_object_unref (header_list);
1123 reply_forward_type =
1124 modest_conf_get_int (modest_runtime_get_conf (),
1125 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1127 /* We assume that we can only select messages of the
1128 same folder and that we reply all of them from the
1129 same account. In fact the interface currently only
1130 allows single selection */
1133 rf_helper = g_slice_new0 (ReplyForwardHelper);
1134 rf_helper->reply_forward_type = reply_forward_type;
1135 rf_helper->action = action;
1136 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1137 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1138 rf_helper->parent_window = GTK_WIDGET (win);
1139 if (!rf_helper->account_name)
1140 rf_helper->account_name =
1141 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1143 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1146 /* Get header and message. Do not free them here, the
1147 reply_forward_cb must do it */
1148 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1149 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1150 if (!msg || !header) {
1152 g_object_unref (msg);
1154 g_object_unref (header);
1155 g_printerr ("modest: no message found\n");
1158 reply_forward_cb (NULL, header, msg, rf_helper);
1164 /* Retrieve messages */
1165 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1167 modest_ui_actions_get_msgs_full_error_handler,
1169 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1171 /* Only reply/forward to one message */
1172 iter = tny_list_create_iterator (header_list);
1173 header = TNY_HEADER (tny_iterator_get_current (iter));
1174 g_object_unref (iter);
1176 modest_mail_operation_get_msg (mail_op,
1181 /* modest_mail_operation_get_msgs_full (mail_op, */
1183 /* reply_forward_cb, */
1185 /* free_reply_forward_helper); */
1188 g_object_unref(mail_op);
1192 g_object_unref (header_list);
1196 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1198 g_return_if_fail (MODEST_IS_WINDOW(win));
1200 reply_forward (ACTION_REPLY, win);
1204 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1206 g_return_if_fail (MODEST_IS_WINDOW(win));
1208 reply_forward (ACTION_FORWARD, win);
1212 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1214 g_return_if_fail (MODEST_IS_WINDOW(win));
1216 reply_forward (ACTION_REPLY_TO_ALL, win);
1220 modest_ui_actions_on_next (GtkAction *action,
1221 ModestWindow *window)
1223 if (MODEST_IS_MAIN_WINDOW (window)) {
1224 GtkWidget *header_view;
1226 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1227 MODEST_WIDGET_TYPE_HEADER_VIEW);
1231 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
1232 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1233 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
1235 g_return_if_reached ();
1240 modest_ui_actions_on_prev (GtkAction *action,
1241 ModestWindow *window)
1243 g_return_if_fail (MODEST_IS_WINDOW(window));
1245 if (MODEST_IS_MAIN_WINDOW (window)) {
1246 GtkWidget *header_view;
1247 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1248 MODEST_WIDGET_TYPE_HEADER_VIEW);
1252 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1253 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1254 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1256 g_return_if_reached ();
1261 modest_ui_actions_on_sort (GtkAction *action,
1262 ModestWindow *window)
1264 g_return_if_fail (MODEST_IS_WINDOW(window));
1266 if (MODEST_IS_MAIN_WINDOW (window)) {
1267 GtkWidget *header_view;
1268 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1269 MODEST_WIDGET_TYPE_HEADER_VIEW);
1273 /* Show sorting dialog */
1274 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1279 new_messages_arrived (ModestMailOperation *self,
1283 if (new_messages == 0)
1286 modest_platform_on_new_msg ();
1290 * This function performs the send & receive required actions. The
1291 * window is used to create the mail operation. Typically it should
1292 * always be the main window, but we pass it as argument in order to
1296 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1298 gchar *acc_name = NULL;
1299 ModestMailOperation *mail_op;
1301 /* If no account name was provided then get the current account, and if
1302 there is no current account then pick the default one: */
1303 if (!account_name) {
1304 acc_name = g_strdup (modest_window_get_active_account(win));
1306 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1308 g_printerr ("modest: cannot get default account\n");
1312 acc_name = g_strdup (account_name);
1315 /* Set send/receive operation in progress */
1316 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1318 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1320 modest_ui_actions_send_receive_error_handler,
1323 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1324 G_CALLBACK (_on_send_receive_progress_changed),
1327 /* Send & receive. */
1328 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1329 /* Receive and then send. The operation is tagged initially as
1330 a receive operation because the account update performs a
1331 receive and then a send. The operation changes its type
1332 internally, so the progress objects will receive the proper
1333 progress information */
1334 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1335 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, NULL);
1336 g_object_unref (G_OBJECT (mail_op));
1343 * Refreshes all accounts. This function will be used by automatic
1347 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1349 GSList *account_names, *iter;
1351 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1354 iter = account_names;
1356 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1357 iter = g_slist_next (iter);
1360 modest_account_mgr_free_account_names (account_names);
1361 account_names = NULL;
1365 * Handler of the click on Send&Receive button in the main toolbar
1368 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1370 /* Check if accounts exist */
1371 gboolean accounts_exist =
1372 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1374 /* If not, allow the user to create an account before trying to send/receive. */
1375 if (!accounts_exist)
1376 modest_ui_actions_on_accounts (NULL, win);
1378 /* Refresh the active account */
1379 modest_ui_actions_do_send_receive (NULL, win);
1384 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1387 GtkWidget *header_view;
1389 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1391 header_view = modest_main_window_get_child_widget (main_window,
1392 MODEST_WIDGET_TYPE_HEADER_VIEW);
1396 conf = modest_runtime_get_conf ();
1398 /* what is saved/restored is depending on the style; thus; we save with
1399 * old style, then update the style, and restore for this new style
1401 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1403 if (modest_header_view_get_style
1404 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1405 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1406 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1408 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1409 MODEST_HEADER_VIEW_STYLE_DETAILS);
1411 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1412 MODEST_CONF_HEADER_VIEW_KEY);
1417 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1419 ModestMainWindow *main_window)
1421 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1422 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1424 /* If no header has been selected then exit */
1429 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1430 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1432 /* Update Main window title */
1433 if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
1434 const gchar *subject = tny_header_get_subject (header);
1435 if (subject && strlen(subject) > 0)
1436 gtk_window_set_title (GTK_WINDOW (main_window), subject);
1438 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
1441 /* Update toolbar dimming state */
1442 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1446 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1448 ModestMainWindow *main_window)
1452 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1457 headers = tny_simple_list_new ();
1458 tny_list_prepend (headers, G_OBJECT (header));
1460 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1462 g_object_unref (headers);
1466 set_active_account_from_tny_account (TnyAccount *account,
1467 ModestWindow *window)
1469 const gchar *server_acc_name = tny_account_get_id (account);
1471 /* We need the TnyAccount provided by the
1472 account store because that is the one that
1473 knows the name of the Modest account */
1474 TnyAccount *modest_server_account = modest_server_account =
1475 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1476 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1479 const gchar *modest_acc_name =
1480 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1481 modest_window_set_active_account (window, modest_acc_name);
1482 g_object_unref (modest_server_account);
1487 folder_refreshed_cb (ModestMailOperation *mail_op,
1491 ModestMainWindow *win = NULL;
1492 GtkWidget *header_view;
1494 g_return_if_fail (TNY_IS_FOLDER (folder));
1496 win = MODEST_MAIN_WINDOW (user_data);
1498 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1500 /* Check if folder is empty and set headers view contents style */
1501 if (tny_folder_get_all_count (folder) == 0) {
1502 printf ("DEBUG: %s: tny_folder_get_all_count() returned 0.\n", __FUNCTION__);
1503 modest_main_window_set_contents_style (win,
1504 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1506 printf ("DEBUG: %s: tny_folder_get_all_count() returned >0.\n", __FUNCTION__);
1511 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1512 TnyFolderStore *folder_store,
1514 ModestMainWindow *main_window)
1517 GtkWidget *header_view;
1519 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1521 header_view = modest_main_window_get_child_widget(main_window,
1522 MODEST_WIDGET_TYPE_HEADER_VIEW);
1526 conf = modest_runtime_get_conf ();
1528 if (TNY_IS_ACCOUNT (folder_store)) {
1530 /* Update active account */
1531 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1532 /* Show account details */
1533 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1536 if (TNY_IS_FOLDER (folder_store) && selected) {
1538 /* Update the active account */
1539 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1541 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1542 g_object_unref (account);
1546 /* Set the header style by default, it could
1547 be changed later by the refresh callback to
1549 modest_main_window_set_contents_style (main_window,
1550 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1552 /* Set folder on header view. This function
1553 will call tny_folder_refresh_async so we
1554 pass a callback that will be called when
1555 finished. We use that callback to set the
1556 empty view if there are no messages */
1557 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1558 TNY_FOLDER (folder_store),
1559 folder_refreshed_cb,
1562 /* Restore configuration. We need to do this
1563 *after* the set_folder because the widget
1564 memory asks the header view about its
1566 modest_widget_memory_restore (modest_runtime_get_conf (),
1567 G_OBJECT(header_view),
1568 MODEST_CONF_HEADER_VIEW_KEY);
1570 /* Update the active account */
1571 modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1572 /* Save only if we're seeing headers */
1573 if (modest_main_window_get_contents_style (main_window) ==
1574 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1575 modest_widget_memory_save (conf, G_OBJECT (header_view),
1576 MODEST_CONF_HEADER_VIEW_KEY);
1577 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1581 /* Update toolbar dimming state */
1582 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1586 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1593 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1595 online = tny_device_is_online (modest_runtime_get_device());
1598 /* already online -- the item is simply not there... */
1599 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1601 GTK_MESSAGE_WARNING,
1603 _("The %s you selected cannot be found"),
1605 gtk_dialog_run (GTK_DIALOG(dialog));
1607 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1611 GTK_RESPONSE_REJECT,
1613 GTK_RESPONSE_ACCEPT,
1615 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1616 "Do you want to get online?"), item);
1617 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1618 gtk_label_new (txt), FALSE, FALSE, 0);
1619 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1622 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1623 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1624 // modest_platform_connect_and_wait ();
1627 gtk_widget_destroy (dialog);
1631 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1634 /* g_message ("%s %s", __FUNCTION__, link); */
1639 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1642 modest_platform_activate_uri (link);
1646 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1649 modest_platform_show_uri_popup (link);
1653 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1656 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
1660 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1661 const gchar *address,
1664 /* g_message ("%s %s", __FUNCTION__, address); */
1668 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1670 TnyTransportAccount *transport_account;
1671 ModestMailOperation *mail_operation;
1673 gchar *account_name, *from;
1674 ModestAccountMgr *account_mgr;
1675 gchar *info_text = NULL;
1676 TnyMsg *new_draft = NULL;
1678 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1680 data = modest_msg_edit_window_get_msg_data (edit_window);
1682 account_mgr = modest_runtime_get_account_mgr();
1683 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1685 account_name = modest_account_mgr_get_default_account (account_mgr);
1686 if (!account_name) {
1687 g_printerr ("modest: no account found\n");
1688 modest_msg_edit_window_free_msg_data (edit_window, data);
1692 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1693 account_name = g_strdup (data->account_name);
1697 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1698 (modest_runtime_get_account_store(),
1700 TNY_ACCOUNT_TYPE_TRANSPORT));
1701 if (!transport_account) {
1702 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1703 g_free (account_name);
1704 modest_msg_edit_window_free_msg_data (edit_window, data);
1707 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1709 /* Create the mail operation */
1710 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
1711 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1713 new_draft = modest_mail_operation_save_to_drafts (mail_operation,
1724 data->priority_flags);
1727 g_free (account_name);
1728 g_object_unref (G_OBJECT (transport_account));
1729 g_object_unref (G_OBJECT (mail_operation));
1731 modest_msg_edit_window_free_msg_data (edit_window, data);
1733 modest_msg_edit_window_set_draft (edit_window, new_draft);
1734 if (new_draft != NULL)
1735 g_object_unref (new_draft);
1737 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
1738 modest_platform_information_banner (NULL, NULL, info_text);
1742 /* For instance, when clicking the Send toolbar button when editing a message: */
1744 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1746 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1748 if (!modest_msg_edit_window_check_names (edit_window))
1751 /* Offer the connection dialog, if necessary: */
1752 if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window)))
1755 /* FIXME: Code added just for testing. The final version will
1756 use the send queue provided by tinymail and some
1758 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
1759 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1761 account_name = modest_account_mgr_get_default_account (account_mgr);
1763 if (!account_name) {
1764 g_printerr ("modest: no account found\n");
1768 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
1770 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1771 account_name = g_strdup (data->account_name);
1774 /* Get the currently-active transport account for this modest account: */
1775 TnyTransportAccount *transport_account =
1776 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1777 (modest_runtime_get_account_store(),
1779 if (!transport_account) {
1780 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1781 g_free (account_name);
1782 modest_msg_edit_window_free_msg_data (edit_window, data);
1786 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
1788 /* mail content checks and dialogs */
1789 if (data->subject == NULL || data->subject[0] == '\0') {
1790 GtkResponseType response;
1791 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1792 _("mcen_nc_subject_is_empty_send"));
1793 if (response == GTK_RESPONSE_CANCEL) {
1794 g_free (account_name);
1799 if (data->plain_body == NULL || data->plain_body[0] == '\0') {
1800 GtkResponseType response;
1801 gchar *note_message;
1802 gchar *note_subject = data->subject;
1803 if (note_subject == NULL || note_subject[0] == '\0')
1804 note_subject = _("mail_va_no_subject");
1805 note_message = g_strdup_printf (_("emev_ni_ui_smtp_message_null"), note_subject);
1806 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (edit_window),
1808 g_free (note_message);
1809 if (response == GTK_RESPONSE_CANCEL) {
1810 g_free (account_name);
1815 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
1817 /* Create the mail operation */
1818 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
1819 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1821 modest_mail_operation_send_new_mail (mail_operation,
1832 data->priority_flags);
1836 g_free (account_name);
1837 g_object_unref (G_OBJECT (transport_account));
1838 g_object_unref (G_OBJECT (mail_operation));
1840 modest_msg_edit_window_free_msg_data (edit_window, data);
1841 modest_msg_edit_window_set_sent (edit_window, TRUE);
1843 /* Save settings and close the window: */
1844 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
1848 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1849 ModestMsgEditWindow *window)
1851 ModestMsgEditFormatState *format_state = NULL;
1853 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1854 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1856 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1859 format_state = modest_msg_edit_window_get_format_state (window);
1860 g_return_if_fail (format_state != NULL);
1862 format_state->bold = gtk_toggle_action_get_active (action);
1863 modest_msg_edit_window_set_format_state (window, format_state);
1864 g_free (format_state);
1869 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1870 ModestMsgEditWindow *window)
1872 ModestMsgEditFormatState *format_state = NULL;
1874 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1875 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1877 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1880 format_state = modest_msg_edit_window_get_format_state (window);
1881 g_return_if_fail (format_state != NULL);
1883 format_state->italics = gtk_toggle_action_get_active (action);
1884 modest_msg_edit_window_set_format_state (window, format_state);
1885 g_free (format_state);
1890 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1891 ModestMsgEditWindow *window)
1893 ModestMsgEditFormatState *format_state = NULL;
1895 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1896 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1898 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1901 format_state = modest_msg_edit_window_get_format_state (window);
1902 g_return_if_fail (format_state != NULL);
1904 format_state->bullet = gtk_toggle_action_get_active (action);
1905 modest_msg_edit_window_set_format_state (window, format_state);
1906 g_free (format_state);
1911 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1912 GtkRadioAction *selected,
1913 ModestMsgEditWindow *window)
1915 ModestMsgEditFormatState *format_state = NULL;
1916 GtkJustification value;
1918 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1920 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1923 value = gtk_radio_action_get_current_value (selected);
1925 format_state = modest_msg_edit_window_get_format_state (window);
1926 g_return_if_fail (format_state != NULL);
1928 format_state->justification = value;
1929 modest_msg_edit_window_set_format_state (window, format_state);
1930 g_free (format_state);
1934 modest_ui_actions_on_select_editor_color (GtkAction *action,
1935 ModestMsgEditWindow *window)
1937 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1938 g_return_if_fail (GTK_IS_ACTION (action));
1940 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1943 modest_msg_edit_window_select_color (window);
1947 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1948 ModestMsgEditWindow *window)
1950 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1951 g_return_if_fail (GTK_IS_ACTION (action));
1953 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1956 modest_msg_edit_window_select_background_color (window);
1960 modest_ui_actions_on_insert_image (GtkAction *action,
1961 ModestMsgEditWindow *window)
1963 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1964 g_return_if_fail (GTK_IS_ACTION (action));
1966 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1969 modest_msg_edit_window_insert_image (window);
1973 modest_ui_actions_on_attach_file (GtkAction *action,
1974 ModestMsgEditWindow *window)
1976 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1977 g_return_if_fail (GTK_IS_ACTION (action));
1979 modest_msg_edit_window_attach_file (window);
1983 modest_ui_actions_on_remove_attachments (GtkAction *action,
1984 ModestMsgEditWindow *window)
1986 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1987 g_return_if_fail (GTK_IS_ACTION (action));
1989 modest_msg_edit_window_remove_attachments (window, NULL);
1993 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1995 TnyFolderStore *parent_folder;
1996 GtkWidget *folder_view;
1998 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2000 folder_view = modest_main_window_get_child_widget (main_window,
2001 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2005 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2007 if (parent_folder) {
2008 gboolean finished = FALSE;
2010 gchar *folder_name = NULL, *suggested_name = NULL;
2012 /* Run the new folder dialog */
2014 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
2019 if (result == GTK_RESPONSE_REJECT) {
2022 ModestMailOperation *mail_op;
2023 TnyFolder *new_folder = NULL;
2025 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO,
2026 G_OBJECT(main_window));
2027 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2029 new_folder = modest_mail_operation_create_folder (mail_op,
2031 (const gchar *) folder_name);
2033 g_object_unref (new_folder);
2036 g_object_unref (mail_op);
2038 g_free (folder_name);
2042 g_object_unref (parent_folder);
2047 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2050 GObject *win = modest_mail_operation_get_source (mail_op);
2051 const GError *error = NULL;
2052 const gchar *message = NULL;
2054 /* Get error message */
2055 error = modest_mail_operation_get_error (mail_op);
2056 if (error != NULL && error->message != NULL) {
2057 message = error->message;
2059 message = _("!!! FIXME: Unable to rename");
2062 /* Show notification dialog */
2063 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
2064 g_object_unref (win);
2068 modest_ui_actions_on_rename_folder (GtkAction *action,
2069 ModestMainWindow *main_window)
2071 TnyFolderStore *folder;
2072 GtkWidget *folder_view;
2073 GtkWidget *header_view;
2075 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2077 folder_view = modest_main_window_get_child_widget (main_window,
2078 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2082 header_view = modest_main_window_get_child_widget (main_window,
2083 MODEST_WIDGET_TYPE_HEADER_VIEW);
2088 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2090 /* Offer the connection dialog if necessary: */
2091 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2092 g_object_unref (G_OBJECT (folder));
2097 if (folder && TNY_IS_FOLDER (folder)) {
2100 const gchar *current_name;
2102 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2103 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window), NULL,
2104 current_name, &folder_name);
2106 if (response == GTK_RESPONSE_ACCEPT && strlen (folder_name) > 0) {
2107 ModestMailOperation *mail_op;
2110 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2111 G_OBJECT(main_window),
2112 modest_ui_actions_rename_folder_error_handler,
2116 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2119 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
2121 modest_mail_operation_rename_folder (mail_op,
2122 TNY_FOLDER (folder),
2123 (const gchar *) folder_name);
2125 g_object_unref (mail_op);
2126 g_free (folder_name);
2128 g_object_unref (folder);
2133 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2136 GObject *win = modest_mail_operation_get_source (mail_op);
2138 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2139 _("mail_in_ui_folder_delete_error"));
2140 g_object_unref (win);
2144 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2146 TnyFolderStore *folder;
2147 GtkWidget *folder_view;
2151 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2153 folder_view = modest_main_window_get_child_widget (main_window,
2154 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2158 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2160 /* Show an error if it's an account */
2161 if (!TNY_IS_FOLDER (folder)) {
2162 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2163 _("mail_in_ui_folder_delete_error"));
2164 g_object_unref (G_OBJECT (folder));
2168 /* Offer the connection dialog if necessary: */
2169 if (!modest_platform_connect_and_wait_if_network_folderstore (NULL, folder)) {
2170 g_object_unref (G_OBJECT (folder));
2175 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2176 tny_folder_get_name (TNY_FOLDER (folder)));
2177 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2178 (const gchar *) message);
2181 if (response == GTK_RESPONSE_OK) {
2182 ModestMailOperation *mail_op =
2183 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2184 G_OBJECT(main_window),
2185 modest_ui_actions_delete_folder_error_handler,
2188 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2190 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2191 g_object_unref (G_OBJECT (mail_op));
2194 g_object_unref (G_OBJECT (folder));
2198 modest_ui_actions_on_delete_folder (GtkAction *action,
2199 ModestMainWindow *main_window)
2201 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2203 delete_folder (main_window, FALSE);
2207 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2209 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2211 delete_folder (main_window, TRUE);
2215 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2216 const gchar* server_account_name,
2221 ModestMainWindow *main_window)
2223 g_return_if_fail(server_account_name);
2224 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2226 /* Initalize output parameters: */
2233 #ifdef MODEST_PLATFORM_MAEMO
2234 /* Maemo uses a different (awkward) button order,
2235 * It should probably just use gtk_alternative_dialog_button_order ().
2237 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2241 GTK_RESPONSE_ACCEPT,
2243 GTK_RESPONSE_REJECT,
2246 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2250 GTK_RESPONSE_REJECT,
2252 GTK_RESPONSE_ACCEPT,
2254 #endif /* MODEST_PLATFORM_MAEMO */
2256 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2258 gchar *server_name = modest_server_account_get_hostname (
2259 modest_runtime_get_account_mgr(), server_account_name);
2260 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2261 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2266 /* This causes a warning because the logical ID has no %s in it,
2267 * though the translation does, but there is not much we can do about that: */
2268 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2269 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2272 g_free (server_name);
2276 gchar *initial_username = modest_server_account_get_username (
2277 modest_runtime_get_account_mgr(), server_account_name);
2279 GtkWidget *entry_username = gtk_entry_new ();
2280 if (initial_username)
2281 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2282 /* Dim this if a connection has ever succeeded with this username,
2283 * as per the UI spec: */
2284 const gboolean username_known =
2285 modest_server_account_get_username_has_succeeded(
2286 modest_runtime_get_account_mgr(), server_account_name);
2287 gtk_widget_set_sensitive (entry_username, !username_known);
2289 #ifdef MODEST_PLATFORM_MAEMO
2290 /* Auto-capitalization is the default, so let's turn it off: */
2291 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2293 /* Create a size group to be used by all captions.
2294 * Note that HildonCaption does not create a default size group if we do not specify one.
2295 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2296 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2298 GtkWidget *caption = hildon_caption_new (sizegroup,
2299 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2300 gtk_widget_show (entry_username);
2301 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2302 FALSE, FALSE, MODEST_MARGIN_HALF);
2303 gtk_widget_show (caption);
2305 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2307 #endif /* MODEST_PLATFORM_MAEMO */
2310 GtkWidget *entry_password = gtk_entry_new ();
2311 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2312 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2314 #ifdef MODEST_PLATFORM_MAEMO
2315 /* Auto-capitalization is the default, so let's turn it off: */
2316 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2317 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2319 caption = hildon_caption_new (sizegroup,
2320 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2321 gtk_widget_show (entry_password);
2322 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2323 FALSE, FALSE, MODEST_MARGIN_HALF);
2324 gtk_widget_show (caption);
2325 g_object_unref (sizegroup);
2327 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2329 #endif /* MODEST_PLATFORM_MAEMO */
2331 /* This is not in the Maemo UI spec:
2332 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2333 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2337 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2339 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2341 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2343 modest_server_account_set_username (
2344 modest_runtime_get_account_mgr(), server_account_name,
2347 const gboolean username_was_changed =
2348 (strcmp (*username, initial_username) != 0);
2349 if (username_was_changed) {
2350 g_warning ("%s: tinymail does not yet support changing the "
2351 "username in the get_password() callback.\n", __FUNCTION__);
2356 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2358 /* We do not save the password in the configuration,
2359 * because this function is only called for passwords that should
2360 * not be remembered:
2361 modest_server_account_set_password (
2362 modest_runtime_get_account_mgr(), server_account_name,
2381 /* This is not in the Maemo UI spec:
2382 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2388 gtk_widget_destroy (dialog);
2390 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2394 modest_ui_actions_on_cut (GtkAction *action,
2395 ModestWindow *window)
2397 GtkWidget *focused_widget;
2399 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2400 if (GTK_IS_EDITABLE (focused_widget)) {
2401 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2402 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2403 GtkTextBuffer *buffer;
2404 GtkClipboard *clipboard;
2406 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2407 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2408 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2409 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2410 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2411 modest_header_view_cut_selection (MODEST_HEADER_VIEW (focused_widget));
2412 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2413 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2418 modest_ui_actions_on_copy (GtkAction *action,
2419 ModestWindow *window)
2421 GtkClipboard *clipboard;
2422 GtkWidget *focused_widget;
2424 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2425 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2427 if (GTK_IS_LABEL (focused_widget)) {
2428 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2429 } else if (GTK_IS_EDITABLE (focused_widget)) {
2430 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2431 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2432 GtkTextBuffer *buffer;
2433 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2434 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2435 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2436 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2437 TnyList *header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (focused_widget));
2438 TnyIterator *iter = tny_list_create_iterator (header_list);
2439 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
2440 TnyFolder *folder = tny_header_get_folder (header);
2441 TnyAccount *account = tny_folder_get_account (folder);
2442 const gchar *proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2443 /* If it's POP then ask */
2444 gboolean ask = (modest_protocol_info_get_transport_store_protocol (proto_str) ==
2445 MODEST_PROTOCOL_STORE_POP) ? TRUE : FALSE;
2446 g_object_unref (account);
2447 g_object_unref (folder);
2448 g_object_unref (header);
2449 g_object_unref (iter);
2451 /* Check that the messages have been previously downloaded */
2452 gboolean continue_download = TRUE;
2454 continue_download = download_uncached_messages (header_list, GTK_WINDOW (window));
2455 if (continue_download)
2456 modest_header_view_copy_selection (MODEST_HEADER_VIEW (focused_widget));
2457 g_object_unref (header_list);
2458 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2459 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2462 /* Show information banner */
2463 modest_platform_information_banner (NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2468 modest_ui_actions_on_undo (GtkAction *action,
2469 ModestWindow *window)
2471 ModestEmailClipboard *clipboard = NULL;
2473 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2474 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2475 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2476 /* Clear clipboard source */
2477 clipboard = modest_runtime_get_email_clipboard ();
2478 modest_email_clipboard_clear (clipboard);
2481 g_return_if_reached ();
2486 modest_ui_actions_on_redo (GtkAction *action,
2487 ModestWindow *window)
2489 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2490 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
2493 g_return_if_reached ();
2499 paste_msgs_cb (const GObject *object, gpointer user_data)
2501 g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2502 g_return_if_fail (GTK_IS_WIDGET (user_data));
2504 /* destroy information note */
2505 gtk_widget_destroy (GTK_WIDGET(user_data));
2509 modest_ui_actions_on_paste (GtkAction *action,
2510 ModestWindow *window)
2512 GtkWidget *focused_widget = NULL;
2513 GtkWidget *inf_note = NULL;
2514 ModestMailOperation *mail_op = NULL;
2516 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2517 if (GTK_IS_EDITABLE (focused_widget)) {
2518 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
2519 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2520 GtkTextBuffer *buffer;
2521 GtkClipboard *clipboard;
2523 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2524 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2525 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
2526 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2527 ModestEmailClipboard *clipboard = NULL;
2528 TnyFolder *src_folder = NULL;
2529 TnyFolderStore *folder_store = NULL;
2530 TnyList *data = NULL;
2531 gboolean delete = FALSE;
2533 /* Check clipboard source */
2534 clipboard = modest_runtime_get_email_clipboard ();
2535 if (modest_email_clipboard_cleared (clipboard))
2538 /* Get elements to paste */
2539 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
2541 /* Create a new mail operation */
2542 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
2543 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2546 /* Get destination folder */
2547 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
2549 /* Launch notification */
2550 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
2551 _CS("ckct_nw_pasting"));
2552 if (inf_note != NULL) {
2553 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
2554 gtk_widget_show (GTK_WIDGET(inf_note));
2557 /* transfer messages */
2559 modest_mail_operation_xfer_msgs (mail_op,
2561 TNY_FOLDER (folder_store),
2566 } else if (src_folder != NULL) {
2567 modest_mail_operation_xfer_folder (mail_op,
2577 g_object_unref (data);
2578 if (src_folder != NULL)
2579 g_object_unref (src_folder);
2580 if (folder_store != NULL)
2581 g_object_unref (folder_store);
2587 modest_ui_actions_on_select_all (GtkAction *action,
2588 ModestWindow *window)
2590 GtkWidget *focused_widget;
2592 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2593 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
2594 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
2595 } else if (GTK_IS_LABEL (focused_widget)) {
2596 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
2597 } else if (GTK_IS_EDITABLE (focused_widget)) {
2598 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
2599 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2600 GtkTextBuffer *buffer;
2601 GtkTextIter start, end;
2603 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2604 gtk_text_buffer_get_start_iter (buffer, &start);
2605 gtk_text_buffer_get_end_iter (buffer, &end);
2606 gtk_text_buffer_select_range (buffer, &start, &end);
2607 } else if (GTK_IS_HTML (focused_widget)) {
2608 gtk_html_select_all (GTK_HTML (focused_widget));
2609 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2610 GtkWidget *header_view = focused_widget;
2611 GtkTreeSelection *selection = NULL;
2613 if (!(MODEST_IS_HEADER_VIEW (focused_widget)))
2614 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
2615 MODEST_WIDGET_TYPE_HEADER_VIEW);
2617 /* Select all messages */
2618 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
2619 gtk_tree_selection_select_all (selection);
2621 /* Set focuse on header view */
2622 gtk_widget_grab_focus (header_view);
2628 modest_ui_actions_on_mark_as_read (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_read, NULL);
2638 modest_ui_actions_on_mark_as_unread (GtkAction *action,
2639 ModestWindow *window)
2641 g_return_if_fail (MODEST_IS_WINDOW(window));
2643 /* Mark each header as read */
2644 do_headers_action (window, headers_action_mark_as_unread, NULL);
2648 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
2649 GtkRadioAction *selected,
2650 ModestWindow *window)
2654 value = gtk_radio_action_get_current_value (selected);
2655 if (MODEST_IS_WINDOW (window)) {
2656 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
2660 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
2661 GtkRadioAction *selected,
2662 ModestWindow *window)
2664 TnyHeaderFlags flags;
2665 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2667 flags = gtk_radio_action_get_current_value (selected);
2668 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
2671 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
2672 GtkRadioAction *selected,
2673 ModestWindow *window)
2677 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2679 file_format = gtk_radio_action_get_current_value (selected);
2680 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
2685 modest_ui_actions_on_zoom_plus (GtkAction *action,
2686 ModestWindow *window)
2688 g_return_if_fail (MODEST_IS_WINDOW (window));
2690 modest_window_zoom_plus (MODEST_WINDOW (window));
2694 modest_ui_actions_on_zoom_minus (GtkAction *action,
2695 ModestWindow *window)
2697 g_return_if_fail (MODEST_IS_WINDOW (window));
2699 modest_window_zoom_minus (MODEST_WINDOW (window));
2703 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
2704 ModestWindow *window)
2706 ModestWindowMgr *mgr;
2707 gboolean fullscreen, active;
2708 g_return_if_fail (MODEST_IS_WINDOW (window));
2710 mgr = modest_runtime_get_window_mgr ();
2712 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
2713 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2715 if (active != fullscreen) {
2716 modest_window_mgr_set_fullscreen_mode (mgr, active);
2717 gtk_window_present (GTK_WINDOW (window));
2722 modest_ui_actions_on_change_fullscreen (GtkAction *action,
2723 ModestWindow *window)
2725 ModestWindowMgr *mgr;
2726 gboolean fullscreen;
2728 g_return_if_fail (MODEST_IS_WINDOW (window));
2730 mgr = modest_runtime_get_window_mgr ();
2731 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
2732 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
2734 gtk_window_present (GTK_WINDOW (window));
2738 * Used by modest_ui_actions_on_details to call do_headers_action
2741 headers_action_show_details (TnyHeader *header,
2742 ModestWindow *window,
2749 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
2752 gtk_widget_show_all (dialog);
2753 gtk_dialog_run (GTK_DIALOG (dialog));
2755 gtk_widget_destroy (dialog);
2759 * Show the folder details in a ModestDetailsDialog widget
2762 show_folder_details (TnyFolder *folder,
2768 dialog = modest_details_dialog_new_with_folder (window, folder);
2771 gtk_widget_show_all (dialog);
2772 gtk_dialog_run (GTK_DIALOG (dialog));
2774 gtk_widget_destroy (dialog);
2778 * Show the header details in a ModestDetailsDialog widget
2781 modest_ui_actions_on_details (GtkAction *action,
2784 TnyList * headers_list;
2788 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
2791 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2794 g_object_unref (msg);
2796 headers_list = get_selected_headers (win);
2800 iter = tny_list_create_iterator (headers_list);
2802 header = TNY_HEADER (tny_iterator_get_current (iter));
2803 headers_action_show_details (header, win, NULL);
2804 g_object_unref (header);
2806 g_object_unref (iter);
2807 g_object_unref (headers_list);
2809 } else if (MODEST_IS_MAIN_WINDOW (win)) {
2810 GtkWidget *folder_view, *header_view;
2812 /* Check which widget has the focus */
2813 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2814 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2815 if (gtk_widget_is_focus (folder_view)) {
2816 TnyFolderStore *folder_store
2817 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2818 if (!folder_store) {
2819 g_warning ("%s: No item was selected.\n", __FUNCTION__);
2822 /* Show only when it's a folder */
2823 /* This function should not be called for account items,
2824 * because we dim the menu item for them. */
2825 if (TNY_IS_FOLDER (folder_store)) {
2826 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
2829 g_object_unref (folder_store);
2832 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2833 MODEST_WIDGET_TYPE_HEADER_VIEW);
2834 /* Show details of each header */
2835 do_headers_action (win, headers_action_show_details, header_view);
2841 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
2842 ModestMsgEditWindow *window)
2844 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2846 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
2850 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
2851 ModestMsgEditWindow *window)
2853 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2855 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
2859 modest_ui_actions_toggle_folders_view (GtkAction *action,
2860 ModestMainWindow *main_window)
2864 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2866 conf = modest_runtime_get_conf ();
2868 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
2869 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
2871 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
2875 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
2876 ModestWindow *window)
2878 gboolean active, fullscreen = FALSE;
2879 ModestWindowMgr *mgr;
2881 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
2883 /* Check if we want to toggle the toolbar vuew in fullscreen
2885 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
2886 "ViewShowToolbarFullScreen")) {
2890 /* Toggle toolbar */
2891 mgr = modest_runtime_get_window_mgr ();
2892 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
2896 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
2897 ModestMsgEditWindow *window)
2899 modest_msg_edit_window_select_font (window);
2903 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
2904 const gchar *display_name,
2907 /* Do not change the application name if the widget has not
2908 the focus. This callback could be called even if the folder
2909 view has not the focus, because the handled signal could be
2910 emitted when the folder view is redrawn */
2911 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2913 gtk_window_set_title (window, display_name);
2915 gtk_window_set_title (window, " ");
2920 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2922 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2923 modest_msg_edit_window_select_contacts (window);
2927 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2929 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2930 modest_msg_edit_window_check_names (window);
2935 create_move_to_dialog (ModestWindow *win,
2936 GtkWidget *folder_view,
2937 GtkWidget **tree_view)
2939 GtkWidget *dialog, *scroll;
2941 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2943 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2945 GTK_RESPONSE_ACCEPT,
2947 GTK_RESPONSE_REJECT,
2950 /* Create scrolled window */
2951 scroll = gtk_scrolled_window_new (NULL, NULL);
2952 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2953 GTK_POLICY_AUTOMATIC,
2954 GTK_POLICY_AUTOMATIC);
2956 /* Create folder view */
2957 *tree_view = modest_platform_create_folder_view (NULL);
2959 /* It could happen that we're trying to move a message from a
2960 window (msg window for example) after the main window was
2961 closed, so we can not just get the model of the folder
2963 if (MODEST_IS_FOLDER_VIEW (folder_view))
2964 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2965 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2967 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
2968 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
2970 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2972 /* Add scroll to dialog */
2973 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2974 scroll, FALSE, FALSE, 0);
2976 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2978 /* Select INBOX or local account */
2979 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (*tree_view));
2985 * Returns TRUE if at least one of the headers of the list belongs to
2986 * a message that has been fully retrieved.
2989 has_retrieved_msgs (TnyList *list)
2992 gboolean found = FALSE;
2994 iter = tny_list_create_iterator (list);
2995 while (tny_iterator_is_done (iter) && !found) {
2997 TnyHeaderFlags flags;
2999 header = TNY_HEADER (tny_iterator_get_current (iter));
3000 flags = tny_header_get_flags (header);
3001 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
3005 tny_iterator_next (iter);
3007 g_object_unref (iter);
3013 * Shows a confirmation dialog to the user when we're moving messages
3014 * from a remote server to the local storage. Returns the dialog
3015 * response. If it's other kind of movement the it always returns
3019 msgs_move_to_confirmation (GtkWindow *win,
3020 TnyFolder *dest_folder,
3023 gint response = GTK_RESPONSE_OK;
3025 /* If the destination is a local folder */
3026 if (modest_tny_folder_is_local_folder (dest_folder)) {
3027 TnyFolder *src_folder;
3031 /* Get source folder */
3032 iter = tny_list_create_iterator (headers);
3033 header = TNY_HEADER (tny_iterator_get_current (iter));
3034 src_folder = tny_header_get_folder (header);
3035 g_object_unref (header);
3036 g_object_unref (iter);
3038 /* if no src_folder, message may be an attahcment */
3039 if (src_folder == NULL)
3040 return GTK_RESPONSE_CANCEL;
3042 /* If the source is a remote folder */
3043 if (!modest_tny_folder_is_local_folder (src_folder)) {
3044 const gchar *message;
3046 if (has_retrieved_msgs (headers))
3047 message = ngettext ("mcen_nc_move_retrieve", "mcen_nc_move_retrieves",
3048 tny_list_get_length (headers));
3050 message = ngettext ("mcen_nc_move_header", "mcen_nc_move_headers",
3051 tny_list_get_length (headers));
3053 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
3054 (const gchar *) message);
3056 g_object_unref (src_folder);
3064 transfer_msgs_from_viewer_cb (const GObject *object, gpointer user_data)
3066 ModestMsgViewWindow *self = NULL;
3067 gboolean last, first;
3069 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (object));
3070 self = MODEST_MSG_VIEW_WINDOW (object);
3072 last = modest_msg_view_window_last_message_selected (self);
3073 first = modest_msg_view_window_first_message_selected (self);
3075 /* No more messages to view, so close this window */
3076 /* gboolean ret_value; */
3077 /* g_signal_emit_by_name (G_OBJECT (self), "delete-event", NULL, &ret_value); */
3078 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3080 modest_msg_view_window_select_previous_message (self);
3082 modest_msg_view_window_select_next_message (self);
3086 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3089 GObject *win = modest_mail_operation_get_source (mail_op);
3090 const GError *error = NULL;
3091 const gchar *message = NULL;
3093 /* Get error message */
3094 error = modest_mail_operation_get_error (mail_op);
3095 if (error != NULL && error->message != NULL) {
3096 message = error->message;
3098 message = _("mail_in_ui_folder_move_target_error");
3101 /* Show notification dialog */
3102 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3103 g_object_unref (win);
3107 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3110 GObject *win = modest_mail_operation_get_source (mail_op);
3111 const GError *error = modest_mail_operation_get_error (mail_op);
3113 g_return_if_fail (error != NULL);
3114 if (error->message != NULL)
3115 g_printerr ("modest: %s\n", error->message);
3117 g_printerr ("modest: unkonw error on send&receive operation");
3119 /* Show error message */
3120 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3121 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3122 /* _CS("sfil_ib_unable_to_receive")); */
3124 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3125 /* _CS("sfil_ib_unable_to_send")); */
3126 g_object_unref (win);
3130 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3137 gint pending_purges = 0;
3138 gboolean some_purged = FALSE;
3139 ModestWindow *win = MODEST_WINDOW (user_data);
3141 /* If there was any error */
3142 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
3145 /* Once the message has been retrieved for purging, we check if
3146 * it's all ok for purging */
3148 parts = tny_simple_list_new ();
3149 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3150 iter = tny_list_create_iterator (parts);
3152 while (!tny_iterator_is_done (iter)) {
3154 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3155 if (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)) {
3156 if (tny_mime_part_is_purged (part))
3161 tny_iterator_next (iter);
3164 if (pending_purges>0) {
3166 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3168 if (response == GTK_RESPONSE_OK) {
3169 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3170 tny_iterator_first (iter);
3171 while (!tny_iterator_is_done (iter)) {
3174 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3175 if (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))
3176 tny_mime_part_set_purged (part);
3177 tny_iterator_next (iter);
3180 tny_msg_rewrite_cache (msg);
3183 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3186 /* remove attachments */
3187 tny_iterator_first (iter);
3188 while (!tny_iterator_is_done (iter)) {
3191 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3192 g_object_unref (part);
3193 tny_iterator_next (iter);
3196 g_object_unref (iter);
3197 g_object_unref (parts);
3201 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3202 ModestMainWindow *win)
3204 GtkWidget *header_view;
3205 TnyList *header_list;
3208 TnyHeaderFlags flags;
3209 ModestWindow *msg_view_window = NULL;
3212 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3214 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3215 MODEST_WIDGET_TYPE_HEADER_VIEW);
3217 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3219 if (tny_list_get_length (header_list) == 1) {
3220 iter = tny_list_create_iterator (header_list);
3221 header = TNY_HEADER (tny_iterator_get_current (iter));
3222 g_object_unref (iter);
3227 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
3228 header, &msg_view_window);
3229 flags = tny_header_get_flags (header);
3230 if (!(flags & TNY_HEADER_FLAG_CACHED))
3233 if (msg_view_window != NULL)
3234 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
3236 /* do nothing; uid was registered before, so window is probably on it's way */
3237 g_warning ("debug: header %p has already been registered", header);
3240 ModestMailOperation *mail_op = NULL;
3241 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
3242 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3244 modest_ui_actions_get_msgs_full_error_handler,
3246 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3247 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
3249 g_object_unref (mail_op);
3252 g_object_unref (header);
3254 g_object_unref (header_list);
3258 * UI handler for the "Move to" action when invoked from the
3262 modest_ui_actions_on_main_window_move_to (GtkAction *action,
3263 ModestMainWindow *win)
3265 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
3266 GtkWidget *header_view = NULL;
3268 TnyFolderStore *folder_store = NULL;
3269 ModestMailOperation *mail_op = NULL;
3271 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3273 /* Get the folder view */
3274 folder_view = modest_main_window_get_child_widget (win,
3275 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3277 TnyFolderStore *src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3279 /* Offer the connection dialog if necessary, if the source folder is in a networked account: */
3280 if (!modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win), src_folder)) {
3282 g_object_unref (src_folder);
3288 /* Get header view */
3289 header_view = modest_main_window_get_child_widget (win,
3290 MODEST_WIDGET_TYPE_HEADER_VIEW);
3292 /* Create and run the dialog */
3293 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
3294 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
3295 result = gtk_dialog_run (GTK_DIALOG(dialog));
3296 g_object_ref (tree_view);
3298 /* We do this to save an indentation level ;-) */
3299 if (result != GTK_RESPONSE_ACCEPT)
3302 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
3304 if (TNY_IS_ACCOUNT (folder_store) &&
3305 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (folder_store))
3308 /* Offer the connection dialog if necessary: */
3309 if (!modest_platform_connect_and_wait_if_network_folderstore (GTK_WINDOW (win), folder_store)) {
3313 /* Get folder or messages to transfer */
3314 if (gtk_widget_is_focus (folder_view)) {
3316 /* Clean folder on header view before moving it */
3317 modest_header_view_clear (MODEST_HEADER_VIEW (header_view));
3319 if (TNY_IS_FOLDER (src_folder)) {
3321 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3323 modest_ui_actions_move_folder_error_handler,
3325 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3327 modest_mail_operation_xfer_folder (mail_op,
3328 TNY_FOLDER (src_folder),
3331 /* Unref mail operation */
3332 g_object_unref (G_OBJECT (mail_op));
3334 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
3337 if (gtk_widget_is_focus (header_view)) {
3338 TnyList *headers = NULL;
3341 /* TODO: Check for connection if the headers are on a network account. */
3342 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3344 /* Ask for user confirmation */
3345 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3346 TNY_FOLDER (folder_store),
3349 /* Transfer messages */
3350 if (response == GTK_RESPONSE_OK) {
3352 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3354 modest_ui_actions_move_folder_error_handler,
3356 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3359 modest_mail_operation_xfer_msgs (mail_op,
3361 TNY_FOLDER (folder_store),
3366 g_object_unref (G_OBJECT (mail_op));
3368 g_object_unref (headers);
3374 g_object_unref (src_folder);
3377 g_object_unref (folder_store);
3379 gtk_widget_destroy (dialog);
3384 * UI handler for the "Move to" action when invoked from the
3385 * ModestMsgViewWindow
3388 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
3389 ModestMsgViewWindow *win)
3391 GtkWidget *dialog, *folder_view, *tree_view = NULL;
3393 ModestMainWindow *main_window = NULL;
3394 TnyHeader *header = NULL;
3395 TnyList *headers = NULL;
3397 /* Get the folder view */
3398 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
3400 folder_view = modest_main_window_get_child_widget (main_window,
3401 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3405 /* Create and run the dialog */
3406 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
3407 result = gtk_dialog_run (GTK_DIALOG(dialog));
3409 if (result == GTK_RESPONSE_ACCEPT) {
3410 TnyFolderStore *folder_store;
3413 /* Create header list */
3414 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
3415 g_return_if_fail (header != NULL);
3417 /* Offer the connection dialog if necessary: */
3418 /* TODO: What's the extra g_object_ref() for? Isn't this leaking a ref? */
3419 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (g_object_ref (tree_view)));
3420 TnyFolder *header_folder = tny_header_get_folder(header);
3421 if (modest_platform_connect_and_wait_if_network_folderstore (NULL, folder_store) &&
3422 modest_platform_connect_and_wait_if_network_folderstore (NULL, TNY_FOLDER_STORE (header_folder))) {
3424 headers = tny_simple_list_new ();
3425 tny_list_prepend (headers, G_OBJECT (header));
3426 g_object_unref (header);
3428 /* Ask user for confirmation. MSG-NOT404 */
3429 response = msgs_move_to_confirmation (GTK_WINDOW (win),
3430 TNY_FOLDER (folder_store),
3433 /* Transfer current msg */
3434 if (response == GTK_RESPONSE_OK) {
3435 ModestMailOperation *mail_op;
3437 /* Create mail op */
3438 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(win));
3439 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3442 /* Transfer messages */
3443 modest_mail_operation_xfer_msgs (mail_op,
3445 TNY_FOLDER (folder_store),
3447 transfer_msgs_from_viewer_cb,
3449 g_object_unref (G_OBJECT (mail_op));
3454 g_object_unref (header_folder);
3457 g_object_unref (headers);
3460 g_object_unref (folder_store);
3463 gtk_widget_destroy (dialog);
3467 modest_ui_actions_on_move_to (GtkAction *action,
3470 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
3471 MODEST_IS_MSG_VIEW_WINDOW (win));
3473 if (MODEST_IS_MAIN_WINDOW (win))
3474 modest_ui_actions_on_main_window_move_to (action,
3475 MODEST_MAIN_WINDOW (win));
3477 modest_ui_actions_on_msg_view_window_move_to (action,
3478 MODEST_MSG_VIEW_WINDOW (win));
3482 * Calls #HeadersFunc for each header already selected in the main
3483 * window or the message currently being shown in the msg view window
3486 do_headers_action (ModestWindow *win,
3490 TnyList *headers_list;
3496 headers_list = get_selected_headers (win);
3500 /* Get the folder */
3501 iter = tny_list_create_iterator (headers_list);
3502 header = TNY_HEADER (tny_iterator_get_current (iter));
3503 folder = tny_header_get_folder (header);
3504 g_object_unref (header);
3506 /* Call the function for each header */
3507 while (!tny_iterator_is_done (iter)) {
3508 header = TNY_HEADER (tny_iterator_get_current (iter));
3509 func (header, win, user_data);
3510 g_object_unref (header);
3511 tny_iterator_next (iter);
3514 /* Trick: do a poke status in order to speed up the signaling
3516 tny_folder_poke_status (folder);
3519 g_object_unref (folder);
3520 g_object_unref (iter);
3521 g_object_unref (headers_list);
3525 modest_ui_actions_view_attachment (GtkAction *action,
3526 ModestWindow *window)
3528 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3529 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
3531 /* not supported window for this action */
3532 g_return_if_reached ();
3537 modest_ui_actions_save_attachments (GtkAction *action,
3538 ModestWindow *window)
3540 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3541 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
3543 /* not supported window for this action */
3544 g_return_if_reached ();
3549 modest_ui_actions_remove_attachments (GtkAction *action,
3550 ModestWindow *window)
3552 if (MODEST_IS_MAIN_WINDOW (window)) {
3553 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
3554 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
3555 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
3557 /* not supported window for this action */
3558 g_return_if_reached ();
3563 modest_ui_actions_on_settings (GtkAction *action,
3568 dialog = modest_platform_get_global_settings_dialog ();
3569 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
3570 gtk_widget_show_all (dialog);
3572 gtk_dialog_run (GTK_DIALOG (dialog));
3574 gtk_widget_destroy (dialog);
3578 modest_ui_actions_on_help (GtkAction *action,
3581 const gchar *help_id = NULL;
3583 if (MODEST_IS_MAIN_WINDOW (win)) {
3584 const gchar *action_name;
3585 action_name = gtk_action_get_name (action);
3587 if (!strcmp (action_name, "FolderViewCSMHelp") ||
3588 !strcmp (action_name, "HeaderViewCSMHelp")) {
3589 GtkWidget *folder_view;
3590 TnyFolderStore *folder_store;
3591 /* Get selected folder */
3592 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3593 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3594 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3596 /* Switch help_id */
3597 if (TNY_IS_FOLDER (folder_store)) {
3598 switch (tny_folder_get_folder_type (TNY_FOLDER (folder_store))) {
3599 case TNY_FOLDER_TYPE_NORMAL:
3600 help_id = "applications_email_userfolder";
3602 case TNY_FOLDER_TYPE_INBOX:
3603 help_id = "applications_email_inbox";
3605 case TNY_FOLDER_TYPE_OUTBOX:
3606 help_id = "applications_email_outbox";
3608 case TNY_FOLDER_TYPE_SENT:
3609 help_id = "applications_email_sent";
3611 case TNY_FOLDER_TYPE_DRAFTS:
3612 help_id = "applications_email_drafts";
3614 case TNY_FOLDER_TYPE_ARCHIVE:
3615 help_id = "applications_email_archive";
3621 g_object_unref (folder_store);
3623 help_id = "applications_email_mainview";
3625 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3626 help_id = "applications_email_viewer";
3627 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
3628 help_id = "applications_email_editor";
3630 modest_platform_show_help (GTK_WINDOW (win), help_id);
3634 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
3635 ModestWindow *window)
3637 ModestMailOperation *mail_op;
3641 headers = get_selected_headers (window);
3645 /* Create mail operation */
3646 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3648 modest_ui_actions_get_msgs_full_error_handler,
3650 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3651 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
3654 g_object_unref (headers);
3655 g_object_unref (mail_op);
3659 modest_ui_actions_on_email_menu_activated (GtkAction *action,
3660 ModestWindow *window)
3662 g_return_if_fail (MODEST_IS_WINDOW (window));
3665 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3669 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
3670 ModestWindow *window)
3672 g_return_if_fail (MODEST_IS_WINDOW (window));
3675 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3679 modest_ui_actions_on_view_menu_activated (GtkAction *action,
3680 ModestWindow *window)
3682 g_return_if_fail (MODEST_IS_WINDOW (window));
3685 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3689 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
3690 ModestWindow *window)
3692 g_return_if_fail (MODEST_IS_WINDOW (window));
3695 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3699 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
3700 ModestWindow *window)
3702 g_return_if_fail (MODEST_IS_WINDOW (window));
3705 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3709 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
3710 ModestWindow *window)
3712 g_return_if_fail (MODEST_IS_WINDOW (window));
3715 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3719 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
3720 ModestWindow *window)
3722 g_return_if_fail (MODEST_IS_WINDOW (window));
3725 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3729 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
3730 ModestWindow *window)
3732 g_return_if_fail (MODEST_IS_WINDOW (window));
3735 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
3739 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
3741 g_return_if_fail (MODEST_IS_WINDOW (window));
3744 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
3748 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
3750 g_return_if_fail (MODEST_IS_WINDOW (window));
3752 modest_platform_show_search_messages (GTK_WINDOW (window));
3756 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
3758 g_return_if_fail (MODEST_IS_WINDOW (win));
3759 modest_platform_show_addressbook (GTK_WINDOW (win));
3764 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
3765 ModestWindow *window)
3767 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3769 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
3773 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
3774 ModestMailOperationState *state,
3777 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
3779 /* Set send/receive operation finished */
3780 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3781 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));