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,