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)
3240 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3242 modest_msg_edit_window_remove_attachments (window, NULL);
3246 do_create_folder_cb (ModestMailOperation *mail_op,
3247 TnyFolderStore *parent_folder,
3248 TnyFolder *new_folder,
3251 gchar *suggested_name = (gchar *) user_data;
3252 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3253 const GError *error;
3255 error = modest_mail_operation_get_error (mail_op);
3257 gboolean disk_full = FALSE;
3258 TnyAccount *account;
3259 /* Show an error. If there was some problem writing to
3260 disk, show it, otherwise show the generic folder
3261 create error. We do it here and not in an error
3262 handler because the call to do_create_folder will
3263 stop the main loop in a gtk_dialog_run and then,
3264 the message won't be shown until that dialog is
3266 account = modest_mail_operation_get_account (mail_op);
3269 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3270 (GtkWidget *) source_win,
3273 _("mail_in_ui_folder_create_error_memory"));
3274 g_object_unref (account);
3277 /* Show an error and try again if there is no
3278 full memory condition */
3279 modest_platform_information_banner ((GtkWidget *) source_win, NULL,
3280 _("mail_in_ui_folder_create_error"));
3281 do_create_folder ((ModestWindow *) source_win,
3282 parent_folder, (const gchar *) suggested_name);
3286 /* the 'source_win' is either the ModestWindow, or the 'Move to folder'-dialog
3287 * FIXME: any other? */
3288 GtkWidget *folder_view;
3290 folder_view = GTK_WIDGET(g_object_get_data (G_OBJECT (source_win),
3291 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
3293 /* Select the newly created folder. It could happen
3294 that the widget is no longer there (i.e. the window
3295 has been destroyed, so we need to check this */
3297 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3299 g_object_unref (new_folder);
3301 /* Free. Note that the first time it'll be NULL so noop */
3302 g_free (suggested_name);
3303 g_object_unref (source_win);
3308 TnyFolderStore *parent;
3309 } CreateFolderConnect;
3312 do_create_folder_performer (gboolean canceled,
3314 ModestWindow *parent_window,
3315 TnyAccount *account,
3318 CreateFolderConnect *helper = (CreateFolderConnect *) user_data;
3319 ModestMailOperation *mail_op;
3321 if (canceled || err) {
3322 /* In disk full conditions we could get this error here */
3323 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3324 (GtkWidget *) parent_window, err,
3325 NULL, _("mail_in_ui_folder_create_error_memory"));
3327 /* This happens if we have selected the outbox folder
3329 if (err && err->code == TNY_SERVICE_ERROR_UNKNOWN &&
3330 TNY_IS_MERGE_FOLDER (helper->parent)) {
3331 /* Show an error and retry */
3332 modest_platform_information_banner ((GtkWidget *) parent_window,
3334 _("mail_in_ui_folder_create_error"));
3336 do_create_folder (parent_window, helper->parent, helper->folder_name);
3342 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3343 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3345 modest_mail_operation_create_folder (mail_op,
3347 (const gchar *) helper->folder_name,
3348 do_create_folder_cb,
3349 g_strdup (helper->folder_name));
3350 g_object_unref (mail_op);
3354 g_object_unref (helper->parent);
3355 if (helper->folder_name)
3356 g_free (helper->folder_name);
3357 g_slice_free (CreateFolderConnect, helper);
3362 do_create_folder (ModestWindow *parent_window,
3363 TnyFolderStore *suggested_parent,
3364 const gchar *suggested_name)
3367 gchar *folder_name = NULL;
3368 TnyFolderStore *parent_folder = NULL;
3369 GtkWindow *toplevel;
3371 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) parent_window);
3372 result = modest_platform_run_new_folder_dialog (toplevel,
3374 (gchar *) suggested_name,
3378 if (result == GTK_RESPONSE_ACCEPT && parent_folder) {
3379 CreateFolderConnect *helper = (CreateFolderConnect *) g_slice_new0 (CreateFolderConnect);
3380 helper->folder_name = g_strdup (folder_name);
3381 helper->parent = g_object_ref (parent_folder);
3383 modest_platform_connect_if_remote_and_perform (parent_window,
3386 do_create_folder_performer,
3391 g_free (folder_name);
3393 g_object_unref (parent_folder);
3397 modest_ui_actions_create_folder(GtkWindow *parent_window,
3398 GtkWidget *folder_view,
3399 TnyFolderStore *parent_folder)
3401 if (!parent_folder) {
3402 ModestTnyAccountStore *acc_store;
3404 acc_store = modest_runtime_get_account_store ();
3406 parent_folder = (TnyFolderStore *)
3407 modest_tny_account_store_get_local_folders_account (acc_store);
3410 if (parent_folder) {
3411 do_create_folder (MODEST_WINDOW (parent_window), parent_folder, NULL);
3412 g_object_unref (parent_folder);
3417 modest_ui_actions_on_new_folder (GtkAction *action, ModestWindow *window)
3420 g_return_if_fail (MODEST_IS_WINDOW(window));
3422 if (MODEST_IS_FOLDER_WINDOW (window)) {
3423 GtkWidget *folder_view;
3424 GtkWindow *toplevel;
3426 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3427 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) window);
3428 modest_ui_actions_create_folder (toplevel, folder_view, NULL);
3430 g_assert_not_reached ();
3435 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3438 const GError *error = NULL;
3439 gchar *message = NULL;
3441 TnyAccount *account = modest_mail_operation_get_account (mail_op);
3443 /* Get error message */
3444 error = modest_mail_operation_get_error (mail_op);
3446 g_return_if_reached ();
3448 mem_full = modest_tny_account_store_is_disk_full_error (modest_runtime_get_account_store(),
3449 (GError *) error, account);
3451 message = g_strdup_printf (_KR("cerm_device_memory_full"), "");
3452 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3453 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3454 message = _CS_FOLDER_ALREADY_EXISTS;
3455 } else if (error->domain == TNY_ERROR_DOMAIN &&
3456 error->code == TNY_SERVICE_ERROR_STATE) {
3457 /* This means that the folder is already in use (a
3458 message is opened for example */
3459 message = _("emev_ni_internal_error");
3461 message = _CS_UNABLE_TO_RENAME;
3464 /* We don't set a parent for the dialog because the dialog
3465 will be destroyed so the banner won't appear */
3466 modest_platform_information_banner (NULL, NULL, message);
3469 g_object_unref (account);
3475 TnyFolderStore *folder;
3480 on_rename_folder_cb (ModestMailOperation *mail_op,
3481 TnyFolder *new_folder,
3484 ModestFolderView *folder_view;
3486 /* If the window was closed when renaming a folder, or if
3487 * it's not a main window this will happen */
3488 if (!MODEST_IS_FOLDER_VIEW (user_data))
3491 folder_view = MODEST_FOLDER_VIEW (user_data);
3492 /* Note that if the rename fails new_folder will be NULL */
3494 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3496 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3500 on_rename_folder_performer (gboolean canceled,
3502 ModestWindow *parent_window,
3503 TnyAccount *account,
3506 ModestMailOperation *mail_op = NULL;
3507 GtkTreeSelection *sel = NULL;
3508 GtkWidget *folder_view = NULL;
3509 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3511 if (canceled || err) {
3512 /* In disk full conditions we could get this error here */
3513 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3514 (GtkWidget *) parent_window, err,
3519 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3520 modest_ui_actions_rename_folder_error_handler,
3521 parent_window, NULL);
3523 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3525 if (MODEST_IS_FOLDER_WINDOW (parent_window)) {
3526 ModestFolderWindow *folder_window = (ModestFolderWindow *) parent_window;
3527 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (folder_window));
3530 /* Clear the folders view */
3531 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3532 gtk_tree_selection_unselect_all (sel);
3534 /* Actually rename the folder */
3535 modest_mail_operation_rename_folder (mail_op,
3536 TNY_FOLDER (data->folder),
3537 (const gchar *) (data->new_name),
3538 on_rename_folder_cb,
3540 g_object_unref (mail_op);
3543 g_object_unref (data->folder);
3544 g_free (data->new_name);
3549 modest_ui_actions_on_rename_folder (GtkAction *action,
3550 ModestWindow *window)
3552 modest_ui_actions_on_edit_mode_rename_folder (window);
3556 modest_ui_actions_on_edit_mode_rename_folder (ModestWindow *window)
3558 TnyFolderStore *folder;
3559 GtkWidget *folder_view;
3560 gboolean do_rename = TRUE;
3562 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3564 if (MODEST_IS_FOLDER_WINDOW (window)) {
3565 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3570 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3575 if (TNY_IS_FOLDER (folder)) {
3576 gchar *folder_name = NULL;
3578 const gchar *current_name;
3579 TnyFolderStore *parent;
3581 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3582 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3583 response = modest_platform_run_rename_folder_dialog (MODEST_WINDOW (window),
3584 parent, current_name,
3586 g_object_unref (parent);
3588 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3591 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3592 rename_folder_data->folder = g_object_ref (folder);
3593 rename_folder_data->new_name = folder_name;
3594 modest_platform_connect_if_remote_and_perform (window, TRUE,
3595 folder, on_rename_folder_performer, rename_folder_data);
3598 g_object_unref (folder);
3603 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3606 GObject *win = modest_mail_operation_get_source (mail_op);
3607 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (win));
3609 modest_platform_run_information_dialog (toplevel,
3610 _("mail_in_ui_folder_delete_error"),
3612 g_object_unref (win);
3616 TnyFolderStore *folder;
3617 gboolean move_to_trash;
3621 on_delete_folder_cb (gboolean canceled,
3623 ModestWindow *parent_window,
3624 TnyAccount *account,
3627 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3628 GtkWidget *folder_view;
3629 ModestMailOperation *mail_op;
3630 GtkTreeSelection *sel;
3631 ModestWindow *modest_window;
3633 #ifdef MODEST_TOOLKIT_HILDON2
3634 modest_window = (ModestWindow*) parent_window;
3636 if (MODEST_IS_SHELL (parent_window)) {
3637 modest_window = modest_shell_peek_window (MODEST_SHELL (parent_window));
3639 modest_window = NULL;
3643 if (!MODEST_IS_WINDOW(modest_window) || canceled || (err!=NULL)) {
3644 /* Note that the connection process can fail due to
3645 memory low conditions as it can not successfully
3646 store the summary */
3647 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
3648 (GtkWidget*) parent_window, err,
3650 g_debug ("Error connecting when trying to delete a folder");
3651 g_object_unref (G_OBJECT (info->folder));
3656 if (MODEST_IS_FOLDER_WINDOW (modest_window)) {
3657 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (modest_window)));
3659 g_object_unref (G_OBJECT (info->folder));
3664 /* Unselect the folder before deleting it to free the headers */
3665 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3666 gtk_tree_selection_unselect_all (sel);
3668 /* Create the mail operation */
3670 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3671 modest_ui_actions_delete_folder_error_handler,
3674 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3676 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3678 g_object_unref (mail_op);
3679 g_object_unref (info->folder);
3684 delete_folder (ModestWindow *window, gboolean move_to_trash)
3686 TnyFolderStore *folder;
3687 GtkWidget *folder_view;
3691 g_return_val_if_fail (MODEST_IS_WINDOW(window), FALSE);
3693 if (MODEST_IS_FOLDER_WINDOW (window)) {
3694 folder_view = GTK_WIDGET (modest_folder_window_get_folder_view (MODEST_FOLDER_WINDOW (window)));
3701 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3706 /* Show an error if it's an account */
3707 if (!TNY_IS_FOLDER (folder)) {
3708 modest_platform_run_information_dialog (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (window))),
3709 _("mail_in_ui_folder_delete_error"),
3711 g_object_unref (G_OBJECT (folder));
3716 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3717 tny_folder_get_name (TNY_FOLDER (folder)));
3718 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (window))),
3719 (const gchar *) message);
3722 if (response == GTK_RESPONSE_OK) {
3723 TnyAccount *account = NULL;
3724 DeleteFolderInfo *info = NULL;
3725 info = g_new0(DeleteFolderInfo, 1);
3726 info->folder = g_object_ref (folder);
3727 info->move_to_trash = move_to_trash;
3729 account = tny_folder_get_account (TNY_FOLDER (folder));
3730 modest_platform_connect_if_remote_and_perform (window,
3732 TNY_FOLDER_STORE (account),
3733 on_delete_folder_cb, info);
3734 g_object_unref (account);
3735 g_object_unref (folder);
3743 modest_ui_actions_on_delete_folder (GtkAction *action,
3744 ModestWindow *window)
3746 modest_ui_actions_on_edit_mode_delete_folder (window);
3750 modest_ui_actions_on_edit_mode_delete_folder (ModestWindow *window)
3752 g_return_val_if_fail (MODEST_IS_WINDOW(window), TRUE);
3754 return delete_folder (window, FALSE);
3758 typedef struct _PasswordDialogFields {
3759 GtkWidget *username;
3760 GtkWidget *password;
3762 } PasswordDialogFields;
3765 password_dialog_check_field (GtkEditable *editable,
3766 PasswordDialogFields *fields)
3769 gboolean any_value_empty = FALSE;
3771 value = modest_entry_get_text (fields->username);
3772 if ((value == NULL) || value[0] == '\0') {
3773 any_value_empty = TRUE;
3775 value = modest_entry_get_text (fields->password);
3776 if ((value == NULL) || value[0] == '\0') {
3777 any_value_empty = TRUE;
3779 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3783 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3784 const gchar* server_account_name,
3789 ModestWindow *window)
3791 g_return_if_fail(server_account_name);
3792 gboolean completed = FALSE;
3793 PasswordDialogFields *fields = NULL;
3795 /* Initalize output parameters: */
3802 #ifndef MODEST_TOOLKIT_GTK
3803 /* Maemo uses a different (awkward) button order,
3804 * It should probably just use gtk_alternative_dialog_button_order ().
3806 #ifdef MODEST_TOOLKIT_HILDON2
3808 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3812 GTK_RESPONSE_ACCEPT,
3814 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
3815 HILDON_MARGIN_DOUBLE);
3818 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3821 _("mcen_bd_dialog_ok"),
3822 GTK_RESPONSE_ACCEPT,
3823 _("mcen_bd_dialog_cancel"),
3824 GTK_RESPONSE_REJECT,
3826 #endif /* MODEST_TOOLKIT_HILDON2 */
3829 gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3833 GTK_RESPONSE_REJECT,
3835 GTK_RESPONSE_ACCEPT,
3837 #endif /* MODEST_TOOLKIT_GTK */
3839 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3841 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3842 modest_runtime_get_account_mgr(), server_account_name);
3843 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3844 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3847 gtk_widget_destroy (dialog);
3851 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3852 GtkWidget *label = gtk_label_new (txt);
3853 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
3855 g_free (server_name);
3856 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), label,
3861 gchar *initial_username = modest_account_mgr_get_server_account_username (
3862 modest_runtime_get_account_mgr(), server_account_name);
3864 GtkWidget *entry_username = modest_toolkit_factory_create_entry (modest_runtime_get_toolkit_factory ());
3865 if (initial_username)
3866 modest_entry_set_text (entry_username, initial_username);
3868 /* Dim this if a connection has ever succeeded with this username,
3869 * as per the UI spec: */
3870 /* const gboolean username_known = */
3871 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3872 /* modest_runtime_get_account_mgr(), server_account_name); */
3873 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3875 /* We drop the username sensitive code and disallow changing it here
3876 * as tinymail does not support really changing the username in the callback
3878 gtk_widget_set_sensitive (entry_username, FALSE);
3880 /* Auto-capitalization is the default, so let's turn it off: */
3881 #ifdef MAEMO_CHANGES
3882 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3885 /* Create a size group to be used by all captions.
3886 * Note that HildonCaption does not create a default size group if we do not specify one.
3887 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3888 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3890 GtkWidget *caption = modest_toolkit_utils_create_captioned (sizegroup, NULL,
3891 _("mail_fi_username"), FALSE,
3893 gtk_widget_show (entry_username);
3894 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3895 FALSE, FALSE, MODEST_MARGIN_HALF);
3896 gtk_widget_show (caption);
3899 GtkWidget *entry_password = modest_toolkit_factory_create_entry (modest_runtime_get_toolkit_factory ());
3900 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3901 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3903 /* Auto-capitalization is the default, so let's turn it off: */
3904 #ifdef MAEMO_CHANGES
3905 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3906 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3909 caption = modest_toolkit_utils_create_captioned (sizegroup, NULL,
3910 _("mail_fi_password"), FALSE,
3912 gtk_widget_show (entry_password);
3913 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3914 FALSE, FALSE, MODEST_MARGIN_HALF);
3915 gtk_widget_show (caption);
3916 g_object_unref (sizegroup);
3918 if (initial_username != NULL)
3919 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3921 /* This is not in the Maemo UI spec:
3922 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3923 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3927 fields = g_slice_new0 (PasswordDialogFields);
3928 fields->username = entry_username;
3929 fields->password = entry_password;
3930 fields->dialog = dialog;
3932 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3933 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3934 password_dialog_check_field (NULL, fields);
3936 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3938 while (!completed) {
3940 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3942 *username = g_strdup (modest_entry_get_text (entry_username));
3944 /* Note that an empty field becomes the "" string */
3945 if (*username && strlen (*username) > 0) {
3946 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
3947 server_account_name,
3951 const gboolean username_was_changed =
3952 (strcmp (*username, initial_username) != 0);
3953 if (username_was_changed) {
3954 g_warning ("%s: tinymail does not yet support changing the "
3955 "username in the get_password() callback.\n", __FUNCTION__);
3961 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
3962 _("mcen_ib_username_pw_incorrect"));
3968 *password = g_strdup (modest_entry_get_text (entry_password));
3970 /* We do not save the password in the configuration,
3971 * because this function is only called for passwords that should
3972 * not be remembered:
3973 modest_server_account_set_password (
3974 modest_runtime_get_account_mgr(), server_account_name,
3991 /* This is not in the Maemo UI spec:
3992 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3998 g_free (initial_username);
3999 gtk_widget_destroy (dialog);
4000 g_slice_free (PasswordDialogFields, fields);
4002 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
4006 modest_ui_actions_on_cut (GtkAction *action,
4007 ModestWindow *window)
4009 GtkWidget *focused_widget;
4010 GtkClipboard *clipboard;
4012 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4013 focused_widget = gtk_container_get_focus_child ((GtkContainer *) window);
4014 if (GTK_IS_EDITABLE (focused_widget)) {
4015 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
4016 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4017 gtk_clipboard_store (clipboard);
4018 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4019 GtkTextBuffer *buffer;
4021 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4022 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4023 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
4024 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4025 gtk_clipboard_store (clipboard);
4027 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4028 TnyList *header_list = modest_header_view_get_selected_headers (
4029 MODEST_HEADER_VIEW (focused_widget));
4030 gboolean continue_download = FALSE;
4031 gint num_of_unc_msgs;
4033 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4035 if (num_of_unc_msgs) {
4036 TnyAccount *account = get_account_from_header_list (header_list);
4038 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4039 g_object_unref (account);
4043 if (num_of_unc_msgs == 0 || continue_download) {
4044 /* modest_platform_information_banner (
4045 NULL, NULL, _CS("mcen_ib_getting_items"));*/
4046 modest_header_view_cut_selection (
4047 MODEST_HEADER_VIEW (focused_widget));
4050 g_object_unref (header_list);
4051 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4052 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
4057 modest_ui_actions_on_copy (GtkAction *action,
4058 ModestWindow *window)
4060 GtkClipboard *clipboard;
4061 GtkWidget *focused_widget;
4062 gboolean copied = TRUE;
4064 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4065 focused_widget = gtk_container_get_focus_child ((GtkContainer *) window);
4067 if (GTK_IS_LABEL (focused_widget)) {
4069 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
4070 gtk_clipboard_set_text (clipboard, selection, -1);
4072 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4073 gtk_clipboard_store (clipboard);
4074 } else if (GTK_IS_EDITABLE (focused_widget)) {
4075 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
4076 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4077 gtk_clipboard_store (clipboard);
4078 } else if (GTK_IS_HTML (focused_widget)) {
4081 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
4082 if ((sel == NULL) || (sel[0] == '\0')) {
4085 gtk_html_copy (GTK_HTML (focused_widget));
4086 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4087 gtk_clipboard_store (clipboard);
4089 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4090 GtkTextBuffer *buffer;
4091 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4092 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
4093 gtk_text_buffer_copy_clipboard (buffer, clipboard);
4094 gtk_clipboard_set_can_store (clipboard, NULL, 0);
4095 gtk_clipboard_store (clipboard);
4097 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
4098 TnyList *header_list = modest_header_view_get_selected_headers (
4099 MODEST_HEADER_VIEW (focused_widget));
4100 gboolean continue_download = FALSE;
4101 gint num_of_unc_msgs;
4103 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
4105 if (num_of_unc_msgs) {
4106 TnyAccount *account = get_account_from_header_list (header_list);
4108 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
4109 g_object_unref (account);
4113 if (num_of_unc_msgs == 0 || continue_download) {
4114 modest_platform_information_banner (
4115 NULL, NULL, _CS_GETTING_ITEMS);
4116 modest_header_view_copy_selection (
4117 MODEST_HEADER_VIEW (focused_widget));
4121 g_object_unref (header_list);
4123 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4124 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
4127 /* Show information banner if there was a copy to clipboard */
4129 modest_platform_information_banner (
4130 NULL, NULL, _CS_COPIED);
4134 modest_ui_actions_on_undo (GtkAction *action,
4135 ModestWindow *window)
4137 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4138 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
4140 g_return_if_reached ();
4145 modest_ui_actions_on_redo (GtkAction *action,
4146 ModestWindow *window)
4148 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4149 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
4152 g_return_if_reached ();
4158 destroy_information_note (ModestMailOperation *mail_op,
4161 /* destroy information note */
4162 gtk_widget_destroy (GTK_WIDGET(user_data));
4166 destroy_folder_information_note (ModestMailOperation *mail_op,
4167 TnyFolder *new_folder,
4170 /* destroy information note */
4171 gtk_widget_destroy (GTK_WIDGET(user_data));
4176 paste_as_attachment_free (gpointer data)
4178 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
4180 if (helper->banner) {
4181 gtk_widget_destroy (helper->banner);
4182 g_object_unref (helper->banner);
4188 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
4193 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
4194 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
4199 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
4204 modest_ui_actions_on_paste (GtkAction *action,
4205 ModestWindow *window)
4207 GtkWidget *focused_widget = NULL;
4208 GtkWidget *inf_note = NULL;
4209 ModestMailOperation *mail_op = NULL;
4211 focused_widget = gtk_container_get_focus_child ((GtkContainer *) window);
4212 if (GTK_IS_EDITABLE (focused_widget)) {
4213 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
4214 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4215 ModestEmailClipboard *e_clipboard = NULL;
4216 e_clipboard = modest_runtime_get_email_clipboard ();
4217 if (modest_email_clipboard_cleared (e_clipboard)) {
4218 GtkTextBuffer *buffer;
4219 GtkClipboard *clipboard;
4221 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4222 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4223 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4224 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4225 ModestMailOperation *mail_op;
4226 TnyFolder *src_folder = NULL;
4227 TnyList *data = NULL;
4229 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4230 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4231 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4233 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4234 mail_op = modest_mail_operation_new (G_OBJECT (window));
4235 if (helper->banner != NULL) {
4236 g_object_ref (G_OBJECT (helper->banner));
4237 gtk_widget_show (GTK_WIDGET (helper->banner));
4241 modest_mail_operation_get_msgs_full (mail_op,
4243 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4245 paste_as_attachment_free);
4249 g_object_unref (data);
4251 g_object_unref (src_folder);
4254 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4255 ModestEmailClipboard *clipboard = NULL;
4256 TnyFolder *src_folder = NULL;
4257 TnyFolderStore *folder_store = NULL;
4258 TnyList *data = NULL;
4259 gboolean delete = FALSE;
4261 /* Check clipboard source */
4262 clipboard = modest_runtime_get_email_clipboard ();
4263 if (modest_email_clipboard_cleared (clipboard))
4266 /* Get elements to paste */
4267 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4269 /* Create a new mail operation */
4270 mail_op = modest_mail_operation_new (G_OBJECT(window));
4272 /* Get destination folder */
4273 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4275 /* transfer messages */
4279 /* Ask for user confirmation */
4281 modest_ui_actions_msgs_move_to_confirmation (window,
4282 TNY_FOLDER (folder_store),
4286 if (response == GTK_RESPONSE_OK) {
4287 /* Launch notification */
4288 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4290 if (inf_note != NULL) {
4291 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4292 gtk_widget_show (GTK_WIDGET(inf_note));
4295 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4296 modest_mail_operation_xfer_msgs (mail_op,
4298 TNY_FOLDER (folder_store),
4300 destroy_information_note,
4303 g_object_unref (mail_op);
4306 } else if (src_folder != NULL) {
4307 /* Launch notification */
4308 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4310 if (inf_note != NULL) {
4311 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4312 gtk_widget_show (GTK_WIDGET(inf_note));
4315 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4316 modest_mail_operation_xfer_folder (mail_op,
4320 destroy_folder_information_note,
4326 g_object_unref (data);
4327 if (src_folder != NULL)
4328 g_object_unref (src_folder);
4329 if (folder_store != NULL)
4330 g_object_unref (folder_store);
4336 modest_ui_actions_on_select_all (GtkAction *action,
4337 ModestWindow *window)
4339 GtkWidget *focused_widget;
4341 focused_widget = gtk_container_get_focus_child ((GtkContainer *) window);
4342 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4343 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4344 } else if (GTK_IS_LABEL (focused_widget)) {
4345 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4346 } else if (GTK_IS_EDITABLE (focused_widget)) {
4347 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4348 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4349 GtkTextBuffer *buffer;
4350 GtkTextIter start, end;
4352 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4353 gtk_text_buffer_get_start_iter (buffer, &start);
4354 gtk_text_buffer_get_end_iter (buffer, &end);
4355 gtk_text_buffer_select_range (buffer, &start, &end);
4356 } else if (GTK_IS_HTML (focused_widget)) {
4357 gtk_html_select_all (GTK_HTML (focused_widget));
4363 modest_ui_actions_on_mark_as_read (GtkAction *action,
4364 ModestWindow *window)
4366 g_return_if_fail (MODEST_IS_WINDOW(window));
4368 /* Mark each header as read */
4369 do_headers_action (window, headers_action_mark_as_read, NULL);
4373 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4374 ModestWindow *window)
4376 g_return_if_fail (MODEST_IS_WINDOW(window));
4378 /* Mark each header as read */
4379 do_headers_action (window, headers_action_mark_as_unread, NULL);
4383 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4384 GtkRadioAction *selected,
4385 ModestWindow *window)
4389 value = gtk_radio_action_get_current_value (selected);
4390 if (MODEST_IS_WINDOW (window)) {
4391 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4396 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4397 GtkRadioAction *selected,
4398 ModestWindow *window)
4400 TnyHeaderFlags flags;
4401 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4403 flags = gtk_radio_action_get_current_value (selected);
4404 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4408 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4409 GtkRadioAction *selected,
4410 ModestWindow *window)
4414 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4416 file_format = gtk_radio_action_get_current_value (selected);
4417 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4422 modest_ui_actions_on_zoom_plus (GtkAction *action,
4423 ModestWindow *window)
4425 g_return_if_fail (MODEST_IS_WINDOW (window));
4427 modest_window_zoom_plus (MODEST_WINDOW (window));
4431 modest_ui_actions_on_zoom_minus (GtkAction *action,
4432 ModestWindow *window)
4434 g_return_if_fail (MODEST_IS_WINDOW (window));
4436 modest_window_zoom_minus (MODEST_WINDOW (window));
4440 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4441 ModestWindow *window)
4443 ModestWindowMgr *mgr;
4444 gboolean fullscreen, active;
4445 g_return_if_fail (MODEST_IS_WINDOW (window));
4447 mgr = modest_runtime_get_window_mgr ();
4449 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4450 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4452 if (active != fullscreen) {
4453 modest_window_mgr_set_fullscreen_mode (mgr, active);
4454 #ifndef MODEST_TOOLKIT_HILDON2
4455 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) window);
4456 gtk_window_present (toplevel);
4462 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4463 ModestWindow *window)
4465 ModestWindowMgr *mgr;
4466 gboolean fullscreen;
4468 g_return_if_fail (MODEST_IS_WINDOW (window));
4470 mgr = modest_runtime_get_window_mgr ();
4471 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4472 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4477 * Used by modest_ui_actions_on_details to call do_headers_action
4480 headers_action_show_details (TnyHeader *header,
4481 ModestWindow *window,
4485 gboolean async_retrieval;
4486 GtkWindow *toplevel;
4489 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4490 async_retrieval = TRUE;
4491 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (window));
4492 async_retrieval = !TNY_IS_CAMEL_BS_MSG (msg);
4494 async_retrieval = FALSE;
4496 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) window);
4497 modest_platform_run_header_details_dialog (toplevel, header, async_retrieval, msg);
4499 g_object_unref (msg);
4503 * Show the header details in a ModestDetailsDialog widget
4506 modest_ui_actions_on_details (GtkAction *action,
4509 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4513 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4517 header = tny_msg_get_header (msg);
4519 headers_action_show_details (header, win, NULL);
4520 g_object_unref (header);
4522 g_object_unref (msg);
4523 } else if (MODEST_IS_HEADER_WINDOW (win)) {
4525 GtkWidget *header_view;
4527 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
4528 folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
4530 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
4532 modest_platform_run_folder_details_dialog (toplevel, folder);
4533 g_object_unref (folder);
4539 modest_ui_actions_on_limit_error (GtkAction *action,
4542 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (win));
4544 modest_platform_information_banner ((GtkWidget *) win, NULL, _CS_MAXIMUM_CHARACTERS_REACHED);
4549 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4550 ModestMsgEditWindow *window)
4552 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4554 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4558 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4559 ModestMsgEditWindow *window)
4561 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4563 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4568 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4569 ModestWindow *window)
4571 gboolean active, fullscreen = FALSE;
4572 ModestWindowMgr *mgr;
4574 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4576 /* Check if we want to toggle the toolbar view in fullscreen
4578 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4579 "ViewShowToolbarFullScreen")) {
4583 /* Toggle toolbar */
4584 mgr = modest_runtime_get_window_mgr ();
4585 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4589 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4590 ModestMsgEditWindow *window)
4592 modest_msg_edit_window_select_font (window);
4597 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4598 const gchar *display_name,
4601 /* don't update the display name if it was already set;
4602 * updating the display name apparently is expensive */
4603 const gchar* old_name = gtk_window_get_title (window);
4605 if (display_name == NULL)
4608 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4609 return; /* don't do anything */
4611 /* This is usually used to change the title of the main window, which
4612 * is the one that holds the folder view. Note that this change can
4613 * happen even when the widget doesn't have the focus. */
4614 gtk_window_set_title (window, display_name);
4619 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4621 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4622 modest_msg_edit_window_select_contacts (window);
4626 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4628 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4629 modest_msg_edit_window_check_names (window, FALSE);
4634 on_move_to_dialog_response (GtkDialog *dialog,
4638 GtkWidget *parent_win;
4639 MoveToInfo *helper = NULL;
4640 ModestFolderView *folder_view;
4641 gboolean unset_edit_mode = FALSE;
4643 helper = (MoveToInfo *) user_data;
4645 parent_win = (GtkWidget *) helper->win;
4646 folder_view = MODEST_FOLDER_VIEW (g_object_get_data (G_OBJECT (dialog),
4647 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4649 TnyFolderStore *dst_folder;
4650 TnyFolderStore *selected;
4652 case MODEST_GTK_RESPONSE_NEW_FOLDER:
4653 selected = modest_folder_view_get_selected (folder_view);
4654 modest_ui_actions_create_folder ((GtkWindow *) dialog, GTK_WIDGET (folder_view), selected);
4655 g_object_unref (selected);
4657 case GTK_RESPONSE_NONE:
4658 case GTK_RESPONSE_CANCEL:
4659 case GTK_RESPONSE_DELETE_EVENT:
4661 case GTK_RESPONSE_OK:
4662 dst_folder = modest_folder_view_get_selected (folder_view);
4664 if (MODEST_IS_FOLDER_WINDOW (parent_win)) {
4665 /* Clean list to move used for filtering */
4666 modest_folder_view_set_list_to_move (folder_view, NULL);
4668 modest_ui_actions_on_folder_window_move_to (GTK_WIDGET (folder_view),
4671 MODEST_WINDOW (parent_win));
4673 /* if the user selected a root folder
4674 (account) then do not perform any action */
4675 if (TNY_IS_ACCOUNT (dst_folder)) {
4676 g_signal_stop_emission_by_name (dialog, "response");
4680 /* Clean list to move used for filtering */
4681 modest_folder_view_set_list_to_move (folder_view, NULL);
4683 /* Moving from headers window in edit mode */
4684 modest_ui_actions_on_window_move_to (NULL, helper->list,
4686 MODEST_WINDOW (parent_win));
4690 g_object_unref (dst_folder);
4692 unset_edit_mode = TRUE;
4695 g_warning ("%s unexpected response id %d", __FUNCTION__, response);
4698 /* Free the helper and exit */
4700 g_object_unref (helper->list);
4701 if (unset_edit_mode) {
4702 #ifdef MODEST_TOOLKIT_HILDON2
4703 modest_hildon2_window_unset_edit_mode (MODEST_HILDON2_WINDOW (helper->win));
4706 g_slice_free (MoveToInfo, helper);
4707 gtk_widget_destroy (GTK_WIDGET (dialog));
4711 create_move_to_dialog (GtkWindow *win,
4712 GtkWidget *folder_view,
4713 TnyList *list_to_move)
4715 GtkWidget *dialog, *tree_view = NULL;
4717 dialog = modest_platform_create_move_to_dialog (win, &tree_view);
4720 /* It could happen that we're trying to move a message from a
4721 window (msg window for example) after the main window was
4722 closed, so we can not just get the model of the folder
4724 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4725 const gchar *visible_id = NULL;
4727 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4728 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4729 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4730 MODEST_FOLDER_VIEW(tree_view));
4733 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4735 /* Show the same account than the one that is shown in the main window */
4736 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(tree_view),
4739 const gchar *active_account_name = NULL;
4740 ModestAccountMgr *mgr = NULL;
4741 ModestAccountSettings *settings = NULL;
4742 ModestServerAccountSettings *store_settings = NULL;
4743 ModestWindow *modest_window;
4745 modest_folder_view_set_style (MODEST_FOLDER_VIEW (tree_view),
4746 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4748 #ifdef MODEST_TOOLKIT_HILDON2
4749 modest_window = (ModestWindow *) win;
4751 modest_window = modest_shell_peek_window (MODEST_SHELL (win));
4753 active_account_name = modest_window_get_active_account (modest_window);
4754 mgr = modest_runtime_get_account_mgr ();
4755 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4758 const gchar *store_account_name;
4759 store_settings = modest_account_settings_get_store_settings (settings);
4760 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4762 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (tree_view),
4763 store_account_name);
4764 g_object_unref (store_settings);
4765 g_object_unref (settings);
4769 /* we keep a pointer to the embedded folder view, so we can
4770 * retrieve it with get_folder_view_from_move_to_dialog (see
4771 * above) later (needed for focus handling)
4773 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, tree_view);
4775 /* Hide special folders */
4777 modest_folder_view_set_list_to_move (MODEST_FOLDER_VIEW (tree_view), list_to_move);
4779 gtk_widget_show (GTK_WIDGET (tree_view));
4785 * Shows a confirmation dialog to the user when we're moving messages
4786 * from a remote server to the local storage. Returns the dialog
4787 * response. If it's other kind of movement then it always returns
4790 * This one is used by the next functions:
4791 * modest_ui_actions_on_paste - commented out
4792 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4795 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4796 TnyFolder *dest_folder,
4800 gint response = GTK_RESPONSE_OK;
4801 TnyAccount *account = NULL;
4802 TnyFolder *src_folder = NULL;
4803 TnyIterator *iter = NULL;
4804 TnyHeader *header = NULL;
4806 /* return with OK if the destination is a remote folder */
4807 if (modest_tny_folder_is_remote_folder (dest_folder))
4808 return GTK_RESPONSE_OK;
4810 /* Get source folder */
4811 iter = tny_list_create_iterator (headers);
4812 header = TNY_HEADER (tny_iterator_get_current (iter));
4814 src_folder = tny_header_get_folder (header);
4815 g_object_unref (header);
4817 g_object_unref (iter);
4819 /* if no src_folder, message may be an attahcment */
4820 if (src_folder == NULL)
4821 return GTK_RESPONSE_CANCEL;
4823 /* If the source is a local or MMC folder */
4824 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4825 g_object_unref (src_folder);
4826 return GTK_RESPONSE_OK;
4829 /* Get the account */
4830 account = tny_folder_get_account (src_folder);
4832 /* now if offline we ask the user */
4833 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4834 response = GTK_RESPONSE_OK;
4836 response = GTK_RESPONSE_CANCEL;
4839 g_object_unref (src_folder);
4840 g_object_unref (account);
4846 move_to_helper_destroyer (gpointer user_data)
4848 MoveToHelper *helper = (MoveToHelper *) user_data;
4850 /* Close the "Pasting" information banner */
4851 if (helper->banner) {
4852 gtk_widget_destroy (GTK_WIDGET (helper->banner));
4853 g_object_unref (helper->banner);
4855 if (gtk_tree_row_reference_valid (helper->reference)) {
4856 gtk_tree_row_reference_free (helper->reference);
4857 helper->reference = NULL;
4863 move_to_cb (ModestMailOperation *mail_op,
4866 MoveToHelper *helper = (MoveToHelper *) user_data;
4867 GObject *object = modest_mail_operation_get_source (mail_op);
4869 /* Note that the operation could have failed, in that case do
4871 if (modest_mail_operation_get_status (mail_op) !=
4872 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
4875 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4876 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4878 if (!modest_msg_view_window_select_next_message (self) &&
4879 !modest_msg_view_window_select_previous_message (self)) {
4880 /* No more messages to view, so close this window */
4881 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4884 g_object_unref (object);
4887 /* Destroy the helper */
4888 move_to_helper_destroyer (helper);
4892 folder_move_to_cb (ModestMailOperation *mail_op,
4893 TnyFolder *new_folder,
4898 object = modest_mail_operation_get_source (mail_op);
4900 move_to_cb (mail_op, user_data);
4905 msgs_move_to_cb (ModestMailOperation *mail_op,
4908 move_to_cb (mail_op, user_data);
4912 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
4915 GObject *win = NULL;
4916 const GError *error;
4917 TnyAccount *account = NULL;
4919 win = modest_mail_operation_get_source (mail_op);
4920 error = modest_mail_operation_get_error (mail_op);
4922 if (TNY_IS_FOLDER (user_data))
4923 account = modest_tny_folder_get_account (TNY_FOLDER (user_data));
4924 else if (TNY_IS_ACCOUNT (user_data))
4925 account = g_object_ref (user_data);
4927 /* If it's not a disk full error then show a generic error */
4928 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
4929 (GtkWidget *) win, (GError *) error,
4931 modest_platform_run_information_dialog ((GtkWindow *) win,
4932 _("mail_in_ui_folder_move_target_error"),
4935 g_object_unref (account);
4937 g_object_unref (win);
4942 * Checks if we need a connection to do the transfer and if the user
4943 * wants to connect to complete it
4946 modest_ui_actions_xfer_messages_check (ModestWindow *parent_window,
4947 TnyFolderStore *src_folder,
4949 TnyFolder *dst_folder,
4950 gboolean delete_originals,
4951 gboolean *need_connection,
4954 TnyAccount *src_account;
4955 gint uncached_msgs = 0;
4957 /* We don't need any further check if
4959 * 1- the source folder is local OR
4960 * 2- the device is already online
4962 if (!modest_tny_folder_store_is_remote (src_folder) ||
4963 tny_device_is_online (modest_runtime_get_device())) {
4964 *need_connection = FALSE;
4969 /* We must ask for a connection when
4971 * - the message(s) is not already cached OR
4972 * - the message(s) is cached but the leave_on_server setting
4973 * is FALSE (because we need to sync the source folder to
4974 * delete the message from the server (for IMAP we could do it
4975 * offline, it'll take place the next time we get a
4978 uncached_msgs = header_list_count_uncached_msgs (headers);
4979 src_account = get_account_from_folder_store (src_folder);
4980 if (uncached_msgs > 0) {
4983 GtkWindow *toplevel;
4985 *need_connection = TRUE;
4986 num_headers = tny_list_get_length (headers);
4987 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
4988 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) parent_window);
4990 if (modest_platform_run_confirmation_dialog (toplevel, msg) ==
4991 GTK_RESPONSE_CANCEL) {
4997 /* The transfer is possible and the user wants to */
5000 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5001 const gchar *account_name;
5002 gboolean leave_on_server;
5004 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5005 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5008 if (leave_on_server == TRUE) {
5009 *need_connection = FALSE;
5011 *need_connection = TRUE;
5014 *need_connection = FALSE;
5019 g_object_unref (src_account);
5023 xfer_messages_error_handler (ModestMailOperation *mail_op,
5027 const GError *error;
5028 TnyAccount *account;
5030 win = modest_mail_operation_get_source (mail_op);
5031 error = modest_mail_operation_get_error (mail_op);
5033 /* We cannot get the account from the mail op as that is the
5034 source account and for checking memory full conditions we
5035 need the destination one */
5036 account = TNY_ACCOUNT (user_data);
5039 !modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5040 (GtkWidget *) win, (GError*) error,
5041 account, _KR("cerm_memory_card_full"))) {
5042 modest_platform_run_information_dialog ((GtkWindow *) win,
5043 _("mail_in_ui_folder_move_target_error"),
5047 g_object_unref (win);
5051 TnyFolderStore *dst_folder;
5056 * Utility function that transfer messages from both the main window
5057 * and the msg view window when using the "Move to" dialog
5060 xfer_messages_performer (gboolean canceled,
5062 ModestWindow *parent_window,
5063 TnyAccount *account,
5066 TnyAccount *dst_account = NULL;
5067 gboolean dst_forbids_message_add = FALSE;
5068 XferMsgsHelper *helper;
5069 MoveToHelper *movehelper;
5070 ModestMailOperation *mail_op;
5072 helper = (XferMsgsHelper *) user_data;
5074 if (canceled || err) {
5075 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5076 (GtkWidget *) parent_window, err,
5078 /* Show the proper error message */
5079 modest_ui_actions_on_account_connection_error (parent_window, account);
5084 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5086 /* tinymail will return NULL for local folders it seems */
5087 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5088 modest_tny_account_get_protocol_type (dst_account),
5089 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_INCOMING_XFERS);
5091 if (dst_forbids_message_add) {
5092 modest_platform_information_banner (GTK_WIDGET (parent_window),
5094 ngettext("mail_in_ui_folder_move_target_error",
5095 "mail_in_ui_folder_move_targets_error",
5096 tny_list_get_length (helper->headers)));
5100 movehelper = g_new0 (MoveToHelper, 1);
5103 /* Perform the mail operation */
5104 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5105 xfer_messages_error_handler,
5106 g_object_ref (dst_account),
5108 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5111 modest_mail_operation_xfer_msgs (mail_op,
5113 TNY_FOLDER (helper->dst_folder),
5118 g_object_unref (G_OBJECT (mail_op));
5121 g_object_unref (dst_account);
5122 g_object_unref (helper->dst_folder);
5123 g_object_unref (helper->headers);
5124 g_slice_free (XferMsgsHelper, helper);
5128 TnyFolder *src_folder;
5129 TnyFolderStore *dst_folder;
5130 gboolean delete_original;
5131 GtkWidget *folder_view;
5135 on_move_folder_cb (gboolean canceled,
5137 ModestWindow *parent_window,
5138 TnyAccount *account,
5141 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5142 GtkTreeSelection *sel;
5143 ModestMailOperation *mail_op = NULL;
5145 if (canceled || err || !MODEST_IS_WINDOW (parent_window)) {
5146 /* Note that the connection process can fail due to
5147 memory low conditions as it can not successfully
5148 store the summary */
5149 if (!modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5150 (GtkWidget*) parent_window, err,
5152 g_debug ("Error connecting when trying to move a folder");
5154 g_object_unref (G_OBJECT (info->src_folder));
5155 g_object_unref (G_OBJECT (info->dst_folder));
5160 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5161 #ifndef MODEST_TOOLKIT_HILDON2
5162 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5164 if (helper->banner != NULL) {
5165 g_object_ref (helper->banner);
5166 gtk_widget_show (GTK_WIDGET(helper->banner));
5169 /* Clean folder on header view before moving it */
5170 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5171 gtk_tree_selection_unselect_all (sel);
5173 /* Let gtk events run. We need that the folder
5174 view frees its reference to the source
5175 folder *before* issuing the mail operation
5176 so we need the signal handler of selection
5177 changed to happen before the mail
5179 while (gtk_events_pending ())
5180 gtk_main_iteration (); */
5183 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5184 modest_ui_actions_move_folder_error_handler,
5185 g_object_ref (info->dst_folder), g_object_unref);
5186 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5189 modest_mail_operation_xfer_folder (mail_op,
5190 TNY_FOLDER (info->src_folder),
5192 info->delete_original,
5195 g_object_unref (G_OBJECT (info->src_folder));
5197 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5200 /* Unref mail operation */
5201 g_object_unref (G_OBJECT (mail_op));
5202 g_object_unref (G_OBJECT (info->dst_folder));
5207 get_account_from_folder_store (TnyFolderStore *folder_store)
5209 if (TNY_IS_ACCOUNT (folder_store))
5210 return g_object_ref (folder_store);
5212 return tny_folder_get_account (TNY_FOLDER (folder_store));
5216 * UI handler for the "Move to" action when invoked from the
5217 * ModestFolderWindow
5220 modest_ui_actions_on_folder_window_move_to (GtkWidget *folder_view,
5221 TnyFolderStore *dst_folder,
5225 TnyFolderStore *src_folder = NULL;
5226 TnyIterator *iterator;
5228 if (tny_list_get_length (selection) != 1)
5231 iterator = tny_list_create_iterator (selection);
5232 src_folder = TNY_FOLDER_STORE (tny_iterator_get_current (iterator));
5233 g_object_unref (iterator);
5236 gboolean do_xfer = TRUE;
5238 /* Allow only to transfer folders to the local root folder */
5239 if (TNY_IS_ACCOUNT (dst_folder) &&
5240 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5241 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5242 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
5246 modest_platform_run_information_dialog (toplevel,
5247 _("mail_in_ui_folder_move_target_error"),
5249 } else if (!TNY_IS_FOLDER (src_folder)) {
5250 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5255 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5256 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5258 info->src_folder = g_object_ref (src_folder);
5259 info->dst_folder = g_object_ref (dst_folder);
5260 info->delete_original = TRUE;
5261 info->folder_view = folder_view;
5263 connect_info->callback = on_move_folder_cb;
5264 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5265 connect_info->data = info;
5267 modest_platform_double_connect_and_perform(win, TRUE,
5268 TNY_FOLDER_STORE (src_folder),
5273 g_object_unref (src_folder);
5278 modest_ui_actions_transfer_messages_helper (ModestWindow *win,
5279 TnyFolder *src_folder,
5281 TnyFolder *dst_folder)
5283 gboolean need_connection = TRUE;
5284 gboolean do_xfer = TRUE;
5285 XferMsgsHelper *helper;
5287 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5288 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5289 g_return_if_fail (TNY_IS_LIST (headers));
5291 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5292 headers, TNY_FOLDER (dst_folder),
5293 TRUE, &need_connection,
5296 /* If we don't want to transfer just return */
5300 /* Create the helper */
5301 helper = g_slice_new (XferMsgsHelper);
5302 helper->dst_folder = g_object_ref (dst_folder);
5303 helper->headers = g_object_ref (headers);
5305 if (need_connection) {
5306 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5307 connect_info->callback = xfer_messages_performer;
5308 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5309 connect_info->data = helper;
5311 modest_platform_double_connect_and_perform(win, TRUE,
5312 TNY_FOLDER_STORE (src_folder),
5315 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5316 xfer_messages_performer (FALSE, NULL, win,
5317 src_account, helper);
5318 g_object_unref (src_account);
5323 * UI handler for the "Move to" action when invoked from the
5324 * ModestMsgViewWindow
5327 modest_ui_actions_on_window_move_to (GtkAction *action,
5329 TnyFolderStore *dst_folder,
5332 TnyFolder *src_folder = NULL;
5334 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5337 TnyHeader *header = NULL;
5340 iter = tny_list_create_iterator (headers);
5341 header = (TnyHeader *) tny_iterator_get_current (iter);
5342 src_folder = tny_header_get_folder (header);
5344 /* Transfer the messages */
5345 modest_ui_actions_transfer_messages_helper (win, src_folder,
5347 TNY_FOLDER (dst_folder));
5350 g_object_unref (header);
5351 g_object_unref (iter);
5352 g_object_unref (src_folder);
5357 modest_ui_actions_on_move_to (GtkAction *action,
5360 modest_ui_actions_on_edit_mode_move_to (win);
5364 modest_ui_actions_on_edit_mode_move_to (ModestWindow *win)
5366 GtkWidget *dialog = NULL;
5367 GtkWindow *toplevel = NULL;
5368 MoveToInfo *helper = NULL;
5369 TnyList *list_to_move;
5371 g_return_val_if_fail (MODEST_IS_WINDOW (win), FALSE);
5374 list_to_move = modest_platform_get_list_to_move (MODEST_WINDOW (win));
5379 if (tny_list_get_length (list_to_move) < 1) {
5380 g_object_unref (list_to_move);
5384 /* Create and run the dialog */
5385 toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
5386 dialog = create_move_to_dialog (toplevel, NULL, list_to_move);
5387 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
5388 GTK_WINDOW (dialog),
5392 helper = g_slice_new0 (MoveToInfo);
5393 helper->list = list_to_move;
5396 /* Listen to response signal */
5397 g_signal_connect (dialog, "response", G_CALLBACK (on_move_to_dialog_response), helper);
5399 /* Show the dialog */
5400 gtk_widget_show (dialog);
5406 * Calls #HeadersFunc for each header already selected in the main
5407 * window or the message currently being shown in the msg view window
5410 do_headers_action (ModestWindow *win,
5414 TnyList *headers_list = NULL;
5415 TnyIterator *iter = NULL;
5416 TnyHeader *header = NULL;
5417 TnyFolder *folder = NULL;
5420 headers_list = get_selected_headers (win);
5424 /* Get the folder */
5425 iter = tny_list_create_iterator (headers_list);
5426 header = TNY_HEADER (tny_iterator_get_current (iter));
5428 folder = tny_header_get_folder (header);
5429 g_object_unref (header);
5432 /* Call the function for each header */
5433 while (!tny_iterator_is_done (iter)) {
5434 header = TNY_HEADER (tny_iterator_get_current (iter));
5435 func (header, win, user_data);
5436 g_object_unref (header);
5437 tny_iterator_next (iter);
5440 /* Trick: do a poke status in order to speed up the signaling
5443 tny_folder_poke_status (folder);
5444 g_object_unref (folder);
5448 g_object_unref (iter);
5449 g_object_unref (headers_list);
5453 modest_ui_actions_view_attachment (GtkAction *action,
5454 ModestWindow *window)
5456 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5457 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5459 /* not supported window for this action */
5460 g_return_if_reached ();
5465 modest_ui_actions_save_attachments (GtkAction *action,
5466 ModestWindow *window)
5468 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5470 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5473 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5475 /* not supported window for this action */
5476 g_return_if_reached ();
5481 modest_ui_actions_remove_attachments (GtkAction *action,
5482 ModestWindow *window)
5484 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5485 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5487 /* not supported window for this action */
5488 g_return_if_reached ();
5493 modest_ui_actions_on_settings (GtkAction *action,
5497 GtkWindow *toplevel;
5499 dialog = modest_platform_get_global_settings_dialog ();
5500 toplevel = (GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (win));
5501 gtk_window_set_transient_for (GTK_WINDOW (dialog), toplevel);
5502 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5503 gtk_widget_show_all (dialog);
5505 gtk_dialog_run (GTK_DIALOG (dialog));
5507 gtk_widget_destroy (dialog);
5511 modest_ui_actions_on_help (GtkAction *action,
5514 /* Help app is not available at all in fremantle */
5515 #ifndef MODEST_TOOLKIT_HILDON2
5516 const gchar *help_id;
5518 g_return_if_fail (win && GTK_IS_WINDOW(win));
5520 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5523 modest_platform_show_help (win, help_id);
5528 modest_ui_actions_on_csm_help (GtkAction *action,
5531 /* Help app is not available at all in fremantle */
5535 retrieve_contents_cb (ModestMailOperation *mail_op,
5542 /* We only need this callback to show an error in case of
5543 memory low condition */
5544 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
5545 g_debug ("%s: message failed to retrieve. Memory low?", __FUNCTION__);
5550 retrieve_msg_contents_performer (gboolean canceled,
5552 ModestWindow *parent_window,
5553 TnyAccount *account,
5556 ModestMailOperation *mail_op;
5557 TnyList *headers = TNY_LIST (user_data);
5559 if (err || canceled) {
5560 modest_tny_account_store_check_disk_full_error (modest_runtime_get_account_store(),
5561 (GtkWidget *) parent_window, err,
5566 /* Create mail operation */
5567 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5568 modest_ui_actions_disk_operations_error_handler,
5570 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5571 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
5574 g_object_unref (mail_op);
5576 g_object_unref (headers);
5577 g_object_unref (account);
5581 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5582 ModestWindow *window)
5584 TnyList *headers = NULL;
5585 TnyAccount *account = NULL;
5586 TnyIterator *iter = NULL;
5587 TnyHeader *header = NULL;
5588 TnyFolder *folder = NULL;
5591 headers = get_selected_headers (window);
5595 /* Pick the account */
5596 iter = tny_list_create_iterator (headers);
5597 header = TNY_HEADER (tny_iterator_get_current (iter));
5598 folder = tny_header_get_folder (header);
5599 account = tny_folder_get_account (folder);
5600 g_object_unref (folder);
5601 g_object_unref (header);
5602 g_object_unref (iter);
5604 /* Connect and perform the message retrieval */
5605 modest_platform_connect_and_perform (window, TRUE,
5606 g_object_ref (account),
5607 retrieve_msg_contents_performer,
5608 g_object_ref (headers));
5611 g_object_unref (account);
5612 g_object_unref (headers);
5616 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
5618 g_return_if_fail (MODEST_IS_WINDOW (window));
5621 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
5625 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
5627 g_return_if_fail (MODEST_IS_WINDOW (window));
5630 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
5634 modest_ui_actions_on_email_menu_activated (GtkAction *action,
5635 ModestWindow *window)
5637 g_return_if_fail (MODEST_IS_WINDOW (window));
5640 modest_ui_actions_check_menu_dimming_rules (window);
5644 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
5645 ModestWindow *window)
5647 g_return_if_fail (MODEST_IS_WINDOW (window));
5650 modest_ui_actions_check_menu_dimming_rules (window);
5654 modest_ui_actions_on_view_menu_activated (GtkAction *action,
5655 ModestWindow *window)
5657 g_return_if_fail (MODEST_IS_WINDOW (window));
5660 modest_ui_actions_check_menu_dimming_rules (window);
5664 modest_ui_actions_on_format_menu_activated (GtkAction *action,
5665 ModestWindow *window)
5667 g_return_if_fail (MODEST_IS_WINDOW (window));
5670 modest_ui_actions_check_menu_dimming_rules (window);
5674 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
5675 ModestWindow *window)
5677 g_return_if_fail (MODEST_IS_WINDOW (window));
5680 modest_ui_actions_check_menu_dimming_rules (window);
5684 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
5685 ModestWindow *window)
5687 g_return_if_fail (MODEST_IS_WINDOW (window));
5690 modest_ui_actions_check_menu_dimming_rules (window);
5694 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
5695 ModestWindow *window)
5697 g_return_if_fail (MODEST_IS_WINDOW (window));
5700 modest_ui_actions_check_menu_dimming_rules (window);
5704 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
5705 ModestWindow *window)
5707 g_return_if_fail (MODEST_IS_WINDOW (window));
5710 modest_ui_actions_check_menu_dimming_rules (window);
5714 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
5715 ModestWindow *window)
5717 g_return_if_fail (MODEST_IS_WINDOW (window));
5720 modest_ui_actions_check_menu_dimming_rules (window);
5724 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
5726 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) window);
5728 g_return_if_fail (MODEST_IS_WINDOW (window));
5730 /* we check for low-mem; in that case, show a warning, and don't allow
5733 if (modest_platform_check_memory_low (window, TRUE))
5736 modest_platform_show_search_messages (toplevel);
5740 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
5742 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) win);
5744 g_return_if_fail (MODEST_IS_WINDOW (win));
5746 /* we check for low-mem; in that case, show a warning, and don't allow
5747 * for the addressbook
5749 if (modest_platform_check_memory_low (win, TRUE))
5752 modest_platform_show_addressbook (toplevel);
5757 modest_ui_actions_on_toggle_find_in_page (GtkAction *action,
5758 ModestWindow *window)
5761 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5763 if (GTK_IS_TOGGLE_ACTION (action))
5764 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
5768 modest_msg_edit_window_toggle_isearch_toolbar (MODEST_MSG_EDIT_WINDOW (window),
5774 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
5780 const gchar* server_name = NULL;
5781 TnyTransportAccount *transport;
5782 gchar *message = NULL;
5783 ModestProtocol *protocol;
5785 /* Don't show anything if the user cancelled something or the
5786 * send receive request is not interactive. Authentication
5787 * errors are managed by the account store so no need to show
5788 * a dialog here again */
5789 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
5790 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
5791 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
5795 /* Get the server name. Note that we could be using a
5796 connection specific transport account */
5797 transport = (TnyTransportAccount *)
5798 tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self));
5800 ModestTnyAccountStore *acc_store;
5801 const gchar *acc_name;
5802 TnyTransportAccount *conn_specific;
5804 acc_store = modest_runtime_get_account_store();
5805 acc_name = modest_tny_account_get_parent_modest_account_name_for_server_account (TNY_ACCOUNT (transport));
5806 conn_specific = (TnyTransportAccount *)
5807 modest_tny_account_store_get_transport_account_for_open_connection (acc_store, acc_name);
5808 if (conn_specific) {
5809 server_name = tny_account_get_hostname (TNY_ACCOUNT (conn_specific));
5810 g_object_unref (conn_specific);
5812 server_name = tny_account_get_hostname (TNY_ACCOUNT (transport));
5814 g_object_unref (transport);
5818 protocol = modest_protocol_registry_get_protocol_by_name (modest_runtime_get_protocol_registry (),
5819 MODEST_PROTOCOL_REGISTRY_TRANSPORT_STORE_PROTOCOLS,
5820 tny_account_get_proto (TNY_ACCOUNT (transport)));
5822 g_warning ("%s: Account with no proto", __FUNCTION__);
5826 /* Show the appropriate message text for the GError: */
5827 switch (err->code) {
5828 case TNY_SERVICE_ERROR_CONNECT:
5829 message = modest_protocol_get_translation (protocol,
5830 MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR,
5833 case TNY_SERVICE_ERROR_SEND:
5834 message = g_strdup (_CS_UNABLE_TO_SEND);
5836 case TNY_SERVICE_ERROR_UNAVAILABLE:
5837 message = modest_protocol_get_translation (protocol,
5838 MODEST_PROTOCOL_TRANSLATION_CONNECT_ERROR,
5842 g_warning ("%s: unexpected ERROR %d",
5843 __FUNCTION__, err->code);
5844 message = g_strdup (_CS_UNABLE_TO_SEND);
5848 modest_platform_run_information_dialog (NULL, message, FALSE);
5853 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
5858 ModestWindow *top_window = NULL;
5859 ModestWindowMgr *mgr = NULL;
5860 GtkWidget *header_view = NULL;
5861 TnyFolder *selected_folder = NULL;
5862 TnyFolderType folder_type;
5864 mgr = modest_runtime_get_window_mgr ();
5865 top_window = modest_window_mgr_get_current_top (mgr);
5870 if (MODEST_IS_HEADER_WINDOW (top_window)) {
5871 header_view = (GtkWidget *)
5872 modest_header_window_get_header_view (MODEST_HEADER_WINDOW (top_window));
5875 /* Get selected folder */
5877 selected_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
5878 if (!selected_folder)
5881 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
5882 #if GTK_CHECK_VERSION(2, 8, 0)
5883 folder_type = modest_tny_folder_guess_folder_type (selected_folder);
5884 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
5885 GtkTreeViewColumn *tree_column;
5887 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
5888 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
5890 gtk_tree_view_column_queue_resize (tree_column);
5892 #else /* #if GTK_CHECK_VERSION(2, 8, 0) */
5893 gtk_widget_queue_draw (header_view);
5896 #ifndef MODEST_TOOLKIT_HILDON2
5897 /* Rerun dimming rules, because the message could become deletable for example */
5898 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
5899 MODEST_DIMMING_RULES_TOOLBAR);
5900 modest_window_check_dimming_rules_group (MODEST_WINDOW (top_window),
5901 MODEST_DIMMING_RULES_MENU);
5905 g_object_unref (selected_folder);
5909 modest_ui_actions_on_account_connection_error (ModestWindow *parent_window,
5910 TnyAccount *account)
5912 ModestProtocolType protocol_type;
5913 ModestProtocol *protocol;
5914 gchar *error_note = NULL;
5916 protocol_type = modest_tny_account_get_protocol_type (account);
5917 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
5920 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
5921 if (error_note == NULL) {
5922 g_warning ("%s: This should not be reached", __FUNCTION__);
5924 GtkWindow *toplevel = (GtkWindow *) gtk_widget_get_toplevel ((GtkWidget *) parent_window);
5925 modest_platform_run_information_dialog (toplevel, error_note, FALSE);
5926 g_free (error_note);
5931 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
5935 TnyFolderStore *folder = NULL;
5936 TnyAccount *account = NULL;
5937 ModestProtocolType proto;
5938 ModestProtocol *protocol;
5939 TnyHeader *header = NULL;
5941 if (MODEST_IS_HEADER_WINDOW (win)) {
5942 GtkWidget *header_view;
5943 TnyList* headers = NULL;
5945 header_view = GTK_WIDGET (modest_header_window_get_header_view (MODEST_HEADER_WINDOW (win)));
5946 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5947 if (!headers || tny_list_get_length (headers) == 0) {
5949 g_object_unref (headers);
5952 iter = tny_list_create_iterator (headers);
5953 header = TNY_HEADER (tny_iterator_get_current (iter));
5955 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
5957 g_warning ("List should contain headers");
5959 g_object_unref (iter);
5960 g_object_unref (headers);
5961 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
5962 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
5964 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
5967 if (!header || !folder)
5970 /* Get the account type */
5971 account = tny_folder_get_account (TNY_FOLDER (folder));
5972 proto = modest_tny_account_get_protocol_type (account);
5973 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
5976 subject = tny_header_dup_subject (header);
5977 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
5981 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
5987 g_object_unref (account);
5989 g_object_unref (folder);
5991 g_object_unref (header);
5997 modest_ui_actions_on_delete_account (GtkWindow *parent_window,
5998 const gchar *account_name,
5999 const gchar *account_title)
6001 ModestAccountMgr *account_mgr;
6004 ModestProtocol *protocol;
6005 gboolean removed = FALSE;
6007 g_return_val_if_fail (account_name, FALSE);
6008 g_return_val_if_fail (account_title, FALSE);
6010 account_mgr = modest_runtime_get_account_mgr();
6012 /* The warning text depends on the account type: */
6013 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6014 modest_account_mgr_get_store_protocol (account_mgr,
6016 txt = modest_protocol_get_translation (protocol,
6017 MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX,
6020 txt = g_strdup_printf (_("emev_nc_delete_mailbox"), account_title);
6022 response = modest_platform_run_confirmation_dialog (parent_window, txt);
6026 if (response == GTK_RESPONSE_OK) {
6027 /* Remove account. If it succeeds then it also removes
6028 the account from the ModestAccountView: */
6029 gboolean is_default = FALSE;
6030 gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
6031 if (default_account_name && (strcmp (default_account_name, account_name) == 0))
6033 g_free (default_account_name);
6035 removed = modest_account_mgr_remove_account (account_mgr, account_name);
6037 #ifdef MODEST_TOOLKIT_HILDON2
6038 hildon_gtk_window_take_screenshot (parent_window, FALSE);
6040 /* Close all email notifications, we cannot
6041 distinguish if the notification belongs to
6042 this account or not, so for safety reasons
6043 we remove them all */
6044 modest_platform_remove_new_mail_notifications (FALSE, account_name);
6046 g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
6053 on_fetch_images_performer (gboolean canceled,
6055 ModestWindow *parent_window,
6056 TnyAccount *account,
6059 if (err || canceled) {
6060 /* Show an unable to retrieve images ??? */
6064 /* Note that the user could have closed the window while connecting */
6065 if (GTK_WIDGET_VISIBLE (parent_window))
6066 modest_msg_view_window_fetch_images ((ModestMsgViewWindow *) parent_window);
6067 g_object_unref ((GObject *) user_data);
6071 modest_ui_actions_on_fetch_images (GtkAction *action,
6072 ModestWindow *window)
6074 g_return_if_fail (MODEST_IS_MSG_VIEW_WINDOW (window));
6076 modest_platform_connect_and_perform (window, TRUE,
6078 on_fetch_images_performer,
6079 g_object_ref (window));
6083 modest_ui_actions_on_reload_message (const gchar *msg_id)
6085 ModestWindow *window = NULL;
6087 g_return_if_fail (msg_id && msg_id[0] != '\0');
6088 if (!modest_window_mgr_find_registered_message_uid (modest_runtime_get_window_mgr (),
6094 if (window == NULL || !MODEST_IS_MSG_VIEW_WINDOW (window))
6097 modest_msg_view_window_reload (MODEST_MSG_VIEW_WINDOW (window));
6100 /** Check whether any connections are active, and cancel them if
6102 * Returns TRUE is there was no problem,
6103 * or if an operation was cancelled so we can continue.
6104 * Returns FALSE if the user chose to cancel his request instead.
6108 modest_ui_actions_check_for_active_account (ModestWindow *self,
6109 const gchar* account_name)
6111 ModestTnySendQueue *send_queue;
6112 ModestTnyAccountStore *acc_store;
6113 ModestMailOperationQueue* queue;
6114 TnyConnectionStatus store_conn_status;
6115 TnyAccount *store_account = NULL, *transport_account = NULL;
6116 gboolean retval = TRUE, sending = FALSE;
6118 acc_store = modest_runtime_get_account_store ();
6119 queue = modest_runtime_get_mail_operation_queue ();
6122 modest_tny_account_store_get_server_account (acc_store,
6124 TNY_ACCOUNT_TYPE_STORE);
6126 /* This could happen if the account was deleted before the
6127 call to this function */
6132 modest_tny_account_store_get_server_account (acc_store,
6134 TNY_ACCOUNT_TYPE_TRANSPORT);
6136 /* This could happen if the account was deleted before the
6137 call to this function */
6138 if (!transport_account) {
6139 g_object_unref (store_account);
6143 /* If the transport account was not used yet, then the send
6144 queue could not exist (it's created on demand) */
6145 send_queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (transport_account), FALSE);
6146 if (TNY_IS_SEND_QUEUE (send_queue))
6147 sending = modest_tny_send_queue_sending_in_progress (send_queue);
6149 store_conn_status = tny_account_get_connection_status (store_account);
6150 if (store_conn_status == TNY_CONNECTION_STATUS_CONNECTED || sending) {
6153 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self))),
6154 _("emev_nc_disconnect_account"));
6155 if (response == GTK_RESPONSE_OK) {
6164 /* FIXME: We should only cancel those of this account */
6165 modest_mail_operation_queue_cancel_all (queue);
6167 /* Also disconnect the account */
6168 if ((tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED) &&
6169 (tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)) {
6170 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
6174 tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (transport_account),
6180 g_object_unref (store_account);
6181 g_object_unref (transport_account);