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>
48 #include <tny-camel-folder.h>
49 #include <tny-camel-imap-folder.h>
50 #include <tny-camel-pop-folder.h>
52 #ifdef MODEST_PLATFORM_MAEMO
53 #include "maemo/modest-osso-state-saving.h"
54 #include "maemo/modest-maemo-utils.h"
55 #include "maemo/modest-hildon-includes.h"
56 #endif /* MODEST_PLATFORM_MAEMO */
58 #include "widgets/modest-ui-constants.h"
59 #include <widgets/modest-main-window.h>
60 #include <widgets/modest-msg-view-window.h>
61 #include <widgets/modest-account-view-window.h>
62 #include <widgets/modest-details-dialog.h>
63 #include <widgets/modest-attachments-view.h>
64 #include "widgets/modest-folder-view.h"
65 #include "widgets/modest-global-settings-dialog.h"
66 #include "modest-connection-specific-smtp-window.h"
67 #include "modest-account-mgr-helpers.h"
68 #include "modest-mail-operation.h"
69 #include "modest-text-utils.h"
71 #ifdef MODEST_HAVE_EASYSETUP
72 #include "easysetup/modest-easysetup-wizard.h"
73 #endif /* MODEST_HAVE_EASYSETUP */
75 #include <modest-widget-memory.h>
76 #include <tny-error.h>
77 #include <tny-simple-list.h>
78 #include <tny-msg-view.h>
79 #include <tny-device.h>
80 #include <tny-merge-folder.h>
82 #include <gtkhtml/gtkhtml.h>
84 typedef struct _GetMsgAsyncHelper {
86 ModestMailOperation *mail_op;
93 typedef enum _ReplyForwardAction {
99 typedef struct _ReplyForwardHelper {
100 guint reply_forward_type;
101 ReplyForwardAction action;
103 GtkWidget *parent_window;
104 } ReplyForwardHelper;
106 typedef struct _MoveToHelper {
107 ModestMailOperation *mail_op;
111 typedef struct _PasteAsAttachmentHelper {
112 ModestMsgEditWindow *window;
114 } PasteAsAttachmentHelper;
118 * The do_headers_action uses this kind of functions to perform some
119 * action to each member of a list of headers
121 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
123 static void do_headers_action (ModestWindow *win,
127 static void open_msg_cb (ModestMailOperation *mail_op,
132 static void reply_forward_cb (ModestMailOperation *mail_op,
137 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
139 static void folder_refreshed_cb (ModestMailOperation *mail_op,
143 static void _on_send_receive_progress_changed (ModestMailOperation *mail_op,
144 ModestMailOperationState *state,
147 static gint header_list_count_uncached_msgs (TnyList *header_list);
148 static gboolean connect_to_get_msg (
150 gint num_of_uncached_msgs);
154 /* Show the account creation wizard dialog.
155 * returns: TRUE if an account was created. FALSE if the user cancelled.
158 modest_run_account_setup_wizard (ModestWindow *win)
160 gboolean result = FALSE;
163 wizard = modest_window_mgr_get_easysetup_dialog
164 (modest_runtime_get_window_mgr());
166 /* old wizard is active already; present it and
167 * act as if the user cancelled the non-existing
170 printf ("wizard already active\n");
173 /* there is no such wizard yet */
174 wizard = GTK_DIALOG(modest_easysetup_wizard_dialog_new ());
175 modest_window_mgr_set_easysetup_dialog
176 (modest_runtime_get_window_mgr(), GTK_DIALOG(wizard));
180 /* always present a main window in the background
181 * we do it here, so we cannot end up with to wizards (as this
182 * function might be called in modest_window_mgr_get_main_window as well */
184 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr());
186 /* make sure the mainwindow is visible */
187 gtk_widget_show_all (GTK_WIDGET(win));
188 gtk_window_present (GTK_WINDOW(win));
191 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
193 /* Don't make this a modal window, because secondary windows will then
194 * be unusable, freezing the UI: */
195 /* gtk_window_set_modal (GTK_WINDOW (wizard), TRUE); */
197 gint dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
198 if (dialog_response == GTK_RESPONSE_CANCEL)
201 /* Check whether an account was created: */
202 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
205 gtk_widget_destroy (GTK_WIDGET (wizard));
207 /* clear it from the window mgr */
208 modest_window_mgr_set_easysetup_dialog
209 (modest_runtime_get_window_mgr(), NULL);
216 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
219 const gchar *authors[] = {
220 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
223 about = gtk_about_dialog_new ();
224 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
225 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
226 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
227 _("Copyright (c) 2006, Nokia Corporation\n"
228 "All rights reserved."));
229 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
230 _("a modest e-mail client\n\n"
231 "design and implementation: Dirk-Jan C. Binnema\n"
232 "contributions from the fine people at KC and Ig\n"
233 "uses the tinymail email framework written by Philip van Hoof"));
234 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
235 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
236 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
237 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
239 gtk_dialog_run (GTK_DIALOG (about));
240 gtk_widget_destroy(about);
244 * Gets the list of currently selected messages. If the win is the
245 * main window, then it returns a newly allocated list of the headers
246 * selected in the header view. If win is the msg view window, then
247 * the value returned is a list with just a single header.
249 * The caller of this funcion must free the list.
252 get_selected_headers (ModestWindow *win)
254 if (MODEST_IS_MAIN_WINDOW(win)) {
255 GtkWidget *header_view;
257 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
258 MODEST_WIDGET_TYPE_HEADER_VIEW);
259 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
261 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
262 /* for MsgViewWindows, we simply return a list with one element */
264 TnyList *list = NULL;
266 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
267 if (header != NULL) {
268 list = tny_simple_list_new ();
269 tny_list_prepend (list, G_OBJECT(header));
270 g_object_unref (G_OBJECT(header));
280 headers_action_mark_as_read (TnyHeader *header,
284 TnyHeaderFlags flags;
286 g_return_if_fail (TNY_IS_HEADER(header));
288 flags = tny_header_get_flags (header);
289 if (flags & TNY_HEADER_FLAG_SEEN) return;
290 tny_header_set_flags (header, TNY_HEADER_FLAG_SEEN);
294 headers_action_mark_as_unread (TnyHeader *header,
298 TnyHeaderFlags flags;
300 g_return_if_fail (TNY_IS_HEADER(header));
302 flags = tny_header_get_flags (header);
303 if (flags & TNY_HEADER_FLAG_SEEN) {
304 tny_header_unset_flags (header, TNY_HEADER_FLAG_SEEN);
308 /** A convenience method, because deleting a message is
309 * otherwise complicated, and it's best to change it in one place
312 void modest_do_message_delete (TnyHeader *header, ModestWindow *win)
314 ModestMailOperation *mail_op = NULL;
315 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE,
316 win ? G_OBJECT(win) : NULL);
317 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
320 /* Always delete. TODO: Move to trash still not supported */
321 modest_mail_operation_remove_msg (mail_op, header, FALSE);
322 g_object_unref (G_OBJECT (mail_op));
325 /** A convenience method, because deleting a message is
326 * otherwise complicated, and it's best to change it in one place
329 void modest_do_messages_delete (TnyList *headers, ModestWindow *win)
331 ModestMailOperation *mail_op = NULL;
332 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_DELETE,
333 win ? G_OBJECT(win) : NULL);
334 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
337 /* Always delete. TODO: Move to trash still not supported */
338 modest_mail_operation_remove_msgs (mail_op, headers, FALSE);
339 g_object_unref (G_OBJECT (mail_op));
343 /* headers_action_delete (TnyHeader *header, */
344 /* ModestWindow *win, */
345 /* gpointer user_data) */
347 /* modest_do_message_delete (header, win); */
351 /** After deleing a message that is currently visible in a window,
352 * show the next message from the list, or close the window if there are no more messages.
354 void modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
356 /* Close msg view window or select next */
357 if (modest_msg_view_window_last_message_selected (win) &&
358 modest_msg_view_window_first_message_selected (win)) {
359 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
361 if (!modest_msg_view_window_select_next_message (win)) {
363 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
369 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
371 TnyList *header_list = NULL;
372 TnyIterator *iter = NULL;
373 TnyHeader *header = NULL;
374 gchar *message = NULL;
377 ModestWindowMgr *mgr;
378 GtkWidget *header_view = NULL;
380 g_return_if_fail (MODEST_IS_WINDOW(win));
382 /* Check first if the header view has the focus */
383 if (MODEST_IS_MAIN_WINDOW (win)) {
385 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
386 MODEST_WIDGET_TYPE_HEADER_VIEW);
387 if (!gtk_widget_is_focus (header_view))
391 /* Get the headers, either from the header view (if win is the main window),
392 * or from the message view window: */
393 header_list = get_selected_headers (win);
394 if (!header_list) return;
396 /* Check if any of the headers are already opened, or in the process of being opened */
397 if (MODEST_IS_MAIN_WINDOW (win)) {
399 iter = tny_list_create_iterator (header_list);
401 mgr = modest_runtime_get_window_mgr ();
402 while (!tny_iterator_is_done (iter) && !found) {
403 header = TNY_HEADER (tny_iterator_get_current (iter));
405 found = modest_window_mgr_find_registered_header (mgr, header, NULL);
406 g_object_unref (header);
409 tny_iterator_next (iter);
411 g_object_unref (iter);
416 num = g_strdup_printf ("%d", tny_list_get_length (header_list));
417 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"), num);
419 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
423 g_object_unref (header_list);
429 if (tny_list_get_length(header_list) == 1) {
430 iter = tny_list_create_iterator (header_list);
431 header = TNY_HEADER (tny_iterator_get_current (iter));
433 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
434 g_object_unref (header);
437 g_object_unref (iter);
439 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
440 tny_list_get_length(header_list)), desc);
442 /* Confirmation dialog */
443 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
447 if (response == GTK_RESPONSE_OK) {
448 ModestWindow *main_window = NULL;
449 ModestWindowMgr *mgr = NULL;
450 GtkTreeModel *model = NULL;
451 GtkTreeSelection *sel = NULL;
452 GList *sel_list = NULL, *tmp = NULL;
453 GtkTreeRowReference *next_row_reference = NULL;
454 GtkTreeRowReference *prev_row_reference = NULL;
455 GtkTreePath *next_path = NULL;
456 GtkTreePath *prev_path = NULL;
459 /* Find last selected row */
460 if (MODEST_IS_MAIN_WINDOW (win)) {
461 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
462 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
463 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
464 for (tmp=sel_list; tmp; tmp=tmp->next) {
465 if (tmp->next == NULL) {
466 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
467 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
469 gtk_tree_path_prev (prev_path);
470 gtk_tree_path_next (next_path);
472 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
473 next_row_reference = gtk_tree_row_reference_new (model, next_path);
478 /* Disable window dimming management */
479 modest_window_disable_dimming (MODEST_WINDOW(win));
481 /* Remove each header. If it's a view window header_view == NULL */
482 modest_do_messages_delete (header_list, win);
484 /* Enable window dimming management */
485 gtk_tree_selection_unselect_all (sel);
486 modest_window_enable_dimming (MODEST_WINDOW(win));
488 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
489 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
491 /* Get main window */
492 mgr = modest_runtime_get_window_mgr ();
493 main_window = modest_window_mgr_get_main_window (mgr);
496 /* Move cursor to next row */
499 /* Select next or previous row */
500 if (gtk_tree_row_reference_valid (next_row_reference)) {
501 /* next_path = gtk_tree_row_reference_get_path (row_reference); */
502 gtk_tree_selection_select_path (sel, next_path);
504 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
505 gtk_tree_selection_select_path (sel, prev_path);
509 if (next_row_reference != NULL)
510 gtk_tree_row_reference_free (next_row_reference);
511 if (next_path != NULL)
512 gtk_tree_path_free (next_path);
513 if (prev_row_reference != NULL)
514 gtk_tree_row_reference_free (prev_row_reference);
515 if (prev_path != NULL)
516 gtk_tree_path_free (prev_path);
520 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, err->code, err->message);
524 /* Update toolbar dimming state */
525 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
528 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
529 g_list_free (sel_list);
535 g_object_unref (header_list);
541 /* delete either message or folder, based on where we are */
543 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
545 g_return_if_fail (MODEST_IS_WINDOW(win));
547 /* Check first if the header view has the focus */
548 if (MODEST_IS_MAIN_WINDOW (win)) {
550 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
551 MODEST_WIDGET_TYPE_FOLDER_VIEW);
552 if (gtk_widget_is_focus (w)) {
553 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
557 modest_ui_actions_on_delete_message (action, win);
563 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
565 ModestWindowMgr *mgr = NULL;
567 #ifdef MODEST_PLATFORM_MAEMO
568 modest_osso_save_state();
569 #endif /* MODEST_PLATFORM_MAEMO */
571 g_debug ("closing down, clearing %d item(s) from operation queue",
572 modest_mail_operation_queue_num_elements
573 (modest_runtime_get_mail_operation_queue()));
575 /* cancel all outstanding operations */
576 modest_mail_operation_queue_cancel_all
577 (modest_runtime_get_mail_operation_queue());
579 g_debug ("queue has been cleared");
582 /* Check if there are opened editing windows */
583 mgr = modest_runtime_get_window_mgr ();
584 modest_window_mgr_close_all_windows (mgr);
586 /* note: when modest-tny-account-store is finalized,
587 it will automatically set all network connections
590 /* gtk_main_quit (); */
594 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
598 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
600 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
601 /* gtk_widget_destroy (GTK_WIDGET (win)); */
602 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
603 /* gboolean ret_value; */
604 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
605 /* } else if (MODEST_IS_WINDOW (win)) { */
606 /* gtk_widget_destroy (GTK_WIDGET (win)); */
608 /* g_return_if_reached (); */
613 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
615 GtkClipboard *clipboard = NULL;
616 gchar *selection = NULL;
618 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
619 selection = gtk_clipboard_wait_for_text (clipboard);
621 /* Question: why is the clipboard being used here?
622 * It doesn't really make a lot of sense. */
626 modest_address_book_add_address (selection);
632 modest_ui_actions_on_accounts (GtkAction *action, ModestWindow *win)
634 /* This is currently only implemented for Maemo */
635 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
636 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
637 modest_run_account_setup_wizard (win);
640 /* Show the list of accounts: */
641 GtkDialog *account_win = GTK_DIALOG(modest_account_view_window_new ());
642 gtk_window_set_transient_for (GTK_WINDOW (account_win), GTK_WINDOW (win));
644 /* Don't make this a modal window, because secondary windows will then
645 * be unusable, freezing the UI: */
646 /* gtk_window_set_modal (GTK_WINDOW (account_win), TRUE); */
647 modest_maemo_show_dialog_and_forget (GTK_WINDOW (win), account_win);
650 GtkWidget *dialog, *label;
652 /* Create the widgets */
654 dialog = gtk_dialog_new_with_buttons ("Message",
656 GTK_DIALOG_DESTROY_WITH_PARENT,
660 label = gtk_label_new ("Hello World!");
662 /* Ensure that the dialog box is destroyed when the user responds. */
664 g_signal_connect_swapped (dialog, "response",
665 G_CALLBACK (gtk_widget_destroy),
668 /* Add the label, and show everything we've added to the dialog. */
670 gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),
672 gtk_widget_show_all (dialog);
673 #endif /* MODEST_PLATFORM_MAEMO */
677 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
679 /* Save any changes. */
680 modest_connection_specific_smtp_window_save_server_accounts (
681 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window));
682 gtk_widget_destroy (GTK_WIDGET (window));
688 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
690 /* This is currently only implemented for Maemo,
691 * because it requires an API (libconic) to detect different connection
694 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
696 /* Create the window if necessary: */
697 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
698 modest_connection_specific_smtp_window_fill_with_connections (
699 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
700 modest_runtime_get_account_mgr());
702 /* Show the window: */
703 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
704 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
705 gtk_widget_show (specific_window);
707 /* Save changes when the window is hidden: */
708 g_signal_connect (specific_window, "hide",
709 G_CALLBACK (on_smtp_servers_window_hide), win);
710 #endif /* MODEST_PLATFORM_MAEMO */
714 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
716 ModestWindow *msg_win = NULL;
718 TnyFolder *folder = NULL;
719 gchar *account_name = NULL;
720 gchar *from_str = NULL;
721 /* GError *err = NULL; */
722 TnyAccount *account = NULL;
723 ModestWindowMgr *mgr;
724 gchar *signature = NULL, *blank_and_signature = NULL;
726 /* if there are no accounts yet, just show the wizard */
727 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
728 const gboolean created = modest_run_account_setup_wizard (win);
733 account_name = g_strdup (modest_window_get_active_account (win));
735 account_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr ());
737 g_printerr ("modest: no account found\n");
741 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
743 TNY_ACCOUNT_TYPE_STORE);
745 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
749 from_str = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(), account_name);
751 g_printerr ("modest: failed get from string for '%s'\n", account_name);
755 gboolean use_signature = FALSE;
756 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr (), account_name, &use_signature);
759 blank_and_signature = g_strconcat ("\n", signature, NULL);
761 blank_and_signature = g_strdup ("");
766 msg = modest_tny_msg_new ("", from_str, "", "", "", blank_and_signature, NULL);
768 g_printerr ("modest: failed to create new msg\n");
772 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
774 g_printerr ("modest: failed to find Drafts folder\n");
779 /* Create and register edit window */
780 /* This is destroyed by TODO. */
781 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
782 mgr = modest_runtime_get_window_mgr ();
783 modest_window_mgr_register_window (mgr, msg_win);
786 gtk_window_set_transient_for (GTK_WINDOW (msg_win),
788 gtk_widget_show_all (GTK_WIDGET (msg_win));
791 g_free (account_name);
793 g_free (blank_and_signature);
795 g_object_unref (msg_win);
797 g_object_unref (G_OBJECT(account));
799 g_object_unref (G_OBJECT(msg));
801 g_object_unref (G_OBJECT(folder));
805 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
809 ModestMailOperationStatus status;
811 /* If there is no message or the operation was not successful */
812 status = modest_mail_operation_get_status (mail_op);
813 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
815 /* Remove the header from the preregistered uids */
816 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
826 open_msg_cb (ModestMailOperation *mail_op, TnyHeader *header, TnyMsg *msg, gpointer user_data)
828 ModestWindowMgr *mgr = NULL;
829 ModestWindow *parent_win = NULL;
830 ModestWindow *win = NULL;
831 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
832 gchar *account = NULL;
835 /* Do nothing if there was any problem with the mail
836 operation. The error will be shown by the error_handler of
837 the mail operation */
838 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
841 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
842 folder = tny_header_get_folder (header);
844 /* Mark header as read */
845 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
848 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
850 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
852 /* Gets folder type (OUTBOX headers will be opened in edit window */
853 if (modest_tny_folder_is_local_folder (folder))
854 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
856 /* If the header is in the drafts folder then open the editor,
857 else the message view window */
858 if ((folder_type == TNY_FOLDER_TYPE_DRAFTS) ||
859 (folder_type == TNY_FOLDER_TYPE_OUTBOX)) {
860 /* we cannot edit without a valid account... */
861 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
862 const gboolean created = modest_run_account_setup_wizard(parent_win);
866 win = modest_msg_edit_window_new (msg, account, TRUE);
870 modest_platform_information_banner (NULL, NULL, _("mail_ib_opening_draft_message"));
873 gchar *uid = modest_tny_folder_get_header_unique_id (header);
875 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
876 GtkWidget *header_view;
877 GtkTreeSelection *sel;
878 GList *sel_list = NULL;
881 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
882 MODEST_WIDGET_TYPE_HEADER_VIEW);
884 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
885 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
887 if (sel_list != NULL) {
888 GtkTreeRowReference *row_reference;
890 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
891 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
892 g_list_free (sel_list);
894 win = modest_msg_view_window_new_with_header_model (
895 msg, account, (const gchar*) uid,
896 model, row_reference);
897 gtk_tree_row_reference_free (row_reference);
899 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
902 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
907 /* Register and show new window */
909 mgr = modest_runtime_get_window_mgr ();
910 modest_window_mgr_register_window (mgr, win);
911 g_object_unref (win);
912 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parent_win));
913 gtk_widget_show_all (GTK_WIDGET(win));
916 /* Update toolbar dimming state */
917 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
918 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
924 g_object_unref (parent_win);
925 g_object_unref (folder);
929 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
933 GObject *win = modest_mail_operation_get_source (mail_op);
935 error = modest_mail_operation_get_error (mail_op);
936 printf ("DEBUG: %s: Error: code=%d, text=%s\n", __FUNCTION__, error->code, error->message);
938 if (error->code == MODEST_MAIL_OPERATION_ERROR_MESSAGE_SIZE_LIMIT) {
940 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
943 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
944 _("mail_ni_ui_folder_get_msg_folder_error"));
948 g_object_unref (win);
952 * This function is used by both modest_ui_actions_on_open and
953 * modest_ui_actions_on_header_activated. This way we always do the
954 * same when trying to open messages.
957 _modest_ui_actions_open (TnyList *headers, ModestWindow *win)
959 ModestWindowMgr *mgr = NULL;
960 TnyIterator *iter = NULL;
961 ModestMailOperation *mail_op = NULL;
962 TnyList *not_opened_headers = NULL;
963 TnyHeaderFlags flags = 0;
965 g_return_if_fail (headers != NULL);
967 /* Check that only one message is selected for opening */
968 if (tny_list_get_length (headers) != 1) {
969 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
970 _("mcen_ib_select_one_message"));
975 /* Look if we already have a message view for each header. If
976 true, then remove the header from the list of headers to
978 mgr = modest_runtime_get_window_mgr ();
979 iter = tny_list_create_iterator (headers);
980 not_opened_headers = tny_simple_list_new ();
982 while (!tny_iterator_is_done (iter)) {
984 ModestWindow *window = NULL;
985 TnyHeader *header = NULL;
986 gboolean found = FALSE;
988 header = TNY_HEADER (tny_iterator_get_current (iter));
990 flags = tny_header_get_flags (header);
993 found = modest_window_mgr_find_registered_header (mgr, header, &window);
995 /* Do not open again the message and present the
996 window to the user */
999 gtk_window_present (GTK_WINDOW (window));
1001 /* the header has been registered already, we don't do
1002 * anything but wait for the window to come up*/
1003 g_debug ("header %p already registered, waiting for window", header);
1005 tny_list_append (not_opened_headers, G_OBJECT (header));
1009 g_object_unref (header);
1011 tny_iterator_next (iter);
1013 g_object_unref (iter);
1016 /* If some messages would have to be downloaded, ask the user to
1017 * make a connection. It's generally easier to do this here (in the mainloop)
1018 * than later in a thread:
1020 if (tny_list_get_length (not_opened_headers) > 0) {
1022 gboolean found = FALSE;
1024 iter = tny_list_create_iterator (not_opened_headers);
1025 while (!tny_iterator_is_done (iter) && !found) {
1026 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1027 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1030 tny_iterator_next (iter);
1032 g_object_unref (header);
1034 g_object_unref (iter);
1036 if (found && !modest_platform_connect_and_wait (GTK_WINDOW (win), NULL)) {
1037 g_object_unref (not_opened_headers);
1042 /* Register the headers before actually creating the windows: */
1043 TnyIterator *iter_not_opened = tny_list_create_iterator (not_opened_headers);
1044 while (!tny_iterator_is_done (iter_not_opened)) {
1045 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1047 modest_window_mgr_register_header (mgr, header);
1048 g_object_unref (header);
1051 tny_iterator_next (iter_not_opened);
1053 g_object_unref (iter_not_opened);
1054 iter_not_opened = NULL;
1056 /* Open each message */
1057 if (tny_list_get_length (not_opened_headers) > 0) {
1058 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1060 modest_ui_actions_get_msgs_full_error_handler,
1062 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1063 if (tny_list_get_length (not_opened_headers) > 1) {
1064 modest_mail_operation_get_msgs_full (mail_op,
1070 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1071 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1072 modest_mail_operation_get_msg (mail_op, header, open_msg_cb, NULL);
1073 g_object_unref (header);
1074 g_object_unref (iter);
1076 g_object_unref (mail_op);
1080 if (not_opened_headers != NULL)
1081 g_object_unref (not_opened_headers);
1085 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1090 headers = get_selected_headers (win);
1095 _modest_ui_actions_open (headers, win);
1097 g_object_unref(headers);
1102 free_reply_forward_helper (gpointer data)
1104 ReplyForwardHelper *helper;
1106 helper = (ReplyForwardHelper *) data;
1107 g_free (helper->account_name);
1108 g_slice_free (ReplyForwardHelper, helper);
1112 reply_forward_cb (ModestMailOperation *mail_op, TnyHeader *header, TnyMsg *msg,
1116 ReplyForwardHelper *rf_helper;
1117 ModestWindow *msg_win = NULL;
1118 ModestEditType edit_type;
1120 TnyAccount *account = NULL;
1121 ModestWindowMgr *mgr = NULL;
1122 gchar *signature = NULL;
1124 /* If there was any error. The mail operation could be NULL,
1125 this means that we already have the message downloaded and
1126 that we didn't do a mail operation to retrieve it */
1127 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1130 g_return_if_fail (user_data != NULL);
1131 rf_helper = (ReplyForwardHelper *) user_data;
1133 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1134 rf_helper->account_name);
1135 if (modest_account_mgr_get_bool (modest_runtime_get_account_mgr(),
1136 rf_helper->account_name,
1137 MODEST_ACCOUNT_USE_SIGNATURE, FALSE)) {
1138 signature = modest_account_mgr_get_string (modest_runtime_get_account_mgr (),
1139 rf_helper->account_name,
1140 MODEST_ACCOUNT_SIGNATURE, FALSE);
1143 /* Create reply mail */
1144 switch (rf_helper->action) {
1147 modest_tny_msg_create_reply_msg (msg, header, from, signature,
1148 rf_helper->reply_forward_type,
1149 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1151 case ACTION_REPLY_TO_ALL:
1153 modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1154 MODEST_TNY_MSG_REPLY_MODE_ALL);
1155 edit_type = MODEST_EDIT_TYPE_REPLY;
1157 case ACTION_FORWARD:
1159 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1160 edit_type = MODEST_EDIT_TYPE_FORWARD;
1163 g_return_if_reached ();
1170 g_printerr ("modest: failed to create message\n");
1174 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1175 rf_helper->account_name,
1176 TNY_ACCOUNT_TYPE_STORE);
1178 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1182 /* Create and register the windows */
1183 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1184 mgr = modest_runtime_get_window_mgr ();
1185 modest_window_mgr_register_window (mgr, msg_win);
1187 if (rf_helper->parent_window != NULL) {
1188 gdouble parent_zoom;
1190 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1191 modest_window_set_zoom (msg_win, parent_zoom);
1194 /* Show edit window */
1195 gtk_widget_show_all (GTK_WIDGET (msg_win));
1199 g_object_unref (msg_win);
1201 g_object_unref (G_OBJECT (new_msg));
1203 g_object_unref (G_OBJECT (account));
1204 /* g_object_unref (msg); */
1205 free_reply_forward_helper (rf_helper);
1208 /* Checks a list of headers. If any of them are not currently
1209 * downloaded (CACHED) then returns TRUE else returns FALSE.
1212 header_list_count_uncached_msgs (TnyList *header_list)
1215 gint uncached_messages = 0;
1217 iter = tny_list_create_iterator (header_list);
1218 while (!tny_iterator_is_done (iter)) {
1221 header = TNY_HEADER (tny_iterator_get_current (iter));
1223 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1224 uncached_messages ++;
1225 g_object_unref (header);
1228 tny_iterator_next (iter);
1230 g_object_unref (iter);
1232 return uncached_messages;
1235 /* Returns FALSE if the user does not want to download the
1236 * messages. Returns TRUE if the user allowed the download.
1239 connect_to_get_msg (GtkWindow *win,
1240 gint num_of_uncached_msgs)
1242 /* Allways download if we are online. */
1243 if (tny_device_is_online (modest_runtime_get_device ()))
1246 /* If offline, then ask for user permission to download the messages */
1247 GtkResponseType response;
1248 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1249 ngettext("mcen_nc_get_msg",
1251 num_of_uncached_msgs));
1252 if (response == GTK_RESPONSE_CANCEL)
1255 return modest_platform_connect_and_wait(win, NULL);
1259 * Common code for the reply and forward actions
1262 reply_forward (ReplyForwardAction action, ModestWindow *win)
1264 ModestMailOperation *mail_op = NULL;
1265 TnyList *header_list = NULL;
1266 ReplyForwardHelper *rf_helper = NULL;
1267 guint reply_forward_type;
1268 gboolean continue_download = TRUE;
1269 gboolean do_retrieve = TRUE;
1271 g_return_if_fail (MODEST_IS_WINDOW(win));
1273 /* we need an account when editing */
1274 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1275 const gboolean created = modest_run_account_setup_wizard (win);
1280 header_list = get_selected_headers (win);
1284 reply_forward_type =
1285 modest_conf_get_int (modest_runtime_get_conf (),
1286 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1289 /* check if we need to download msg before asking about it */
1290 do_retrieve = (action == ACTION_FORWARD) ||
1291 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1294 gint num_of_unc_msgs;
1295 /* check that the messages have been previously downloaded */
1296 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
1297 /* If there are any uncached message ask the user
1298 * whether he/she wants to download them. */
1299 if (num_of_unc_msgs)
1300 continue_download = connect_to_get_msg (
1305 if (!continue_download) {
1306 g_object_unref (header_list);
1310 /* We assume that we can only select messages of the
1311 same folder and that we reply all of them from the
1312 same account. In fact the interface currently only
1313 allows single selection */
1316 rf_helper = g_slice_new0 (ReplyForwardHelper);
1317 rf_helper->reply_forward_type = reply_forward_type;
1318 rf_helper->action = action;
1319 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1321 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1322 rf_helper->parent_window = GTK_WIDGET (win);
1323 if (!rf_helper->account_name)
1324 rf_helper->account_name =
1325 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1327 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1330 /* Get header and message. Do not free them here, the
1331 reply_forward_cb must do it */
1332 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1333 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1334 if (!msg || !header) {
1336 g_object_unref (msg);
1337 g_printerr ("modest: no message found\n");
1340 reply_forward_cb (NULL, header, msg, rf_helper);
1343 g_object_unref (header);
1348 /* Only reply/forward to one message */
1349 iter = tny_list_create_iterator (header_list);
1350 header = TNY_HEADER (tny_iterator_get_current (iter));
1351 g_object_unref (iter);
1354 /* Retrieve messages */
1356 mail_op = modest_mail_operation_new_with_error_handling (
1357 MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1359 modest_ui_actions_get_msgs_full_error_handler,
1361 modest_mail_operation_queue_add (
1362 modest_runtime_get_mail_operation_queue (), mail_op);
1364 modest_mail_operation_get_msg (mail_op,
1369 g_object_unref(mail_op);
1371 /* we put a ref here to prevent double unref as the reply
1372 * forward callback unrefs the header at its end */
1373 reply_forward_cb (NULL, header, NULL, rf_helper);
1377 g_object_unref (header);
1383 g_object_unref (header_list);
1387 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1389 g_return_if_fail (MODEST_IS_WINDOW(win));
1391 reply_forward (ACTION_REPLY, win);
1395 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1397 g_return_if_fail (MODEST_IS_WINDOW(win));
1399 reply_forward (ACTION_FORWARD, win);
1403 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1405 g_return_if_fail (MODEST_IS_WINDOW(win));
1407 reply_forward (ACTION_REPLY_TO_ALL, win);
1411 modest_ui_actions_on_next (GtkAction *action,
1412 ModestWindow *window)
1414 if (MODEST_IS_MAIN_WINDOW (window)) {
1415 GtkWidget *header_view;
1417 header_view = modest_main_window_get_child_widget (
1418 MODEST_MAIN_WINDOW(window),
1419 MODEST_WIDGET_TYPE_HEADER_VIEW);
1423 modest_header_view_select_next (
1424 MODEST_HEADER_VIEW(header_view));
1425 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1426 modest_msg_view_window_select_next_message (
1427 MODEST_MSG_VIEW_WINDOW (window));
1429 g_return_if_reached ();
1434 modest_ui_actions_on_prev (GtkAction *action,
1435 ModestWindow *window)
1437 g_return_if_fail (MODEST_IS_WINDOW(window));
1439 if (MODEST_IS_MAIN_WINDOW (window)) {
1440 GtkWidget *header_view;
1441 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1442 MODEST_WIDGET_TYPE_HEADER_VIEW);
1446 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1447 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1448 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1450 g_return_if_reached ();
1455 modest_ui_actions_on_sort (GtkAction *action,
1456 ModestWindow *window)
1458 g_return_if_fail (MODEST_IS_WINDOW(window));
1460 if (MODEST_IS_MAIN_WINDOW (window)) {
1461 GtkWidget *header_view;
1462 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1463 MODEST_WIDGET_TYPE_HEADER_VIEW);
1465 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1470 /* Show sorting dialog */
1471 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1476 new_messages_arrived (ModestMailOperation *self,
1480 ModestMainWindow *win = NULL;
1481 GtkWidget *folder_view = NULL;
1482 TnyFolderStore *folder = NULL;
1483 gboolean folder_empty = FALSE;
1485 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
1486 win = MODEST_MAIN_WINDOW (user_data);
1488 /* Set contents style of headers view */
1489 if (modest_main_window_get_contents_style (win) == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1490 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1491 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1492 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
1495 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1498 modest_main_window_set_contents_style (win,
1499 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1502 /* Notify new messages have been downloaded */
1503 if (new_messages > 0)
1504 modest_platform_on_new_msg ();
1508 * This function performs the send & receive required actions. The
1509 * window is used to create the mail operation. Typically it should
1510 * always be the main window, but we pass it as argument in order to
1514 modest_ui_actions_do_send_receive (const gchar *account_name, ModestWindow *win)
1516 gchar *acc_name = NULL;
1517 ModestMailOperation *mail_op;
1519 /* If no account name was provided then get the current account, and if
1520 there is no current account then pick the default one: */
1521 if (!account_name) {
1522 acc_name = g_strdup (modest_window_get_active_account(win));
1524 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1526 g_printerr ("modest: cannot get default account\n");
1530 acc_name = g_strdup (account_name);
1533 /* Set send/receive operation in progress */
1534 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW(win));
1536 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
1538 modest_ui_actions_send_receive_error_handler,
1541 g_signal_connect (G_OBJECT(mail_op), "progress-changed",
1542 G_CALLBACK (_on_send_receive_progress_changed),
1545 /* Send & receive. */
1546 /* TODO: The spec wants us to first do any pending deletions, before receiving. */
1547 /* Receive and then send. The operation is tagged initially as
1548 a receive operation because the account update performs a
1549 receive and then a send. The operation changes its type
1550 internally, so the progress objects will receive the proper
1551 progress information */
1552 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1553 modest_mail_operation_update_account (mail_op, acc_name, new_messages_arrived, win);
1554 g_object_unref (G_OBJECT (mail_op));
1562 modest_ui_actions_do_cancel_send (const gchar *account_name,
1565 TnyTransportAccount *transport_account;
1566 TnySendQueue *send_queue = NULL;
1567 GError *error = NULL;
1569 /* Get transport account */
1571 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1572 (modest_runtime_get_account_store(),
1574 TNY_ACCOUNT_TYPE_TRANSPORT));
1575 if (!transport_account) {
1576 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1581 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1582 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1583 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1584 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1585 "modest: could not find send queue for account\n");
1587 /* Keeep messages in outbox folder */
1588 tny_send_queue_cancel (send_queue, FALSE, &error);
1592 if (transport_account != NULL)
1593 g_object_unref (G_OBJECT (transport_account));
1597 modest_ui_actions_cancel_send_all (ModestWindow *win)
1599 GSList *account_names, *iter;
1601 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1604 iter = account_names;
1606 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1607 iter = g_slist_next (iter);
1610 modest_account_mgr_free_account_names (account_names);
1611 account_names = NULL;
1615 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1618 /* Check if accounts exist */
1619 gboolean accounts_exist =
1620 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1622 /* If not, allow the user to create an account before trying to send/receive. */
1623 if (!accounts_exist)
1624 modest_ui_actions_on_accounts (NULL, win);
1626 /* Cancel all sending operaitons */
1627 modest_ui_actions_cancel_send_all (win);
1631 * Refreshes all accounts. This function will be used by automatic
1635 modest_ui_actions_do_send_receive_all (ModestWindow *win)
1637 GSList *account_names, *iter;
1639 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1642 iter = account_names;
1644 modest_ui_actions_do_send_receive ((const char*) iter->data, win);
1645 iter = g_slist_next (iter);
1648 modest_account_mgr_free_account_names (account_names);
1649 account_names = NULL;
1653 modest_do_refresh_current_folder(ModestWindow *win)
1655 /* Refresh currently selected folder. Note that if we only
1656 want to retreive the headers, then the refresh only will
1657 invoke a poke_status over all folders, i.e., only the
1658 total/unread count will be updated */
1659 if (MODEST_IS_MAIN_WINDOW (win)) {
1660 GtkWidget *header_view, *folder_view;
1661 TnyFolderStore *folder_store;
1663 /* Get folder and header view */
1665 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1666 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1670 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1672 if (folder_store && TNY_IS_FOLDER (folder_store)) {
1674 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1675 MODEST_WIDGET_TYPE_HEADER_VIEW);
1677 /* We do not need to set the contents style
1678 because it hasn't changed. We also do not
1679 need to save the widget status. Just force
1681 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1682 TNY_FOLDER (folder_store),
1683 folder_refreshed_cb,
1684 MODEST_MAIN_WINDOW (win));
1688 g_object_unref (folder_store);
1694 * Handler of the click on Send&Receive button in the main toolbar
1697 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1699 /* Check if accounts exist */
1700 gboolean accounts_exist =
1701 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1703 /* If not, allow the user to create an account before trying to send/receive. */
1704 if (!accounts_exist)
1705 modest_ui_actions_on_accounts (NULL, win);
1707 modest_do_refresh_current_folder (win);
1709 /* Refresh the active account */
1710 modest_ui_actions_do_send_receive (NULL, win);
1715 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1718 GtkWidget *header_view;
1720 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1722 header_view = modest_main_window_get_child_widget (main_window,
1723 MODEST_WIDGET_TYPE_HEADER_VIEW);
1727 conf = modest_runtime_get_conf ();
1729 /* what is saved/restored is depending on the style; thus; we save with
1730 * old style, then update the style, and restore for this new style
1732 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1734 if (modest_header_view_get_style
1735 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1736 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1737 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1739 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1740 MODEST_HEADER_VIEW_STYLE_DETAILS);
1742 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1743 MODEST_CONF_HEADER_VIEW_KEY);
1748 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1750 ModestMainWindow *main_window)
1752 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1753 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1755 /* in the case the folder is empty, show the empty folder message and focus
1757 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1758 if (modest_header_view_is_empty (header_view)) {
1759 TnyFolder *folder = modest_header_view_get_folder (header_view);
1760 GtkWidget *folder_view =
1761 modest_main_window_get_child_widget (main_window,
1762 MODEST_WIDGET_TYPE_FOLDER_VIEW);
1764 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1765 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1769 /* If no header has been selected then exit */
1774 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1775 gtk_widget_grab_focus (GTK_WIDGET(header_view));
1777 /* Update toolbar dimming state */
1778 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1782 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
1784 ModestMainWindow *main_window)
1788 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1794 /* headers = tny_simple_list_new (); */
1795 /* tny_list_prepend (headers, G_OBJECT (header)); */
1796 headers = modest_header_view_get_selected_headers (header_view);
1798 _modest_ui_actions_open (headers, MODEST_WINDOW (main_window));
1800 g_object_unref (headers);
1804 set_active_account_from_tny_account (TnyAccount *account,
1805 ModestWindow *window)
1807 const gchar *server_acc_name = tny_account_get_id (account);
1809 /* We need the TnyAccount provided by the
1810 account store because that is the one that
1811 knows the name of the Modest account */
1812 TnyAccount *modest_server_account = modest_server_account =
1813 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
1814 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
1816 if (!modest_server_account) {
1817 g_warning ("%s: could not get tny account\n", __FUNCTION__);
1821 /* Update active account, but only if it's not a pseudo-account */
1822 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
1823 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
1824 const gchar *modest_acc_name =
1825 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
1826 if (modest_acc_name)
1827 modest_window_set_active_account (window, modest_acc_name);
1830 g_object_unref (modest_server_account);
1835 folder_refreshed_cb (ModestMailOperation *mail_op,
1839 ModestMainWindow *win = NULL;
1840 GtkWidget *header_view;
1841 gboolean folder_empty = FALSE;
1842 gboolean all_marked_as_deleted = FALSE;
1844 g_return_if_fail (TNY_IS_FOLDER (folder));
1846 win = MODEST_MAIN_WINDOW (user_data);
1848 modest_main_window_get_child_widget(win, MODEST_WIDGET_TYPE_HEADER_VIEW);
1851 TnyFolder *current_folder;
1853 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
1854 if (current_folder != NULL && folder != current_folder) {
1855 g_object_unref (current_folder);
1858 g_object_unref (current_folder);
1861 /* Check if folder is empty and set headers view contents style */
1862 folder_empty = (tny_folder_get_all_count (folder) == 0);
1863 all_marked_as_deleted = modest_header_view_is_empty (MODEST_HEADER_VIEW(header_view));
1864 if (folder_empty || all_marked_as_deleted)
1865 modest_main_window_set_contents_style (win,
1866 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1870 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
1871 TnyFolderStore *folder_store,
1873 ModestMainWindow *main_window)
1876 GtkWidget *header_view;
1878 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1880 header_view = modest_main_window_get_child_widget(main_window,
1881 MODEST_WIDGET_TYPE_HEADER_VIEW);
1885 conf = modest_runtime_get_conf ();
1887 if (TNY_IS_ACCOUNT (folder_store)) {
1889 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
1891 /* Show account details */
1892 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
1895 if (TNY_IS_FOLDER (folder_store) && selected) {
1897 /* Update the active account */
1898 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
1900 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
1901 g_object_unref (account);
1905 /* Set the header style by default, it could
1906 be changed later by the refresh callback to
1908 modest_main_window_set_contents_style (main_window,
1909 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1911 /* Set folder on header view. This function
1912 will call tny_folder_refresh_async so we
1913 pass a callback that will be called when
1914 finished. We use that callback to set the
1915 empty view if there are no messages */
1916 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
1917 TNY_FOLDER (folder_store),
1918 folder_refreshed_cb,
1921 /* Restore configuration. We need to do this
1922 *after* the set_folder because the widget
1923 memory asks the header view about its
1925 modest_widget_memory_restore (modest_runtime_get_conf (),
1926 G_OBJECT(header_view),
1927 MODEST_CONF_HEADER_VIEW_KEY);
1929 /* Update the active account */
1930 //modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
1931 /* Save only if we're seeing headers */
1932 if (modest_main_window_get_contents_style (main_window) ==
1933 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1934 modest_widget_memory_save (conf, G_OBJECT (header_view),
1935 MODEST_CONF_HEADER_VIEW_KEY);
1936 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
1940 /* Update toolbar dimming state */
1941 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
1945 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
1952 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
1954 online = tny_device_is_online (modest_runtime_get_device());
1957 /* already online -- the item is simply not there... */
1958 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
1960 GTK_MESSAGE_WARNING,
1962 _("The %s you selected cannot be found"),
1964 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
1965 gtk_dialog_run (GTK_DIALOG(dialog));
1967 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
1970 _("mcen_bd_dialog_cancel"),
1971 GTK_RESPONSE_REJECT,
1972 _("mcen_bd_dialog_ok"),
1973 GTK_RESPONSE_ACCEPT,
1975 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
1976 "Do you want to get online?"), item);
1977 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
1978 gtk_label_new (txt), FALSE, FALSE, 0);
1979 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
1982 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
1983 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1984 /* TODO: Comment about why is this commented out: */
1985 /* modest_platform_connect_and_wait (); */
1988 gtk_widget_destroy (dialog);
1992 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
1995 /* g_message ("%s %s", __FUNCTION__, link); */
2000 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2003 modest_platform_activate_uri (link);
2007 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2010 modest_platform_show_uri_popup (link);
2014 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2017 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2021 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2022 const gchar *address,
2025 /* g_message ("%s %s", __FUNCTION__, address); */
2029 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2031 TnyTransportAccount *transport_account;
2032 ModestMailOperation *mail_operation;
2034 gchar *account_name, *from;
2035 ModestAccountMgr *account_mgr;
2036 gchar *info_text = NULL;
2038 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2040 data = modest_msg_edit_window_get_msg_data (edit_window);
2042 account_mgr = modest_runtime_get_account_mgr();
2043 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2045 account_name = modest_account_mgr_get_default_account (account_mgr);
2046 if (!account_name) {
2047 g_printerr ("modest: no account found\n");
2048 modest_msg_edit_window_free_msg_data (edit_window, data);
2052 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2053 account_name = g_strdup (data->account_name);
2057 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2058 (modest_runtime_get_account_store(),
2060 TNY_ACCOUNT_TYPE_TRANSPORT));
2061 if (!transport_account) {
2062 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2063 g_free (account_name);
2064 modest_msg_edit_window_free_msg_data (edit_window, data);
2067 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2069 /* Create the mail operation */
2070 mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_INFO, G_OBJECT(edit_window));
2071 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2073 modest_mail_operation_save_to_drafts (mail_operation,
2085 data->priority_flags);
2088 g_free (account_name);
2089 g_object_unref (G_OBJECT (transport_account));
2090 g_object_unref (G_OBJECT (mail_operation));
2092 modest_msg_edit_window_free_msg_data (edit_window, data);
2094 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2095 modest_platform_information_banner (NULL, NULL, info_text);
2099 /* For instance, when clicking the Send toolbar button when editing a message: */
2101 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2103 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2105 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2108 /* Offer the connection dialog, if necessary: */
2109 if (!modest_platform_connect_and_wait (GTK_WINDOW (edit_window), NULL))
2112 /* FIXME: Code added just for testing. The final version will
2113 use the send queue provided by tinymail and some
2115 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2116 gchar *account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2118 account_name = modest_account_mgr_get_default_account (account_mgr);
2120 if (!account_name) {
2121 /* Run account setup wizard */
2122 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2127 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2129 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2130 account_name = g_strdup (data->account_name);
2133 /* Get the currently-active transport account for this modest account: */
2134 TnyTransportAccount *transport_account =
2135 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_transport_account_for_open_connection
2136 (modest_runtime_get_account_store(),
2138 if (!transport_account) {
2139 /* Run account setup wizard */
2140 const gboolean created = modest_run_account_setup_wizard(MODEST_WINDOW(edit_window));
2145 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2147 /* Create the mail operation */
2148 ModestMailOperation *mail_operation = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_SEND, G_OBJECT(edit_window));
2149 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2151 modest_mail_operation_send_new_mail (mail_operation,
2162 data->priority_flags);
2166 g_free (account_name);
2167 g_object_unref (G_OBJECT (transport_account));
2168 g_object_unref (G_OBJECT (mail_operation));
2170 modest_msg_edit_window_free_msg_data (edit_window, data);
2171 modest_msg_edit_window_set_sent (edit_window, TRUE);
2173 /* Save settings and close the window: */
2174 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2178 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2179 ModestMsgEditWindow *window)
2181 ModestMsgEditFormatState *format_state = NULL;
2183 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2184 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2186 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2189 format_state = modest_msg_edit_window_get_format_state (window);
2190 g_return_if_fail (format_state != NULL);
2192 format_state->bold = gtk_toggle_action_get_active (action);
2193 modest_msg_edit_window_set_format_state (window, format_state);
2194 g_free (format_state);
2199 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2200 ModestMsgEditWindow *window)
2202 ModestMsgEditFormatState *format_state = NULL;
2204 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2205 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2207 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2210 format_state = modest_msg_edit_window_get_format_state (window);
2211 g_return_if_fail (format_state != NULL);
2213 format_state->italics = gtk_toggle_action_get_active (action);
2214 modest_msg_edit_window_set_format_state (window, format_state);
2215 g_free (format_state);
2220 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2221 ModestMsgEditWindow *window)
2223 ModestMsgEditFormatState *format_state = NULL;
2225 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2226 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2228 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2231 format_state = modest_msg_edit_window_get_format_state (window);
2232 g_return_if_fail (format_state != NULL);
2234 format_state->bullet = gtk_toggle_action_get_active (action);
2235 modest_msg_edit_window_set_format_state (window, format_state);
2236 g_free (format_state);
2241 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2242 GtkRadioAction *selected,
2243 ModestMsgEditWindow *window)
2245 ModestMsgEditFormatState *format_state = NULL;
2246 GtkJustification value;
2248 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2250 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2253 value = gtk_radio_action_get_current_value (selected);
2255 format_state = modest_msg_edit_window_get_format_state (window);
2256 g_return_if_fail (format_state != NULL);
2258 format_state->justification = value;
2259 modest_msg_edit_window_set_format_state (window, format_state);
2260 g_free (format_state);
2264 modest_ui_actions_on_select_editor_color (GtkAction *action,
2265 ModestMsgEditWindow *window)
2267 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2268 g_return_if_fail (GTK_IS_ACTION (action));
2270 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2273 modest_msg_edit_window_select_color (window);
2277 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2278 ModestMsgEditWindow *window)
2280 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2281 g_return_if_fail (GTK_IS_ACTION (action));
2283 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2286 modest_msg_edit_window_select_background_color (window);
2290 modest_ui_actions_on_insert_image (GtkAction *action,
2291 ModestMsgEditWindow *window)
2293 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2294 g_return_if_fail (GTK_IS_ACTION (action));
2296 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2299 modest_msg_edit_window_insert_image (window);
2303 modest_ui_actions_on_attach_file (GtkAction *action,
2304 ModestMsgEditWindow *window)
2306 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2307 g_return_if_fail (GTK_IS_ACTION (action));
2309 modest_msg_edit_window_offer_attach_file (window);
2313 modest_ui_actions_on_remove_attachments (GtkAction *action,
2314 ModestMsgEditWindow *window)
2316 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2317 g_return_if_fail (GTK_IS_ACTION (action));
2319 modest_msg_edit_window_remove_attachments (window, NULL);
2323 modest_ui_actions_new_folder_error_handler (ModestMailOperation *mail_op,
2326 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2327 const GError *error = modest_mail_operation_get_error (mail_op);
2331 modest_platform_information_banner (GTK_WIDGET (window), NULL,
2332 modest_mail_operation_get_error (mail_op)->message);
2337 modest_ui_actions_create_folder(GtkWidget *parent_window,
2338 GtkWidget *folder_view)
2340 TnyFolderStore *parent_folder;
2342 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2344 if (parent_folder) {
2345 gboolean finished = FALSE;
2347 gchar *folder_name = NULL, *suggested_name = NULL;
2348 const gchar *proto_str = NULL;
2349 TnyAccount *account;
2351 if (TNY_IS_ACCOUNT (parent_folder))
2352 account = g_object_ref (parent_folder);
2354 account = tny_folder_get_account (TNY_FOLDER (parent_folder));
2355 proto_str = tny_account_get_proto (TNY_ACCOUNT (account));
2357 if (proto_str && modest_protocol_info_get_transport_store_protocol (proto_str) ==
2358 MODEST_PROTOCOL_STORE_POP) {
2360 hildon_banner_show_information (NULL, NULL, _("mail_in_ui_folder_create_error"));
2362 g_object_unref (account);
2364 /* Run the new folder dialog */
2366 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2371 g_free (suggested_name);
2372 suggested_name = NULL;
2374 if (result == GTK_RESPONSE_REJECT) {
2377 ModestMailOperation *mail_op;
2378 TnyFolder *new_folder = NULL;
2380 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2381 G_OBJECT(parent_window),
2382 modest_ui_actions_new_folder_error_handler,
2385 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2387 new_folder = modest_mail_operation_create_folder (mail_op,
2389 (const gchar *) folder_name);
2391 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2394 g_object_unref (new_folder);
2397 g_object_unref (mail_op);
2400 suggested_name = folder_name;
2404 g_object_unref (parent_folder);
2409 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2411 GtkWidget *folder_view;
2413 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2415 folder_view = modest_main_window_get_child_widget (main_window,
2416 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2420 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2424 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2427 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2428 const GError *error = NULL;
2429 const gchar *message = NULL;
2431 /* Get error message */
2432 error = modest_mail_operation_get_error (mail_op);
2434 g_return_if_reached ();
2436 switch (error->code) {
2437 case MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS:
2438 message = _CS("ckdg_ib_folder_already_exists");
2441 g_return_if_reached ();
2444 modest_platform_information_banner (GTK_WIDGET (window), NULL, message);
2448 modest_ui_actions_on_rename_folder (GtkAction *action,
2449 ModestMainWindow *main_window)
2451 TnyFolderStore *folder;
2452 GtkWidget *folder_view;
2453 GtkWidget *header_view;
2455 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2457 folder_view = modest_main_window_get_child_widget (main_window,
2458 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2462 header_view = modest_main_window_get_child_widget (main_window,
2463 MODEST_WIDGET_TYPE_HEADER_VIEW);
2468 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2473 if (TNY_IS_FOLDER (folder)) {
2476 const gchar *current_name;
2477 TnyFolderStore *parent;
2478 gboolean do_rename = TRUE;
2480 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2481 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
2482 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
2483 parent, current_name,
2485 g_object_unref (parent);
2487 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
2489 } else if (modest_platform_is_network_folderstore(folder) &&
2490 !tny_device_is_online (modest_runtime_get_device())) {
2491 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2492 do_rename = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2493 g_object_unref(account);
2497 ModestMailOperation *mail_op;
2498 GtkTreeSelection *sel = NULL;
2501 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_INFO,
2502 G_OBJECT(main_window),
2503 modest_ui_actions_rename_folder_error_handler,
2506 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2509 /* Clear the headers view */
2510 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2511 gtk_tree_selection_unselect_all (sel);
2513 /* Select *after* the changes */
2514 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view),
2515 TNY_FOLDER(folder), TRUE);
2517 /* Actually rename the folder */
2518 modest_mail_operation_rename_folder (mail_op,
2519 TNY_FOLDER (folder),
2520 (const gchar *) folder_name);
2522 g_object_unref (mail_op);
2523 g_free (folder_name);
2526 g_object_unref (folder);
2530 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2533 GObject *win = modest_mail_operation_get_source (mail_op);
2535 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2536 _("mail_in_ui_folder_delete_error"));
2537 g_object_unref (win);
2541 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2543 TnyFolderStore *folder;
2544 GtkWidget *folder_view;
2547 gboolean do_delete = TRUE;
2549 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
2551 folder_view = modest_main_window_get_child_widget (main_window,
2552 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2556 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2558 /* Show an error if it's an account */
2559 if (!TNY_IS_FOLDER (folder)) {
2560 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2561 _("mail_in_ui_folder_delete_error"));
2562 g_object_unref (G_OBJECT (folder));
2567 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2568 tny_folder_get_name (TNY_FOLDER (folder)));
2569 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2570 (const gchar *) message);
2573 if (response != GTK_RESPONSE_OK) {
2575 } else if (modest_platform_is_network_folderstore(folder) &&
2576 !tny_device_is_online (modest_runtime_get_device())) {
2577 TnyAccount *account = tny_folder_get_account(TNY_FOLDER(folder));
2578 do_delete = modest_platform_connect_and_wait(GTK_WINDOW(main_window), account);
2579 g_object_unref(account);
2583 ModestMailOperation *mail_op;
2584 GtkTreeSelection *sel;
2586 /* Unselect the folder before deleting it to free the headers */
2587 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2588 gtk_tree_selection_unselect_all (sel);
2590 /* Create the mail operation */
2592 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_DELETE,
2593 G_OBJECT(main_window),
2594 modest_ui_actions_delete_folder_error_handler,
2597 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2599 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (folder), move_to_trash);
2600 g_object_unref (G_OBJECT (mail_op));
2603 g_object_unref (G_OBJECT (folder));
2607 modest_ui_actions_on_delete_folder (GtkAction *action,
2608 ModestMainWindow *main_window)
2610 GtkWidget *folder_view;
2611 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2613 delete_folder (main_window, FALSE);
2614 folder_view = modest_main_window_get_child_widget (main_window,
2615 MODEST_WIDGET_TYPE_FOLDER_VIEW);
2618 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2622 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
2624 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2626 delete_folder (main_window, TRUE);
2631 show_error (GtkWidget *parent_widget, const gchar* text)
2633 hildon_banner_show_information(parent_widget, NULL, text);
2636 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
2638 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
2645 gtk_dialog_run (dialog);
2646 gtk_widget_destroy (GTK_WIDGET (dialog));
2651 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
2652 const gchar* server_account_name,
2657 ModestMainWindow *main_window)
2659 g_return_if_fail(server_account_name);
2660 /* printf("DEBUG: %s: server_account_name=%s\n", __FUNCTION__, server_account_name); */
2662 /* Initalize output parameters: */
2669 #ifdef MODEST_PLATFORM_MAEMO
2670 /* Maemo uses a different (awkward) button order,
2671 * It should probably just use gtk_alternative_dialog_button_order ().
2673 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2676 _("mcen_bd_dialog_ok"),
2677 GTK_RESPONSE_ACCEPT,
2678 _("mcen_bd_dialog_cancel"),
2679 GTK_RESPONSE_REJECT,
2682 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
2686 GTK_RESPONSE_REJECT,
2688 GTK_RESPONSE_ACCEPT,
2690 #endif /* MODEST_PLATFORM_MAEMO */
2692 gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(main_window));
2694 gchar *server_name = modest_server_account_get_hostname (
2695 modest_runtime_get_account_mgr(), server_account_name);
2696 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
2697 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
2702 /* This causes a warning because the logical ID has no %s in it,
2703 * though the translation does, but there is not much we can do about that: */
2704 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
2705 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
2708 g_free (server_name);
2712 gchar *initial_username = modest_server_account_get_username (
2713 modest_runtime_get_account_mgr(), server_account_name);
2715 GtkWidget *entry_username = gtk_entry_new ();
2716 if (initial_username)
2717 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
2718 /* Dim this if a connection has ever succeeded with this username,
2719 * as per the UI spec: */
2720 const gboolean username_known =
2721 modest_server_account_get_username_has_succeeded(
2722 modest_runtime_get_account_mgr(), server_account_name);
2723 gtk_widget_set_sensitive (entry_username, !username_known);
2725 #ifdef MODEST_PLATFORM_MAEMO
2726 /* Auto-capitalization is the default, so let's turn it off: */
2727 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
2729 /* Create a size group to be used by all captions.
2730 * Note that HildonCaption does not create a default size group if we do not specify one.
2731 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
2732 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
2734 GtkWidget *caption = hildon_caption_new (sizegroup,
2735 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
2736 gtk_widget_show (entry_username);
2737 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2738 FALSE, FALSE, MODEST_MARGIN_HALF);
2739 gtk_widget_show (caption);
2741 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
2743 #endif /* MODEST_PLATFORM_MAEMO */
2746 GtkWidget *entry_password = gtk_entry_new ();
2747 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
2748 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
2750 #ifdef MODEST_PLATFORM_MAEMO
2751 /* Auto-capitalization is the default, so let's turn it off: */
2752 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
2753 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
2755 caption = hildon_caption_new (sizegroup,
2756 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
2757 gtk_widget_show (entry_password);
2758 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
2759 FALSE, FALSE, MODEST_MARGIN_HALF);
2760 gtk_widget_show (caption);
2761 g_object_unref (sizegroup);
2763 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
2765 #endif /* MODEST_PLATFORM_MAEMO */
2767 /* This is not in the Maemo UI spec:
2768 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
2769 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
2773 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2775 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2777 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
2779 modest_server_account_set_username (
2780 modest_runtime_get_account_mgr(), server_account_name,
2783 const gboolean username_was_changed =
2784 (strcmp (*username, initial_username) != 0);
2785 if (username_was_changed) {
2786 g_warning ("%s: tinymail does not yet support changing the "
2787 "username in the get_password() callback.\n", __FUNCTION__);
2792 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
2794 /* We do not save the password in the configuration,
2795 * because this function is only called for passwords that should
2796 * not be remembered:
2797 modest_server_account_set_password (
2798 modest_runtime_get_account_mgr(), server_account_name,
2807 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
2819 /* This is not in the Maemo UI spec:
2820 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
2826 gtk_widget_destroy (dialog);
2828 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
2832 modest_ui_actions_on_cut (GtkAction *action,
2833 ModestWindow *window)
2835 GtkWidget *focused_widget;
2836 GtkClipboard *clipboard;
2838 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2839 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2840 if (GTK_IS_EDITABLE (focused_widget)) {
2841 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
2842 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2843 gtk_clipboard_store (clipboard);
2844 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2845 GtkTextBuffer *buffer;
2847 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2848 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
2849 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2850 gtk_clipboard_store (clipboard);
2851 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2852 TnyList *header_list = modest_header_view_get_selected_headers (
2853 MODEST_HEADER_VIEW (focused_widget));
2854 gboolean continue_download = FALSE;
2855 gint num_of_unc_msgs;
2857 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
2859 if (num_of_unc_msgs)
2860 continue_download = connect_to_get_msg(
2861 GTK_WINDOW (window),
2864 if (num_of_unc_msgs == 0 || continue_download) {
2865 /* modest_platform_information_banner (
2866 NULL, NULL, _CS("mcen_ib_getting_items"));*/
2867 modest_header_view_cut_selection (
2868 MODEST_HEADER_VIEW (focused_widget));
2871 g_object_unref (header_list);
2872 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2873 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
2878 modest_ui_actions_on_copy (GtkAction *action,
2879 ModestWindow *window)
2881 GtkClipboard *clipboard;
2882 GtkWidget *focused_widget;
2883 gboolean copied = TRUE;
2885 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
2886 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
2888 if (GTK_IS_LABEL (focused_widget)) {
2889 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
2890 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2891 gtk_clipboard_store (clipboard);
2892 } else if (GTK_IS_EDITABLE (focused_widget)) {
2893 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
2894 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2895 gtk_clipboard_store (clipboard);
2896 } else if (GTK_IS_HTML (focused_widget)) {
2897 gtk_html_copy (GTK_HTML (focused_widget));
2898 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2899 gtk_clipboard_store (clipboard);
2900 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
2901 GtkTextBuffer *buffer;
2902 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
2903 gtk_text_buffer_copy_clipboard (buffer, clipboard);
2904 gtk_clipboard_set_can_store (clipboard, NULL, 0);
2905 gtk_clipboard_store (clipboard);
2906 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
2907 TnyList *header_list = modest_header_view_get_selected_headers (
2908 MODEST_HEADER_VIEW (focused_widget));
2909 gboolean continue_download = FALSE;
2910 gint num_of_unc_msgs;
2912 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
2914 if (num_of_unc_msgs)
2915 continue_download = connect_to_get_msg(
2916 GTK_WINDOW (window),
2919 if (num_of_unc_msgs == 0 || continue_download) {
2920 modest_platform_information_banner (
2921 NULL, NULL, _CS("mcen_ib_getting_items"));
2922 modest_header_view_copy_selection (
2923 MODEST_HEADER_VIEW (focused_widget));
2927 g_object_unref (header_list);
2929 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
2930 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
2933 /* Show information banner if there was a copy to clipboard */
2935 modest_platform_information_banner (
2936 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
2940 modest_ui_actions_on_undo (GtkAction *action,
2941 ModestWindow *window)
2943 ModestEmailClipboard *clipboard = NULL;
2945 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2946 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
2947 } else if (MODEST_IS_MAIN_WINDOW (window)) {
2948 /* Clear clipboard source */
2949 clipboard = modest_runtime_get_email_clipboard ();
2950 modest_email_clipboard_clear (clipboard);
2953 g_return_if_reached ();
2958 modest_ui_actions_on_redo (GtkAction *action,
2959 ModestWindow *window)
2961 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
2962 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
2965 g_return_if_reached ();
2971 paste_msgs_cb (const GObject *object, gpointer user_data)
2973 g_return_if_fail (MODEST_IS_MAIN_WINDOW (object));
2974 g_return_if_fail (GTK_IS_WIDGET (user_data));
2976 /* destroy information note */
2977 gtk_widget_destroy (GTK_WIDGET(user_data));
2982 paste_as_attachment_free (gpointer data)
2984 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
2986 gtk_widget_destroy (helper->banner);
2987 g_object_unref (helper->banner);
2992 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
2997 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
2998 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3003 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3008 modest_ui_actions_on_paste (GtkAction *action,
3009 ModestWindow *window)
3011 GtkWidget *focused_widget = NULL;
3012 GtkWidget *inf_note = NULL;
3013 ModestMailOperation *mail_op = NULL;
3015 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3016 if (GTK_IS_EDITABLE (focused_widget)) {
3017 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3018 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3019 ModestEmailClipboard *e_clipboard = NULL;
3020 e_clipboard = modest_runtime_get_email_clipboard ();
3021 if (modest_email_clipboard_cleared (e_clipboard)) {
3022 GtkTextBuffer *buffer;
3023 GtkClipboard *clipboard;
3025 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3026 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3027 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3028 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3029 ModestMailOperation *mail_op;
3030 TnyFolder *src_folder;
3033 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3034 helper->window = MODEST_MSG_EDIT_WINDOW (window);
3035 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3036 _CS("ckct_nw_pasting"));
3037 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
3038 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
3040 if (helper->banner != NULL) {
3041 g_object_ref (G_OBJECT (helper->banner));
3042 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
3043 gtk_widget_show (GTK_WIDGET (helper->banner));
3047 modest_mail_operation_get_msgs_full (mail_op,
3049 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
3051 paste_as_attachment_free);
3054 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3055 ModestEmailClipboard *clipboard = NULL;
3056 TnyFolder *src_folder = NULL;
3057 TnyFolderStore *folder_store = NULL;
3058 TnyList *data = NULL;
3059 gboolean delete = FALSE;
3061 /* Check clipboard source */
3062 clipboard = modest_runtime_get_email_clipboard ();
3063 if (modest_email_clipboard_cleared (clipboard))
3066 /* Get elements to paste */
3067 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
3069 /* Create a new mail operation */
3070 mail_op = modest_mail_operation_new (MODEST_MAIL_OPERATION_TYPE_RECEIVE, G_OBJECT(window));
3072 /* Get destination folder */
3073 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
3075 /* transfer messages */
3079 /* Ask for user confirmation */
3080 response = msgs_move_to_confirmation (GTK_WINDOW (window),
3081 TNY_FOLDER (folder_store),
3085 if (response == GTK_RESPONSE_OK) {
3086 /* Launch notification */
3087 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3088 _CS("ckct_nw_pasting"));
3089 if (inf_note != NULL) {
3090 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3091 gtk_widget_show (GTK_WIDGET(inf_note));
3094 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3095 modest_mail_operation_xfer_msgs (mail_op,
3097 TNY_FOLDER (folder_store),
3102 g_object_unref (mail_op);
3105 } else if (src_folder != NULL) {
3106 /* Launch notification */
3107 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3108 _CS("ckct_nw_pasting"));
3109 if (inf_note != NULL) {
3110 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3111 gtk_widget_show (GTK_WIDGET(inf_note));
3114 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3115 modest_mail_operation_xfer_folder (mail_op,
3125 g_object_unref (data);
3126 if (src_folder != NULL)
3127 g_object_unref (src_folder);
3128 if (folder_store != NULL)
3129 g_object_unref (folder_store);
3135 modest_ui_actions_on_select_all (GtkAction *action,
3136 ModestWindow *window)
3138 GtkWidget *focused_widget;
3140 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3141 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3142 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3143 } else if (GTK_IS_LABEL (focused_widget)) {
3144 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3145 } else if (GTK_IS_EDITABLE (focused_widget)) {
3146 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3147 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3148 GtkTextBuffer *buffer;
3149 GtkTextIter start, end;
3151 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3152 gtk_text_buffer_get_start_iter (buffer, &start);
3153 gtk_text_buffer_get_end_iter (buffer, &end);
3154 gtk_text_buffer_select_range (buffer, &start, &end);
3155 } else if (GTK_IS_HTML (focused_widget)) {
3156 gtk_html_select_all (GTK_HTML (focused_widget));
3157 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3158 GtkWidget *header_view = focused_widget;
3159 GtkTreeSelection *selection = NULL;
3161 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
3162 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3163 MODEST_WIDGET_TYPE_HEADER_VIEW);
3166 /* Disable window dimming management */
3167 modest_window_disable_dimming (MODEST_WINDOW(window));
3169 /* Select all messages */
3170 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3171 gtk_tree_selection_select_all (selection);
3173 /* Set focuse on header view */
3174 gtk_widget_grab_focus (header_view);
3177 /* Enable window dimming management */
3178 modest_window_enable_dimming (MODEST_WINDOW(window));
3179 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3185 modest_ui_actions_on_mark_as_read (GtkAction *action,
3186 ModestWindow *window)
3188 g_return_if_fail (MODEST_IS_WINDOW(window));
3190 /* Mark each header as read */
3191 do_headers_action (window, headers_action_mark_as_read, NULL);
3195 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3196 ModestWindow *window)
3198 g_return_if_fail (MODEST_IS_WINDOW(window));
3200 /* Mark each header as read */
3201 do_headers_action (window, headers_action_mark_as_unread, NULL);
3205 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3206 GtkRadioAction *selected,
3207 ModestWindow *window)
3211 value = gtk_radio_action_get_current_value (selected);
3212 if (MODEST_IS_WINDOW (window)) {
3213 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3218 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3219 GtkRadioAction *selected,
3220 ModestWindow *window)
3222 TnyHeaderFlags flags;
3223 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3225 flags = gtk_radio_action_get_current_value (selected);
3226 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3230 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3231 GtkRadioAction *selected,
3232 ModestWindow *window)
3236 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3238 file_format = gtk_radio_action_get_current_value (selected);
3239 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3244 modest_ui_actions_on_zoom_plus (GtkAction *action,
3245 ModestWindow *window)
3247 g_return_if_fail (MODEST_IS_WINDOW (window));
3249 modest_window_zoom_plus (MODEST_WINDOW (window));
3253 modest_ui_actions_on_zoom_minus (GtkAction *action,
3254 ModestWindow *window)
3256 g_return_if_fail (MODEST_IS_WINDOW (window));
3258 modest_window_zoom_minus (MODEST_WINDOW (window));
3262 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3263 ModestWindow *window)
3265 ModestWindowMgr *mgr;
3266 gboolean fullscreen, active;
3267 g_return_if_fail (MODEST_IS_WINDOW (window));
3269 mgr = modest_runtime_get_window_mgr ();
3271 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3272 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3274 if (active != fullscreen) {
3275 modest_window_mgr_set_fullscreen_mode (mgr, active);
3276 gtk_window_present (GTK_WINDOW (window));
3281 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3282 ModestWindow *window)
3284 ModestWindowMgr *mgr;
3285 gboolean fullscreen;
3287 g_return_if_fail (MODEST_IS_WINDOW (window));
3289 mgr = modest_runtime_get_window_mgr ();
3290 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3291 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3293 gtk_window_present (GTK_WINDOW (window));
3297 * Used by modest_ui_actions_on_details to call do_headers_action
3300 headers_action_show_details (TnyHeader *header,
3301 ModestWindow *window,
3308 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3311 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3312 gtk_widget_show_all (dialog);
3313 gtk_dialog_run (GTK_DIALOG (dialog));
3315 gtk_widget_destroy (dialog);
3319 * Show the folder details in a ModestDetailsDialog widget
3322 show_folder_details (TnyFolder *folder,
3328 dialog = modest_details_dialog_new_with_folder (window, folder);
3331 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3332 gtk_widget_show_all (dialog);
3333 gtk_dialog_run (GTK_DIALOG (dialog));
3335 gtk_widget_destroy (dialog);
3339 * Show the header details in a ModestDetailsDialog widget
3342 modest_ui_actions_on_details (GtkAction *action,
3345 TnyList * headers_list;
3349 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3352 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3355 g_object_unref (msg);
3357 headers_list = get_selected_headers (win);
3361 iter = tny_list_create_iterator (headers_list);
3363 header = TNY_HEADER (tny_iterator_get_current (iter));
3365 headers_action_show_details (header, win, NULL);
3366 g_object_unref (header);
3369 g_object_unref (iter);
3370 g_object_unref (headers_list);
3372 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3373 GtkWidget *folder_view, *header_view;
3375 /* Check which widget has the focus */
3376 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3377 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3378 if (gtk_widget_is_focus (folder_view)) {
3379 TnyFolderStore *folder_store
3380 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3381 if (!folder_store) {
3382 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3385 /* Show only when it's a folder */
3386 /* This function should not be called for account items,
3387 * because we dim the menu item for them. */
3388 if (TNY_IS_FOLDER (folder_store)) {
3389 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3392 g_object_unref (folder_store);
3395 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3396 MODEST_WIDGET_TYPE_HEADER_VIEW);
3397 /* Show details of each header */
3398 do_headers_action (win, headers_action_show_details, header_view);
3404 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3405 ModestMsgEditWindow *window)
3407 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3409 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3413 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3414 ModestMsgEditWindow *window)
3416 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3418 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3422 modest_ui_actions_toggle_folders_view (GtkAction *action,
3423 ModestMainWindow *main_window)
3425 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3427 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3428 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3430 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3434 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3435 ModestWindow *window)
3437 gboolean active, fullscreen = FALSE;
3438 ModestWindowMgr *mgr;
3440 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3442 /* Check if we want to toggle the toolbar vuew in fullscreen
3444 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3445 "ViewShowToolbarFullScreen")) {
3449 /* Toggle toolbar */
3450 mgr = modest_runtime_get_window_mgr ();
3451 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
3455 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3456 ModestMsgEditWindow *window)
3458 modest_msg_edit_window_select_font (window);
3462 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3463 const gchar *display_name,
3466 /* Do not change the application name if the widget has not
3467 the focus. This callback could be called even if the folder
3468 view has not the focus, because the handled signal could be
3469 emitted when the folder view is redrawn */
3470 if (gtk_widget_is_focus (GTK_WIDGET (folder_view))) {
3472 gtk_window_set_title (window, display_name);
3474 gtk_window_set_title (window, " ");
3479 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3481 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3482 modest_msg_edit_window_select_contacts (window);
3486 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3488 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3489 modest_msg_edit_window_check_names (window, FALSE);
3493 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3495 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3496 GTK_WIDGET (user_data));
3500 * This function is used to track changes in the selection of the
3501 * folder view that is inside the "move to" dialog to enable/disable
3502 * the OK button because we do not want the user to select a disallowed
3503 * destination for a folder.
3504 * The user also not desired to be able to use NEW button on items where
3505 * folder creation is not possibel.
3508 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
3509 TnyFolderStore *folder_store,
3513 GtkWidget *dialog = NULL;
3514 GtkWidget *ok_button = NULL, *new_button = NULL;
3515 GList *children = NULL;
3516 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
3517 gboolean moving_folder = FALSE;
3518 gboolean is_local_account = TRUE;
3519 GtkWidget *folder_view = NULL;
3520 ModestTnyFolderRules rules;
3525 /* Get the OK button */
3526 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
3530 children = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
3531 ok_button = GTK_WIDGET (children->next->next->data);
3532 new_button = GTK_WIDGET (children->next->data);
3533 g_list_free (children);
3535 /* check if folder_store is an remote account */
3536 if (TNY_IS_ACCOUNT (folder_store)) {
3537 TnyAccount *local_account = NULL;
3538 ModestTnyAccountStore *account_store = NULL;
3540 account_store = modest_runtime_get_account_store ();
3541 local_account = modest_tny_account_store_get_local_folders_account (account_store);
3543 if ((gpointer) local_account != (gpointer) folder_store) {
3544 is_local_account = FALSE;
3545 /* New button should be dimmed on remote
3547 new_sensitive = FALSE;
3549 g_object_unref (local_account);
3552 /* Check the target folder rules */
3553 if (TNY_IS_FOLDER (folder_store)) {
3554 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
3555 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
3556 ok_sensitive = FALSE;
3557 new_sensitive = FALSE;
3562 /* Check if we're moving a folder */
3563 if (MODEST_IS_MAIN_WINDOW (user_data)) {
3564 /* Get the widgets */
3565 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
3566 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3567 if (gtk_widget_is_focus (folder_view))
3568 moving_folder = TRUE;
3571 if (moving_folder) {
3572 TnyFolderStore *moved_folder = NULL, *parent = NULL;
3574 /* Get the folder to move */
3575 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3577 /* Check that we're not moving to the same folder */
3578 if (TNY_IS_FOLDER (moved_folder)) {
3579 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
3580 if (parent == folder_store)
3581 ok_sensitive = FALSE;
3582 g_object_unref (parent);
3585 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
3586 /* Do not allow to move to an account unless it's the
3587 local folders account */
3588 if (!is_local_account)
3589 ok_sensitive = FALSE;
3592 if (ok_sensitive && (moved_folder == folder_store)) {
3593 /* Do not allow to move to itself */
3594 ok_sensitive = FALSE;
3596 g_object_unref (moved_folder);
3598 TnyHeader *header = NULL;
3599 TnyFolder *src_folder = NULL;
3601 /* Moving a message */
3602 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
3603 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (user_data));
3604 src_folder = tny_header_get_folder (header);
3605 g_object_unref (header);
3608 TNY_FOLDER (modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view)));
3611 /* Do not allow to move the msg to the same folder */
3612 /* Do not allow to move the msg to an account */
3613 if ((gpointer) src_folder == (gpointer) folder_store ||
3614 TNY_IS_ACCOUNT (folder_store))
3615 ok_sensitive = FALSE;
3616 g_object_unref (src_folder);
3620 /* Set sensitivity of the OK button */
3621 gtk_widget_set_sensitive (ok_button, ok_sensitive);
3622 /* Set sensitivity of the NEW button */
3623 gtk_widget_set_sensitive (new_button, new_sensitive);
3627 create_move_to_dialog (GtkWindow *win,
3628 GtkWidget *folder_view,
3629 GtkWidget **tree_view)
3631 GtkWidget *dialog, *scroll;
3632 GtkWidget *new_button;
3634 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
3636 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
3639 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
3640 /* We do this manually so GTK+ does not associate a response ID for
3642 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
3643 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
3644 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
3646 /* Create scrolled window */
3647 scroll = gtk_scrolled_window_new (NULL, NULL);
3648 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
3649 GTK_POLICY_AUTOMATIC,
3650 GTK_POLICY_AUTOMATIC);
3652 /* Create folder view */
3653 *tree_view = modest_platform_create_folder_view (NULL);
3655 /* Track changes in the selection to
3656 * disable the OK button whenever "Move to" is not possible
3657 * disbale NEW button whenever New is not possible */
3658 g_signal_connect (*tree_view,
3659 "folder_selection_changed",
3660 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
3663 /* Listen to clicks on New button */
3664 g_signal_connect (G_OBJECT (new_button),
3666 G_CALLBACK(create_move_to_dialog_on_new_folder),
3669 /* It could happen that we're trying to move a message from a
3670 window (msg window for example) after the main window was
3671 closed, so we can not just get the model of the folder
3673 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
3674 const gchar *visible_id = NULL;
3676 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
3677 MODEST_FOLDER_VIEW(*tree_view));
3680 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
3682 /* Show the same account than the one that is shown in the main window */
3683 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
3686 const gchar *active_account_name = NULL;
3687 ModestAccountMgr *mgr = NULL;
3688 ModestAccountData *acc_data = NULL;
3690 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
3691 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
3693 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
3694 mgr = modest_runtime_get_account_mgr ();
3695 acc_data = modest_account_mgr_get_account_data (mgr, active_account_name);
3697 /* Set the new visible & active account */
3698 if (acc_data && acc_data->store_account) {
3699 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
3700 acc_data->store_account->account_name);
3701 modest_account_mgr_free_account_data (mgr, acc_data);
3705 /* Hide special folders */
3706 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
3708 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
3710 /* Add scroll to dialog */
3711 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
3712 scroll, TRUE, TRUE, 0);
3714 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3715 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
3721 * Returns TRUE if at least one of the headers of the list belongs to
3722 * a message that has been fully retrieved.
3724 #if 0 /* no longer in use. delete in 2007.10 */
3726 has_retrieved_msgs (TnyList *list)
3729 gboolean found = FALSE;
3731 iter = tny_list_create_iterator (list);
3732 while (!tny_iterator_is_done (iter) && !found) {
3734 TnyHeaderFlags flags = 0;
3736 header = TNY_HEADER (tny_iterator_get_current (iter));
3738 flags = tny_header_get_flags (header);
3739 if (flags & TNY_HEADER_FLAG_CACHED)
3740 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
3743 g_object_unref (header);
3747 tny_iterator_next (iter);
3749 g_object_unref (iter);
3757 * Shows a confirmation dialog to the user when we're moving messages
3758 * from a remote server to the local storage. Returns the dialog
3759 * response. If it's other kind of movement then it always returns
3762 * This one is used by the next functions:
3763 * modest_ui_actions_xfer_messages_from_move_to
3764 * modest_ui_actions_on_paste - commented out
3765 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
3768 msgs_move_to_confirmation (GtkWindow *win,
3769 TnyFolder *dest_folder,
3773 gint response = GTK_RESPONSE_OK;
3775 /* return with OK if the destination is a remote folder */
3776 if (modest_tny_folder_is_remote_folder (dest_folder))
3777 return GTK_RESPONSE_OK;
3779 TnyFolder *src_folder = NULL;
3780 TnyIterator *iter = NULL;
3781 TnyHeader *header = NULL;
3783 /* Get source folder */
3784 iter = tny_list_create_iterator (headers);
3785 header = TNY_HEADER (tny_iterator_get_current (iter));
3787 src_folder = tny_header_get_folder (header);
3788 g_object_unref (header);
3790 g_object_unref (iter);
3792 /* if no src_folder, message may be an attahcment */
3793 if (src_folder == NULL)
3794 return GTK_RESPONSE_CANCEL;
3796 /* If the source is a local or MMC folder */
3797 if (!modest_tny_folder_is_remote_folder (src_folder)) {
3798 g_object_unref (src_folder);
3799 return GTK_RESPONSE_OK;
3801 g_object_unref (src_folder);
3803 /* now if offline we ask the user */
3804 if(connect_to_get_msg( GTK_WINDOW (win),
3805 tny_list_get_length (headers)))
3806 response = GTK_RESPONSE_OK;
3808 response = GTK_RESPONSE_CANCEL;
3816 move_to_cb (const GObject *object, gpointer user_data)
3818 ModestMsgViewWindow *self = NULL;
3819 g_return_if_fail (GTK_IS_WIDGET (user_data));
3820 g_return_if_fail (MODEST_IS_WINDOW (object));
3822 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
3823 self = MODEST_MSG_VIEW_WINDOW (object);
3825 if (!modest_msg_view_window_select_next_message (self))
3826 if (!modest_msg_view_window_select_previous_message (self))
3827 /* No more messages to view, so close this window */
3828 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
3830 gtk_widget_destroy (GTK_WIDGET(user_data));
3834 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
3837 ModestMainWindow *main_window = NULL;
3838 GtkWidget *folder_view = NULL;
3839 GObject *win = modest_mail_operation_get_source (mail_op);
3840 const GError *error = NULL;
3841 const gchar *message = NULL;
3843 /* Get error message */
3844 error = modest_mail_operation_get_error (mail_op);
3845 if (error != NULL && error->message != NULL) {
3846 message = error->message;
3848 message = _("mail_in_ui_folder_move_target_error");
3851 /* Disable next automatic folder selection */
3852 if (MODEST_IS_MAIN_WINDOW (user_data)) {
3853 main_window = MODEST_MAIN_WINDOW(user_data);
3854 folder_view = modest_main_window_get_child_widget (main_window,
3855 MODEST_WIDGET_TYPE_FOLDER_VIEW);
3856 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
3859 /* Show notification dialog */
3860 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, message);
3861 g_object_unref (win);
3865 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
3868 GObject *win = modest_mail_operation_get_source (mail_op);
3869 const GError *error = modest_mail_operation_get_error (mail_op);
3871 g_return_if_fail (error != NULL);
3872 if (error->message != NULL)
3873 g_printerr ("modest: %s\n", error->message);
3875 g_printerr ("modest: unkonw error on send&receive operation");
3877 /* Show error message */
3878 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
3879 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3880 /* _CS("sfil_ib_unable_to_receive")); */
3882 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
3883 /* _CS("sfil_ib_unable_to_send")); */
3884 g_object_unref (win);
3888 open_msg_for_purge_cb (ModestMailOperation *mail_op,
3895 gint pending_purges = 0;
3896 gboolean some_purged = FALSE;
3897 ModestWindow *win = MODEST_WINDOW (user_data);
3898 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
3900 /* If there was any error */
3901 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
3902 modest_window_mgr_unregister_header (mgr, header);
3906 /* Once the message has been retrieved for purging, we check if
3907 * it's all ok for purging */
3909 parts = tny_simple_list_new ();
3910 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
3911 iter = tny_list_create_iterator (parts);
3913 while (!tny_iterator_is_done (iter)) {
3915 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3916 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
3917 if (tny_mime_part_is_purged (part))
3924 g_object_unref (part);
3926 tny_iterator_next (iter);
3929 if (pending_purges>0) {
3931 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
3933 if (response == GTK_RESPONSE_OK) {
3934 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
3935 tny_iterator_first (iter);
3936 while (!tny_iterator_is_done (iter)) {
3939 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3940 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
3941 tny_mime_part_set_purged (part);
3944 g_object_unref (part);
3946 tny_iterator_next (iter);
3949 tny_msg_rewrite_cache (msg);
3952 modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged"));
3955 /* remove attachments */
3956 tny_iterator_first (iter);
3957 while (!tny_iterator_is_done (iter)) {
3960 part = TNY_MIME_PART (tny_iterator_get_current (iter));
3962 /* One for the reference given by tny_iterator_get_current(): */
3963 g_object_unref (part);
3965 /* TODO: Is this meant to remove the attachment by doing another unref()?
3966 * Otherwise, this seems useless. */
3969 tny_iterator_next (iter);
3971 modest_window_mgr_unregister_header (mgr, header);
3973 g_object_unref (iter);
3974 g_object_unref (parts);
3978 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
3979 ModestMainWindow *win)
3981 GtkWidget *header_view;
3982 TnyList *header_list;
3985 TnyHeaderFlags flags;
3986 ModestWindow *msg_view_window = NULL;
3989 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
3991 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3992 MODEST_WIDGET_TYPE_HEADER_VIEW);
3994 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
3996 if (tny_list_get_length (header_list) == 1) {
3997 iter = tny_list_create_iterator (header_list);
3998 header = TNY_HEADER (tny_iterator_get_current (iter));
3999 g_object_unref (iter);
4004 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
4005 header, &msg_view_window);
4006 flags = tny_header_get_flags (header);
4007 if (!(flags & TNY_HEADER_FLAG_CACHED))
4010 if (msg_view_window != NULL)
4011 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
4013 /* do nothing; uid was registered before, so window is probably on it's way */
4014 g_warning ("debug: header %p has already been registered", header);
4017 ModestMailOperation *mail_op = NULL;
4018 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header);
4019 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4021 modest_ui_actions_get_msgs_full_error_handler,
4023 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4024 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
4026 g_object_unref (mail_op);
4029 g_object_unref (header);
4031 g_object_unref (header_list);
4035 * Utility function that transfer messages from both the main window
4036 * and the msg view window when using the "Move to" dialog
4039 modest_ui_actions_xfer_messages_from_move_to (TnyFolderStore *dst_folder,
4042 TnyList *headers = NULL;
4044 TnyAccount *dst_account = NULL;
4045 const gchar *proto_str = NULL;
4046 gboolean dst_is_pop = FALSE;
4048 if (!TNY_IS_FOLDER (dst_folder)) {
4049 modest_platform_information_banner (GTK_WIDGET (win),
4051 _CS("ckdg_ib_unable_to_move_to_current_location"));
4055 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
4056 proto_str = tny_account_get_proto (dst_account);
4058 /* tinymail will return NULL for local folders it seems */
4059 dst_is_pop = proto_str &&
4060 (modest_protocol_info_get_transport_store_protocol (proto_str) ==
4061 MODEST_PROTOCOL_STORE_POP);
4063 g_object_unref (dst_account);
4065 /* Get selected headers */
4066 headers = get_selected_headers (MODEST_WINDOW (win));
4069 modest_platform_information_banner (GTK_WIDGET (win),
4071 ngettext("mail_in_ui_folder_move_target_error",
4072 "mail_in_ui_folder_move_targets_error",
4073 tny_list_get_length (headers)));
4074 g_object_unref (headers);
4078 /* Ask for user confirmation */
4079 response = msgs_move_to_confirmation (GTK_WINDOW (win),
4080 TNY_FOLDER (dst_folder),
4084 /* Transfer messages */
4085 if (response == GTK_RESPONSE_OK) {
4086 GtkWidget *inf_note;
4087 inf_note = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4088 _CS("ckct_nw_pasting"));
4089 if (inf_note != NULL) {
4090 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4091 gtk_widget_show (GTK_WIDGET(inf_note));
4094 ModestMailOperation *mail_op =
4095 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4097 modest_ui_actions_move_folder_error_handler,
4099 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4102 modest_mail_operation_xfer_msgs (mail_op,
4104 TNY_FOLDER (dst_folder),
4109 g_object_unref (G_OBJECT (mail_op));
4111 g_object_unref (headers);
4115 * UI handler for the "Move to" action when invoked from the
4119 modest_ui_actions_on_main_window_move_to (GtkAction *action,
4120 GtkWidget *folder_view,
4121 TnyFolderStore *dst_folder,
4122 ModestMainWindow *win)
4124 ModestHeaderView *header_view = NULL;
4125 ModestMailOperation *mail_op = NULL;
4126 TnyFolderStore *src_folder;
4127 gboolean online = (tny_device_is_online (modest_runtime_get_device()));
4129 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4131 /* Get the source folder */
4132 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4134 /* Get header view */
4135 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_WIDGET_TYPE_HEADER_VIEW));
4137 /* Get folder or messages to transfer */
4138 if (gtk_widget_is_focus (folder_view)) {
4139 GtkTreeSelection *sel;
4140 gboolean do_xfer = TRUE;
4142 /* Allow only to transfer folders to the local root folder */
4143 if (TNY_IS_ACCOUNT (dst_folder) &&
4144 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder)) {
4146 } else if (!TNY_IS_FOLDER (src_folder)) {
4147 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
4149 } else if (!online && modest_platform_is_network_folderstore(src_folder)) {
4150 guint num_headers = tny_folder_get_all_count(TNY_FOLDER(src_folder));
4151 if (!connect_to_get_msg(GTK_WINDOW(win), num_headers)) {
4157 GtkWidget *inf_note;
4158 inf_note = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4159 _CS("ckct_nw_pasting"));
4160 if (inf_note != NULL) {
4161 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4162 gtk_widget_show (GTK_WIDGET(inf_note));
4164 /* Clean folder on header view before moving it */
4165 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
4166 gtk_tree_selection_unselect_all (sel);
4169 modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4171 modest_ui_actions_move_folder_error_handler,
4173 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4176 /* Select *after* the changes */
4177 /* TODO: this function hangs UI after transfer */
4178 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
4179 /* TNY_FOLDER (src_folder), TRUE); */
4181 modest_mail_operation_xfer_folder (mail_op,
4182 TNY_FOLDER (src_folder),
4184 TRUE, move_to_cb, inf_note);
4185 /* Unref mail operation */
4186 g_object_unref (G_OBJECT (mail_op));
4188 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
4189 gboolean do_xfer = TRUE;
4190 /* Ask for confirmation if the source folder is remote and we're not connected */
4191 if (!online && modest_platform_is_network_folderstore(src_folder)) {
4192 guint num_headers = modest_header_view_count_selected_headers(header_view);
4193 if (!connect_to_get_msg(GTK_WINDOW(win), num_headers)) {
4197 if (do_xfer) /* Transfer messages */
4198 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4202 g_object_unref (src_folder);
4207 * UI handler for the "Move to" action when invoked from the
4208 * ModestMsgViewWindow
4211 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
4212 TnyFolderStore *dst_folder,
4213 ModestMsgViewWindow *win)
4215 TnyHeader *header = NULL;
4216 TnyFolderStore *src_folder;
4218 /* Create header list */
4219 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
4220 src_folder = TNY_FOLDER_STORE(tny_header_get_folder(header));
4221 g_object_unref (header);
4223 /* Transfer the message if online or confirmed by the user */
4224 if (tny_device_is_online (modest_runtime_get_device()) ||
4225 (modest_platform_is_network_folderstore(src_folder) && connect_to_get_msg(GTK_WINDOW(win), 1))) {
4226 modest_ui_actions_xfer_messages_from_move_to (dst_folder, MODEST_WINDOW (win));
4229 g_object_unref (src_folder);
4233 modest_ui_actions_on_move_to (GtkAction *action,
4236 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
4238 TnyFolderStore *dst_folder = NULL;
4239 ModestMainWindow *main_window;
4241 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
4242 MODEST_IS_MSG_VIEW_WINDOW (win));
4244 /* Get the main window if exists */
4245 if (MODEST_IS_MAIN_WINDOW (win))
4246 main_window = MODEST_MAIN_WINDOW (win);
4249 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
4251 /* Get the folder view widget if exists */
4253 folder_view = modest_main_window_get_child_widget (main_window,
4254 MODEST_WIDGET_TYPE_FOLDER_VIEW);
4258 /* Create and run the dialog */
4259 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
4260 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
4261 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4262 result = gtk_dialog_run (GTK_DIALOG(dialog));
4263 g_object_ref (tree_view);
4264 gtk_widget_destroy (dialog);
4266 if (result != GTK_RESPONSE_ACCEPT)
4269 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
4270 /* Do window specific stuff */
4271 if (MODEST_IS_MAIN_WINDOW (win)) {
4272 modest_ui_actions_on_main_window_move_to (action,
4275 MODEST_MAIN_WINDOW (win));
4277 modest_ui_actions_on_msg_view_window_move_to (action,
4279 MODEST_MSG_VIEW_WINDOW (win));
4283 g_object_unref (dst_folder);
4287 * Calls #HeadersFunc for each header already selected in the main
4288 * window or the message currently being shown in the msg view window
4291 do_headers_action (ModestWindow *win,
4295 TnyList *headers_list = NULL;
4296 TnyIterator *iter = NULL;
4297 TnyHeader *header = NULL;
4298 TnyFolder *folder = NULL;
4301 headers_list = get_selected_headers (win);
4305 /* Get the folder */
4306 iter = tny_list_create_iterator (headers_list);
4307 header = TNY_HEADER (tny_iterator_get_current (iter));
4309 folder = tny_header_get_folder (header);
4310 g_object_unref (header);
4313 /* Call the function for each header */
4314 while (!tny_iterator_is_done (iter)) {
4315 header = TNY_HEADER (tny_iterator_get_current (iter));
4316 func (header, win, user_data);
4317 g_object_unref (header);
4318 tny_iterator_next (iter);
4321 /* Trick: do a poke status in order to speed up the signaling
4323 tny_folder_poke_status (folder);
4326 g_object_unref (folder);
4327 g_object_unref (iter);
4328 g_object_unref (headers_list);
4332 modest_ui_actions_view_attachment (GtkAction *action,
4333 ModestWindow *window)
4335 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4336 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4338 /* not supported window for this action */
4339 g_return_if_reached ();
4344 modest_ui_actions_save_attachments (GtkAction *action,
4345 ModestWindow *window)
4347 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4348 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4350 /* not supported window for this action */
4351 g_return_if_reached ();
4356 modest_ui_actions_remove_attachments (GtkAction *action,
4357 ModestWindow *window)
4359 if (MODEST_IS_MAIN_WINDOW (window)) {
4360 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4361 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4362 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4364 /* not supported window for this action */
4365 g_return_if_reached ();
4370 modest_ui_actions_on_settings (GtkAction *action,
4375 dialog = modest_platform_get_global_settings_dialog ();
4376 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4377 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4378 gtk_widget_show_all (dialog);
4380 gtk_dialog_run (GTK_DIALOG (dialog));
4382 gtk_widget_destroy (dialog);
4386 modest_ui_actions_on_help (GtkAction *action,
4389 const gchar *help_id = NULL;
4391 if (MODEST_IS_MAIN_WINDOW (win)) {
4392 GtkWidget *folder_view;
4393 TnyFolderStore *folder_store;
4395 /* Get selected folder */
4396 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4397 MODEST_WIDGET_TYPE_FOLDER_VIEW);
4398 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4400 /* Switch help_id */
4401 if (TNY_IS_FOLDER (folder_store)) {
4402 switch (modest_tny_folder_guess_folder_type (TNY_FOLDER (folder_store))) {
4403 case TNY_FOLDER_TYPE_NORMAL:
4404 help_id = "applications_email_managefolders";
4406 case TNY_FOLDER_TYPE_INBOX:
4407 help_id = "applications_email_inbox";
4409 case TNY_FOLDER_TYPE_OUTBOX:
4410 help_id = "applications_email_outbox";
4412 case TNY_FOLDER_TYPE_SENT:
4413 help_id = "applications_email_sent";
4415 case TNY_FOLDER_TYPE_DRAFTS:
4416 help_id = "applications_email_drafts";
4418 case TNY_FOLDER_TYPE_ARCHIVE:
4419 help_id = "applications_email_managefolders";
4422 help_id = "applications_email_managefolders";
4425 help_id = "applications_email_mainview";
4427 g_object_unref (folder_store);
4428 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4429 help_id = "applications_email_viewer";
4430 } else if (MODEST_IS_MSG_EDIT_WINDOW (win))
4431 help_id = "applications_email_editor";
4433 modest_platform_show_help (GTK_WINDOW (win), help_id);
4437 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
4438 ModestWindow *window)
4440 ModestMailOperation *mail_op;
4444 headers = get_selected_headers (window);
4448 /* Create mail operation */
4449 mail_op = modest_mail_operation_new_with_error_handling (MODEST_MAIL_OPERATION_TYPE_RECEIVE,
4451 modest_ui_actions_get_msgs_full_error_handler,
4453 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4454 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
4457 g_object_unref (headers);
4458 g_object_unref (mail_op);
4462 modest_ui_actions_on_email_menu_activated (GtkAction *action,
4463 ModestWindow *window)
4465 g_return_if_fail (MODEST_IS_WINDOW (window));
4468 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4472 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
4473 ModestWindow *window)
4475 g_return_if_fail (MODEST_IS_WINDOW (window));
4478 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4482 modest_ui_actions_on_view_menu_activated (GtkAction *action,
4483 ModestWindow *window)
4485 g_return_if_fail (MODEST_IS_WINDOW (window));
4488 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4492 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
4493 ModestWindow *window)
4495 g_return_if_fail (MODEST_IS_WINDOW (window));
4498 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4502 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
4503 ModestWindow *window)
4505 g_return_if_fail (MODEST_IS_WINDOW (window));
4508 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4512 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
4513 ModestWindow *window)
4515 g_return_if_fail (MODEST_IS_WINDOW (window));
4518 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4522 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
4523 ModestWindow *window)
4525 g_return_if_fail (MODEST_IS_WINDOW (window));
4528 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4532 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
4533 ModestWindow *window)
4535 g_return_if_fail (MODEST_IS_WINDOW (window));
4538 modest_window_check_dimming_rules_group (window, "ModestMenuDimmingRules");
4542 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
4544 g_return_if_fail (MODEST_IS_WINDOW (window));
4547 modest_window_check_dimming_rules_group (window, "ModestToolbarDimmingRules");
4551 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
4553 g_return_if_fail (MODEST_IS_WINDOW (window));
4555 modest_platform_show_search_messages (GTK_WINDOW (window));
4559 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
4561 g_return_if_fail (MODEST_IS_WINDOW (win));
4562 modest_platform_show_addressbook (GTK_WINDOW (win));
4567 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
4568 ModestWindow *window)
4570 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4572 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
4576 _on_send_receive_progress_changed (ModestMailOperation *mail_op,
4577 ModestMailOperationState *state,
4580 g_return_if_fail (MODEST_IS_MAIN_WINDOW(user_data));
4582 /* Set send/receive operation finished */
4583 if (state->status != MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
4584 modest_main_window_notify_send_receive_completed (MODEST_MAIN_WINDOW(user_data));