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-defs.h>
39 #include <modest-tny-folder.h>
40 #include <modest-tny-msg.h>
41 #include <modest-tny-account.h>
42 #include <modest-address-book.h>
43 #include "modest-error.h"
44 #include "modest-ui-actions.h"
45 #include "modest-tny-platform-factory.h"
46 #include "modest-platform.h"
47 #include "modest-debug.h"
48 #include <tny-mime-part.h>
49 #include <tny-error.h>
50 #include <tny-camel-folder.h>
51 #include <tny-camel-imap-folder.h>
52 #include <tny-camel-pop-folder.h>
53 #include <widgets/modest-header-window.h>
54 #include <widgets/modest-folder-window.h>
55 #include <widgets/modest-accounts-window.h>
57 #ifdef MODEST_TOOLKIT_HILDON2
58 #include <hildon/hildon-gtk.h>
59 #include <modest-maemo-utils.h>
61 #include <gtk/modest-shell-window.h>
63 #include "modest-utils.h"
64 #include "widgets/modest-connection-specific-smtp-window.h"
65 #include "widgets/modest-ui-constants.h"
66 #include <widgets/modest-msg-view-window.h>
67 #include <widgets/modest-account-view-window.h>
68 #include <widgets/modest-details-dialog.h>
69 #include <widgets/modest-attachments-view.h>
70 #include "widgets/modest-folder-view.h"
71 #include "widgets/modest-global-settings-dialog.h"
72 #include "modest-account-mgr-helpers.h"
73 #include "modest-mail-operation.h"
74 #include "modest-text-utils.h"
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>
81 #include <widgets/modest-toolkit-utils.h>
82 #include <tny-camel-bs-msg.h>
83 #include <tny-camel-bs-mime-part.h>
86 #include <gtkhtml/gtkhtml.h>
88 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
90 typedef struct _GetMsgAsyncHelper {
92 ModestMailOperation *mail_op;
99 typedef enum _ReplyForwardAction {
103 } ReplyForwardAction;
105 typedef struct _ReplyForwardHelper {
106 guint reply_forward_type;
107 ReplyForwardAction action;
110 GtkWidget *parent_window;
112 TnyHeader *top_header;
115 } ReplyForwardHelper;
117 typedef struct _MoveToHelper {
118 GtkTreeRowReference *reference;
122 typedef struct _PasteAsAttachmentHelper {
123 ModestMsgEditWindow *window;
125 } PasteAsAttachmentHelper;
133 * The do_headers_action uses this kind of functions to perform some
134 * action to each member of a list of headers
136 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
138 static void do_headers_action (ModestWindow *win,
142 static void open_msg_cb (ModestMailOperation *mail_op,
149 static void reply_forward_cb (ModestMailOperation *mail_op,
156 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
158 static gint header_list_count_uncached_msgs (TnyList *header_list);
160 static gboolean connect_to_get_msg (ModestWindow *win,
161 gint num_of_uncached_msgs,
162 TnyAccount *account);
164 static gboolean remote_folder_has_leave_on_server (TnyFolderStore *folder);
166 static void do_create_folder (ModestWindow *window,
167 TnyFolderStore *parent_folder,
168 const gchar *suggested_name);
170 static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store);
172 static void modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
173 TnyFolderStore *dst_folder,
177 static void modest_ui_actions_on_window_move_to (GtkAction *action,
178 TnyList *list_to_move,
179 TnyFolderStore *dst_folder,
183 * This function checks whether a TnyFolderStore is a pop account
186 remote_folder_has_leave_on_server (TnyFolderStore *folder)
191 g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
193 account = get_account_from_folder_store (folder);
194 result = (modest_protocol_registry_protocol_type_has_leave_on_server (modest_runtime_get_protocol_registry (),
195 modest_tny_account_get_protocol_type (account)));
196 g_object_unref (account);
201 /* FIXME: this should be merged with the similar code in modest-account-view-window */
202 /* Show the account creation wizard dialog.
203 * returns: TRUE if an account was created. FALSE if the user cancelled.
206 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
208 gboolean result = FALSE;
210 gint dialog_response;
212 /* there is no such wizard yet */
213 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
214 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (wizard), (GtkWindow *) win);
218 ModestWindowMgr *mgr;
220 mgr = modest_runtime_get_window_mgr ();
222 window_list = modest_window_mgr_get_window_list (mgr);
223 if (window_list == NULL) {
224 win = MODEST_WINDOW (modest_accounts_window_new ());
225 if (modest_window_mgr_register_window (mgr, win, NULL)) {
226 gtk_widget_show_all (GTK_WIDGET (win));
228 gtk_widget_destroy (GTK_WIDGET (win));
233 g_list_free (window_list);
238 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
239 gtk_window_set_transient_for (GTK_WINDOW (wizard), toplevel);
242 /* make sure the mainwindow is visible. We need to present the
243 wizard again to give it the focus back. show_all are needed
244 in order to get the widgets properly drawn (MainWindow main
245 paned won't be in its right position and the dialog will be
248 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
249 gtk_widget_destroy (GTK_WIDGET (wizard));
250 if (gtk_events_pending ())
251 gtk_main_iteration ();
253 if (dialog_response == GTK_RESPONSE_CANCEL) {
256 /* Check whether an account was created: */
257 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
264 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
268 const gchar *authors[] = {
269 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
272 about = gtk_about_dialog_new ();
273 gtk_about_dialog_set_program_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
274 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
275 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
276 _("Copyright (c) 2006, Nokia Corporation\n"
277 "All rights reserved."));
278 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
279 _("a modest e-mail client\n\n"
280 "design and implementation: Dirk-Jan C. Binnema\n"
281 "contributions from the fine people at KC and Ig\n"
282 "uses the tinymail email framework written by Philip van Hoof"));
283 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
284 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
286 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
287 gtk_window_set_transient_for (GTK_WINDOW (about), toplevel);
288 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
290 gtk_dialog_run (GTK_DIALOG (about));
291 gtk_widget_destroy(about);
295 * Gets the list of currently selected messages. If the win is the
296 * main window, then it returns a newly allocated list of the headers
297 * selected in the header view. If win is the msg view window, then
298 * the value returned is a list with just a single header.
300 * The caller of this funcion must free the list.
303 get_selected_headers (ModestWindow *win)
305 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
306 /* for MsgViewWindows, we simply return a list with one element */
308 TnyList *list = NULL;
310 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
311 if (header != NULL) {
312 list = tny_simple_list_new ();
313 tny_list_prepend (list, G_OBJECT(header));
314 g_object_unref (G_OBJECT(header));
318 } else if (MODEST_IS_HEADER_WINDOW (win)) {
319 GtkWidget *header_view;
321 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
322 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
329 headers_action_mark_as_read (TnyHeader *header,
333 TnyHeaderFlags flags;
336 g_return_if_fail (TNY_IS_HEADER(header));
338 flags = tny_header_get_flags (header);
339 if (flags & TNY_HEADER_FLAG_SEEN) return;
340 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
341 uid = modest_tny_folder_get_header_unique_id (header);
342 modest_platform_emit_msg_read_changed_signal (uid, TRUE);
347 headers_action_mark_as_unread (TnyHeader *header,
351 TnyHeaderFlags flags;
353 g_return_if_fail (TNY_IS_HEADER(header));
355 flags = tny_header_get_flags (header);
356 if (flags & TNY_HEADER_FLAG_SEEN) {
358 uid = modest_tny_folder_get_header_unique_id (header);
359 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
360 modest_platform_emit_msg_read_changed_signal (uid, FALSE);
364 /** After deleing a message that is currently visible in a window,
365 * show the next message from the list, or close the window if there are no more messages.
368 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
370 /* Close msg view window or select next */
371 if (!modest_msg_view_window_select_next_message (win) &&
372 !modest_msg_view_window_select_previous_message (win)) {
374 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
380 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
382 modest_ui_actions_on_edit_mode_delete_message (win);
386 modest_ui_actions_on_edit_mode_delete_message (ModestWindow *win)
388 TnyList *header_list = NULL;
389 TnyIterator *iter = NULL;
390 TnyHeader *header = NULL;
391 gchar *message = NULL;
394 ModestWindowMgr *mgr;
395 gboolean retval = TRUE;
397 g_return_val_if_fail (MODEST_IS_WINDOW(win), FALSE);
399 /* Get the headers, either from the header view (if win is the main window),
400 * or from the message view window: */
401 header_list = get_selected_headers (win);
402 if (!header_list) return FALSE;
404 /* Check if any of the headers are already opened, or in the process of being opened */
407 if (tny_list_get_length(header_list) == 1) {
408 iter = tny_list_create_iterator (header_list);
409 header = TNY_HEADER (tny_iterator_get_current (iter));
412 subject = tny_header_dup_subject (header);
414 subject = g_strdup (_("mail_va_no_subject"));
415 desc = g_strdup_printf ("%s", subject);
417 g_object_unref (header);
420 g_object_unref (iter);
422 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
423 tny_list_get_length(header_list)), desc);
425 /* Confirmation dialog */
426 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (win))),
429 if (response == GTK_RESPONSE_OK) {
430 GtkTreeSelection *sel = NULL;
431 GList *sel_list = NULL;
432 ModestMailOperation *mail_op = NULL;
434 /* Find last selected row */
436 /* Disable window dimming management */
437 modest_window_disable_dimming (win);
439 /* Remove each header. If it's a view window header_view == NULL */
440 mail_op = modest_mail_operation_new ((GObject *) win);
441 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
443 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
444 g_object_unref (mail_op);
446 /* Enable window dimming management */
448 gtk_tree_selection_unselect_all (sel);
450 modest_window_enable_dimming (win);
452 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
453 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
455 /* Get main window */
456 mgr = modest_runtime_get_window_mgr ();
459 /* Update toolbar dimming state */
460 modest_ui_actions_check_menu_dimming_rules (win);
461 modest_ui_actions_check_toolbar_dimming_rules (win);
464 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
465 g_list_free (sel_list);
474 g_object_unref (header_list);
482 /* delete either message or folder, based on where we are */
484 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
486 g_return_if_fail (MODEST_IS_WINDOW(win));
488 /* Check first if the header view has the focus */
489 modest_ui_actions_on_delete_message (action, win);
493 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
495 ModestWindowMgr *mgr = NULL;
497 #ifdef MODEST_PLATFORM_MAEMO
498 modest_window_mgr_save_state_for_all_windows (modest_runtime_get_window_mgr ());
499 #endif /* MODEST_PLATFORM_MAEMO */
501 g_debug ("closing down, clearing %d item(s) from operation queue",
502 modest_mail_operation_queue_num_elements
503 (modest_runtime_get_mail_operation_queue()));
505 /* cancel all outstanding operations */
506 modest_mail_operation_queue_cancel_all
507 (modest_runtime_get_mail_operation_queue());
509 g_debug ("queue has been cleared");
512 /* Check if there are opened editing windows */
513 mgr = modest_runtime_get_window_mgr ();
514 modest_window_mgr_close_all_windows (mgr);
516 /* note: when modest-tny-account-store is finalized,
517 it will automatically set all network connections
520 /* gtk_main_quit (); */
524 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
528 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
530 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
531 /* gtk_widget_destroy (GTK_WIDGET (win)); */
532 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
533 /* gboolean ret_value; */
534 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
535 /* } else if (MODEST_IS_WINDOW (win)) { */
536 /* gtk_widget_destroy (GTK_WIDGET (win)); */
538 /* g_return_if_reached (); */
543 modest_ui_actions_add_to_contacts (GtkAction *action, ModestWindow *win)
545 if (MODEST_IS_MSG_VIEW_WINDOW (win))
546 modest_msg_view_window_add_to_contacts (MODEST_MSG_VIEW_WINDOW (win));
547 else if (MODEST_IS_MSG_EDIT_WINDOW (win))
548 modest_msg_edit_window_add_to_contacts (MODEST_MSG_EDIT_WINDOW (win));
552 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
554 GtkClipboard *clipboard = NULL;
555 gchar *selection = NULL;
557 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
558 selection = gtk_clipboard_wait_for_text (clipboard);
561 modest_address_book_add_address (selection, (GtkWindow *) win);
567 modest_ui_actions_on_new_account (GtkAction *action,
568 ModestWindow *window)
570 if (!modest_ui_actions_run_account_setup_wizard (window)) {
571 g_debug ("%s: wizard was already running", __FUNCTION__);
576 modest_ui_actions_on_accounts (GtkAction *action,
579 /* This is currently only implemented for Maemo */
580 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
581 if (!modest_ui_actions_run_account_setup_wizard (win))
582 g_debug ("%s: wizard was already running", __FUNCTION__);
586 /* Show the list of accounts */
587 GtkWindow *win_toplevel, *acc_toplevel;
588 GtkWidget *account_win;
590 account_win = modest_account_view_window_new ();
591 acc_toplevel = (GtkWindow *) gtk_widget_get_toplevel (account_win);
593 /* The accounts dialog must be modal */
594 win_toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
595 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), acc_toplevel, win_toplevel);
596 modest_utils_show_dialog_and_forget (win_toplevel, GTK_DIALOG (account_win));
601 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
603 /* Create the window if necessary: */
604 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
605 modest_connection_specific_smtp_window_fill_with_connections (
606 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
607 modest_runtime_get_account_mgr());
609 /* Show the window: */
610 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
611 GTK_WINDOW (specific_window), (GtkWindow *) win);
612 gtk_widget_show (specific_window);
616 count_part_size (const gchar *part)
618 GnomeVFSURI *vfs_uri;
619 gchar *escaped_filename;
621 GnomeVFSFileInfo *info;
624 /* Estimation of attachment size if we cannot get it from file info */
627 vfs_uri = gnome_vfs_uri_new (part);
629 escaped_filename = g_path_get_basename (gnome_vfs_uri_get_path (vfs_uri));
630 filename = gnome_vfs_unescape_string_for_display (escaped_filename);
631 g_free (escaped_filename);
632 gnome_vfs_uri_unref (vfs_uri);
634 info = gnome_vfs_file_info_new ();
636 if (gnome_vfs_get_file_info (part,
638 GNOME_VFS_FILE_INFO_GET_MIME_TYPE)
640 if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) {
645 gnome_vfs_file_info_unref (info);
651 count_parts_size (GSList *parts)
656 for (node = parts; node != NULL; node = g_slist_next (node)) {
657 result += count_part_size ((const gchar *) node->data);
664 modest_ui_actions_compose_msg(ModestWindow *win,
667 const gchar *bcc_str,
668 const gchar *subject_str,
669 const gchar *body_str,
671 gboolean set_as_modified)
673 gchar *account_name = NULL;
674 const gchar *mailbox;
676 TnyAccount *account = NULL;
677 TnyFolder *folder = NULL;
678 gchar *from_str = NULL, *signature = NULL, *body = NULL, *recipient = NULL, *tmp = NULL;
679 gboolean use_signature = FALSE;
680 ModestWindow *msg_win = NULL;
681 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
682 ModestTnyAccountStore *store = modest_runtime_get_account_store();
683 GnomeVFSFileSize total_size, allowed_size;
684 guint64 available_disk, expected_size, parts_size;
686 TnyList *header_pairs;
688 /* we check for low-mem */
689 if (modest_platform_check_memory_low (win, TRUE))
692 available_disk = modest_utils_get_available_space (NULL);
693 parts_count = g_slist_length (attachments);
694 parts_size = count_parts_size (attachments);
695 expected_size = modest_tny_msg_estimate_size (body, NULL, parts_count, parts_size);
697 /* Double check: disk full condition or message too big */
698 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
699 expected_size > available_disk) {
700 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
701 modest_platform_system_banner (NULL, NULL, msg);
707 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
708 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
709 modest_platform_run_information_dialog (toplevel,
710 _("mail_ib_error_attachment_size"),
717 account_name = g_strdup (modest_window_get_active_account(win));
719 account_name = modest_account_mgr_get_default_account(mgr);
722 g_printerr ("modest: no account found\n");
727 mailbox = modest_window_get_active_mailbox (win);
730 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
732 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
735 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
737 g_printerr ("modest: failed to find Drafts folder\n");
740 from_str = modest_account_mgr_get_from_string (mgr, account_name, mailbox);
742 g_printerr ("modest: failed get from string for '%s'\n", account_name);
747 recipient = modest_text_utils_get_email_address (from_str);
748 tmp = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr (),
751 signature = modest_text_utils_create_colored_signature (tmp);
755 body = use_signature ? g_strconcat ((body_str) ? body_str : "", signature, NULL) :
758 header_pairs = TNY_LIST (tny_simple_list_new ());
759 msg = modest_tny_msg_new_html_plain (to_str, from_str, cc_str, bcc_str, subject_str,
760 NULL, NULL, body, NULL, NULL, NULL, NULL, header_pairs, NULL);
761 g_object_unref (header_pairs);
764 g_printerr ("modest: failed to create new msg\n");
768 /* Create and register edit window */
769 /* This is destroyed by TODO. */
771 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
772 msg_win = modest_msg_edit_window_new (msg, account_name, mailbox, FALSE);
774 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, win)) {
775 gtk_widget_destroy (GTK_WIDGET (msg_win));
778 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
779 gtk_widget_show_all (GTK_WIDGET (msg_win));
781 while (attachments) {
782 GnomeVFSFileSize att_size;
784 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
785 attachments->data, allowed_size);
786 total_size += att_size;
788 if (att_size > allowed_size) {
789 g_debug ("%s: total size: %u",
790 __FUNCTION__, (unsigned int)total_size);
793 allowed_size -= att_size;
795 attachments = g_slist_next(attachments);
802 g_free (account_name);
804 g_object_unref (G_OBJECT(account));
806 g_object_unref (G_OBJECT(folder));
808 g_object_unref (G_OBJECT(msg));
812 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
814 /* if there are no accounts yet, just show the wizard */
815 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
816 if (!modest_ui_actions_run_account_setup_wizard (win))
819 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
824 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
828 ModestMailOperationStatus status;
830 /* If there is no message or the operation was not successful */
831 status = modest_mail_operation_get_status (mail_op);
832 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
835 /* If it's a memory low issue, then show a banner */
836 error = modest_mail_operation_get_error (mail_op);
837 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
838 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
839 GtkWindow *toplevel = NULL;
840 GObject *source = modest_mail_operation_get_source (mail_op);
842 toplevel = (GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (source));
843 modest_platform_run_information_dialog (toplevel,
844 _KR("memr_ib_operation_disabled"),
846 g_object_unref (source);
849 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
850 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
851 gchar *subject, *msg, *format = NULL;
854 subject = (header) ? tny_header_dup_subject (header) : NULL;
856 subject = g_strdup (_("mail_va_no_subject"));
858 account = modest_mail_operation_get_account (mail_op);
860 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
861 ModestProtocol *protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), proto);
864 if (tny_account_get_connection_status (account) ==
865 TNY_CONNECTION_STATUS_CONNECTED) {
867 format = modest_protocol_get_translation (protocol,
868 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE,
871 format = modest_protocol_get_translation (protocol,
872 MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE_LOST_HEADER);
875 format = g_strdup_printf (_("mail_ib_backend_server_invalid"),
876 tny_account_get_hostname (account));
879 g_object_unref (account);
884 format = g_strdup (_("emev_ni_ui_imap_message_not_available_in_server"));
886 format = g_strdup (_("emev_ni_ui_pop3_msg_recv_error"));
890 msg = g_strdup_printf (format, subject);
891 modest_platform_run_information_dialog (NULL, msg, FALSE);
897 /* Remove the header from the preregistered uids */
898 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
916 ModestWindow *caller_window;
917 OpenMsgBannerInfo *banner_info;
918 GtkTreeRowReference *rowref;
922 open_msg_banner_idle (gpointer userdata)
924 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
926 gdk_threads_enter ();
927 banner_info->idle_handler = 0;
928 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
929 if (banner_info->banner)
930 g_object_ref (banner_info->banner);
932 gdk_threads_leave ();
938 get_header_view_from_window (ModestWindow *window)
940 GtkWidget *header_view;
942 if (MODEST_IS_HEADER_WINDOW (window)){
943 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
952 get_info_from_header (TnyHeader *header, gboolean *is_draft, gboolean *can_open)
955 gchar *account = NULL;
956 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
961 folder = tny_header_get_folder (header);
962 /* Gets folder type (OUTBOX headers will be opened in edit window */
963 if (modest_tny_folder_is_local_folder (folder)) {
964 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
965 if (folder_type == TNY_FOLDER_TYPE_INVALID)
966 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
969 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
970 TnyTransportAccount *traccount = NULL;
971 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
972 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
974 ModestTnySendQueue *send_queue = NULL;
975 ModestTnySendQueueStatus status;
977 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
978 TNY_ACCOUNT(traccount)));
979 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
980 if (TNY_IS_SEND_QUEUE (send_queue)) {
981 msg_id = modest_tny_send_queue_get_msg_id (header);
982 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
984 /* Only open messages in outbox with the editor if they are in Failed state */
985 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
989 /* In Fremantle we can not
990 open any message from
991 outbox which is not in
996 g_object_unref(traccount);
998 g_warning("Cannot get transport account for message in outbox!!");
1000 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
1001 *is_draft = TRUE; /* Open in editor if the message is in the Drafts folder */
1005 TnyAccount *acc = tny_folder_get_account (folder);
1008 g_strdup (modest_tny_account_get_parent_modest_account_name_for_server_account (acc));
1009 g_object_unref (acc);
1013 g_object_unref (folder);
1019 open_msg_cb (ModestMailOperation *mail_op,
1026 ModestWindowMgr *mgr = NULL;
1027 ModestWindow *parent_win = NULL;
1028 ModestWindow *win = NULL;
1029 gchar *account = NULL;
1030 gboolean open_in_editor = FALSE;
1032 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1034 /* Do nothing if there was any problem with the mail
1035 operation. The error will be shown by the error_handler of
1036 the mail operation */
1037 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1040 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
1042 /* Mark header as read */
1043 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
1045 account = get_info_from_header (header, &open_in_editor, &can_open);
1049 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
1051 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1053 if (open_in_editor) {
1054 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
1055 gchar *from_header = NULL, *acc_name;
1056 gchar *mailbox = NULL;
1058 from_header = tny_header_dup_from (header);
1060 /* we cannot edit without a valid account... */
1061 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
1062 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
1063 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1065 g_free (from_header);
1070 acc_name = modest_utils_get_account_name_from_recipient (from_header, &mailbox);
1071 g_free (from_header);
1077 win = modest_msg_edit_window_new (msg, account, mailbox, TRUE);
1081 gchar *uid = modest_tny_folder_get_header_unique_id (header);
1082 const gchar *mailbox = NULL;
1084 if (parent_win && MODEST_IS_WINDOW (parent_win))
1085 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (parent_win));
1087 if (helper->rowref && helper->model) {
1088 win = modest_msg_view_window_new_with_header_model (msg, account, mailbox, (const gchar*) uid,
1089 helper->model, helper->rowref);
1091 win = modest_msg_view_window_new_for_attachment (msg, NULL, account, mailbox, (const gchar*) uid);
1096 /* Register and show new window */
1098 mgr = modest_runtime_get_window_mgr ();
1099 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1100 gtk_widget_destroy (GTK_WIDGET (win));
1103 gtk_widget_show_all (GTK_WIDGET(win));
1110 g_object_unref (parent_win);
1114 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1117 const GError *error;
1118 GObject *win = NULL;
1119 ModestMailOperationStatus status;
1121 win = modest_mail_operation_get_source (mail_op);
1122 error = modest_mail_operation_get_error (mail_op);
1123 status = modest_mail_operation_get_status (mail_op);
1125 /* If the mail op has been cancelled then it's not an error:
1126 don't show any message */
1127 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1128 TnyAccount *account = modest_mail_operation_get_account (mail_op);
1129 if (modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
1130 (GError *) error, account)) {
1131 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
1132 modest_platform_information_banner ((GtkWidget *) win, NULL, msg);
1134 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1135 modest_platform_information_banner ((GtkWidget *) win,
1136 NULL, _("emev_ui_imap_inbox_select_error"));
1137 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1138 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1139 modest_platform_information_banner ((GtkWidget *) win,
1140 NULL, _CS_UNABLE_TO_OPEN_FILE_NOT_FOUND);
1141 } else if (user_data) {
1142 modest_platform_information_banner ((GtkWidget *) win,
1146 g_object_unref (account);
1150 g_object_unref (win);
1154 * Returns the account a list of headers belongs to. It returns a
1155 * *new* reference so don't forget to unref it
1158 get_account_from_header_list (TnyList *headers)
1160 TnyAccount *account = NULL;
1162 if (tny_list_get_length (headers) > 0) {
1163 TnyIterator *iter = tny_list_create_iterator (headers);
1164 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1165 TnyFolder *folder = tny_header_get_folder (header);
1168 g_object_unref (header);
1170 while (!tny_iterator_is_done (iter)) {
1171 header = TNY_HEADER (tny_iterator_get_current (iter));
1172 folder = tny_header_get_folder (header);
1175 g_object_unref (header);
1177 tny_iterator_next (iter);
1182 account = tny_folder_get_account (folder);
1183 g_object_unref (folder);
1187 g_object_unref (header);
1189 g_object_unref (iter);
1195 get_account_from_header (TnyHeader *header)
1197 TnyAccount *account = NULL;
1200 folder = tny_header_get_folder (header);
1203 account = tny_folder_get_account (folder);
1204 g_object_unref (folder);
1210 caller_win_destroyed (OpenMsgHelper *helper, GObject *object)
1212 if (helper->caller_window)
1213 helper->caller_window = NULL;
1217 open_msg_helper_destroyer (gpointer user_data)
1219 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1221 if (helper->caller_window) {
1222 g_object_weak_unref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1223 helper->caller_window = NULL;
1226 if (helper->banner_info) {
1227 g_free (helper->banner_info->message);
1228 if (helper->banner_info->idle_handler > 0) {
1229 g_source_remove (helper->banner_info->idle_handler);
1230 helper->banner_info->idle_handler = 0;
1232 if (helper->banner_info->banner != NULL) {
1233 gtk_widget_destroy (helper->banner_info->banner);
1234 g_object_unref (helper->banner_info->banner);
1235 helper->banner_info->banner = NULL;
1237 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1238 helper->banner_info = NULL;
1240 g_object_unref (helper->model);
1241 g_object_unref (helper->header);
1242 gtk_tree_row_reference_free (helper->rowref);
1243 g_slice_free (OpenMsgHelper, helper);
1247 open_msg_performer(gboolean canceled,
1249 ModestWindow *parent_window,
1250 TnyAccount *account,
1253 ModestMailOperation *mail_op = NULL;
1254 gchar *error_msg = NULL;
1255 ModestProtocolType proto;
1256 TnyConnectionStatus status;
1257 OpenMsgHelper *helper = NULL;
1258 ModestProtocol *protocol;
1259 ModestProtocolRegistry *protocol_registry;
1262 helper = (OpenMsgHelper *) user_data;
1264 status = tny_account_get_connection_status (account);
1265 if (err || canceled || helper->caller_window == NULL) {
1266 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1267 /* Free the helper */
1268 open_msg_helper_destroyer (helper);
1270 /* In disk full conditions we could get this error here */
1271 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
1272 (GtkWidget *) parent_window, err,
1278 /* Get the error message depending on the protocol */
1279 proto = modest_tny_account_get_protocol_type (account);
1280 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1281 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1284 protocol_registry = modest_runtime_get_protocol_registry ();
1285 subject = tny_header_dup_subject (helper->header);
1287 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1288 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1292 if (error_msg == NULL) {
1293 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1298 gchar *account_name = get_info_from_header (helper->header, &is_draft, &can_open);
1300 if (!g_strcmp0 (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) ||
1301 !g_strcmp0 (account_name, MODEST_MMC_ACCOUNT_ID)) {
1302 g_free (account_name);
1303 account_name = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_window)));
1307 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (), helper->header);
1308 g_free (account_name);
1309 open_msg_helper_destroyer (helper);
1314 ModestWindow *window;
1315 GtkWidget *header_view;
1318 header_view = get_header_view_from_window (parent_window);
1319 uid = modest_tny_folder_get_header_unique_id (helper->header);
1321 const gchar *mailbox = NULL;
1322 mailbox = modest_window_get_active_mailbox (parent_window);
1323 window = modest_msg_view_window_new_from_header_view
1324 (MODEST_HEADER_VIEW (header_view), account_name, mailbox, uid, helper->rowref);
1325 if (window != NULL) {
1326 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr (),
1328 gtk_widget_destroy (GTK_WIDGET (window));
1330 gtk_widget_show_all (GTK_WIDGET(window));
1334 g_free (account_name);
1336 open_msg_helper_destroyer (helper);
1339 g_free (account_name);
1340 /* Create the mail operation */
1342 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1343 modest_ui_actions_disk_operations_error_handler,
1344 g_strdup (error_msg), g_free);
1345 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1351 headers = TNY_LIST (tny_simple_list_new ());
1352 tny_list_prepend (headers, G_OBJECT (helper->header));
1353 modest_mail_operation_get_msgs_full (mail_op,
1357 open_msg_helper_destroyer);
1358 g_object_unref (headers);
1365 g_object_unref (mail_op);
1366 g_object_unref (account);
1370 * This function is used by both modest_ui_actions_on_open and
1371 * modest_ui_actions_on_header_activated. This way we always do the
1372 * same when trying to open messages.
1375 open_msg_from_header (TnyHeader *header, GtkTreeRowReference *rowref, ModestWindow *win)
1377 ModestWindowMgr *mgr = NULL;
1378 TnyAccount *account;
1379 gboolean cached = FALSE;
1381 GtkWidget *header_view = NULL;
1382 OpenMsgHelper *helper;
1383 ModestWindow *window;
1385 g_return_if_fail (header != NULL && rowref != NULL && gtk_tree_row_reference_valid (rowref));
1387 mgr = modest_runtime_get_window_mgr ();
1390 header_view = get_header_view_from_window (MODEST_WINDOW (win));
1391 if (header_view == NULL)
1394 /* Get the account */
1395 account = get_account_from_header (header);
1400 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1402 /* Do not open again the message and present the
1403 window to the user */
1406 #ifndef MODEST_TOOLKIT_HILDON2
1407 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) window);
1408 gtk_window_present (toplevel);
1411 /* the header has been registered already, we don't do
1412 * anything but wait for the window to come up*/
1413 g_debug ("header %p already registered, waiting for window", header);
1418 /* Open each message */
1419 cached = tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED;
1421 /* Allways download if we are online. */
1422 if (!tny_device_is_online (modest_runtime_get_device ())) {
1424 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
1426 /* If ask for user permission to download the messages */
1427 response = modest_platform_run_confirmation_dialog (toplevel,
1428 _("mcen_nc_get_msg"));
1430 /* End if the user does not want to continue */
1431 if (response == GTK_RESPONSE_CANCEL) {
1437 /* We register the window for opening */
1438 modest_window_mgr_register_header (mgr, header, NULL);
1440 /* Create the helper. We need to get a reference to the model
1441 here because it could change while the message is readed
1442 (the user could switch between folders) */
1443 helper = g_slice_new (OpenMsgHelper);
1444 helper->model = g_object_ref (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)));
1445 helper->caller_window = win;
1446 g_object_weak_ref ((GObject *) helper->caller_window, (GWeakNotify) caller_win_destroyed, helper);
1447 helper->header = g_object_ref (header);
1448 helper->rowref = gtk_tree_row_reference_copy (rowref);
1449 helper->banner_info = NULL;
1451 /* Connect to the account and perform */
1453 modest_platform_connect_and_perform (win, TRUE, g_object_ref (account),
1454 open_msg_performer, helper);
1456 /* Call directly the performer, do not need to connect */
1457 open_msg_performer (FALSE, NULL, win,
1458 g_object_ref (account), helper);
1463 g_object_unref (account);
1467 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1474 /* we check for low-mem; in that case, show a warning, and don't allow
1477 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1481 headers = get_selected_headers (win);
1485 headers_count = tny_list_get_length (headers);
1486 if (headers_count != 1) {
1487 if (headers_count > 1) {
1488 /* Don't allow activation if there are more than one message selected */
1489 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
1492 g_object_unref (headers);
1496 iter = tny_list_create_iterator (headers);
1497 header = TNY_HEADER (tny_iterator_get_current (iter));
1498 g_object_unref (iter);
1502 open_msg_from_header (header, NULL, win);
1503 g_object_unref (header);
1506 g_object_unref(headers);
1510 rf_helper_window_closed (gpointer data,
1513 ReplyForwardHelper *helper = (ReplyForwardHelper *) data;
1515 helper->parent_window = NULL;
1518 static ReplyForwardHelper*
1519 create_reply_forward_helper (ReplyForwardAction action,
1521 guint reply_forward_type,
1524 TnyHeader *top_header,
1527 ReplyForwardHelper *rf_helper = NULL;
1528 const gchar *active_acc = modest_window_get_active_account (win);
1529 const gchar *active_mailbox = modest_window_get_active_mailbox (win);
1531 rf_helper = g_slice_new0 (ReplyForwardHelper);
1532 rf_helper->reply_forward_type = reply_forward_type;
1533 rf_helper->action = action;
1534 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1535 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1536 rf_helper->top_header = (top_header) ? g_object_ref (top_header) : NULL;
1537 rf_helper->msg_part = (msg_part) ? g_object_ref (msg_part) : NULL;
1538 rf_helper->account_name = (active_acc) ?
1539 g_strdup (active_acc) :
1540 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1541 rf_helper->mailbox = g_strdup (active_mailbox);
1543 rf_helper->parts = g_object_ref (parts);
1545 rf_helper->parts = NULL;
1547 /* Note that window could be destroyed just AFTER calling
1548 register_window so we must ensure that this pointer does
1549 not hold invalid references */
1550 if (rf_helper->parent_window)
1551 g_object_weak_ref (G_OBJECT (rf_helper->parent_window),
1552 rf_helper_window_closed, rf_helper);
1558 free_reply_forward_helper (gpointer data)
1560 ReplyForwardHelper *helper;
1562 helper = (ReplyForwardHelper *) data;
1563 g_free (helper->account_name);
1564 g_free (helper->mailbox);
1566 g_object_unref (helper->header);
1567 if (helper->top_header)
1568 g_object_unref (helper->top_header);
1569 if (helper->msg_part)
1570 g_object_unref (helper->msg_part);
1572 g_object_unref (helper->parts);
1573 if (helper->parent_window)
1574 g_object_weak_unref (G_OBJECT (helper->parent_window),
1575 rf_helper_window_closed, helper);
1576 g_slice_free (ReplyForwardHelper, helper);
1580 reply_forward_cb (ModestMailOperation *mail_op,
1587 TnyMsg *new_msg = NULL;
1588 ReplyForwardHelper *rf_helper;
1589 ModestWindow *msg_win = NULL;
1590 ModestEditType edit_type;
1592 TnyAccount *account = NULL;
1593 ModestWindowMgr *mgr = NULL;
1594 gchar *signature = NULL, *recipient = NULL;
1595 gboolean use_signature;
1597 /* If there was any error. The mail operation could be NULL,
1598 this means that we already have the message downloaded and
1599 that we didn't do a mail operation to retrieve it */
1600 rf_helper = (ReplyForwardHelper *) user_data;
1601 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1604 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1605 rf_helper->account_name, rf_helper->mailbox);
1607 recipient = modest_text_utils_get_email_address (from);
1608 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr (),
1613 /* Create reply mail */
1614 switch (rf_helper->action) {
1615 /* Use the msg_header to ensure that we have all the
1616 information. The summary can lack some data */
1617 TnyHeader *msg_header;
1619 msg_header = tny_msg_get_header (rf_helper->msg_part?rf_helper->msg_part:msg);
1621 modest_tny_msg_create_reply_msg (rf_helper->msg_part?rf_helper->msg_part:msg, msg_header, from,
1622 (use_signature) ? signature : NULL,
1623 rf_helper->reply_forward_type,
1624 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1625 g_object_unref (msg_header);
1627 case ACTION_REPLY_TO_ALL:
1628 msg_header = tny_msg_get_header (rf_helper->msg_part?rf_helper->msg_part:msg);
1630 modest_tny_msg_create_reply_msg (rf_helper->msg_part?rf_helper->msg_part:msg, msg_header, from,
1631 (use_signature) ? signature : NULL,
1632 rf_helper->reply_forward_type,
1633 MODEST_TNY_MSG_REPLY_MODE_ALL);
1634 edit_type = MODEST_EDIT_TYPE_REPLY;
1635 g_object_unref (msg_header);
1637 case ACTION_FORWARD:
1639 modest_tny_msg_create_forward_msg (rf_helper->msg_part?rf_helper->msg_part:msg, from,
1640 (use_signature) ? signature : NULL,
1641 rf_helper->reply_forward_type);
1642 edit_type = MODEST_EDIT_TYPE_FORWARD;
1645 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1647 g_return_if_reached ();
1655 g_warning ("%s: failed to create message\n", __FUNCTION__);
1659 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1660 rf_helper->account_name,
1661 TNY_ACCOUNT_TYPE_STORE);
1663 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1667 /* Create and register the windows */
1668 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, rf_helper->mailbox, FALSE);
1669 mgr = modest_runtime_get_window_mgr ();
1670 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1672 /* Note that register_window could have deleted the account */
1673 if (MODEST_IS_WINDOW (rf_helper->parent_window)) {
1674 gdouble parent_zoom;
1676 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1677 modest_window_set_zoom (msg_win, parent_zoom);
1680 /* Show edit window */
1681 gtk_widget_show_all (GTK_WIDGET (msg_win));
1684 /* We always unregister the header because the message is
1685 forwarded or replied so the original one is no longer
1687 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1690 g_object_unref (G_OBJECT (new_msg));
1692 g_object_unref (G_OBJECT (account));
1693 free_reply_forward_helper (rf_helper);
1696 /* Checks a list of headers. If any of them are not currently
1697 * downloaded (CACHED) then returns TRUE else returns FALSE.
1700 header_list_count_uncached_msgs (TnyList *header_list)
1703 gint uncached_messages = 0;
1705 iter = tny_list_create_iterator (header_list);
1706 while (!tny_iterator_is_done (iter)) {
1709 header = TNY_HEADER (tny_iterator_get_current (iter));
1711 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1712 uncached_messages ++;
1713 g_object_unref (header);
1716 tny_iterator_next (iter);
1718 g_object_unref (iter);
1720 return uncached_messages;
1723 /* Returns FALSE if the user does not want to download the
1724 * messages. Returns TRUE if the user allowed the download.
1727 connect_to_get_msg (ModestWindow *win,
1728 gint num_of_uncached_msgs,
1729 TnyAccount *account)
1731 GtkResponseType response;
1732 GtkWindow *toplevel;
1734 /* Allways download if we are online. */
1735 if (tny_device_is_online (modest_runtime_get_device ()))
1738 /* If offline, then ask for user permission to download the messages */
1739 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
1740 response = modest_platform_run_confirmation_dialog (toplevel,
1741 ngettext("mcen_nc_get_msg",
1743 num_of_uncached_msgs));
1745 if (response == GTK_RESPONSE_CANCEL)
1748 return modest_platform_connect_and_wait(toplevel, account);
1752 reply_forward_performer (gboolean canceled,
1754 ModestWindow *parent_window,
1755 TnyAccount *account,
1758 ReplyForwardHelper *rf_helper = NULL;
1759 ModestMailOperation *mail_op;
1761 rf_helper = (ReplyForwardHelper *) user_data;
1763 if (canceled || err) {
1764 free_reply_forward_helper (rf_helper);
1768 /* Retrieve the message */
1769 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1770 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1771 modest_ui_actions_disk_operations_error_handler,
1773 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1774 modest_mail_operation_get_msg_and_parts (mail_op, rf_helper->top_header, rf_helper->parts, TRUE, reply_forward_cb, rf_helper);
1777 g_object_unref(mail_op);
1781 all_parts_retrieved (TnyMimePart *part)
1783 if (!TNY_IS_CAMEL_BS_MIME_PART (part)) {
1786 TnyList *pending_parts;
1787 TnyIterator *iterator;
1788 gboolean all_retrieved = TRUE;
1790 pending_parts = TNY_LIST (tny_simple_list_new ());
1791 tny_mime_part_get_parts (part, pending_parts);
1792 iterator = tny_list_create_iterator (pending_parts);
1793 while (all_retrieved && !tny_iterator_is_done (iterator)) {
1796 child = TNY_MIME_PART (tny_iterator_get_current (iterator));
1798 if (tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (child))) {
1799 all_retrieved = all_parts_retrieved (TNY_MIME_PART (child));
1801 all_retrieved = FALSE;
1804 g_object_unref (child);
1805 tny_iterator_next (iterator);
1807 g_object_unref (iterator);
1808 g_object_unref (pending_parts);
1809 return all_retrieved;
1814 forward_pending_parts_helper (TnyMimePart *part, TnyList *list)
1817 TnyIterator *iterator;
1819 if (!tny_camel_bs_mime_part_is_fetched (TNY_CAMEL_BS_MIME_PART (part))) {
1820 tny_list_append (list, G_OBJECT (part));
1822 parts = TNY_LIST (tny_simple_list_new ());
1823 tny_mime_part_get_parts (part, parts);
1824 for (iterator = tny_list_create_iterator (parts);
1825 !tny_iterator_is_done (iterator);
1826 tny_iterator_next (iterator)) {
1829 child = TNY_MIME_PART (tny_iterator_get_current (iterator));
1830 forward_pending_parts_helper (child, list);
1831 g_object_unref (child);
1833 g_object_unref (iterator);
1834 g_object_unref (parts);
1838 forward_pending_parts (TnyMsg *msg)
1840 TnyList *result = TNY_LIST (tny_simple_list_new ());
1841 if (TNY_IS_CAMEL_BS_MIME_PART (msg)) {
1842 forward_pending_parts_helper (TNY_MIME_PART (msg), result);
1849 * Common code for the reply and forward actions
1852 reply_forward (ReplyForwardAction action, ModestWindow *win)
1854 ReplyForwardHelper *rf_helper = NULL;
1855 guint reply_forward_type;
1857 g_return_if_fail (win && MODEST_IS_WINDOW(win));
1859 /* we check for low-mem; in that case, show a warning, and don't allow
1860 * reply/forward (because it could potentially require a lot of memory */
1861 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1865 /* we need an account when editing */
1866 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1867 if (!modest_ui_actions_run_account_setup_wizard (win))
1871 reply_forward_type =
1872 modest_conf_get_int (modest_runtime_get_conf (),
1873 (action == ACTION_FORWARD) ?
1874 MODEST_CONF_FORWARD_TYPE :
1875 MODEST_CONF_REPLY_TYPE,
1878 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1880 TnyMsg *top_msg = NULL;
1881 TnyHeader *header = NULL;
1882 /* Get header and message. Do not free them here, the
1883 reply_forward_cb must do it */
1884 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1885 top_msg = modest_msg_view_window_get_top_message (MODEST_MSG_VIEW_WINDOW(win));
1886 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1888 if (msg && header && (action != ACTION_FORWARD || all_parts_retrieved (TNY_MIME_PART (msg)))) {
1890 rf_helper = create_reply_forward_helper (action, win,
1891 reply_forward_type, header, NULL, NULL, NULL);
1892 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1894 gboolean do_download = TRUE;
1896 if (msg && header && action == ACTION_FORWARD) {
1897 if (top_msg == NULL)
1898 top_msg = g_object_ref (msg);
1899 /* Not all parts retrieved. Then we have to retrieve them all before
1900 * creating the forward message */
1901 if (!tny_device_is_online (modest_runtime_get_device ())) {
1903 GtkWindow *toplevel;
1905 /* If ask for user permission to download the messages */
1906 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
1907 response = modest_platform_run_confirmation_dialog (toplevel,
1908 ngettext("mcen_nc_get_msg",
1912 /* End if the user does not want to continue */
1913 if (response == GTK_RESPONSE_CANCEL)
1914 do_download = FALSE;
1918 TnyList *pending_parts;
1920 TnyAccount *account;
1921 TnyHeader *top_header;
1924 top_header = tny_msg_get_header (top_msg);
1925 pending_parts = forward_pending_parts (top_msg);
1926 rf_helper = create_reply_forward_helper (action, win,
1927 reply_forward_type, header, msg, top_header, pending_parts);
1928 g_object_unref (pending_parts);
1930 folder = tny_header_get_folder (top_header);
1931 account = tny_folder_get_account (folder);
1932 modest_platform_connect_and_perform (win,
1934 reply_forward_performer,
1936 if (folder) g_object_unref (folder);
1937 g_object_unref (account);
1938 if (top_header) g_object_unref (top_header);
1942 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1947 g_object_unref (msg);
1949 g_object_unref (top_msg);
1951 g_object_unref (header);
1953 TnyHeader *header = NULL;
1955 gboolean do_retrieve = TRUE;
1956 TnyList *header_list = NULL;
1958 header_list = get_selected_headers (win);
1961 /* Check that only one message is selected for replying */
1962 if (tny_list_get_length (header_list) != 1) {
1963 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1964 NULL, _("mcen_ib_select_one_message"));
1965 g_object_unref (header_list);
1969 /* Only reply/forward to one message */
1970 iter = tny_list_create_iterator (header_list);
1971 header = TNY_HEADER (tny_iterator_get_current (iter));
1972 g_object_unref (iter);
1974 /* Retrieve messages */
1975 do_retrieve = (action == ACTION_FORWARD) ||
1976 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1979 TnyAccount *account = NULL;
1980 TnyFolder *folder = NULL;
1981 gdouble download = TRUE;
1982 guint uncached_msgs = 0;
1984 folder = tny_header_get_folder (header);
1986 goto do_retrieve_frees;
1987 account = tny_folder_get_account (folder);
1989 goto do_retrieve_frees;
1991 uncached_msgs = header_list_count_uncached_msgs (header_list);
1993 if (uncached_msgs > 0) {
1994 /* Allways download if we are online. */
1995 if (!tny_device_is_online (modest_runtime_get_device ())) {
1997 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
1999 /* If ask for user permission to download the messages */
2000 response = modest_platform_run_confirmation_dialog (toplevel,
2001 ngettext("mcen_nc_get_msg",
2005 /* End if the user does not want to continue */
2006 if (response == GTK_RESPONSE_CANCEL)
2013 rf_helper = create_reply_forward_helper (action, win,
2014 reply_forward_type, header, NULL, NULL, NULL);
2015 if (uncached_msgs > 0) {
2016 modest_platform_connect_and_perform (win,
2018 reply_forward_performer,
2021 reply_forward_performer (FALSE, NULL, win,
2022 account, rf_helper);
2027 g_object_unref (account);
2029 g_object_unref (folder);
2031 reply_forward_cb (NULL, header, FALSE, NULL, NULL, NULL);
2034 g_object_unref (header_list);
2035 g_object_unref (header);
2040 modest_ui_actions_reply_calendar (ModestWindow *win, TnyList *header_pairs)
2042 modest_ui_actions_reply_calendar_with_subject (win, NULL, header_pairs);
2046 modest_ui_actions_reply_calendar_with_subject (ModestWindow *win, const gchar *custom_subject, TnyList *header_pairs)
2051 gboolean use_signature;
2054 const gchar *account_name;
2055 const gchar *mailbox;
2056 TnyHeader *msg_header;
2057 ModestWindowMgr *mgr;
2060 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW(win));
2062 /* we check for low-mem; in that case, show a warning, and don't allow
2063 * reply/forward (because it could potentially require a lot of memory */
2064 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2067 account_name = modest_window_get_active_account (MODEST_WINDOW (win));
2068 mailbox = modest_window_get_active_mailbox (MODEST_WINDOW (win));
2069 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
2070 account_name, mailbox);
2071 recipient = modest_text_utils_get_email_address (from);
2072 signature = modest_account_mgr_get_signature_from_recipient (modest_runtime_get_account_mgr(),
2077 msg = modest_msg_view_window_get_message(MODEST_MSG_VIEW_WINDOW(win));
2078 g_return_if_fail(msg);
2080 msg_header = tny_msg_get_header (msg);
2082 modest_tny_msg_create_reply_calendar_msg (msg, msg_header, from,
2083 (use_signature) ? signature : NULL,
2085 g_object_unref (msg_header);
2091 g_warning ("%s: failed to create message\n", __FUNCTION__);
2095 if (custom_subject) {
2096 TnyHeader *new_msg_header;
2098 new_msg_header = tny_msg_get_header (new_msg);
2099 tny_header_set_subject (new_msg_header, custom_subject);
2100 g_object_unref (new_msg_header);
2103 msg_win = (GtkWidget *) modest_msg_edit_window_new (new_msg, account_name, mailbox, FALSE);
2104 mgr = modest_runtime_get_window_mgr ();
2105 modest_window_mgr_register_window (mgr, MODEST_WINDOW (msg_win), (ModestWindow *) win);
2107 /* Show edit window */
2108 gtk_widget_show_all (GTK_WIDGET (msg_win));
2112 g_object_unref (G_OBJECT (new_msg));
2116 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
2118 g_return_if_fail (MODEST_IS_WINDOW(win));
2120 reply_forward (ACTION_REPLY, win);
2124 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
2126 g_return_if_fail (MODEST_IS_WINDOW(win));
2128 reply_forward (ACTION_FORWARD, win);
2132 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
2134 g_return_if_fail (MODEST_IS_WINDOW(win));
2136 reply_forward (ACTION_REPLY_TO_ALL, win);
2140 modest_ui_actions_on_next (GtkAction *action,
2141 ModestWindow *window)
2143 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2144 modest_msg_view_window_select_next_message (
2145 MODEST_MSG_VIEW_WINDOW (window));
2147 g_return_if_reached ();
2152 modest_ui_actions_on_prev (GtkAction *action,
2153 ModestWindow *window)
2155 g_return_if_fail (MODEST_IS_WINDOW(window));
2157 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
2158 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
2160 g_return_if_reached ();
2165 modest_ui_actions_on_sort (GtkAction *action,
2166 ModestWindow *window)
2168 GtkWidget *header_view = NULL;
2170 g_return_if_fail (MODEST_IS_WINDOW(window));
2172 if (MODEST_IS_HEADER_WINDOW (window)) {
2173 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (window)));
2177 modest_platform_information_banner (NULL, NULL, _CS_NOTHING_TO_SORT);
2182 /* Show sorting dialog */
2183 modest_utils_run_sort_dialog (MODEST_WINDOW (window), MODEST_SORT_HEADERS);
2187 sync_folder_cb (ModestMailOperation *mail_op,
2191 ModestHeaderView *header_view = (ModestHeaderView *) user_data;
2193 if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
2194 ModestWindow *parent = (ModestWindow *) modest_mail_operation_get_source (mail_op);
2196 /* We must clear first, because otherwise set_folder will ignore */
2197 /* the change as the folders are the same */
2198 modest_header_view_clear (header_view);
2199 modest_header_view_set_folder (header_view, folder, TRUE, parent, NULL, NULL);
2201 g_object_unref (parent);
2204 g_object_unref (header_view);
2208 idle_refresh_folder (gpointer source)
2210 ModestHeaderView *header_view = NULL;
2212 /* If the window still exists */
2213 if (!GTK_IS_WIDGET (source) ||
2214 !GTK_WIDGET_VISIBLE (source))
2217 /* Refresh the current view */
2218 if (MODEST_IS_HEADER_WINDOW (source))
2219 header_view = modest_header_window_get_header_view ((ModestHeaderWindow *) source);
2221 TnyFolder *folder = modest_header_view_get_folder (header_view);
2223 /* Sync the folder status */
2224 ModestMailOperation *mail_op = modest_mail_operation_new (source);
2225 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
2226 modest_mail_operation_sync_folder (mail_op, folder, FALSE, sync_folder_cb, g_object_ref (header_view));
2227 g_object_unref (folder);
2228 g_object_unref (mail_op);
2236 update_account_cb (ModestMailOperation *self,
2237 TnyList *new_headers,
2241 gboolean show_visual_notifications;
2243 top = modest_window_mgr_get_current_top (modest_runtime_get_window_mgr ());
2244 show_visual_notifications = (top) ? FALSE : TRUE;
2246 /* Notify new messages have been downloaded. If the
2247 send&receive was invoked by the user then do not show any
2248 visual notification, only play a sound and activate the LED
2249 (for the Maemo version) */
2250 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0) {
2252 /* We only notify about really new messages (not seen) we get */
2253 TnyList *actually_new_list;
2254 TnyIterator *iterator;
2255 actually_new_list = TNY_LIST (tny_simple_list_new ());
2256 for (iterator = tny_list_create_iterator (new_headers);
2257 !tny_iterator_is_done (iterator);
2258 tny_iterator_next (iterator)) {
2260 TnyHeaderFlags flags;
2261 header = TNY_HEADER (tny_iterator_get_current (iterator));
2262 flags = tny_header_get_flags (header);
2264 if (!(flags & TNY_HEADER_FLAG_SEEN)) {
2265 /* Messages are ordered from most
2266 recent to oldest. But we want to
2267 show notifications starting from
2268 the oldest message. That's why we
2270 tny_list_prepend (actually_new_list, G_OBJECT (header));
2272 g_object_unref (header);
2274 g_object_unref (iterator);
2276 if (tny_list_get_length (actually_new_list) > 0) {
2277 GList *new_headers_list = NULL;
2279 new_headers_list = modest_utils_create_notification_list_from_header_list (actually_new_list);
2281 /* Send notifications */
2282 if (new_headers_list) {
2283 modest_platform_on_new_headers_received (new_headers_list,
2284 show_visual_notifications);
2286 modest_utils_free_notification_list (new_headers_list);
2289 g_object_unref (actually_new_list);
2293 /* Refresh the current folder in an idle. We do this
2294 in order to avoid refresh cancelations if the
2295 currently viewed folder is the inbox */
2296 g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
2297 idle_refresh_folder,
2304 TnyAccount *account;
2306 gchar *account_name;
2307 gboolean poke_status;
2308 gboolean interactive;
2309 ModestMailOperation *mail_op;
2313 do_send_receive_performer (gboolean canceled,
2315 ModestWindow *parent_window,
2316 TnyAccount *account,
2319 SendReceiveInfo *info;
2321 info = (SendReceiveInfo *) user_data;
2323 if (err || canceled) {
2324 /* In disk full conditions we could get this error here */
2325 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
2326 (GtkWidget *) parent_window, err,
2329 if (info->mail_op) {
2330 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2337 /* Send & receive. */
2338 modest_mail_operation_update_account (info->mail_op, info->account_name,
2339 info->poke_status, info->interactive,
2340 update_account_cb, info->win);
2345 g_object_unref (G_OBJECT (info->mail_op));
2346 if (info->account_name)
2347 g_free (info->account_name);
2349 g_object_unref (info->win);
2351 g_object_unref (info->account);
2352 g_slice_free (SendReceiveInfo, info);
2356 * This function performs the send & receive required actions. The
2357 * window is used to create the mail operation. Typically it should
2358 * always be the main window, but we pass it as argument in order to
2362 modest_ui_actions_do_send_receive (const gchar *account_name,
2363 gboolean force_connection,
2364 gboolean poke_status,
2365 gboolean interactive,
2368 gchar *acc_name = NULL;
2369 SendReceiveInfo *info;
2370 ModestTnyAccountStore *acc_store;
2371 TnyAccount *account;
2373 /* If no account name was provided then get the current account, and if
2374 there is no current account then pick the default one: */
2375 if (!account_name) {
2377 acc_name = g_strdup (modest_window_get_active_account (win));
2379 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2381 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2385 acc_name = g_strdup (account_name);
2388 acc_store = modest_runtime_get_account_store ();
2389 account = modest_tny_account_store_get_server_account (acc_store, acc_name, TNY_ACCOUNT_TYPE_STORE);
2393 modest_platform_information_banner (NULL, NULL, _("emev_ni_internal_error"));
2397 /* Do not automatically refresh accounts that are flagged as
2398 NO_AUTO_UPDATE. This could be useful for accounts that
2399 handle their own update times */
2401 ModestProtocolType proto = modest_tny_account_get_protocol_type (account);
2402 if (proto != MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
2403 const gchar *tag = MODEST_PROTOCOL_REGISTRY_NO_AUTO_UPDATE_PROTOCOLS;
2404 ModestProtocolRegistry *registry = modest_runtime_get_protocol_registry ();
2406 if (modest_protocol_registry_protocol_type_has_tag (registry, proto, tag)) {
2407 g_debug ("%s no auto update allowed for account %s", __FUNCTION__, account_name);
2408 g_object_unref (account);
2415 /* Create the info for the connect and perform */
2416 info = g_slice_new (SendReceiveInfo);
2417 info->account_name = acc_name;
2418 info->win = (win) ? g_object_ref (win) : NULL;
2419 info->poke_status = poke_status;
2420 info->interactive = interactive;
2421 info->account = account;
2422 /* We need to create the operation here, because otherwise it
2423 could happen that the queue emits the queue-empty signal
2424 while we're trying to connect the account */
2425 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2426 modest_ui_actions_disk_operations_error_handler,
2428 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2430 /* Invoke the connect and perform */
2431 modest_platform_connect_and_perform (win, force_connection, info->account,
2432 do_send_receive_performer, info);
2437 modest_ui_actions_do_cancel_send (const gchar *account_name,
2440 TnyTransportAccount *transport_account;
2441 TnySendQueue *send_queue = NULL;
2442 GError *error = NULL;
2444 /* Get transport account */
2446 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2447 (modest_runtime_get_account_store(),
2449 TNY_ACCOUNT_TYPE_TRANSPORT));
2450 if (!transport_account) {
2451 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2456 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2457 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2458 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2459 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2460 "modest: could not find send queue for account\n");
2462 /* Cancel the current send */
2463 tny_account_cancel (TNY_ACCOUNT (transport_account));
2465 /* Suspend all pending messages */
2466 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2470 if (transport_account != NULL)
2471 g_object_unref (G_OBJECT (transport_account));
2475 modest_ui_actions_cancel_send_all (ModestWindow *win)
2477 GSList *account_names, *iter;
2479 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2482 iter = account_names;
2484 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2485 iter = g_slist_next (iter);
2488 modest_account_mgr_free_account_names (account_names);
2489 account_names = NULL;
2493 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2496 /* Check if accounts exist */
2497 gboolean accounts_exist =
2498 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2500 /* If not, allow the user to create an account before trying to send/receive. */
2501 if (!accounts_exist)
2502 modest_ui_actions_on_accounts (NULL, win);
2504 /* Cancel all sending operaitons */
2505 modest_ui_actions_cancel_send_all (win);
2509 * Refreshes all accounts. This function will be used by automatic
2513 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2514 gboolean force_connection,
2515 gboolean poke_status,
2516 gboolean interactive)
2518 GSList *account_names, *iter;
2520 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2523 iter = account_names;
2525 modest_ui_actions_do_send_receive ((const char*) iter->data,
2527 poke_status, interactive, win);
2528 iter = g_slist_next (iter);
2531 modest_account_mgr_free_account_names (account_names);
2532 account_names = NULL;
2536 * Handler of the click on Send&Receive button in the main toolbar
2539 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2541 /* Check if accounts exist */
2542 gboolean accounts_exist;
2545 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2547 /* If not, allow the user to create an account before trying to send/receive. */
2548 if (!accounts_exist)
2549 modest_ui_actions_on_accounts (NULL, win);
2551 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2552 if (MODEST_IS_ACCOUNTS_WINDOW (win)) {
2553 modest_ui_actions_do_send_receive_all (win, TRUE, TRUE, TRUE);
2555 const gchar *active_account;
2556 active_account = modest_window_get_active_account (MODEST_WINDOW (win));
2558 modest_ui_actions_do_send_receive (active_account, TRUE, TRUE, TRUE, win);
2565 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2568 ModestWindow *window)
2570 GtkTreeRowReference *rowref;
2572 g_return_if_fail (MODEST_IS_WINDOW(window));
2573 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2574 g_return_if_fail (TNY_IS_HEADER (header));
2576 if (modest_header_view_count_selected_headers (header_view) > 1) {
2577 /* Don't allow activation if there are more than one message selected */
2578 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2582 /* we check for low-mem; in that case, show a warning, and don't allow
2583 * activating headers
2585 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
2589 rowref = gtk_tree_row_reference_new (gtk_tree_view_get_model (GTK_TREE_VIEW (header_view)), path);
2590 open_msg_from_header (header, rowref, MODEST_WINDOW (window));
2591 gtk_tree_row_reference_free (rowref);
2595 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2601 GtkWindow *toplevel;
2603 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
2604 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2606 online = tny_device_is_online (modest_runtime_get_device());
2609 /* already online -- the item is simply not there... */
2610 dialog = gtk_message_dialog_new (toplevel,
2612 GTK_MESSAGE_WARNING,
2614 _("The %s you selected cannot be found"),
2616 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2617 gtk_dialog_run (GTK_DIALOG(dialog));
2619 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2622 _("mcen_bd_dialog_cancel"),
2623 GTK_RESPONSE_REJECT,
2624 _("mcen_bd_dialog_ok"),
2625 GTK_RESPONSE_ACCEPT,
2627 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2628 "Do you want to get online?"), item);
2629 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2630 gtk_label_new (txt), FALSE, FALSE, 0);
2631 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2634 gtk_window_set_default_size ((GtkWindow *) dialog, 300, 300);
2635 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2636 /* TODO: Comment about why is this commented out: */
2637 /* modest_platform_connect_and_wait (); */
2640 gtk_widget_destroy (dialog);
2644 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2647 /* g_debug ("%s %s", __FUNCTION__, link); */
2652 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2655 modest_platform_activate_uri (link);
2659 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2662 modest_platform_show_uri_popup (link);
2666 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2669 /* we check for low-mem; in that case, show a warning, and don't allow
2670 * viewing attachments
2672 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2675 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2679 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2680 const gchar *address,
2683 /* g_debug ("%s %s", __FUNCTION__, address); */
2687 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2688 TnyMsg *saved_draft,
2691 ModestMsgEditWindow *edit_window;
2693 /* TODO: in hildon 2 we have to dim and undim the header views while we're saving */
2695 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2697 /* Set draft is there was no error */
2698 if (!modest_mail_operation_get_error (mail_op))
2699 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2701 g_object_unref(edit_window);
2705 enough_space_for_message (ModestMsgEditWindow *edit_window,
2708 guint64 available_disk, expected_size;
2713 available_disk = modest_utils_get_available_space (NULL);
2714 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2715 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2720 /* Double check: disk full condition or message too big */
2721 if (available_disk < MODEST_TNY_ACCOUNT_STORE_MIN_FREE_SPACE ||
2722 expected_size > available_disk) {
2723 gchar *msg = g_strdup_printf (_KR("cerm_device_memory_full"), "");
2724 modest_platform_information_banner (NULL, NULL, msg);
2731 * djcb: if we're in low-memory state, we only allow for
2732 * saving messages smaller than
2733 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2734 * should still allow for sending anything critical...
2736 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2737 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2741 * djcb: we also make sure that the attachments are smaller than the max size
2742 * this is for the case where we'd try to forward a message with attachments
2743 * bigger than our max allowed size, or sending an message from drafts which
2744 * somehow got past our checks when attaching.
2746 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2747 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) edit_window);
2748 modest_platform_run_information_dialog (toplevel,
2749 _("mail_ib_error_attachment_size"),
2758 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2760 TnyTransportAccount *transport_account;
2761 ModestMailOperation *mail_operation;
2763 gchar *account_name;
2764 ModestAccountMgr *account_mgr;
2765 gboolean had_error = FALSE;
2767 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2769 data = modest_msg_edit_window_get_msg_data (edit_window);
2772 if (!enough_space_for_message (edit_window, data)) {
2773 modest_msg_edit_window_free_msg_data (edit_window, data);
2777 account_name = g_strdup (data->account_name);
2778 account_mgr = modest_runtime_get_account_mgr();
2780 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2782 account_name = modest_account_mgr_get_default_account (account_mgr);
2783 if (!account_name) {
2784 g_printerr ("modest: no account found\n");
2785 modest_msg_edit_window_free_msg_data (edit_window, data);
2789 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2790 account_name = g_strdup (data->account_name);
2794 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2795 (modest_runtime_get_account_store (),
2797 TNY_ACCOUNT_TYPE_TRANSPORT));
2798 if (!transport_account) {
2799 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2800 g_free (account_name);
2801 modest_msg_edit_window_free_msg_data (edit_window, data);
2805 /* Create the mail operation */
2806 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
2808 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2810 modest_mail_operation_save_to_drafts (mail_operation,
2822 data->priority_flags,
2825 data->custom_header_pairs,
2826 on_save_to_drafts_cb,
2827 g_object_ref(edit_window));
2829 /* In hildon2 we always show the information banner on saving to drafts.
2830 * It will be a system information banner in this case.
2832 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2833 modest_platform_information_banner (NULL, NULL, text);
2835 modest_msg_edit_window_set_modified (edit_window, FALSE);
2838 g_free (account_name);
2839 g_object_unref (G_OBJECT (transport_account));
2840 g_object_unref (G_OBJECT (mail_operation));
2842 modest_msg_edit_window_free_msg_data (edit_window, data);
2848 /* For instance, when clicking the Send toolbar button when editing a message: */
2850 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2852 TnyTransportAccount *transport_account = NULL;
2853 gboolean result = TRUE, add_to_contacts;
2855 ModestAccountMgr *account_mgr;
2856 gchar *account_name;
2859 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
2861 /* Check whether to automatically add new contacts to addressbook or not */
2862 add_to_contacts = modest_conf_get_bool (modest_runtime_get_conf (),
2863 MODEST_CONF_AUTO_ADD_TO_CONTACTS, NULL);
2864 if (!modest_msg_edit_window_check_names (edit_window, add_to_contacts))
2867 data = modest_msg_edit_window_get_msg_data (edit_window);
2869 recipients = g_strconcat (data->to?data->to:"",
2870 data->cc?data->cc:"",
2871 data->bcc?data->bcc:"",
2873 if (recipients == NULL || recipients[0] == '\0') {
2874 /* Empty subject -> no send */
2875 g_free (recipients);
2876 modest_msg_edit_window_free_msg_data (edit_window, data);
2879 g_free (recipients);
2882 if (!enough_space_for_message (edit_window, data)) {
2883 modest_msg_edit_window_free_msg_data (edit_window, data);
2887 account_mgr = modest_runtime_get_account_mgr();
2888 account_name = g_strdup (data->account_name);
2890 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2893 account_name = modest_account_mgr_get_default_account (account_mgr);
2895 if (!account_name) {
2896 modest_msg_edit_window_free_msg_data (edit_window, data);
2897 /* Run account setup wizard */
2898 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
2903 /* Get the currently-active transport account for this modest account: */
2904 if (account_name && strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
2906 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2907 (modest_runtime_get_account_store (),
2908 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
2911 if (!transport_account) {
2912 modest_msg_edit_window_free_msg_data (edit_window, data);
2913 /* Run account setup wizard */
2914 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2918 result = modest_ui_actions_send_msg_with_transport (transport_account,
2931 data->priority_flags,
2932 data->custom_header_pairs);
2936 g_free (account_name);
2937 g_object_unref (G_OBJECT (transport_account));
2939 modest_msg_edit_window_free_msg_data (edit_window, data);
2942 modest_msg_edit_window_set_sent (edit_window, TRUE);
2944 /* Save settings and close the window: */
2945 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2951 /* For instance, when clicking the Send toolbar button when editing a message: */
2953 modest_ui_actions_on_send_custom_msg (const gchar *account_name,
2954 const gchar *from, const gchar *to, const gchar *cc, const gchar *bcc,
2955 const gchar *subject,
2956 const gchar *plain_body, const gchar *html_body,
2957 const GList *attachments_list, const GList *images_list,
2958 const gchar *references, const gchar *in_reply_to,
2959 TnyHeaderFlags priority_flags, TnyList *header_pairs)
2961 TnyTransportAccount *transport_account = NULL;
2962 gboolean result = FALSE;
2964 g_return_val_if_fail (account_name, FALSE);
2967 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2968 (modest_runtime_get_account_store (),
2969 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
2971 g_return_val_if_fail (transport_account, FALSE);
2973 result = modest_ui_actions_send_msg_with_transport (transport_account,
2977 plain_body, html_body,
2978 attachments_list, images_list,
2979 references, in_reply_to,
2980 priority_flags, header_pairs);
2983 g_object_unref (G_OBJECT (transport_account));
2989 modest_ui_actions_send_msg_with_transport (TnyTransportAccount *transport_account,
2991 const gchar *from, const gchar *to, const gchar *cc, const gchar *bcc,
2992 const gchar *subject,
2993 const gchar *plain_body, const gchar *html_body,
2994 const GList *attachments_list, const GList *images_list,
2995 const gchar *references, const gchar *in_reply_to,
2996 TnyHeaderFlags priority_flags, TnyList *header_pairs)
2998 gboolean had_error = FALSE;
2999 ModestMailOperation *mail_operation;
3001 g_return_val_if_fail (transport_account, FALSE);
3003 /* Create the mail operation */
3004 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
3005 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3007 modest_mail_operation_send_new_mail (mail_operation,
3024 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3025 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
3027 if (modest_mail_operation_get_error (mail_operation) != NULL) {
3028 const GError *error = modest_mail_operation_get_error (mail_operation);
3029 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3030 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3031 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3032 modest_platform_information_banner (NULL, NULL, _CS_NOT_ENOUGH_MEMORY);
3038 g_object_unref (G_OBJECT (mail_operation));
3044 modest_ui_actions_on_send_msg (ModestWindow *window,
3047 TnyTransportAccount *transport_account = NULL;
3048 gboolean had_error = FALSE;
3049 ModestAccountMgr *account_mgr;
3050 gchar *account_name;
3051 ModestMailOperation *mail_operation;
3053 account_mgr = modest_runtime_get_account_mgr();
3054 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(window)));
3057 account_name = modest_account_mgr_get_default_account (account_mgr);
3059 /* Get the currently-active transport account for this modest account: */
3060 if (account_name && strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
3062 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
3063 (modest_runtime_get_account_store (),
3064 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
3067 /* Create the mail operation */
3068 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
3069 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
3071 modest_mail_operation_send_mail (mail_operation,
3075 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
3076 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
3078 if (modest_mail_operation_get_error (mail_operation) != NULL) {
3079 const GError *error = modest_mail_operation_get_error (mail_operation);
3080 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3081 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
3082 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
3083 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
3089 g_free (account_name);
3090 g_object_unref (G_OBJECT (transport_account));
3091 g_object_unref (G_OBJECT (mail_operation));
3097 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
3098 ModestMsgEditWindow *window)
3100 ModestMsgEditFormatState *format_state = NULL;
3102 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3103 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3105 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3108 format_state = modest_msg_edit_window_get_format_state (window);
3109 g_return_if_fail (format_state != NULL);
3111 format_state->bold = gtk_toggle_action_get_active (action);
3112 modest_msg_edit_window_set_format_state (window, format_state);
3113 g_free (format_state);
3118 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
3119 ModestMsgEditWindow *window)
3121 ModestMsgEditFormatState *format_state = NULL;
3123 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3124 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3126 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3129 format_state = modest_msg_edit_window_get_format_state (window);
3130 g_return_if_fail (format_state != NULL);
3132 format_state->italics = gtk_toggle_action_get_active (action);
3133 modest_msg_edit_window_set_format_state (window, format_state);
3134 g_free (format_state);
3139 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
3140 ModestMsgEditWindow *window)
3142 ModestMsgEditFormatState *format_state = NULL;
3144 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3145 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
3147 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3150 format_state = modest_msg_edit_window_get_format_state (window);
3151 g_return_if_fail (format_state != NULL);
3153 format_state->bullet = gtk_toggle_action_get_active (action);
3154 modest_msg_edit_window_set_format_state (window, format_state);
3155 g_free (format_state);
3160 modest_ui_actions_on_change_justify (GtkRadioAction *action,
3161 GtkRadioAction *selected,
3162 ModestMsgEditWindow *window)
3164 ModestMsgEditFormatState *format_state = NULL;
3165 GtkJustification value;
3167 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3169 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3172 value = gtk_radio_action_get_current_value (selected);
3174 format_state = modest_msg_edit_window_get_format_state (window);
3175 g_return_if_fail (format_state != NULL);
3177 format_state->justification = value;
3178 modest_msg_edit_window_set_format_state (window, format_state);
3179 g_free (format_state);
3183 modest_ui_actions_on_select_editor_color (GtkAction *action,
3184 ModestMsgEditWindow *window)
3186 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3187 g_return_if_fail (GTK_IS_ACTION (action));
3189 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3192 modest_msg_edit_window_select_color (window);
3196 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3197 ModestMsgEditWindow *window)
3199 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3200 g_return_if_fail (GTK_IS_ACTION (action));
3202 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3208 modest_ui_actions_on_insert_image (GObject *object,
3209 ModestMsgEditWindow *window)
3211 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3214 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3217 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3220 modest_msg_edit_window_insert_image (window);
3224 modest_ui_actions_on_attach_file (GtkAction *action,
3225 ModestMsgEditWindow *window)
3227 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3228 g_return_if_fail (GTK_IS_ACTION (action));
3230 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3233 modest_msg_edit_window_offer_attach_file (window);
3237 modest_ui_actions_on_remove_attachments (GtkAction *action,
3238 ModestMsgEditWindow *window)