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>
36 #include <modest-runtime.h>
37 #include <modest-tny-folder.h>
38 #include <modest-tny-msg.h>
39 #include <modest-tny-account.h>
40 #include <modest-address-book.h>
42 #include "modest-ui-actions.h"
44 #include "modest-tny-platform-factory.h"
45 #include "modest-platform.h"
47 #include <widgets/modest-main-window.h>
48 #include <widgets/modest-msg-view-window.h>
49 #include <widgets/modest-account-view-window.h>
50 #include <widgets/modest-details-dialog.h>
52 #include "modest-account-mgr-helpers.h"
53 #include "modest-mail-operation.h"
54 #include "modest-text-utils.h"
56 #ifdef MODEST_HAVE_EASYSETUP
57 #include "easysetup/modest-easysetup-wizard.h"
58 #endif /*MODEST_HAVE_EASYSETUP*/
60 #include <modest-widget-memory.h>
61 #include <tny-error.h>
62 #include <tny-simple-list.h>
63 #include <tny-msg-view.h>
64 #include <tny-device.h>
66 typedef struct _GetMsgAsyncHelper {
68 ModestMailOperation *mail_op;
75 typedef enum _ReplyForwardAction {
81 typedef struct _ReplyForwardHelper {
82 guint reply_forward_type;
83 ReplyForwardAction action;
88 * The do_headers_action uses this kind of functions to perform some
89 * action to each member of a list of headers
91 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
94 do_headers_action (ModestWindow *win,
99 static void reply_forward_func (gpointer data, gpointer user_data);
101 static void get_msg_cb (TnyFolder *folder, gboolean canceled, TnyMsg *msg, GError **err,
103 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
105 static gchar* ask_for_folder_name (GtkWindow *parent_window, const gchar *title);
108 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
111 const gchar *authors[] = {
112 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
115 about = gtk_about_dialog_new ();
116 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
117 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
118 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
119 _("Copyright (c) 2006, Nokia Corporation\n"
120 "All rights reserved."));
121 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
122 _("a modest e-mail client\n\n"
123 "design and implementation: Dirk-Jan C. Binnema\n"
124 "contributions from the fine people at KC and Ig\n"
125 "uses the tinymail email framework written by Philip van Hoof"));
126 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
127 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
129 gtk_dialog_run (GTK_DIALOG (about));
130 gtk_widget_destroy(about);
135 get_selected_headers (ModestWindow *win)
137 if (MODEST_IS_MAIN_WINDOW(win)) {
138 GtkWidget *header_view;
140 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
141 MODEST_WIDGET_TYPE_HEADER_VIEW);
142 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
144 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
145 /* for MsgViewWindows, we simply return a list with one element */
148 TnyList *list = NULL;
150 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
152 header = tny_msg_get_header (msg);
153 list = tny_simple_list_new ();
154 tny_list_prepend (list, G_OBJECT(header));
155 g_object_unref (G_OBJECT(header));
164 headers_action_delete (TnyHeader *header,
168 ModestMailOperation *mail_op;
170 /* TODO: add confirmation dialog */
171 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_DELETE, G_OBJECT(win));
172 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
175 /* Always delete. TODO: Move to trash still not supported */
176 modest_mail_operation_remove_msg (mail_op, header, FALSE);
177 g_object_unref (G_OBJECT (mail_op));
181 modest_ui_actions_on_delete (GtkAction *action, ModestWindow *win)
183 g_return_if_fail (MODEST_IS_WINDOW(win));
185 if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
187 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
191 /* Remove each header */
192 do_headers_action (win, headers_action_delete, NULL);
194 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
195 gtk_widget_destroy (GTK_WIDGET(win));
201 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
207 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
209 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
210 gtk_widget_destroy (GTK_WIDGET (win));
211 } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) {
213 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
214 } else if (MODEST_IS_WINDOW (win)) {
215 gtk_widget_destroy (GTK_WIDGET (win));
217 g_return_if_reached ();
222 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
224 GtkClipboard *clipboard = NULL;
225 gchar *selection = NULL;
227 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
228 selection = gtk_clipboard_wait_for_text (clipboard);
230 modest_address_book_add_address (selection);
235 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
238 /* This is currently only implemented for Maemo,
239 * because it requires a providers preset file which is not publically available.
241 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
242 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
243 TRUE /* enabled accounts only */);
244 gboolean accounts_exist = account_names != NULL;
245 g_slist_free (account_names);
247 if (!accounts_exist) {
248 /* If there are no accounts yet, just show the easy-setup wizard, as per the UI spec: */
249 ModestEasysetupWizardDialog *wizard = modest_easysetup_wizard_dialog_new ();
250 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
251 gtk_dialog_run (GTK_DIALOG (wizard));
252 gtk_widget_destroy (GTK_WIDGET (wizard));
254 /* Show the list of accounts: */
255 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
256 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW(win));
257 gtk_dialog_run (account_win);
258 gtk_widget_destroy (GTK_WIDGET(account_win));
261 GtkWidget *dialog, *label;
263 /* Create the widgets */
265 dialog = gtk_dialog_new_with_buttons ("Message",
267 GTK_DIALOG_DESTROY_WITH_PARENT,
271 label = gtk_label_new ("Hello World!");
273 /* Ensure that the dialog box is destroyed when the user responds. */
275 g_signal_connect_swapped (dialog, "response",
276 G_CALLBACK (gtk_widget_destroy),
279 /* Add the label, and show everything we've added to the dialog. */
281 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
283 gtk_widget_show_all (dialog);
284 #endif /* MODEST_PLATFORM_MAEMO */
288 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
290 ModestWindow *msg_win;
292 TnyFolder *folder = NULL;
293 gchar *account_name = NULL;
294 gchar *from_str = NULL;
295 /* GError *err = NULL; */
296 TnyAccount *account = NULL;
297 ModestWindowMgr *mgr;
298 gchar *signature = NULL;
300 account_name = g_strdup(modest_window_get_active_account (win));
302 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
304 g_printerr ("modest: no account found\n");
308 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
310 TNY_ACCOUNT_TYPE_STORE);
312 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
316 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
318 g_printerr ("modest: failed get from string for '%s'\n", account_name);
322 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr (), account_name,
323 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
324 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (), account_name,
325 MODEST_ACCOUNT_SIGNATURE, FALSE);
327 signature = g_strdup ("");
330 msg = modest_tny_msg_new ("", from_str, "", "", "", signature, NULL);
332 g_printerr ("modest: failed to create new msg\n");
336 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
338 g_printerr ("modest: failed to find Drafts folder\n");
342 /* tny_folder_add_msg (folder, msg, &err); */
344 /* g_printerr ("modest: error adding msg to Drafts folder: %s", */
346 /* g_error_free (err); */
350 /* Create and register edit window */
351 msg_win = modest_msg_edit_window_new (msg, account_name);
352 mgr = modest_runtime_get_window_mgr ();
353 modest_window_mgr_register_window (mgr, msg_win);
356 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
358 gtk_widget_show_all (GTK_WIDGET (msg_win));
361 g_free (account_name);
365 g_object_unref (G_OBJECT(account));
367 g_object_unref (G_OBJECT(msg));
369 g_object_unref (G_OBJECT(folder));
373 headers_action_open (TnyHeader *header,
377 modest_ui_actions_on_header_activated (MODEST_HEADER_VIEW (user_data),
379 MODEST_MAIN_WINDOW (win));
383 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
385 GtkWidget *header_view;
387 /* Get header view */
388 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
389 MODEST_WIDGET_TYPE_HEADER_VIEW);
391 /* Open each message */
392 do_headers_action (win, headers_action_open, header_view);
397 reply_forward_func (gpointer data, gpointer user_data)
399 TnyMsg *msg, *new_msg;
400 GetMsgAsyncHelper *helper;
401 ReplyForwardHelper *rf_helper;
402 ModestWindow *msg_win;
403 ModestEditType edit_type;
406 TnyFolder *folder = NULL;
407 TnyAccount *account = NULL;
408 ModestWindowMgr *mgr;
409 gchar *signature = NULL;
411 msg = TNY_MSG (data);
412 helper = (GetMsgAsyncHelper *) user_data;
413 rf_helper = (ReplyForwardHelper *) helper->user_data;
415 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
416 rf_helper->account_name);
417 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
418 rf_helper->account_name,
419 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
420 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
421 rf_helper->account_name,
422 MODEST_ACCOUNT_SIGNATURE, FALSE);
424 /* Create reply mail */
425 switch (rf_helper->action) {
428 modest_tny_msg_create_reply_msg (msg, from, signature,
429 rf_helper->reply_forward_type,
430 MODEST_TNY_MSG_REPLY_MODE_SENDER);
432 case ACTION_REPLY_TO_ALL:
434 modest_tny_msg_create_reply_msg (msg, from, signature, rf_helper->reply_forward_type,
435 MODEST_TNY_MSG_REPLY_MODE_ALL);
436 edit_type = MODEST_EDIT_TYPE_REPLY;
440 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
441 edit_type = MODEST_EDIT_TYPE_FORWARD;
444 g_return_if_reached ();
451 g_printerr ("modest: failed to create message\n");
455 account = modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
456 rf_helper->account_name,
457 TNY_ACCOUNT_TYPE_STORE);
459 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
463 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
465 g_printerr ("modest: failed to find Drafts folder\n");
469 tny_folder_add_msg (folder, msg, &err);
471 g_printerr ("modest: error adding msg to Drafts folder: %s",
477 /* Create and register the windows */
478 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name);
479 mgr = modest_runtime_get_window_mgr ();
480 modest_window_mgr_register_window (mgr, msg_win);
482 /* Show edit window */
483 gtk_widget_show_all (GTK_WIDGET (msg_win));
487 g_object_unref (G_OBJECT (new_msg));
489 g_object_unref (G_OBJECT (folder));
491 g_object_unref (G_OBJECT (account));
493 /* g_free (rf_helper->account_name); */
494 /* g_slice_free (ReplyForwardHelper, rf_helper); */
497 * Common code for the reply and forward actions
500 reply_forward (ReplyForwardAction action, ModestWindow *win)
502 TnyList *header_list;
503 guint reply_forward_type;
505 GetMsgAsyncHelper *helper;
506 ReplyForwardHelper *rf_helper;
508 g_return_if_fail (MODEST_IS_WINDOW(win));
510 header_list = get_selected_headers (win);
514 reply_forward_type = modest_conf_get_int (modest_runtime_get_conf (),
515 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
517 /* We assume that we can only select messages of the
518 same folder and that we reply all of them from the
519 same account. In fact the interface currently only
520 allows single selection */
523 rf_helper = g_slice_new0 (ReplyForwardHelper);
524 rf_helper->reply_forward_type = reply_forward_type;
525 rf_helper->action = action;
527 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
528 if (!rf_helper->account_name)
529 rf_helper->account_name =
530 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
532 helper = g_slice_new0 (GetMsgAsyncHelper);
533 helper->window = win;
534 helper->func = reply_forward_func;
535 helper->iter = tny_list_create_iterator (header_list);
536 helper->user_data = rf_helper;
537 helper->num_ops = tny_list_get_length (header_list);
539 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
541 msg = modest_msg_view_window_get_message(MODEST_MSG_VIEW_WINDOW(win));
543 g_printerr ("modest: no message found\n");
546 reply_forward_func (msg, helper);
548 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
550 helper->mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(win));
551 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), helper->mail_op);
552 modest_mail_operation_process_msg (helper->mail_op, header, helper->num_ops, get_msg_cb, helper);
555 g_object_unref (G_OBJECT (header));
561 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
563 g_return_if_fail (MODEST_IS_WINDOW(win));
565 reply_forward (ACTION_REPLY, win);
569 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
571 g_return_if_fail (MODEST_IS_WINDOW(win));
573 reply_forward (ACTION_FORWARD, win);
577 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
579 g_return_if_fail (MODEST_IS_WINDOW(win));
581 reply_forward (ACTION_REPLY_TO_ALL, win);
585 modest_ui_actions_on_next (GtkAction *action,
586 ModestWindow *window)
588 if (MODEST_IS_MAIN_WINDOW (window)) {
589 GtkWidget *header_view;
591 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
592 MODEST_WIDGET_TYPE_HEADER_VIEW);
596 modest_header_view_select_next (MODEST_HEADER_VIEW(header_view));
597 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
598 modest_msg_view_window_select_next_message (MODEST_MSG_VIEW_WINDOW (window));
600 g_return_if_reached ();
605 modest_ui_actions_on_prev (GtkAction *action,
606 ModestWindow *window)
608 g_return_if_fail (MODEST_IS_WINDOW(window));
610 if (MODEST_IS_MAIN_WINDOW (window)) {
611 GtkWidget *header_view;
612 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
613 MODEST_WIDGET_TYPE_HEADER_VIEW);
617 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
618 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
619 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
621 g_return_if_reached ();
626 modest_ui_actions_on_sort (GtkAction *action,
627 ModestWindow *window)
629 g_return_if_fail (MODEST_IS_WINDOW(window));
631 if (MODEST_IS_MAIN_WINDOW (window)) {
632 GtkWidget *header_view;
633 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
634 MODEST_WIDGET_TYPE_HEADER_VIEW);
638 /* Show sorting dialog */
639 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
645 action_send (const gchar* account_name)
647 TnyAccount *tny_account;
648 ModestTnySendQueue *send_queue;
650 g_return_val_if_fail (account_name, FALSE);
652 /* Get the transport account according to the open connection,
653 * because the account might specify connection-specific SMTP servers.
656 modest_tny_account_store_get_transport_account_for_open_connection (modest_runtime_get_account_store(),
659 g_printerr ("modest: cannot get tny transport account for %s\n", account_name);
663 send_queue = modest_tny_send_queue_new (TNY_CAMEL_TRANSPORT_ACCOUNT(tny_account));
665 g_object_unref (G_OBJECT(tny_account));
666 g_printerr ("modest: cannot get send queue for %s\n", account_name);
670 modest_tny_send_queue_flush (send_queue);
672 g_object_unref (G_OBJECT(send_queue));
673 g_object_unref (G_OBJECT(tny_account));
680 action_receive (const gchar* account_name,
683 TnyAccount *tny_account;
684 ModestMailOperation *mail_op;
686 g_return_val_if_fail (account_name, FALSE);
689 modest_tny_account_store_get_tny_account_by_account (modest_runtime_get_account_store(),
691 TNY_ACCOUNT_TYPE_STORE);
693 g_printerr ("modest: cannot get tny store account for %s\n", account_name);
697 /* Create the mail operation */
698 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
699 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(win));
700 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
701 modest_mail_operation_update_account (mail_op, TNY_STORE_ACCOUNT(tny_account));
703 g_object_unref (G_OBJECT(tny_account));
704 g_object_unref (G_OBJECT (mail_op));
709 /** Check that an appropriate connection is open.
711 gboolean check_for_connection (const gchar *account_name)
713 TnyDevice *device = modest_runtime_get_device ();
716 g_assert (TNY_IS_MAEMO_CONIC_DEVICE (device));
718 TnyMaemoConicDevice *maemo_device = TNY_MAEMO_CONIC_DEVICE (device);
721 if (tny_device_is_online (device))
724 modest_platform_connect_and_wait (NULL);
726 /* TODO: Wait until a result. */
732 do_send_receive_current_or_default (ModestWindow *win)
736 g_message ("%s: online? %s", __FUNCTION__,
737 tny_device_is_online(modest_runtime_get_device()) ? "yes":"no");
739 /* As per the UI spec, only the active account should be affected,
740 * else the default folder if there is no active account: */
742 g_strdup(modest_window_get_active_account(MODEST_WINDOW(win)));
744 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
746 g_printerr ("modest: cannot get default account\n");
750 /* Do not continue if no suitable connection is open: */
751 if (check_for_connection (account_name)) {
752 /* As per the UI spec,
753 * for POP accounts, we should receive,
754 * for IMAP we should synchronize everything, including receiving,
755 * for SMTP we should send,
756 * first receiving, then sending:
758 if (!action_receive(account_name, win))
759 g_printerr ("modest: failed to receive\n");
760 if (!action_send(account_name))
761 g_printerr ("modest: failed to send\n");
763 g_free (account_name);
769 do_send_receive_auto (ModestWindow *win)
771 g_message ("%s: online? %s", __FUNCTION__,
772 tny_device_is_online(modest_runtime_get_device()) ? "yes":"no");
774 /* TODO: Delete the item->data strings as well as the list? */
775 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
776 TRUE /* enabled accounts only */);
777 GSList *iter = account_names;
779 const gchar * account_name = (const char*) iter->data;
781 /* Do not continue if no suitable connection is open: */
782 if (account_name && check_for_connection (account_name)) {
783 /* As per the UI spec,
784 * for POP accounts, we should receive,
785 * for IMAP we should synchronize everything, including receiving,
786 * for SMTP we should send,
787 * first receiving, then sending:
789 if (!action_receive(account_name, win))
790 g_printerr ("modest: failed to receive for account %s\n", account_name);
791 if (!action_send(account_name))
792 g_printerr ("modest: failed to send for account %s\n", account_name);
797 g_slist_free (account_names);
801 do_send_receive (ModestWindow *win)
803 const gboolean auto_update = TRUE; /* TODO: Get gconf setting. */
805 do_send_receive_current_or_default (win);
807 do_send_receive_auto (win);
811 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
813 /* Check that at least one account exists: */
814 GSList *account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
815 TRUE /* enabled accounts only */);
816 gboolean accounts_exist = account_names != NULL;
817 g_slist_free (account_names);
819 /* If not, allow the user to create an account before trying to send/receive. */
820 if (!accounts_exist) {
821 modest_ui_actions_on_accounts (NULL, win);
824 do_send_receive (win);
831 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
834 GtkWidget *header_view;
836 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
838 header_view = modest_main_window_get_child_widget (main_window,
839 MODEST_WIDGET_TYPE_HEADER_VIEW);
843 conf = modest_runtime_get_conf ();
845 /* what is saved/restored is depending on the style; thus; we save with
846 * old style, then update the style, and restore for this new style
848 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
850 if (modest_header_view_get_style
851 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
852 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
853 MODEST_HEADER_VIEW_STYLE_TWOLINES);
855 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
856 MODEST_HEADER_VIEW_STYLE_DETAILS);
858 modest_widget_memory_restore (conf, G_OBJECT(header_view),
859 MODEST_CONF_HEADER_VIEW_KEY);
863 * This function is a generic handler for the tny_folder_get_msg_async
864 * call. It expects as user_data a #GetMsgAsyncHelper. This helper
865 * contains a user provided function that is called inside this
866 * method. This will allow us to use this callback in many different
867 * places. This callback performs the common actions for the
868 * get_msg_async call, more specific actions will be done by the user
872 get_msg_cb (TnyFolder *folder, gboolean canceled, TnyMsg *msg, GError **err, gpointer user_data)
874 GetMsgAsyncHelper *helper;
876 helper = (GetMsgAsyncHelper *) user_data;
879 if ((*err && ((*err)->code == TNY_FOLDER_ERROR_GET_MSG)) || !msg) {
880 modest_ui_actions_on_item_not_found (NULL,
881 MODEST_ITEM_TYPE_MESSAGE,
886 /* Call user function */
888 helper->func (msg, user_data);
890 /* Process next element (if exists) */
891 tny_iterator_next (helper->iter);
892 if (tny_iterator_is_done (helper->iter)) {
893 /* Notify the queue */
894 if (helper->mail_op != NULL)
895 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (), helper->mail_op);
899 ReplyForwardHelper *rf_helper = (ReplyForwardHelper *) helper->user_data;
900 headers = tny_iterator_get_list (helper->iter);
901 g_object_unref (G_OBJECT (headers));
902 g_object_unref (G_OBJECT (helper->iter));
903 g_object_unref (G_OBJECT (helper->mail_op));
904 if (rf_helper != NULL) {
905 g_free (rf_helper->account_name);
906 g_slice_free (ReplyForwardHelper, rf_helper);
908 g_slice_free (GetMsgAsyncHelper, helper);
911 header = TNY_HEADER (tny_iterator_get_current (helper->iter));
912 modest_mail_operation_process_msg (helper->mail_op, header, helper->num_ops, get_msg_cb, helper);
914 g_object_unref (G_OBJECT(header));
919 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
921 ModestMainWindow *main_window)
923 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
925 /* If no header has been selected then exit */
929 /* Update Main window title */
930 if (GTK_WIDGET_HAS_FOCUS (header_view)) {
931 const gchar *subject = tny_header_get_subject (header);
932 if (subject && strcmp (subject, ""))
933 gtk_window_set_title (GTK_WINDOW (main_window), subject);
935 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
942 modest_ui_actions_on_header_activated (ModestHeaderView *header_view, TnyHeader *header,
943 ModestMainWindow *main_window)
945 ModestWindow *win = NULL;
946 TnyFolder *folder = NULL;
948 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
949 ModestWindowMgr *mgr;
952 GtkTreeSelection *sel = NULL;
953 GList *sel_list = NULL;
955 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
960 folder = tny_header_get_folder (header);
962 g_printerr ("modest: cannot get folder for header\n");
965 if (modest_tny_folder_is_local_folder (folder))
966 folder_type = modest_tny_folder_get_local_folder_type (folder);
968 /* FIXME: make async?; check error */
969 msg = tny_folder_get_msg (folder, header, NULL);
971 g_printerr ("modest: cannot get msg for header\n");
975 /* Look if we already have a message view for that header */
976 mgr = modest_runtime_get_window_mgr ();
977 win = modest_window_mgr_find_window_by_msguid (mgr, tny_header_get_uid (header));
979 /* If not, create a new window */
983 account = g_strdup(modest_window_get_active_account(MODEST_WINDOW(main_window)));
985 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
987 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
988 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
989 if (sel_list != NULL) {
990 gtk_tree_model_get_iter (model, &iter, (GtkTreePath *) sel_list->data);
992 switch (folder_type) {
993 case TNY_FOLDER_TYPE_DRAFTS:
994 win = modest_msg_edit_window_new (msg, account);
997 win = modest_msg_view_window_new_with_header_model (msg, account, model, iter);
1000 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
1001 g_list_free (sel_list);
1003 win = modest_msg_view_window_new (msg, account);
1005 modest_window_mgr_register_window (mgr, win);
1007 gtk_window_set_transient_for (GTK_WINDOW (win),
1008 GTK_WINDOW (main_window));
1011 gtk_widget_show_all (GTK_WIDGET(win));
1013 g_object_unref (G_OBJECT (msg));
1016 g_object_unref (G_OBJECT (folder));
1020 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1021 TnyFolderStore *folder_store,
1023 ModestMainWindow *main_window)
1026 GtkWidget *header_view;
1028 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1030 header_view = modest_main_window_get_child_widget(main_window,
1031 MODEST_WIDGET_TYPE_HEADER_VIEW);
1035 conf = modest_runtime_get_conf ();
1037 if (TNY_IS_FOLDER (folder_store)) {
1039 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1042 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1043 TNY_FOLDER (folder_store));
1044 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1045 MODEST_CONF_HEADER_VIEW_KEY);
1047 modest_widget_memory_save (conf, G_OBJECT (header_view), MODEST_CONF_HEADER_VIEW_KEY);
1048 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view), NULL);
1050 } else if (TNY_IS_ACCOUNT (folder_store)) {
1052 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1057 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1064 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1066 if (g_main_depth > 0)
1067 gdk_threads_enter ();
1068 online = tny_device_is_online (modest_runtime_get_device());
1071 /* already online -- the item is simply not there... */
1072 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1074 GTK_MESSAGE_WARNING,
1076 _("The %s you selected cannot be found"),
1078 gtk_dialog_run (GTK_DIALOG(dialog));
1080 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1084 GTK_RESPONSE_REJECT,
1086 GTK_RESPONSE_ACCEPT,
1088 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1089 "Do you want to get online?"), item);
1090 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1091 gtk_label_new (txt), FALSE, FALSE, 0);
1092 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1095 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1096 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1097 // modest_platform_connect_and_wait ();;
1100 gtk_widget_destroy (dialog);
1101 if (g_main_depth > 0)
1102 gdk_threads_leave ();
1106 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1109 g_message ("%s %s", __FUNCTION__, link);
1114 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
1117 modest_platform_activate_uri (link);
1121 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
1124 modest_platform_show_uri_popup (link);
1128 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
1131 g_message (__FUNCTION__);
1136 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
1137 const gchar *address,
1140 g_message ("%s %s", __FUNCTION__, address);
1144 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1146 TnyTransportAccount *transport_account;
1147 ModestMailOperation *mail_operation;
1149 gchar *account_name, *from;
1150 ModestAccountMgr *account_mgr;
1152 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1154 data = modest_msg_edit_window_get_msg_data (edit_window);
1156 account_mgr = modest_runtime_get_account_mgr();
1157 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1159 account_name = modest_account_mgr_get_default_account (account_mgr);
1160 if (!account_name) {
1161 g_printerr ("modest: no account found\n");
1162 modest_msg_edit_window_free_msg_data (edit_window, data);
1166 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_tny_account_by_account
1167 (modest_runtime_get_account_store(),
1169 TNY_ACCOUNT_TYPE_TRANSPORT));
1170 if (!transport_account) {
1171 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1172 g_free (account_name);
1173 modest_msg_edit_window_free_msg_data (edit_window, data);
1176 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1178 /* Create the mail operation */
1179 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_INFO, G_OBJECT(edit_window));
1180 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1182 modest_mail_operation_save_to_drafts (mail_operation,
1192 data->priority_flags);
1195 g_free (account_name);
1196 g_object_unref (G_OBJECT (transport_account));
1197 g_object_unref (G_OBJECT (mail_operation));
1199 modest_msg_edit_window_free_msg_data (edit_window, data);
1201 /* Save settings and close the window */
1202 gtk_widget_destroy (GTK_WIDGET (edit_window));
1205 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
1207 TnyTransportAccount *transport_account;
1208 ModestMailOperation *mail_operation;
1210 gchar *account_name, *from;
1211 ModestAccountMgr *account_mgr;
1213 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
1215 if (!modest_msg_edit_window_check_names (edit_window))
1218 data = modest_msg_edit_window_get_msg_data (edit_window);
1220 /* FIXME: Code added just for testing. The final version will
1221 use the send queue provided by tinymail and some
1223 account_mgr = modest_runtime_get_account_mgr();
1224 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
1226 account_name = modest_account_mgr_get_default_account (account_mgr);
1227 if (!account_name) {
1228 g_printerr ("modest: no account found\n");
1229 modest_msg_edit_window_free_msg_data (edit_window, data);
1233 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
1234 (modest_runtime_get_account_store(),
1236 if (!transport_account) {
1237 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1238 g_free (account_name);
1239 modest_msg_edit_window_free_msg_data (edit_window, data);
1242 from = modest_account_mgr_get_from_string (account_mgr, account_name);
1244 /* Create the mail operation */
1245 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_SEND, G_OBJECT(edit_window));
1246 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
1248 modest_mail_operation_send_new_mail (mail_operation,
1258 data->priority_flags);
1261 g_free (account_name);
1262 g_object_unref (G_OBJECT (transport_account));
1263 g_object_unref (G_OBJECT (mail_operation));
1265 modest_msg_edit_window_free_msg_data (edit_window, data);
1267 /* Save settings and close the window */
1268 gtk_widget_destroy (GTK_WIDGET (edit_window));
1272 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
1273 ModestMsgEditWindow *window)
1275 ModestMsgEditFormatState *format_state = NULL;
1277 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1278 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1280 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1283 format_state = modest_msg_edit_window_get_format_state (window);
1284 g_return_if_fail (format_state != NULL);
1286 format_state->bold = gtk_toggle_action_get_active (action);
1287 modest_msg_edit_window_set_format_state (window, format_state);
1288 g_free (format_state);
1293 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
1294 ModestMsgEditWindow *window)
1296 ModestMsgEditFormatState *format_state = NULL;
1298 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1299 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1301 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1304 format_state = modest_msg_edit_window_get_format_state (window);
1305 g_return_if_fail (format_state != NULL);
1307 format_state->italics = gtk_toggle_action_get_active (action);
1308 modest_msg_edit_window_set_format_state (window, format_state);
1309 g_free (format_state);
1314 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
1315 ModestMsgEditWindow *window)
1317 ModestMsgEditFormatState *format_state = NULL;
1319 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1320 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
1322 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1325 format_state = modest_msg_edit_window_get_format_state (window);
1326 g_return_if_fail (format_state != NULL);
1328 format_state->bullet = gtk_toggle_action_get_active (action);
1329 modest_msg_edit_window_set_format_state (window, format_state);
1330 g_free (format_state);
1335 modest_ui_actions_on_change_justify (GtkRadioAction *action,
1336 GtkRadioAction *selected,
1337 ModestMsgEditWindow *window)
1339 ModestMsgEditFormatState *format_state = NULL;
1340 GtkJustification value;
1342 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1344 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1347 value = gtk_radio_action_get_current_value (selected);
1349 format_state = modest_msg_edit_window_get_format_state (window);
1350 g_return_if_fail (format_state != NULL);
1352 format_state->justification = value;
1353 modest_msg_edit_window_set_format_state (window, format_state);
1354 g_free (format_state);
1358 modest_ui_actions_on_select_editor_color (GtkAction *action,
1359 ModestMsgEditWindow *window)
1361 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1362 g_return_if_fail (GTK_IS_ACTION (action));
1364 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1367 modest_msg_edit_window_select_color (window);
1371 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
1372 ModestMsgEditWindow *window)
1374 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1375 g_return_if_fail (GTK_IS_ACTION (action));
1377 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1380 modest_msg_edit_window_select_background_color (window);
1384 modest_ui_actions_on_insert_image (GtkAction *action,
1385 ModestMsgEditWindow *window)
1387 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1388 g_return_if_fail (GTK_IS_ACTION (action));
1390 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
1393 modest_msg_edit_window_insert_image (window);
1397 * Shows a dialog with an entry that asks for some text. The returned
1398 * value must be freed by the caller. The dialog window title will be
1402 ask_for_folder_name (GtkWindow *parent_window,
1405 GtkWidget *dialog, *entry;
1406 gchar *folder_name = NULL;
1408 /* Ask for folder name */
1409 dialog = gtk_dialog_new_with_buttons (_("New Folder Name"),
1413 GTK_RESPONSE_REJECT,
1415 GTK_RESPONSE_ACCEPT,
1417 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1418 gtk_label_new(title),
1421 entry = gtk_entry_new_with_max_length (40);
1422 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1426 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1428 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1429 folder_name = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
1431 gtk_widget_destroy (dialog);
1437 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
1439 TnyFolderStore *parent_folder;
1440 GtkWidget *folder_view;
1442 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1444 folder_view = modest_main_window_get_child_widget (main_window,
1445 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1449 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1451 if (parent_folder) {
1452 gboolean finished = FALSE;
1454 gchar *folder_name = NULL, *suggested_name = NULL;
1456 /* Run the new folder dialog */
1458 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (main_window),
1463 if (result == GTK_RESPONSE_REJECT) {
1466 ModestMailOperation *mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_INFO, G_OBJECT(main_window));
1467 TnyFolder *new_folder = NULL;
1469 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1472 new_folder = modest_mail_operation_create_folder (mail_op,
1474 (const gchar *) folder_name);
1476 g_object_unref (new_folder);
1480 /* /\* TODO: check error and follow proper actions *\/ */
1481 /* /\* suggested_name = X; *\/ */
1482 /* /\* Show error to the user *\/ */
1483 /* modest_platform_run_information_dialog (GTK_WINDOW (main_window), */
1484 /* MODEST_INFORMATION_CREATE_FOLDER); */
1486 g_object_unref (mail_op);
1488 g_free (folder_name);
1492 g_object_unref (parent_folder);
1497 modest_ui_actions_on_rename_folder (GtkAction *action,
1498 ModestMainWindow *main_window)
1500 TnyFolderStore *folder;
1501 GtkWidget *folder_view;
1503 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1505 folder_view = modest_main_window_get_child_widget (main_window,
1506 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1510 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1512 if (folder && TNY_IS_FOLDER (folder)) {
1514 folder_name = ask_for_folder_name (GTK_WINDOW (main_window),
1515 _("Please enter a new name for the folder"));
1517 if (folder_name != NULL && strlen (folder_name) > 0) {
1518 ModestMailOperation *mail_op;
1520 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_INFO, G_OBJECT(main_window));
1521 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1524 modest_mail_operation_rename_folder (mail_op,
1525 TNY_FOLDER (folder),
1526 (const gchar *) folder_name);
1528 g_object_unref (mail_op);
1529 g_free (folder_name);
1531 g_object_unref (folder);
1536 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
1538 TnyFolderStore *folder;
1539 GtkWidget *folder_view;
1543 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1545 folder_view = modest_main_window_get_child_widget (main_window,
1546 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1550 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1553 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
1554 tny_folder_get_name (TNY_FOLDER (folder)));
1555 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
1556 (const gchar *) message);
1559 if (response == GTK_RESPONSE_OK) {
1560 ModestMailOperation *mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_DELETE, G_OBJECT(main_window));
1562 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1564 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
1566 /* Show error if happened */
1567 if (modest_mail_operation_get_error (mail_op))
1568 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
1569 MODEST_INFORMATION_DELETE_FOLDER);
1571 g_object_unref (G_OBJECT (mail_op));
1574 g_object_unref (G_OBJECT (folder));
1578 modest_ui_actions_on_delete_folder (GtkAction *action,
1579 ModestMainWindow *main_window)
1581 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1583 delete_folder (main_window, FALSE);
1587 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
1589 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1591 delete_folder (main_window, TRUE);
1595 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
1596 const gchar* account_name,
1600 ModestMainWindow *main_window)
1603 GtkWidget *dialog, *entry, *remember_pass_check;
1605 dialog = gtk_dialog_new_with_buttons (_("Password requested"),
1609 GTK_RESPONSE_REJECT,
1611 GTK_RESPONSE_ACCEPT,
1613 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
1615 txt = g_strdup_printf (_("Please enter your password for %s"), account_name);
1616 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
1620 entry = gtk_entry_new_with_max_length (40);
1621 gtk_entry_set_visibility (GTK_ENTRY(entry), FALSE);
1622 gtk_entry_set_invisible_char (GTK_ENTRY(entry), 0x2022); /* bullet unichar */
1624 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry,
1627 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
1628 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
1631 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1633 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1634 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry)));
1641 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
1646 gtk_widget_destroy (dialog);
1650 modest_ui_actions_on_cut (GtkAction *action,
1651 ModestWindow *window)
1653 GtkWidget *focused_widget;
1655 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1656 if (GTK_IS_EDITABLE (focused_widget)) {
1657 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
1658 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1659 GtkTextBuffer *buffer;
1660 GtkClipboard *clipboard;
1662 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1663 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1664 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
1669 modest_ui_actions_on_copy (GtkAction *action,
1670 ModestWindow *window)
1672 GtkClipboard *clipboard;
1673 GtkWidget *focused_widget;
1675 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1676 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1677 if (GTK_IS_LABEL (focused_widget)) {
1678 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
1679 } else if (GTK_IS_EDITABLE (focused_widget)) {
1680 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
1681 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1682 GtkTextBuffer *buffer;
1684 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1685 gtk_text_buffer_copy_clipboard (buffer, clipboard);
1690 modest_ui_actions_on_undo (GtkAction *action,
1691 ModestWindow *window)
1693 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
1694 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
1696 g_return_if_reached ();
1701 modest_ui_actions_on_paste (GtkAction *action,
1702 ModestWindow *window)
1704 GtkWidget *focused_widget;
1706 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1707 if (GTK_IS_EDITABLE (focused_widget)) {
1708 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
1709 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1710 GtkTextBuffer *buffer;
1711 GtkClipboard *clipboard;
1713 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
1714 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1715 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
1720 modest_ui_actions_on_select_all (GtkAction *action,
1721 ModestWindow *window)
1723 GtkWidget *focused_widget;
1725 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
1726 if (GTK_IS_LABEL (focused_widget)) {
1727 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
1728 } else if (GTK_IS_EDITABLE (focused_widget)) {
1729 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
1730 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
1731 GtkTextBuffer *buffer;
1732 GtkTextIter start, end;
1734 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
1735 gtk_text_buffer_get_start_iter (buffer, &start);
1736 gtk_text_buffer_get_end_iter (buffer, &end);
1737 gtk_text_buffer_select_range (buffer, &start, &end);
1742 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
1743 GtkRadioAction *selected,
1744 ModestWindow *window)
1748 value = gtk_radio_action_get_current_value (selected);
1749 if (MODEST_IS_WINDOW (window)) {
1750 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
1754 void modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
1755 GtkRadioAction *selected,
1756 ModestWindow *window)
1758 TnyHeaderFlags flags;
1759 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1761 flags = gtk_radio_action_get_current_value (selected);
1762 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
1765 void modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
1766 GtkRadioAction *selected,
1767 ModestWindow *window)
1771 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1773 file_format = gtk_radio_action_get_current_value (selected);
1774 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
1779 modest_ui_actions_on_zoom_plus (GtkAction *action,
1780 ModestWindow *window)
1782 g_return_if_fail (MODEST_IS_WINDOW (window));
1784 modest_window_zoom_plus (MODEST_WINDOW (window));
1788 modest_ui_actions_on_zoom_minus (GtkAction *action,
1789 ModestWindow *window)
1791 g_return_if_fail (MODEST_IS_WINDOW (window));
1793 modest_window_zoom_minus (MODEST_WINDOW (window));
1797 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
1798 ModestWindow *window)
1800 ModestWindowMgr *mgr;
1801 gboolean fullscreen, active;
1802 g_return_if_fail (MODEST_IS_WINDOW (window));
1804 mgr = modest_runtime_get_window_mgr ();
1806 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
1807 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1809 if (active != fullscreen) {
1810 modest_window_mgr_set_fullscreen_mode (mgr, active);
1811 gtk_window_present (GTK_WINDOW (window));
1816 modest_ui_actions_on_change_fullscreen (GtkAction *action,
1817 ModestWindow *window)
1819 ModestWindowMgr *mgr;
1820 gboolean fullscreen;
1822 g_return_if_fail (MODEST_IS_WINDOW (window));
1824 mgr = modest_runtime_get_window_mgr ();
1825 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1826 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
1828 gtk_window_present (GTK_WINDOW (window));
1832 * Used by modest_ui_actions_on_details to call do_headers_action
1835 headers_action_show_details (TnyHeader *header,
1836 ModestWindow *window,
1843 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
1846 gtk_widget_show_all (dialog);
1847 gtk_dialog_run (GTK_DIALOG (dialog));
1849 gtk_widget_destroy (dialog);
1853 * Show the folder details in a ModestDetailsDialog widget
1856 show_folder_details (TnyFolder *folder,
1862 dialog = modest_details_dialog_new_with_folder (window, folder);
1865 gtk_widget_show_all (dialog);
1866 gtk_dialog_run (GTK_DIALOG (dialog));
1868 gtk_widget_destroy (dialog);
1872 * Show the header details in a ModestDetailsDialog widget
1875 modest_ui_actions_on_details (GtkAction *action,
1878 TnyList * headers_list;
1882 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1885 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
1889 headers_list = get_selected_headers (win);
1893 iter = tny_list_create_iterator (headers_list);
1895 header = TNY_HEADER (tny_iterator_get_current (iter));
1896 headers_action_show_details (header, win, NULL);
1897 g_object_unref (header);
1899 g_object_unref (iter);
1901 } else if (MODEST_IS_MAIN_WINDOW (win)) {
1902 GtkWidget *folder_view, *header_view;
1904 /* Check which widget has the focus */
1905 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1906 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1907 if (gtk_widget_is_focus (folder_view)) {
1910 folder = (TnyFolder *) modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1912 /* Show only when it's a folder */
1913 if (!folder || !TNY_IS_FOLDER (folder))
1916 show_folder_details (folder, GTK_WINDOW (win));
1919 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1920 MODEST_WIDGET_TYPE_HEADER_VIEW);
1921 /* Show details of each header */
1922 do_headers_action (win, headers_action_show_details, header_view);
1928 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
1929 ModestMsgEditWindow *window)
1931 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1933 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
1937 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
1938 ModestMsgEditWindow *window)
1940 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
1942 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
1946 modest_ui_actions_toggle_folders_view (GtkAction *action,
1947 ModestMainWindow *main_window)
1951 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1953 conf = modest_runtime_get_conf ();
1955 if (modest_main_window_get_style (main_window) == MODEST_MAIN_WINDOW_STYLE_SPLIT)
1956 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
1958 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
1962 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
1963 ModestWindow *window)
1965 gboolean active, fullscreen = FALSE;
1966 ModestWindowMgr *mgr;
1968 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
1970 /* Check if we want to toggle the toolbar vuew in fullscreen
1972 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
1973 "ViewShowToolbarFullScreen")) {
1977 /* Toggle toolbar */
1978 mgr = modest_runtime_get_window_mgr ();
1979 modest_window_mgr_show_toolbars (mgr, active, fullscreen);
1983 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
1984 ModestMsgEditWindow *window)
1986 modest_msg_edit_window_select_font (window);
1990 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
1991 const gchar *display_name,
1994 /* Do not change the application name if the widget has not
1995 the focus. This callback could be called even if the folder
1996 view has not the focus, because the handled signal could be
1997 emitted when the folder view is redrawn */
1998 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
2000 gtk_window_set_title (window, display_name);
2002 gtk_window_set_title (window, " ");
2007 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
2009 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2010 modest_msg_edit_window_select_contacts (window);
2014 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
2016 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2017 modest_msg_edit_window_check_names (window);
2022 create_move_to_dialog (ModestWindow *win,
2023 GtkWidget *folder_view,
2024 GtkWidget **tree_view)
2026 GtkWidget *dialog, *scroll;
2028 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
2030 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
2032 GTK_RESPONSE_ACCEPT,
2034 GTK_RESPONSE_REJECT,
2037 /* Create scrolled window */
2038 scroll = gtk_scrolled_window_new (NULL, NULL);
2039 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
2040 GTK_POLICY_AUTOMATIC,
2041 GTK_POLICY_AUTOMATIC);
2043 /* Create folder view */
2044 *tree_view = modest_folder_view_new (NULL);
2045 gtk_tree_view_set_model (GTK_TREE_VIEW (*tree_view),
2046 gtk_tree_view_get_model (GTK_TREE_VIEW (folder_view)));
2047 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
2049 /* Add scroll to dialog */
2050 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
2051 scroll, FALSE, FALSE, 0);
2053 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2059 * Returns TRUE if at least one of the headers of the list belongs to
2060 * a message that has been fully retrieved.
2063 has_retrieved_msgs (TnyList *list)
2066 gboolean found = FALSE;
2068 iter = tny_list_create_iterator (list);
2069 while (tny_iterator_is_done (iter) && !found) {
2071 TnyHeaderFlags flags;
2073 header = TNY_HEADER (tny_iterator_get_current (iter));
2074 flags = tny_header_get_flags (header);
2075 if (!(flags & TNY_HEADER_FLAG_PARTIAL))
2079 tny_iterator_next (iter);
2081 g_object_unref (iter);
2087 * Shows a confirmation dialog to the user when we're moving messages
2088 * from a remote server to the local storage. Returns the dialog
2089 * response. If it's other kind of movement the it always returns
2093 msgs_move_to_confirmation (GtkWindow *win,
2094 TnyFolder *dest_folder,
2097 gint response = GTK_RESPONSE_OK;
2099 /* If the destination is a local folder */
2100 if (modest_tny_folder_is_local_folder (dest_folder)) {
2101 TnyFolder *src_folder;
2105 /* Get source folder */
2106 iter = tny_list_create_iterator (headers);
2107 header = TNY_HEADER (tny_iterator_get_current (iter));
2108 src_folder = tny_header_get_folder (header);
2109 g_object_unref (header);
2110 g_object_unref (iter);
2112 /* If the source is a remote folder */
2113 if (!modest_tny_folder_is_local_folder (src_folder)) {
2114 const gchar *message;
2116 if (tny_list_get_length (headers) == 1)
2117 if (has_retrieved_msgs (headers))
2118 message = _("mcen_nc_move_retrieve");
2120 message = _("mcen_nc_move_header");
2122 if (has_retrieved_msgs (headers))
2123 message = _("mcen_nc_move_retrieves");
2125 message = _("mcen_nc_move_headers");
2127 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
2128 (const gchar *) message);
2135 * UI handler for the "Move to" action when invoked from the
2139 modest_ui_actions_on_main_window_move_to (GtkAction *action,
2140 ModestMainWindow *win)
2142 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2144 TnyFolderStore *folder_store;
2145 ModestMailOperation *mail_op = NULL;
2147 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
2149 /* Get the folder view */
2150 folder_view = modest_main_window_get_child_widget (win,
2151 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2153 /* Create and run the dialog */
2154 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2155 result = gtk_dialog_run (GTK_DIALOG(dialog));
2157 /* We do this to save an indentation level ;-) */
2158 if (result != GTK_RESPONSE_ACCEPT)
2161 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2163 if (TNY_IS_ACCOUNT (folder_store))
2166 /* Get folder or messages to transfer */
2167 if (gtk_widget_is_focus (folder_view)) {
2168 TnyFolderStore *src_folder;
2169 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2171 if (TNY_IS_FOLDER (src_folder)) {
2172 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(win));
2173 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2176 modest_mail_operation_xfer_folder (mail_op,
2177 TNY_FOLDER (src_folder),
2180 g_object_unref (G_OBJECT (mail_op));
2184 g_object_unref (G_OBJECT (src_folder));
2186 GtkWidget *header_view;
2187 header_view = modest_main_window_get_child_widget (win,
2188 MODEST_WIDGET_TYPE_HEADER_VIEW);
2189 if (gtk_widget_is_focus (header_view)) {
2193 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
2195 /* Ask for user confirmation */
2196 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2197 TNY_FOLDER (folder_store),
2200 /* Transfer messages */
2201 if (response == GTK_RESPONSE_OK) {
2202 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(win));
2203 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2206 modest_mail_operation_xfer_msgs (mail_op,
2208 TNY_FOLDER (folder_store),
2210 g_object_unref (G_OBJECT (mail_op));
2214 g_object_unref (folder_store);
2217 gtk_widget_destroy (dialog);
2222 * UI handler for the "Move to" action when invoked from the
2223 * ModestMsgViewWindow
2226 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
2227 ModestMsgViewWindow *win)
2229 GtkWidget *dialog, *folder_view, *tree_view = NULL;
2231 ModestMainWindow *main_window;
2236 /* Get the folder view */
2237 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2238 folder_view = modest_main_window_get_child_widget (main_window,
2239 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2241 /* Create and run the dialog */
2242 dialog = create_move_to_dialog (MODEST_WINDOW (win), folder_view, &tree_view);
2243 result = gtk_dialog_run (GTK_DIALOG(dialog));
2245 if (result == GTK_RESPONSE_ACCEPT) {
2246 TnyFolderStore *folder_store;
2249 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
2251 /* Create header list */
2252 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
2253 header = tny_msg_get_header (msg);
2254 headers = tny_simple_list_new ();
2255 tny_list_prepend (headers, G_OBJECT (header));
2256 g_object_unref (header);
2257 g_object_unref (msg);
2259 /* Ask user for confirmation. MSG-NOT404 */
2260 response = msgs_move_to_confirmation (GTK_WINDOW (win),
2261 TNY_FOLDER (folder_store),
2264 /* Transfer current msg */
2265 if (response == GTK_RESPONSE_OK) {
2266 ModestMailOperation *mail_op;
2268 /* Create mail op */
2269 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_ID_RECEIVE, G_OBJECT(win));
2270 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2273 /* Transfer messages */
2274 modest_mail_operation_xfer_msgs (mail_op,
2276 TNY_FOLDER (folder_store),
2278 g_object_unref (G_OBJECT (mail_op));
2280 g_object_unref (headers);
2282 g_object_unref (folder_store);
2284 gtk_widget_destroy (dialog);
2288 modest_ui_actions_on_move_to (GtkAction *action,
2291 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
2292 MODEST_IS_MSG_VIEW_WINDOW (win));
2294 if (MODEST_IS_MAIN_WINDOW (win))
2295 modest_ui_actions_on_main_window_move_to (action,
2296 MODEST_MAIN_WINDOW (win));
2298 modest_ui_actions_on_msg_view_window_move_to (action,
2299 MODEST_MSG_VIEW_WINDOW (win));
2303 * Calls #HeadersFunc for each header already selected in the main
2304 * window or the message currently being shown in the msg view window
2307 do_headers_action (ModestWindow *win,
2311 TnyList *headers_list;
2315 headers_list = get_selected_headers (win);
2319 /* Call the function for each header */
2320 iter = tny_list_create_iterator (headers_list);
2321 while (!tny_iterator_is_done (iter)) {
2324 header = TNY_HEADER (tny_iterator_get_current (iter));
2325 func (header, win, user_data);
2326 g_object_unref (header);
2327 tny_iterator_next (iter);
2329 g_object_unref (iter);