1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #endif /*HAVE_CONFIG_H*/
34 #include <glib/gi18n.h>
35 #include <glib/gprintf.h>
37 #include <modest-runtime.h>
38 #include <modest-tny-folder.h>
39 #include <modest-tny-msg.h>
40 #include <modest-tny-account.h>
41 #include <modest-address-book.h>
42 #include "modest-error.h"
43 #include "modest-ui-actions.h"
44 #include "modest-tny-platform-factory.h"
45 #include "modest-platform.h"
46 #include "modest-debug.h"
47 #include <tny-mime-part.h>
48 #include <tny-camel-folder.h>
49 #include <tny-camel-imap-folder.h>
50 #include <tny-camel-pop-folder.h>
52 #ifdef MODEST_PLATFORM_MAEMO
53 #include "maemo/modest-osso-state-saving.h"
54 #endif /* MODEST_PLATFORM_MAEMO */
55 #ifndef MODEST_TOOLKIT_GTK
56 #include "maemo/modest-hildon-includes.h"
57 #include "maemo/modest-connection-specific-smtp-window.h"
58 #endif /* !MODEST_TOOLKIT_GTK */
59 #include <modest-utils.h>
61 #include "widgets/modest-ui-constants.h"
62 #include <widgets/modest-main-window.h>
63 #include <widgets/modest-msg-view-window.h>
64 #include <widgets/modest-account-view-window.h>
65 #include <widgets/modest-details-dialog.h>
66 #include <widgets/modest-attachments-view.h>
67 #include "widgets/modest-folder-view.h"
68 #include "widgets/modest-global-settings-dialog.h"
69 #include "modest-account-mgr-helpers.h"
70 #include "modest-mail-operation.h"
71 #include "modest-text-utils.h"
73 #ifdef MODEST_HAVE_EASYSETUP
74 #ifdef MODEST_TOOLKIT_HILDON2
75 #include "modest-easysetup-wizard-dialog.h"
77 #include "easysetup/modest-easysetup-wizard-dialog.h"
79 #endif /* MODEST_HAVE_EASYSETUP */
81 #include <modest-widget-memory.h>
82 #include <tny-error.h>
83 #include <tny-simple-list.h>
84 #include <tny-msg-view.h>
85 #include <tny-device.h>
86 #include <tny-merge-folder.h>
88 #include <gtkhtml/gtkhtml.h>
90 #define MIN_FREE_SPACE 5 * 1024 * 1024
92 typedef struct _GetMsgAsyncHelper {
94 ModestMailOperation *mail_op;
101 typedef enum _ReplyForwardAction {
105 } ReplyForwardAction;
107 typedef struct _ReplyForwardHelper {
108 guint reply_forward_type;
109 ReplyForwardAction action;
111 GtkWidget *parent_window;
113 } ReplyForwardHelper;
115 typedef struct _MoveToHelper {
116 GtkTreeRowReference *reference;
120 typedef struct _PasteAsAttachmentHelper {
121 ModestMsgEditWindow *window;
123 } PasteAsAttachmentHelper;
127 * The do_headers_action uses this kind of functions to perform some
128 * action to each member of a list of headers
130 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
132 static void do_headers_action (ModestWindow *win,
136 static void open_msg_cb (ModestMailOperation *mail_op,
143 static void reply_forward_cb (ModestMailOperation *mail_op,
150 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
152 static void folder_refreshed_cb (ModestMailOperation *mail_op,
156 static void on_send_receive_finished (ModestMailOperation *mail_op,
159 static gint header_list_count_uncached_msgs (TnyList *header_list);
161 static gboolean connect_to_get_msg (ModestWindow *win,
162 gint num_of_uncached_msgs,
163 TnyAccount *account);
165 static gboolean remote_folder_has_leave_on_server (TnyFolderStore *folder);
167 static void do_create_folder (GtkWindow *window,
168 TnyFolderStore *parent_folder,
169 const gchar *suggested_name);
171 static GtkWidget* get_folder_view_from_move_to_dialog (GtkWidget *move_to_dialog);
173 static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store);
176 * This function checks whether a TnyFolderStore is a pop account
179 remote_folder_has_leave_on_server (TnyFolderStore *folder)
184 g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
186 account = get_account_from_folder_store (folder);
187 result = (modest_protocol_registry_protocol_type_has_leave_on_server (modest_runtime_get_protocol_registry (),
188 modest_tny_account_get_protocol_type (account)));
189 g_object_unref (account);
194 /* FIXME: this should be merged with the similar code in modest-account-view-window */
195 /* Show the account creation wizard dialog.
196 * returns: TRUE if an account was created. FALSE if the user cancelled.
199 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
201 gboolean result = FALSE;
202 GtkWindow *dialog, *wizard;
203 gint dialog_response;
205 /* Show the easy-setup wizard: */
206 dialog = modest_window_mgr_get_modal (modest_runtime_get_window_mgr());
208 /* old wizard is active already;
210 gtk_window_present (GTK_WINDOW(dialog));
215 /* there is no such wizard yet */
216 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
217 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), wizard);
219 /* always present a main window in the background
220 * we do it here, so we cannot end up with two wizards (as this
221 * function might be called in modest_window_mgr_get_main_window as well */
223 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
224 TRUE); /* create if not existent */
226 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
228 /* make sure the mainwindow is visible. We need to present the
229 wizard again to give it the focus back. show_all are needed
230 in order to get the widgets properly drawn (MainWindow main
231 paned won't be in its right position and the dialog will be
233 gtk_widget_show_all (GTK_WIDGET (win));
234 gtk_widget_show_all (GTK_WIDGET (wizard));
235 gtk_window_present (GTK_WINDOW (win));
236 gtk_window_present (GTK_WINDOW (wizard));
238 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
239 gtk_widget_destroy (GTK_WIDGET (wizard));
240 if (gtk_events_pending ())
241 gtk_main_iteration ();
243 if (dialog_response == GTK_RESPONSE_CANCEL) {
246 /* Check whether an account was created: */
247 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
254 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
257 const gchar *authors[] = {
258 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
261 about = gtk_about_dialog_new ();
262 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
263 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
264 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
265 _("Copyright (c) 2006, Nokia Corporation\n"
266 "All rights reserved."));
267 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
268 _("a modest e-mail client\n\n"
269 "design and implementation: Dirk-Jan C. Binnema\n"
270 "contributions from the fine people at KC and Ig\n"
271 "uses the tinymail email framework written by Philip van Hoof"));
272 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
273 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
274 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
275 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
277 gtk_dialog_run (GTK_DIALOG (about));
278 gtk_widget_destroy(about);
282 * Gets the list of currently selected messages. If the win is the
283 * main window, then it returns a newly allocated list of the headers
284 * selected in the header view. If win is the msg view window, then
285 * the value returned is a list with just a single header.
287 * The caller of this funcion must free the list.
290 get_selected_headers (ModestWindow *win)
292 if (MODEST_IS_MAIN_WINDOW(win)) {
293 GtkWidget *header_view;
295 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
296 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
297 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
299 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
300 /* for MsgViewWindows, we simply return a list with one element */
302 TnyList *list = NULL;
304 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
305 if (header != NULL) {
306 list = tny_simple_list_new ();
307 tny_list_prepend (list, G_OBJECT(header));
308 g_object_unref (G_OBJECT(header));
317 static GtkTreeRowReference *
318 get_next_after_selected_headers (ModestHeaderView *header_view)
320 GtkTreeSelection *sel;
321 GList *selected_rows, *node;
323 GtkTreeRowReference *result;
326 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
327 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
328 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
330 if (selected_rows == NULL)
333 node = g_list_last (selected_rows);
334 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
335 gtk_tree_path_next (path);
337 result = gtk_tree_row_reference_new (model, path);
339 gtk_tree_path_free (path);
340 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
341 g_list_free (selected_rows);
347 headers_action_mark_as_read (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) return;
357 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
361 headers_action_mark_as_unread (TnyHeader *header,
365 TnyHeaderFlags flags;
367 g_return_if_fail (TNY_IS_HEADER(header));
369 flags = tny_header_get_flags (header);
370 if (flags & TNY_HEADER_FLAG_SEEN) {
371 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
375 /** After deleing a message that is currently visible in a window,
376 * show the next message from the list, or close the window if there are no more messages.
379 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
381 /* Close msg view window or select next */
382 if (!modest_msg_view_window_select_next_message (win) &&
383 !modest_msg_view_window_select_previous_message (win)) {
385 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
391 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
393 TnyList *header_list = NULL;
394 TnyIterator *iter = NULL;
395 TnyHeader *header = NULL;
396 gchar *message = NULL;
399 ModestWindowMgr *mgr;
400 GtkWidget *header_view = NULL;
402 g_return_if_fail (MODEST_IS_WINDOW(win));
404 /* Check first if the header view has the focus */
405 if (MODEST_IS_MAIN_WINDOW (win)) {
407 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
408 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
409 if (!gtk_widget_is_focus (header_view))
413 /* Get the headers, either from the header view (if win is the main window),
414 * or from the message view window: */
415 header_list = get_selected_headers (win);
416 if (!header_list) return;
418 /* Check if any of the headers are already opened, or in the process of being opened */
419 if (MODEST_IS_MAIN_WINDOW (win)) {
420 gint opened_headers = 0;
422 iter = tny_list_create_iterator (header_list);
423 mgr = modest_runtime_get_window_mgr ();
424 while (!tny_iterator_is_done (iter)) {
425 header = TNY_HEADER (tny_iterator_get_current (iter));
427 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
429 g_object_unref (header);
431 tny_iterator_next (iter);
433 g_object_unref (iter);
435 if (opened_headers > 0) {
438 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
441 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg, FALSE);
444 g_object_unref (header_list);
450 if (tny_list_get_length(header_list) == 1) {
451 iter = tny_list_create_iterator (header_list);
452 header = TNY_HEADER (tny_iterator_get_current (iter));
455 subject = tny_header_dup_subject (header);
456 desc = g_strdup_printf ("%s", subject);
458 g_object_unref (header);
461 g_object_unref (iter);
463 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
464 tny_list_get_length(header_list)), desc);
466 /* Confirmation dialog */
467 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
471 if (response == GTK_RESPONSE_OK) {
472 ModestWindow *main_window = NULL;
473 ModestWindowMgr *mgr = NULL;
474 GtkTreeModel *model = NULL;
475 GtkTreeSelection *sel = NULL;
476 GList *sel_list = NULL, *tmp = NULL;
477 GtkTreeRowReference *next_row_reference = NULL;
478 GtkTreeRowReference *prev_row_reference = NULL;
479 GtkTreePath *next_path = NULL;
480 GtkTreePath *prev_path = NULL;
481 ModestMailOperation *mail_op = NULL;
483 /* Find last selected row */
484 if (MODEST_IS_MAIN_WINDOW (win)) {
485 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
486 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
487 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
488 for (tmp=sel_list; tmp; tmp=tmp->next) {
489 if (tmp->next == NULL) {
490 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
491 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
493 gtk_tree_path_prev (prev_path);
494 gtk_tree_path_next (next_path);
496 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
497 next_row_reference = gtk_tree_row_reference_new (model, next_path);
502 /* Disable window dimming management */
503 modest_window_disable_dimming (MODEST_WINDOW(win));
505 /* Remove each header. If it's a view window header_view == NULL */
506 mail_op = modest_mail_operation_new ((GObject *) win);
507 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
509 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
510 g_object_unref (mail_op);
512 /* Enable window dimming management */
514 gtk_tree_selection_unselect_all (sel);
516 modest_window_enable_dimming (MODEST_WINDOW(win));
518 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
519 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
521 /* Get main window */
522 mgr = modest_runtime_get_window_mgr ();
523 main_window = modest_window_mgr_get_main_window (mgr, FALSE); /* don't create */
525 /* Move cursor to next row */
528 /* Select next or previous row */
529 if (gtk_tree_row_reference_valid (next_row_reference)) {
530 gtk_tree_selection_select_path (sel, next_path);
532 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
533 gtk_tree_selection_select_path (sel, prev_path);
537 if (next_row_reference != NULL)
538 gtk_tree_row_reference_free (next_row_reference);
539 if (next_path != NULL)
540 gtk_tree_path_free (next_path);
541 if (prev_row_reference != NULL)
542 gtk_tree_row_reference_free (prev_row_reference);
543 if (prev_path != NULL)
544 gtk_tree_path_free (prev_path);
547 /* Update toolbar dimming state */
549 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
550 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
554 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
555 g_list_free (sel_list);
561 g_object_unref (header_list);
567 /* delete either message or folder, based on where we are */
569 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
571 g_return_if_fail (MODEST_IS_WINDOW(win));
573 /* Check first if the header view has the focus */
574 if (MODEST_IS_MAIN_WINDOW (win)) {
576 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
577 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
578 if (gtk_widget_is_focus (w)) {
579 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
583 modest_ui_actions_on_delete_message (action, win);
587 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
589 ModestWindowMgr *mgr = NULL;
591 #ifdef MODEST_PLATFORM_MAEMO
592 modest_osso_save_state();
593 #endif /* MODEST_PLATFORM_MAEMO */
595 g_debug ("closing down, clearing %d item(s) from operation queue",
596 modest_mail_operation_queue_num_elements
597 (modest_runtime_get_mail_operation_queue()));
599 /* cancel all outstanding operations */
600 modest_mail_operation_queue_cancel_all
601 (modest_runtime_get_mail_operation_queue());
603 g_debug ("queue has been cleared");
606 /* Check if there are opened editing windows */
607 mgr = modest_runtime_get_window_mgr ();
608 modest_window_mgr_close_all_windows (mgr);
610 /* note: when modest-tny-account-store is finalized,
611 it will automatically set all network connections
614 /* gtk_main_quit (); */
618 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
622 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
624 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
625 /* gtk_widget_destroy (GTK_WIDGET (win)); */
626 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
627 /* gboolean ret_value; */
628 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
629 /* } else if (MODEST_IS_WINDOW (win)) { */
630 /* gtk_widget_destroy (GTK_WIDGET (win)); */
632 /* g_return_if_reached (); */
637 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
639 GtkClipboard *clipboard = NULL;
640 gchar *selection = NULL;
642 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
643 selection = gtk_clipboard_wait_for_text (clipboard);
645 /* Question: why is the clipboard being used here?
646 * It doesn't really make a lot of sense. */
650 modest_address_book_add_address (selection);
656 modest_ui_actions_on_accounts (GtkAction *action,
659 /* This is currently only implemented for Maemo */
660 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
661 if (!modest_ui_actions_run_account_setup_wizard (win))
662 g_debug ("%s: wizard was already running", __FUNCTION__);
666 /* Show the list of accounts */
667 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
669 /* The accounts dialog must be modal */
670 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), account_win);
671 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
676 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
678 /* This is currently only implemented for Maemo,
679 * because it requires an API (libconic) to detect different connection
682 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
684 /* Create the window if necessary: */
685 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
686 modest_connection_specific_smtp_window_fill_with_connections (
687 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
688 modest_runtime_get_account_mgr());
690 /* Show the window: */
691 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
692 GTK_WINDOW (specific_window));
693 gtk_widget_show (specific_window);
694 #endif /* !MODEST_TOOLKIT_GTK */
698 modest_ui_actions_compose_msg(ModestWindow *win,
701 const gchar *bcc_str,
702 const gchar *subject_str,
703 const gchar *body_str,
705 gboolean set_as_modified)
707 gchar *account_name = NULL;
709 TnyAccount *account = NULL;
710 TnyFolder *folder = NULL;
711 gchar *from_str = NULL, *signature = NULL, *body = NULL;
712 gboolean use_signature = FALSE;
713 ModestWindow *msg_win = NULL;
714 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
715 ModestTnyAccountStore *store = modest_runtime_get_account_store();
716 GnomeVFSFileSize total_size, allowed_size;
718 /* we check for low-mem; in that case, show a warning, and don't allow
719 * composing a message with attachments
721 if (attachments && modest_platform_check_memory_low (win, TRUE))
724 account_name = modest_account_mgr_get_default_account(mgr);
726 g_printerr ("modest: no account found\n");
729 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
731 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
734 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
736 g_printerr ("modest: failed to find Drafts folder\n");
739 from_str = modest_account_mgr_get_from_string (mgr, account_name);
741 g_printerr ("modest: failed get from string for '%s'\n", account_name);
745 signature = modest_account_mgr_get_signature (mgr, account_name, &use_signature);
746 if (body_str != NULL) {
747 body = use_signature ? g_strconcat(body_str, "\n--\n", signature, NULL) : g_strdup(body_str);
749 body = use_signature ? g_strconcat("\n--\n", signature, NULL) : g_strdup("");
752 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, body, NULL, NULL, NULL);
754 g_printerr ("modest: failed to create new msg\n");
758 /* Create and register edit window */
759 /* This is destroyed by TODO. */
761 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
762 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
764 modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win);
765 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
766 gtk_widget_show_all (GTK_WIDGET (msg_win));
768 while (attachments) {
770 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
771 attachments->data, allowed_size);
773 if (total_size > allowed_size) {
774 g_warning ("%s: total size: %u",
775 __FUNCTION__, (unsigned int)total_size);
778 allowed_size -= total_size;
780 attachments = g_slist_next(attachments);
787 g_free (account_name);
789 g_object_unref (G_OBJECT(account));
791 g_object_unref (G_OBJECT(folder));
793 g_object_unref (G_OBJECT(msg));
797 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
799 /* if there are no accounts yet, just show the wizard */
800 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
801 if (!modest_ui_actions_run_account_setup_wizard (win))
804 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
809 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
813 ModestMailOperationStatus status;
815 /* If there is no message or the operation was not successful */
816 status = modest_mail_operation_get_status (mail_op);
817 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
820 /* If it's a memory low issue, then show a banner */
821 error = modest_mail_operation_get_error (mail_op);
822 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
823 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
824 GObject *source = modest_mail_operation_get_source (mail_op);
825 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
826 dgettext("ke-recv","memr_ib_operation_disabled"),
828 g_object_unref (source);
831 /* Remove the header from the preregistered uids */
832 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
850 OpenMsgBannerInfo *banner_info;
851 GHashTable *row_refs_per_header;
855 open_msg_banner_idle (gpointer userdata)
857 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
859 gdk_threads_enter ();
860 banner_info->idle_handler = 0;
861 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
863 g_object_ref (banner_info->banner);
865 gdk_threads_leave ();
872 open_msg_cb (ModestMailOperation *mail_op,
879 ModestWindowMgr *mgr = NULL;
880 ModestWindow *parent_win = NULL;
881 ModestWindow *win = NULL;
882 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
883 gchar *account = NULL;
885 gboolean open_in_editor = FALSE;
886 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
888 /* Do nothing if there was any problem with the mail
889 operation. The error will be shown by the error_handler of
890 the mail operation */
891 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
894 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
895 folder = tny_header_get_folder (header);
897 /* Mark header as read */
898 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
900 /* Gets folder type (OUTBOX headers will be opened in edit window */
901 if (modest_tny_folder_is_local_folder (folder)) {
902 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
903 if (folder_type == TNY_FOLDER_TYPE_INVALID)
904 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
908 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
909 TnyTransportAccount *traccount = NULL;
910 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
911 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
913 ModestTnySendQueue *send_queue = NULL;
914 ModestTnySendQueueStatus status;
916 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
917 TNY_ACCOUNT(traccount)));
918 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
919 if (TNY_IS_SEND_QUEUE (send_queue)) {
920 msg_id = modest_tny_send_queue_get_msg_id (header);
921 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
922 /* Only open messages in outbox with the editor if they are in Failed state */
923 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
924 open_in_editor = TRUE;
928 g_object_unref(traccount);
930 g_warning("Cannot get transport account for message in outbox!!");
932 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
933 open_in_editor = TRUE; /* Open in editor if the message is in the Drafts folder */
938 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
940 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
942 if (open_in_editor) {
943 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
944 gchar *from_header = NULL, *acc_name;
946 from_header = tny_header_dup_from (header);
948 /* we cannot edit without a valid account... */
949 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
950 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
951 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
953 g_free (from_header);
958 acc_name = modest_utils_get_account_name_from_recipient (from_header);
959 g_free (from_header);
965 win = modest_msg_edit_window_new (msg, account, TRUE);
967 gchar *uid = modest_tny_folder_get_header_unique_id (header);
969 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
970 GtkTreeRowReference *row_reference;
972 row_reference = (GtkTreeRowReference *) g_hash_table_lookup (helper->row_refs_per_header, header);
974 win = modest_msg_view_window_new_with_header_model (msg, account, (const gchar*) uid,
975 helper->model, row_reference);
977 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
982 /* Register and show new window */
984 mgr = modest_runtime_get_window_mgr ();
985 modest_window_mgr_register_window (mgr, win);
986 gtk_widget_show_all (GTK_WIDGET(win));
989 /* Update toolbar dimming state */
990 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
991 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
997 g_object_unref (parent_win);
998 g_object_unref (folder);
1002 is_memory_full_error (GError *error)
1004 gboolean enough_free_space = TRUE;
1005 GnomeVFSURI *cache_dir_uri;
1006 const gchar *cache_dir;
1007 GnomeVFSFileSize free_space;
1009 cache_dir = tny_account_store_get_cache_dir (TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
1010 cache_dir_uri = gnome_vfs_uri_new (cache_dir);
1011 if (gnome_vfs_get_volume_free_space (cache_dir_uri, &free_space) == GNOME_VFS_OK) {
1012 if (free_space < MIN_FREE_SPACE)
1013 enough_free_space = FALSE;
1015 gnome_vfs_uri_unref (cache_dir_uri);
1017 if ((error->code == TNY_SYSTEM_ERROR_MEMORY ||
1018 /* When asking for a mail and no space left on device
1019 tinymail returns this error */
1020 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE ||
1021 /* When the folder summary could not be read or
1023 error->code == TNY_IO_ERROR_WRITE ||
1024 error->code == TNY_IO_ERROR_READ) &&
1025 !enough_free_space) {
1033 check_memory_full_error (GtkWidget *parent_window, GError *err)
1038 if (is_memory_full_error (err))
1039 modest_platform_information_banner (parent_window,
1040 NULL, dgettext("ke-recv",
1041 "cerm_device_memory_full"));
1042 else if (err->code == TNY_SYSTEM_ERROR_MEMORY)
1043 /* If the account was created in memory full
1044 conditions then tinymail won't be able to
1045 connect so it'll return this error code */
1046 modest_platform_information_banner (parent_window,
1047 NULL, _("emev_ui_imap_inbox_select_error"));
1055 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1058 const GError *error;
1059 GObject *win = NULL;
1060 ModestMailOperationStatus status;
1062 win = modest_mail_operation_get_source (mail_op);
1063 error = modest_mail_operation_get_error (mail_op);
1064 status = modest_mail_operation_get_status (mail_op);
1066 /* If the mail op has been cancelled then it's not an error:
1067 don't show any message */
1068 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1069 if (is_memory_full_error ((GError *) error)) {
1070 modest_platform_information_banner ((GtkWidget *) win,
1071 NULL, dgettext("ke-recv",
1072 "cerm_device_memory_full"));
1073 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1074 modest_platform_information_banner ((GtkWidget *) win,
1075 NULL, _("emev_ui_imap_inbox_select_error"));
1076 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1077 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1078 modest_platform_information_banner ((GtkWidget *) win,
1079 NULL, dgettext ("hildon-common-strings", "sfil_ni_unable_to_open_file_not_found"));
1080 } else if (user_data) {
1081 modest_platform_information_banner ((GtkWidget *) win,
1087 g_object_unref (win);
1091 * Returns the account a list of headers belongs to. It returns a
1092 * *new* reference so don't forget to unref it
1095 get_account_from_header_list (TnyList *headers)
1097 TnyAccount *account = NULL;
1099 if (tny_list_get_length (headers) > 0) {
1100 TnyIterator *iter = tny_list_create_iterator (headers);
1101 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1102 TnyFolder *folder = tny_header_get_folder (header);
1105 g_object_unref (header);
1107 while (!tny_iterator_is_done (iter)) {
1108 header = TNY_HEADER (tny_iterator_get_current (iter));
1109 folder = tny_header_get_folder (header);
1112 g_object_unref (header);
1114 tny_iterator_next (iter);
1119 account = tny_folder_get_account (folder);
1120 g_object_unref (folder);
1124 g_object_unref (header);
1126 g_object_unref (iter);
1132 foreach_unregister_headers (gpointer data,
1135 ModestWindowMgr *mgr = (ModestWindowMgr *) user_data;
1136 TnyHeader *header = TNY_HEADER (data);
1138 modest_window_mgr_unregister_header (mgr, header);
1142 open_msgs_helper_destroyer (gpointer user_data)
1144 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1146 if (helper->banner_info) {
1147 g_free (helper->banner_info->message);
1148 if (helper->banner_info->idle_handler > 0) {
1149 g_source_remove (helper->banner_info->idle_handler);
1150 helper->banner_info->idle_handler = 0;
1152 if (helper->banner_info->banner != NULL) {
1153 gtk_widget_destroy (helper->banner_info->banner);
1154 g_object_unref (helper->banner_info->banner);
1155 helper->banner_info->banner = NULL;
1157 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1158 helper->banner_info = NULL;
1160 g_object_unref (helper->model);
1161 g_object_unref (helper->headers);
1162 g_hash_table_destroy (helper->row_refs_per_header);
1163 g_slice_free (OpenMsgHelper, helper);
1167 open_msgs_performer(gboolean canceled,
1169 GtkWindow *parent_window,
1170 TnyAccount *account,
1173 ModestMailOperation *mail_op = NULL;
1175 ModestProtocolType proto;
1176 TnyList *not_opened_headers;
1177 TnyConnectionStatus status;
1178 gboolean show_open_draft = FALSE;
1179 OpenMsgHelper *helper = NULL;
1181 helper = (OpenMsgHelper *) user_data;
1182 not_opened_headers = helper->headers;
1184 status = tny_account_get_connection_status (account);
1185 if (err || canceled) {
1186 /* Unregister the already registered headers */
1187 tny_list_foreach (not_opened_headers, foreach_unregister_headers,
1188 modest_runtime_get_window_mgr ());
1189 /* Free the helper */
1190 open_msgs_helper_destroyer (helper);
1192 /* In memory full conditions we could get this error here */
1193 check_memory_full_error ((GtkWidget *) parent_window, err);
1198 /* Get the error message depending on the protocol */
1199 proto = modest_tny_account_get_protocol_type (account);
1200 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1201 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1204 /* Create the error messages */
1205 if (tny_list_get_length (not_opened_headers) == 1) {
1206 ModestProtocol *protocol;
1207 ModestProtocolRegistry *protocol_registry;
1212 protocol_registry = modest_runtime_get_protocol_registry ();
1213 iter = tny_list_create_iterator (not_opened_headers);
1214 header = TNY_HEADER (tny_iterator_get_current (iter));
1215 subject = tny_header_dup_subject (header);
1217 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1218 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1220 g_object_unref (header);
1221 g_object_unref (iter);
1223 if (error_msg == NULL) {
1224 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1227 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1229 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1233 TnyFolderType folder_type;
1235 iter = tny_list_create_iterator (not_opened_headers);
1236 header = TNY_HEADER (tny_iterator_get_current (iter));
1237 folder = tny_header_get_folder (header);
1238 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1239 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1240 g_object_unref (folder);
1241 g_object_unref (header);
1242 g_object_unref (iter);
1245 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1248 /* Create the mail operation */
1250 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1251 modest_ui_actions_disk_operations_error_handler,
1253 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1256 if (show_open_draft) {
1257 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1258 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1259 helper->banner_info->banner = NULL;
1260 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1261 helper->banner_info);
1264 modest_mail_operation_get_msgs_full (mail_op,
1268 open_msgs_helper_destroyer);
1273 g_object_unref (mail_op);
1274 g_object_unref (account);
1278 * This function is used by both modest_ui_actions_on_open and
1279 * modest_ui_actions_on_header_activated. This way we always do the
1280 * same when trying to open messages.
1283 open_msgs_from_headers (TnyList *headers, ModestWindow *win)
1285 ModestWindowMgr *mgr = NULL;
1286 TnyIterator *iter = NULL, *iter_not_opened = NULL;
1287 TnyList *not_opened_headers = NULL;
1288 TnyHeaderFlags flags = 0;
1289 TnyAccount *account;
1290 gint uncached_msgs = 0;
1291 GtkWidget *header_view;
1292 GtkTreeModel *model;
1293 GHashTable *refs_for_headers;
1294 OpenMsgHelper *helper;
1295 GtkTreeSelection *sel;
1296 GList *sel_list = NULL, *sel_list_iter = NULL;
1298 g_return_if_fail (headers != NULL);
1300 /* Check that only one message is selected for opening */
1301 if (tny_list_get_length (headers) != 1) {
1302 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1303 NULL, _("mcen_ib_select_one_message"));
1307 mgr = modest_runtime_get_window_mgr ();
1308 iter = tny_list_create_iterator (headers);
1310 /* Get the account */
1311 account = get_account_from_header_list (headers);
1316 /* Get the selections, we need to get the references to the
1317 rows here because the treeview/model could dissapear (the
1318 user might want to select another folder)*/
1319 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1320 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1321 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
1322 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
1323 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
1324 refs_for_headers = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
1325 (GDestroyNotify) gtk_tree_row_reference_free);
1327 /* Look if we already have a message view for each header. If
1328 true, then remove the header from the list of headers to
1330 sel_list_iter = sel_list;
1331 not_opened_headers = tny_simple_list_new ();
1332 while (!tny_iterator_is_done (iter) && sel_list_iter) {
1334 ModestWindow *window = NULL;
1335 TnyHeader *header = NULL;
1336 gboolean found = FALSE;
1338 header = TNY_HEADER (tny_iterator_get_current (iter));
1340 flags = tny_header_get_flags (header);
1343 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1345 /* Do not open again the message and present the
1346 window to the user */
1349 gtk_window_present (GTK_WINDOW (window));
1351 /* the header has been registered already, we don't do
1352 * anything but wait for the window to come up*/
1353 g_debug ("header %p already registered, waiting for window", header);
1356 GtkTreeRowReference *row_reference;
1358 tny_list_append (not_opened_headers, G_OBJECT (header));
1359 /* Create a new row reference and add it to the hash table */
1360 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list_iter->data);
1361 g_hash_table_insert (refs_for_headers, header, row_reference);
1365 g_object_unref (header);
1368 tny_iterator_next (iter);
1369 sel_list_iter = g_list_next (sel_list_iter);
1371 g_object_unref (iter);
1373 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
1374 g_list_free (sel_list);
1376 /* Open each message */
1377 if (tny_list_get_length (not_opened_headers) == 0) {
1378 g_hash_table_destroy (refs_for_headers);
1382 /* If some messages would have to be downloaded, ask the user to
1383 * make a connection. It's generally easier to do this here (in the mainloop)
1384 * than later in a thread:
1386 if (tny_list_get_length (not_opened_headers) > 0) {
1387 uncached_msgs = header_list_count_uncached_msgs (not_opened_headers);
1389 if (uncached_msgs > 0) {
1390 /* Allways download if we are online. */
1391 if (!tny_device_is_online (modest_runtime_get_device ())) {
1394 /* If ask for user permission to download the messages */
1395 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1396 ngettext("mcen_nc_get_msg",
1400 /* End if the user does not want to continue */
1401 if (response == GTK_RESPONSE_CANCEL) {
1402 g_hash_table_destroy (refs_for_headers);
1409 /* Register the headers before actually creating the windows: */
1410 iter_not_opened = tny_list_create_iterator (not_opened_headers);
1411 while (!tny_iterator_is_done (iter_not_opened)) {
1412 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1414 modest_window_mgr_register_header (mgr, header, NULL);
1415 g_object_unref (header);
1417 tny_iterator_next (iter_not_opened);
1419 g_object_unref (iter_not_opened);
1420 iter_not_opened = NULL;
1422 /* Create the helper. We need to get a reference to the model
1423 here because it could change while the message is readed
1424 (the user could switch between folders) */
1425 helper = g_slice_new (OpenMsgHelper);
1426 helper->model = g_object_ref (model);
1427 helper->headers = g_object_ref (not_opened_headers);
1428 helper->row_refs_per_header = refs_for_headers;
1429 helper->banner_info = NULL;
1431 /* Connect to the account and perform */
1432 if (uncached_msgs > 0) {
1433 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1434 open_msgs_performer, helper);
1436 /* Call directly the performer, do not need to connect */
1437 open_msgs_performer (FALSE, NULL, (GtkWindow *) win,
1438 g_object_ref (account), helper);
1443 g_object_unref (account);
1444 if (not_opened_headers)
1445 g_object_unref (not_opened_headers);
1449 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1453 /* we check for low-mem; in that case, show a warning, and don't allow
1456 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1460 headers = get_selected_headers (win);
1465 open_msgs_from_headers (headers, win);
1467 g_object_unref(headers);
1470 static ReplyForwardHelper*
1471 create_reply_forward_helper (ReplyForwardAction action,
1473 guint reply_forward_type,
1476 ReplyForwardHelper *rf_helper = NULL;
1477 const gchar *active_acc = modest_window_get_active_account (win);
1479 rf_helper = g_slice_new0 (ReplyForwardHelper);
1480 rf_helper->reply_forward_type = reply_forward_type;
1481 rf_helper->action = action;
1482 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1483 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1484 rf_helper->account_name = (active_acc) ?
1485 g_strdup (active_acc) :
1486 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1492 free_reply_forward_helper (gpointer data)
1494 ReplyForwardHelper *helper;
1496 helper = (ReplyForwardHelper *) data;
1497 g_free (helper->account_name);
1499 g_object_unref (helper->header);
1500 g_slice_free (ReplyForwardHelper, helper);
1504 reply_forward_cb (ModestMailOperation *mail_op,
1511 TnyMsg *new_msg = NULL;
1512 ReplyForwardHelper *rf_helper;
1513 ModestWindow *msg_win = NULL;
1514 ModestEditType edit_type;
1516 TnyAccount *account = NULL;
1517 ModestWindowMgr *mgr = NULL;
1518 gchar *signature = NULL;
1519 gboolean use_signature;
1521 /* If there was any error. The mail operation could be NULL,
1522 this means that we already have the message downloaded and
1523 that we didn't do a mail operation to retrieve it */
1524 rf_helper = (ReplyForwardHelper *) user_data;
1525 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1528 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1529 rf_helper->account_name);
1530 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr(),
1531 rf_helper->account_name,
1534 /* Create reply mail */
1535 switch (rf_helper->action) {
1538 modest_tny_msg_create_reply_msg (msg, header, from,
1539 (use_signature) ? signature : NULL,
1540 rf_helper->reply_forward_type,
1541 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1543 case ACTION_REPLY_TO_ALL:
1545 modest_tny_msg_create_reply_msg (msg, header, from,
1546 (use_signature) ? signature : NULL,
1547 rf_helper->reply_forward_type,
1548 MODEST_TNY_MSG_REPLY_MODE_ALL);
1549 edit_type = MODEST_EDIT_TYPE_REPLY;
1551 case ACTION_FORWARD:
1553 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1554 rf_helper->reply_forward_type);
1555 edit_type = MODEST_EDIT_TYPE_FORWARD;
1558 g_return_if_reached ();
1566 g_warning ("%s: failed to create message\n", __FUNCTION__);
1570 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1571 rf_helper->account_name,
1572 TNY_ACCOUNT_TYPE_STORE);
1574 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1578 /* Create and register the windows */
1579 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1580 mgr = modest_runtime_get_window_mgr ();
1581 modest_window_mgr_register_window (mgr, msg_win);
1583 if (rf_helper->parent_window != NULL) {
1584 gdouble parent_zoom;
1586 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1587 modest_window_set_zoom (msg_win, parent_zoom);
1590 /* Show edit window */
1591 gtk_widget_show_all (GTK_WIDGET (msg_win));
1595 g_object_unref (G_OBJECT (new_msg));
1597 g_object_unref (G_OBJECT (account));
1598 free_reply_forward_helper (rf_helper);
1601 /* Checks a list of headers. If any of them are not currently
1602 * downloaded (CACHED) then returns TRUE else returns FALSE.
1605 header_list_count_uncached_msgs (TnyList *header_list)
1608 gint uncached_messages = 0;
1610 iter = tny_list_create_iterator (header_list);
1611 while (!tny_iterator_is_done (iter)) {
1614 header = TNY_HEADER (tny_iterator_get_current (iter));
1616 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1617 uncached_messages ++;
1618 g_object_unref (header);
1621 tny_iterator_next (iter);
1623 g_object_unref (iter);
1625 return uncached_messages;
1628 /* Returns FALSE if the user does not want to download the
1629 * messages. Returns TRUE if the user allowed the download.
1632 connect_to_get_msg (ModestWindow *win,
1633 gint num_of_uncached_msgs,
1634 TnyAccount *account)
1636 GtkResponseType response;
1638 /* Allways download if we are online. */
1639 if (tny_device_is_online (modest_runtime_get_device ()))
1642 /* If offline, then ask for user permission to download the messages */
1643 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1644 ngettext("mcen_nc_get_msg",
1646 num_of_uncached_msgs));
1648 if (response == GTK_RESPONSE_CANCEL)
1651 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1655 reply_forward_performer (gboolean canceled,
1657 GtkWindow *parent_window,
1658 TnyAccount *account,
1661 ReplyForwardHelper *rf_helper = NULL;
1662 ModestMailOperation *mail_op;
1664 rf_helper = (ReplyForwardHelper *) user_data;
1666 if (canceled || err) {
1667 free_reply_forward_helper (rf_helper);
1671 /* Retrieve the message */
1672 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1673 modest_ui_actions_disk_operations_error_handler,
1675 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1676 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1679 g_object_unref(mail_op);
1683 * Common code for the reply and forward actions
1686 reply_forward (ReplyForwardAction action, ModestWindow *win)
1688 ReplyForwardHelper *rf_helper = NULL;
1689 guint reply_forward_type;
1691 g_return_if_fail (MODEST_IS_WINDOW(win));
1693 /* we check for low-mem; in that case, show a warning, and don't allow
1694 * reply/forward (because it could potentially require a lot of memory */
1695 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1699 /* we need an account when editing */
1700 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1701 if (!modest_ui_actions_run_account_setup_wizard (win))
1705 reply_forward_type =
1706 modest_conf_get_int (modest_runtime_get_conf (),
1707 (action == ACTION_FORWARD) ?
1708 MODEST_CONF_FORWARD_TYPE :
1709 MODEST_CONF_REPLY_TYPE,
1712 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1714 TnyHeader *header = NULL;
1715 /* Get header and message. Do not free them here, the
1716 reply_forward_cb must do it */
1717 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1718 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1720 if (msg && header) {
1722 rf_helper = create_reply_forward_helper (action, win,
1723 reply_forward_type, header);
1724 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1726 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1730 g_object_unref (msg);
1732 g_object_unref (header);
1734 TnyHeader *header = NULL;
1736 gboolean do_retrieve = TRUE;
1737 TnyList *header_list = NULL;
1739 header_list = get_selected_headers (win);
1742 /* Check that only one message is selected for replying */
1743 if (tny_list_get_length (header_list) != 1) {
1744 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1745 NULL, _("mcen_ib_select_one_message"));
1746 g_object_unref (header_list);
1750 /* Only reply/forward to one message */
1751 iter = tny_list_create_iterator (header_list);
1752 header = TNY_HEADER (tny_iterator_get_current (iter));
1753 g_object_unref (iter);
1755 /* Retrieve messages */
1756 do_retrieve = (action == ACTION_FORWARD) ||
1757 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1760 TnyAccount *account = NULL;
1761 TnyFolder *folder = NULL;
1762 gdouble download = TRUE;
1763 guint uncached_msgs = 0;
1765 folder = tny_header_get_folder (header);
1767 goto do_retrieve_frees;
1768 account = tny_folder_get_account (folder);
1770 goto do_retrieve_frees;
1772 uncached_msgs = header_list_count_uncached_msgs (header_list);
1774 if (uncached_msgs > 0) {
1775 /* Allways download if we are online. */
1776 if (!tny_device_is_online (modest_runtime_get_device ())) {
1779 /* If ask for user permission to download the messages */
1780 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1781 ngettext("mcen_nc_get_msg",
1785 /* End if the user does not want to continue */
1786 if (response == GTK_RESPONSE_CANCEL)
1793 rf_helper = create_reply_forward_helper (action, win,
1794 reply_forward_type, header);
1795 if (uncached_msgs > 0) {
1796 modest_platform_connect_and_perform (GTK_WINDOW (win),
1798 reply_forward_performer,
1801 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
1802 account, rf_helper);
1807 g_object_unref (account);
1809 g_object_unref (folder);
1811 reply_forward_cb (NULL, header, FALSE, NULL, NULL, rf_helper);
1814 g_object_unref (header_list);
1815 g_object_unref (header);
1820 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1822 g_return_if_fail (MODEST_IS_WINDOW(win));
1824 reply_forward (ACTION_REPLY, win);
1828 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1830 g_return_if_fail (MODEST_IS_WINDOW(win));
1832 reply_forward (ACTION_FORWARD, win);
1836 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1838 g_return_if_fail (MODEST_IS_WINDOW(win));
1840 reply_forward (ACTION_REPLY_TO_ALL, win);
1844 modest_ui_actions_on_next (GtkAction *action,
1845 ModestWindow *window)
1847 if (MODEST_IS_MAIN_WINDOW (window)) {
1848 GtkWidget *header_view;
1850 header_view = modest_main_window_get_child_widget (
1851 MODEST_MAIN_WINDOW(window),
1852 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1856 modest_header_view_select_next (
1857 MODEST_HEADER_VIEW(header_view));
1858 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1859 modest_msg_view_window_select_next_message (
1860 MODEST_MSG_VIEW_WINDOW (window));
1862 g_return_if_reached ();
1867 modest_ui_actions_on_prev (GtkAction *action,
1868 ModestWindow *window)
1870 g_return_if_fail (MODEST_IS_WINDOW(window));
1872 if (MODEST_IS_MAIN_WINDOW (window)) {
1873 GtkWidget *header_view;
1874 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1875 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1879 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1880 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1881 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1883 g_return_if_reached ();
1888 modest_ui_actions_on_sort (GtkAction *action,
1889 ModestWindow *window)
1891 g_return_if_fail (MODEST_IS_WINDOW(window));
1893 if (MODEST_IS_MAIN_WINDOW (window)) {
1894 GtkWidget *header_view;
1895 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1896 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1898 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1903 /* Show sorting dialog */
1904 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1909 new_messages_arrived (ModestMailOperation *self,
1910 TnyList *new_headers,
1914 gboolean show_visual_notifications;
1916 source = modest_mail_operation_get_source (self);
1917 show_visual_notifications = (source) ? FALSE : TRUE;
1919 g_object_unref (source);
1921 /* Notify new messages have been downloaded. If the
1922 send&receive was invoked by the user then do not show any
1923 visual notification, only play a sound and activate the LED
1924 (for the Maemo version) */
1925 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0)
1926 modest_platform_on_new_headers_received (new_headers,
1927 show_visual_notifications);
1932 retrieve_all_messages_cb (GObject *source,
1934 guint retrieve_limit)
1940 window = GTK_WINDOW (source);
1941 msg = g_strdup_printf (_("mail_nc_msg_count_limit_exceeded"),
1942 num_msgs, retrieve_limit);
1944 /* Ask the user if they want to retrieve all the messages */
1946 modest_platform_run_confirmation_dialog_with_buttons (window, msg,
1947 _("mcen_bd_get_all"),
1948 _("mcen_bd_newest_only"));
1949 /* Free and return */
1951 return (response == GTK_RESPONSE_ACCEPT) ? TRUE : FALSE;
1955 TnyAccount *account;
1957 gchar *account_name;
1958 gboolean poke_status;
1959 gboolean interactive;
1960 ModestMailOperation *mail_op;
1964 do_send_receive_performer (gboolean canceled,
1966 GtkWindow *parent_window,
1967 TnyAccount *account,
1970 SendReceiveInfo *info;
1972 info = (SendReceiveInfo *) user_data;
1974 if (err || canceled) {
1975 /* In memory full conditions we could get this error here */
1976 check_memory_full_error ((GtkWidget *) parent_window, err);
1978 if (info->mail_op) {
1979 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
1985 /* Set send/receive operation in progress */
1986 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
1987 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
1990 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
1991 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
1992 G_CALLBACK (on_send_receive_finished),
1995 /* Send & receive. */
1996 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
1997 (info->win) ? retrieve_all_messages_cb : NULL,
1998 new_messages_arrived, info->win);
2003 g_object_unref (G_OBJECT (info->mail_op));
2004 if (info->account_name)
2005 g_free (info->account_name);
2007 g_object_unref (info->win);
2009 g_object_unref (info->account);
2010 g_slice_free (SendReceiveInfo, info);
2014 * This function performs the send & receive required actions. The
2015 * window is used to create the mail operation. Typically it should
2016 * always be the main window, but we pass it as argument in order to
2020 modest_ui_actions_do_send_receive (const gchar *account_name,
2021 gboolean force_connection,
2022 gboolean poke_status,
2023 gboolean interactive,
2026 gchar *acc_name = NULL;
2027 SendReceiveInfo *info;
2028 ModestTnyAccountStore *acc_store;
2030 /* If no account name was provided then get the current account, and if
2031 there is no current account then pick the default one: */
2032 if (!account_name) {
2034 acc_name = g_strdup (modest_window_get_active_account (win));
2036 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2038 g_printerr ("modest: cannot get default account\n");
2042 acc_name = g_strdup (account_name);
2045 acc_store = modest_runtime_get_account_store ();
2047 /* Create the info for the connect and perform */
2048 info = g_slice_new (SendReceiveInfo);
2049 info->account_name = acc_name;
2050 info->win = (win) ? g_object_ref (win) : NULL;
2051 info->poke_status = poke_status;
2052 info->interactive = interactive;
2053 info->account = modest_tny_account_store_get_server_account (acc_store, acc_name,
2054 TNY_ACCOUNT_TYPE_STORE);
2055 /* We need to create the operation here, because otherwise it
2056 could happen that the queue emits the queue-empty signal
2057 while we're trying to connect the account */
2058 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2059 modest_ui_actions_disk_operations_error_handler,
2061 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2063 /* Invoke the connect and perform */
2064 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2065 force_connection, info->account,
2066 do_send_receive_performer, info);
2071 modest_ui_actions_do_cancel_send (const gchar *account_name,
2074 TnyTransportAccount *transport_account;
2075 TnySendQueue *send_queue = NULL;
2076 GError *error = NULL;
2078 /* Get transport account */
2080 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2081 (modest_runtime_get_account_store(),
2083 TNY_ACCOUNT_TYPE_TRANSPORT));
2084 if (!transport_account) {
2085 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2090 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2091 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2092 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2093 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2094 "modest: could not find send queue for account\n");
2096 /* Cancel the current send */
2097 tny_account_cancel (TNY_ACCOUNT (transport_account));
2099 /* Suspend all pending messages */
2100 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2104 if (transport_account != NULL)
2105 g_object_unref (G_OBJECT (transport_account));
2109 modest_ui_actions_cancel_send_all (ModestWindow *win)
2111 GSList *account_names, *iter;
2113 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2116 iter = account_names;
2118 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2119 iter = g_slist_next (iter);
2122 modest_account_mgr_free_account_names (account_names);
2123 account_names = NULL;
2127 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2130 /* Check if accounts exist */
2131 gboolean accounts_exist =
2132 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2134 /* If not, allow the user to create an account before trying to send/receive. */
2135 if (!accounts_exist)
2136 modest_ui_actions_on_accounts (NULL, win);
2138 /* Cancel all sending operaitons */
2139 modest_ui_actions_cancel_send_all (win);
2143 * Refreshes all accounts. This function will be used by automatic
2147 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2148 gboolean force_connection,
2149 gboolean poke_status,
2150 gboolean interactive)
2152 GSList *account_names, *iter;
2154 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2157 iter = account_names;
2159 modest_ui_actions_do_send_receive ((const char*) iter->data,
2161 poke_status, interactive, win);
2162 iter = g_slist_next (iter);
2165 modest_account_mgr_free_account_names (account_names);
2166 account_names = NULL;
2170 * Handler of the click on Send&Receive button in the main toolbar
2173 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2175 /* Check if accounts exist */
2176 gboolean accounts_exist;
2179 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2181 /* If not, allow the user to create an account before trying to send/receive. */
2182 if (!accounts_exist)
2183 modest_ui_actions_on_accounts (NULL, win);
2185 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2186 if (MODEST_IS_MAIN_WINDOW (win)) {
2187 GtkWidget *folder_view;
2188 TnyFolderStore *folder_store;
2191 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2192 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2196 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2199 g_object_unref (folder_store);
2202 /* Refresh the active account. Force the connection if needed
2203 and poke the status of all folders */
2204 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2209 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2212 GtkWidget *header_view;
2214 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2216 header_view = modest_main_window_get_child_widget (main_window,
2217 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2221 conf = modest_runtime_get_conf ();
2223 /* what is saved/restored is depending on the style; thus; we save with
2224 * old style, then update the style, and restore for this new style
2226 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2228 if (modest_header_view_get_style
2229 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2230 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2231 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2233 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2234 MODEST_HEADER_VIEW_STYLE_DETAILS);
2236 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2237 MODEST_CONF_HEADER_VIEW_KEY);
2242 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2244 ModestMainWindow *main_window)
2246 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2247 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2249 /* in the case the folder is empty, show the empty folder message and focus
2251 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2252 if (modest_header_view_is_empty (header_view)) {
2253 TnyFolder *folder = modest_header_view_get_folder (header_view);
2254 GtkWidget *folder_view =
2255 modest_main_window_get_child_widget (main_window,
2256 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2257 if (folder != NULL) {
2258 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2259 g_object_unref (folder);
2261 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2265 /* If no header has been selected then exit */
2270 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2271 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2273 /* Update toolbar dimming state */
2274 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2275 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2279 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2281 ModestMainWindow *main_window)
2284 GtkWidget *open_widget;
2286 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2291 if (modest_header_view_count_selected_headers (header_view) > 1) {
2292 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2296 /* we check for low-mem; in that case, show a warning, and don't allow
2297 * activating headers
2299 if (modest_platform_check_memory_low (MODEST_WINDOW(main_window), TRUE))
2302 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2303 open_widget = modest_window_get_action_widget (MODEST_WINDOW (main_window), "/MenuBar/EmailMenu/EmailOpenMenu");
2304 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2307 headers = modest_header_view_get_selected_headers (header_view);
2309 open_msgs_from_headers (headers, MODEST_WINDOW (main_window));
2311 g_object_unref (headers);
2315 set_active_account_from_tny_account (TnyAccount *account,
2316 ModestWindow *window)
2318 const gchar *server_acc_name = tny_account_get_id (account);
2320 /* We need the TnyAccount provided by the
2321 account store because that is the one that
2322 knows the name of the Modest account */
2323 TnyAccount *modest_server_account = modest_server_account =
2324 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2325 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2327 if (!modest_server_account) {
2328 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2332 /* Update active account, but only if it's not a pseudo-account */
2333 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2334 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2335 const gchar *modest_acc_name =
2336 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2337 if (modest_acc_name)
2338 modest_window_set_active_account (window, modest_acc_name);
2341 g_object_unref (modest_server_account);
2346 folder_refreshed_cb (ModestMailOperation *mail_op,
2350 ModestMainWindow *win = NULL;
2351 GtkWidget *folder_view;
2352 const GError *error;
2354 g_return_if_fail (TNY_IS_FOLDER (folder));
2356 win = MODEST_MAIN_WINDOW (user_data);
2358 /* Check if the operation failed due to memory low conditions */
2359 error = modest_mail_operation_get_error (mail_op);
2360 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2361 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2362 modest_platform_run_information_dialog (GTK_WINDOW (win),
2363 dgettext("ke-recv","memr_ib_operation_disabled"),
2369 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2372 TnyFolderStore *current_folder;
2374 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2375 if (current_folder) {
2376 gboolean different = ((TnyFolderStore *) folder != current_folder);
2377 g_object_unref (current_folder);
2383 /* Check if folder is empty and set headers view contents style */
2384 if (tny_folder_get_all_count (folder) == 0)
2385 modest_main_window_set_contents_style (win,
2386 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2391 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2392 TnyFolderStore *folder_store,
2394 ModestMainWindow *main_window)
2397 GtkWidget *header_view;
2399 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2401 header_view = modest_main_window_get_child_widget(main_window,
2402 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2406 conf = modest_runtime_get_conf ();
2408 if (TNY_IS_ACCOUNT (folder_store)) {
2410 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2412 /* Show account details */
2413 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2416 if (TNY_IS_FOLDER (folder_store) && selected) {
2417 TnyAccount *account;
2418 const gchar *account_name = NULL;
2420 /* Update the active account */
2421 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2423 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2425 modest_tny_account_get_parent_modest_account_name_for_server_account (account);
2426 g_object_unref (account);
2430 /* Set the header style by default, it could
2431 be changed later by the refresh callback to
2433 modest_main_window_set_contents_style (main_window,
2434 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2436 /* Set folder on header view. This function
2437 will call tny_folder_refresh_async so we
2438 pass a callback that will be called when
2439 finished. We use that callback to set the
2440 empty view if there are no messages */
2441 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2442 TNY_FOLDER (folder_store),
2444 folder_refreshed_cb,
2447 /* Restore configuration. We need to do this
2448 *after* the set_folder because the widget
2449 memory asks the header view about its
2451 modest_widget_memory_restore (modest_runtime_get_conf (),
2452 G_OBJECT(header_view),
2453 MODEST_CONF_HEADER_VIEW_KEY);
2455 /* No need to save the header view
2456 configuration for Maemo because it only
2457 saves the sorting stuff and that it's
2458 already being done by the sort
2459 dialog. Remove it when the GNOME version
2460 has the same behaviour */
2461 #ifdef MODEST_TOOLKIT_GTK
2462 if (modest_main_window_get_contents_style (main_window) ==
2463 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2464 modest_widget_memory_save (conf, G_OBJECT (header_view),
2465 MODEST_CONF_HEADER_VIEW_KEY);
2467 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2471 /* Update dimming state */
2472 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2473 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2477 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2484 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2486 online = tny_device_is_online (modest_runtime_get_device());
2489 /* already online -- the item is simply not there... */
2490 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2492 GTK_MESSAGE_WARNING,
2494 _("The %s you selected cannot be found"),
2496 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2497 gtk_dialog_run (GTK_DIALOG(dialog));
2499 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2502 _("mcen_bd_dialog_cancel"),
2503 GTK_RESPONSE_REJECT,
2504 _("mcen_bd_dialog_ok"),
2505 GTK_RESPONSE_ACCEPT,
2507 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2508 "Do you want to get online?"), item);
2509 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2510 gtk_label_new (txt), FALSE, FALSE, 0);
2511 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2514 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2515 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2516 /* TODO: Comment about why is this commented out: */
2517 /* modest_platform_connect_and_wait (); */
2520 gtk_widget_destroy (dialog);
2524 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2527 /* g_message ("%s %s", __FUNCTION__, link); */
2532 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2535 modest_platform_activate_uri (link);
2539 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2542 modest_platform_show_uri_popup (link);
2546 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2549 /* we check for low-mem; in that case, show a warning, and don't allow
2550 * viewing attachments
2552 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2555 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2559 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2560 const gchar *address,
2563 /* g_message ("%s %s", __FUNCTION__, address); */
2567 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2568 TnyMsg *saved_draft,
2571 ModestMsgEditWindow *edit_window;
2572 ModestMainWindow *win;
2574 /* FIXME. Make the header view sensitive again. This is a
2575 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2577 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2578 modest_runtime_get_window_mgr(), FALSE));
2580 GtkWidget *hdrview = modest_main_window_get_child_widget(
2581 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2582 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2585 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2587 /* Set draft is there was no error */
2588 if (!modest_mail_operation_get_error (mail_op))
2589 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2591 g_object_unref(edit_window);
2595 enough_space_for_message (ModestMsgEditWindow *edit_window,
2598 TnyAccountStore *acc_store;
2599 guint64 available_disk, expected_size;
2604 acc_store = TNY_ACCOUNT_STORE (modest_runtime_get_account_store());
2605 available_disk = modest_utils_get_available_space (NULL);
2606 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2607 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2612 /* Double check: memory full condition or message too big */
2613 if (available_disk < MIN_FREE_SPACE ||
2614 expected_size > available_disk) {
2616 modest_platform_information_banner (NULL, NULL,
2618 "cerm_device_memory_full"));
2623 * djcb: if we're in low-memory state, we only allow for
2624 * saving messages smaller than
2625 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2626 * should still allow for sending anything critical...
2628 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2629 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2633 * djcb: we also make sure that the attachments are smaller than the max size
2634 * this is for the case where we'd try to forward a message with attachments
2635 * bigger than our max allowed size, or sending an message from drafts which
2636 * somehow got past our checks when attaching.
2638 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2639 modest_platform_run_information_dialog (
2640 GTK_WINDOW(edit_window),
2641 dgettext("ke-recv","memr_ib_operation_disabled"),
2650 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2652 TnyTransportAccount *transport_account;
2653 ModestMailOperation *mail_operation;
2655 gchar *account_name, *from;
2656 ModestAccountMgr *account_mgr;
2657 gboolean had_error = FALSE;
2658 ModestMainWindow *win;
2660 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2662 data = modest_msg_edit_window_get_msg_data (edit_window);
2665 if (!enough_space_for_message (edit_window, data)) {
2666 modest_msg_edit_window_free_msg_data (edit_window, data);
2670 account_name = g_strdup (data->account_name);
2671 account_mgr = modest_runtime_get_account_mgr();
2673 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2675 account_name = modest_account_mgr_get_default_account (account_mgr);
2676 if (!account_name) {
2677 g_printerr ("modest: no account found\n");
2678 modest_msg_edit_window_free_msg_data (edit_window, data);
2682 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2683 account_name = g_strdup (data->account_name);
2687 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2688 (modest_runtime_get_account_store (),
2690 TNY_ACCOUNT_TYPE_TRANSPORT));
2691 if (!transport_account) {
2692 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2693 g_free (account_name);
2694 modest_msg_edit_window_free_msg_data (edit_window, data);
2697 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2699 /* Create the mail operation */
2700 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
2702 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2704 modest_mail_operation_save_to_drafts (mail_operation,
2716 data->priority_flags,
2717 on_save_to_drafts_cb,
2718 g_object_ref(edit_window));
2720 /* Use the main window as the parent of the banner, if the
2721 main window does not exist it won't be shown, if the parent
2722 window exists then it's properly shown. We don't use the
2723 editor window because it could be closed (save to drafts
2724 could happen after closing the window */
2725 win = (ModestMainWindow *)
2726 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
2728 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2729 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
2732 modest_msg_edit_window_set_modified (edit_window, FALSE);
2736 g_free (account_name);
2737 g_object_unref (G_OBJECT (transport_account));
2738 g_object_unref (G_OBJECT (mail_operation));
2740 modest_msg_edit_window_free_msg_data (edit_window, data);
2743 * If the drafts folder is selected then make the header view
2744 * insensitive while the message is being saved to drafts
2745 * (it'll be sensitive again in on_save_to_drafts_cb()). This
2746 * is not very clean but it avoids letting the drafts folder
2747 * in an inconsistent state: the user could edit the message
2748 * being saved and undesirable things would happen.
2749 * In the average case the user won't notice anything at
2750 * all. In the worst case (the user is editing a really big
2751 * file from Drafts) the header view will be insensitive
2752 * during the saving process (10 or 20 seconds, depending on
2753 * the message). Anyway this is just a quick workaround: once
2754 * we find a better solution it should be removed
2755 * See NB#65125 (commend #18) for details.
2757 if (!had_error && win != NULL) {
2758 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
2759 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
2761 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
2763 if (modest_tny_folder_is_local_folder(folder)) {
2764 TnyFolderType folder_type;
2765 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
2766 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
2767 GtkWidget *hdrview = modest_main_window_get_child_widget(
2768 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2769 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
2773 if (folder != NULL) g_object_unref(folder);
2780 /* For instance, when clicking the Send toolbar button when editing a message: */
2782 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2784 TnyTransportAccount *transport_account = NULL;
2785 gboolean had_error = FALSE;
2787 ModestAccountMgr *account_mgr;
2788 gchar *account_name;
2790 ModestMailOperation *mail_operation;
2792 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
2794 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2797 data = modest_msg_edit_window_get_msg_data (edit_window);
2800 if (!enough_space_for_message (edit_window, data)) {
2801 modest_msg_edit_window_free_msg_data (edit_window, data);
2805 account_mgr = modest_runtime_get_account_mgr();
2806 account_name = g_strdup (data->account_name);
2808 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2811 account_name = modest_account_mgr_get_default_account (account_mgr);
2813 if (!account_name) {
2814 modest_msg_edit_window_free_msg_data (edit_window, data);
2815 /* Run account setup wizard */
2816 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
2821 /* Get the currently-active transport account for this modest account: */
2822 if (strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
2824 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2825 (modest_runtime_get_account_store (),
2826 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
2829 if (!transport_account) {
2830 modest_msg_edit_window_free_msg_data (edit_window, data);
2831 /* Run account setup wizard */
2832 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2837 /* Create the mail operation */
2838 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2839 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
2840 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2842 modest_mail_operation_send_new_mail (mail_operation,
2854 data->priority_flags);
2856 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
2857 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2860 if (modest_mail_operation_get_error (mail_operation) != NULL) {
2861 const GError *error = modest_mail_operation_get_error (mail_operation);
2862 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
2863 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
2864 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
2865 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
2872 g_free (account_name);
2873 g_object_unref (G_OBJECT (transport_account));
2874 g_object_unref (G_OBJECT (mail_operation));
2876 modest_msg_edit_window_free_msg_data (edit_window, data);
2879 modest_msg_edit_window_set_sent (edit_window, TRUE);
2881 /* Save settings and close the window: */
2882 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2889 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2890 ModestMsgEditWindow *window)
2892 ModestMsgEditFormatState *format_state = NULL;
2894 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2895 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2897 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2900 format_state = modest_msg_edit_window_get_format_state (window);
2901 g_return_if_fail (format_state != NULL);
2903 format_state->bold = gtk_toggle_action_get_active (action);
2904 modest_msg_edit_window_set_format_state (window, format_state);
2905 g_free (format_state);
2910 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2911 ModestMsgEditWindow *window)
2913 ModestMsgEditFormatState *format_state = NULL;
2915 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2916 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2918 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2921 format_state = modest_msg_edit_window_get_format_state (window);
2922 g_return_if_fail (format_state != NULL);
2924 format_state->italics = gtk_toggle_action_get_active (action);
2925 modest_msg_edit_window_set_format_state (window, format_state);
2926 g_free (format_state);
2931 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2932 ModestMsgEditWindow *window)
2934 ModestMsgEditFormatState *format_state = NULL;
2936 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2937 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2939 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2942 format_state = modest_msg_edit_window_get_format_state (window);
2943 g_return_if_fail (format_state != NULL);
2945 format_state->bullet = gtk_toggle_action_get_active (action);
2946 modest_msg_edit_window_set_format_state (window, format_state);
2947 g_free (format_state);
2952 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2953 GtkRadioAction *selected,
2954 ModestMsgEditWindow *window)
2956 ModestMsgEditFormatState *format_state = NULL;
2957 GtkJustification value;
2959 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2961 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2964 value = gtk_radio_action_get_current_value (selected);
2966 format_state = modest_msg_edit_window_get_format_state (window);
2967 g_return_if_fail (format_state != NULL);
2969 format_state->justification = value;
2970 modest_msg_edit_window_set_format_state (window, format_state);
2971 g_free (format_state);
2975 modest_ui_actions_on_select_editor_color (GtkAction *action,
2976 ModestMsgEditWindow *window)
2978 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2979 g_return_if_fail (GTK_IS_ACTION (action));
2981 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2984 modest_msg_edit_window_select_color (window);
2988 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2989 ModestMsgEditWindow *window)
2991 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2992 g_return_if_fail (GTK_IS_ACTION (action));
2994 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2997 modest_msg_edit_window_select_background_color (window);
3001 modest_ui_actions_on_insert_image (GtkAction *action,
3002 ModestMsgEditWindow *window)
3004 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3005 g_return_if_fail (GTK_IS_ACTION (action));
3008 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3011 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3014 modest_msg_edit_window_insert_image (window);
3018 modest_ui_actions_on_attach_file (GtkAction *action,
3019 ModestMsgEditWindow *window)
3021 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3022 g_return_if_fail (GTK_IS_ACTION (action));
3024 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3027 modest_msg_edit_window_offer_attach_file (window);
3031 modest_ui_actions_on_remove_attachments (GtkAction *action,
3032 ModestMsgEditWindow *window)
3034 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3035 g_return_if_fail (GTK_IS_ACTION (action));
3037 modest_msg_edit_window_remove_attachments (window, NULL);
3041 #ifndef MODEST_TOOLKIT_GTK
3046 TnyFolderStore *folder;
3047 } CreateFolderHelper;
3050 show_create_folder_in_timeout (gpointer data)
3052 CreateFolderHelper *helper = (CreateFolderHelper *) data;
3054 /* Remove the timeout ASAP, we can not wait until the dialog
3055 is shown because it could take a lot of time and so the
3056 timeout could be called twice or more times */
3057 g_source_remove (helper->handler);
3059 gdk_threads_enter ();
3060 do_create_folder (helper->win, helper->folder, helper->name);
3061 gdk_threads_leave ();
3063 g_object_unref (helper->win);
3064 g_object_unref (helper->folder);
3065 g_free (helper->name);
3066 g_slice_free (CreateFolderHelper, helper);
3073 do_create_folder_cb (ModestMailOperation *mail_op,
3074 TnyFolderStore *parent_folder,
3075 TnyFolder *new_folder,
3078 gchar *suggested_name = (gchar *) user_data;
3079 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3081 if (modest_mail_operation_get_error (mail_op)) {
3083 /* Show an error. If there was some problem writing to
3084 disk, show it, otherwise show the generic folder
3085 create error. We do it here and not in an error
3086 handler because the call to do_create_folder will
3087 stop the main loop in a gtk_dialog_run and then,
3088 the message won't be shown until that dialog is
3090 modest_ui_actions_disk_operations_error_handler (mail_op,
3091 _("mail_in_ui_folder_create_error"));
3093 /* Try again. Do *NOT* show any error because the mail
3094 operations system will do it for us because we
3095 created the mail_op with new_with_error_handler */
3096 #ifndef MODEST_TOOLKIT_GTK
3097 CreateFolderHelper *helper;
3098 helper = g_slice_new0 (CreateFolderHelper);
3099 helper->name = g_strdup (suggested_name);
3100 helper->folder = g_object_ref (parent_folder);
3101 helper->win = g_object_ref (source_win);
3103 /* Ugly but neccesary stuff. The problem is that the
3104 dialog when is shown calls a function that destroys
3105 all the temporary windows, so the banner is
3107 helper->handler = g_timeout_add (2000, show_create_folder_in_timeout, helper);
3109 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3112 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3113 * FIXME: any other? */
3114 GtkWidget *folder_view;
3116 if (MODEST_IS_MAIN_WINDOW(source_win))
3118 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3119 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3122 get_folder_view_from_move_to_dialog (GTK_WIDGET(source_win));
3124 /* Select the newly created folder. It could happen
3125 that the widget is no longer there (i.e. the window
3126 has been destroyed, so we need to check this */
3128 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3130 g_object_unref (new_folder);
3132 /* Free. Note that the first time it'll be NULL so noop */
3133 g_free (suggested_name);
3134 g_object_unref (source_win);
3138 do_create_folder (GtkWindow *parent_window,
3139 TnyFolderStore *parent_folder,
3140 const gchar *suggested_name)
3143 gchar *folder_name = NULL;
3145 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3147 (gchar *) suggested_name,
3150 if (result == GTK_RESPONSE_ACCEPT) {
3151 ModestMailOperation *mail_op;
3153 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3154 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3156 modest_mail_operation_create_folder (mail_op,
3158 (const gchar *) folder_name,
3159 do_create_folder_cb,
3161 g_object_unref (mail_op);
3166 create_folder_performer (gboolean canceled,
3168 GtkWindow *parent_window,
3169 TnyAccount *account,
3172 TnyFolderStore *parent_folder = TNY_FOLDER_STORE (user_data);
3174 if (canceled || err) {
3175 /* In memory full conditions we could get this error here */
3176 check_memory_full_error ((GtkWidget *) parent_window, err);
3180 /* Run the new folder dialog */
3181 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3184 g_object_unref (parent_folder);
3188 modest_ui_actions_create_folder(GtkWidget *parent_window,
3189 GtkWidget *folder_view)
3191 TnyFolderStore *parent_folder;
3193 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3195 if (parent_folder) {
3196 /* The parent folder will be freed in the callback */
3197 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3200 create_folder_performer,
3206 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
3208 GtkWidget *folder_view;
3210 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3212 folder_view = modest_main_window_get_child_widget (main_window,
3213 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3217 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
3221 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3224 const GError *error = NULL;
3225 const gchar *message = NULL;
3227 /* Get error message */
3228 error = modest_mail_operation_get_error (mail_op);
3230 g_return_if_reached ();
3232 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3233 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3234 message = _CS("ckdg_ib_folder_already_exists");
3235 } else if (error->domain == TNY_ERROR_DOMAIN &&
3236 error->code == TNY_SERVICE_ERROR_STATE) {
3237 /* This means that the folder is already in use (a
3238 message is opened for example */
3239 message = _("emev_ni_internal_error");
3241 message = _("emev_ib_ui_imap_unable_to_rename");
3244 /* We don't set a parent for the dialog because the dialog
3245 will be destroyed so the banner won't appear */
3246 modest_platform_information_banner (NULL, NULL, message);
3250 TnyFolderStore *folder;
3255 on_rename_folder_cb (ModestMailOperation *mail_op,
3256 TnyFolder *new_folder,
3259 ModestFolderView *folder_view;
3261 /* If the window was closed when renaming a folder this could
3263 if (!MODEST_IS_FOLDER_VIEW (user_data))
3266 folder_view = MODEST_FOLDER_VIEW (user_data);
3267 /* Note that if the rename fails new_folder will be NULL */
3269 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3271 modest_folder_view_select_first_inbox_or_local (folder_view);
3273 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3277 on_rename_folder_performer (gboolean canceled,
3279 GtkWindow *parent_window,
3280 TnyAccount *account,
3283 ModestMailOperation *mail_op = NULL;
3284 GtkTreeSelection *sel = NULL;
3285 GtkWidget *folder_view = NULL;
3286 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3288 if (canceled || err) {
3289 /* In memory full conditions we could get this error here */
3290 check_memory_full_error ((GtkWidget *) parent_window, err);
3291 } else if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3293 folder_view = modest_main_window_get_child_widget (
3294 MODEST_MAIN_WINDOW (parent_window),
3295 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3298 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3299 modest_ui_actions_rename_folder_error_handler,
3300 parent_window, NULL);
3302 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3305 /* Clear the headers view */
3306 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3307 gtk_tree_selection_unselect_all (sel);
3309 /* Actually rename the folder */
3310 modest_mail_operation_rename_folder (mail_op,
3311 TNY_FOLDER (data->folder),
3312 (const gchar *) (data->new_name),
3313 on_rename_folder_cb,
3315 g_object_unref (data->folder);
3316 g_object_unref (mail_op);
3319 g_free (data->new_name);
3324 modest_ui_actions_on_rename_folder (GtkAction *action,
3325 ModestMainWindow *main_window)
3327 TnyFolderStore *folder;
3328 GtkWidget *folder_view;
3329 GtkWidget *header_view;
3331 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3333 folder_view = modest_main_window_get_child_widget (main_window,
3334 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3338 header_view = modest_main_window_get_child_widget (main_window,
3339 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3344 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3349 if (TNY_IS_FOLDER (folder)) {
3352 const gchar *current_name;
3353 TnyFolderStore *parent;
3354 gboolean do_rename = TRUE;
3356 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3357 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3358 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
3359 parent, current_name,
3361 g_object_unref (parent);
3363 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3366 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3367 rename_folder_data->folder = g_object_ref (folder);
3368 rename_folder_data->new_name = folder_name;
3369 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(main_window), TRUE,
3370 folder, on_rename_folder_performer, rename_folder_data);
3373 g_object_unref (folder);
3377 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3380 GObject *win = modest_mail_operation_get_source (mail_op);
3382 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3383 _("mail_in_ui_folder_delete_error"),
3385 g_object_unref (win);
3389 TnyFolderStore *folder;
3390 gboolean move_to_trash;
3394 on_delete_folder_cb (gboolean canceled,
3396 GtkWindow *parent_window,
3397 TnyAccount *account,
3400 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3401 GtkWidget *folder_view;
3402 ModestMailOperation *mail_op;
3403 GtkTreeSelection *sel;
3405 if (!MODEST_IS_MAIN_WINDOW(parent_window) || canceled || (err!=NULL)) {
3406 g_object_unref (G_OBJECT (info->folder));
3411 folder_view = modest_main_window_get_child_widget (
3412 MODEST_MAIN_WINDOW (parent_window),
3413 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3415 /* Unselect the folder before deleting it to free the headers */
3416 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3417 gtk_tree_selection_unselect_all (sel);
3419 /* Create the mail operation */
3421 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3422 modest_ui_actions_delete_folder_error_handler,
3425 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3427 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3429 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3431 g_object_unref (G_OBJECT (mail_op));
3432 g_object_unref (G_OBJECT (info->folder));
3437 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
3439 TnyFolderStore *folder;
3440 GtkWidget *folder_view;
3444 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3446 folder_view = modest_main_window_get_child_widget (main_window,
3447 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3451 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3453 /* Show an error if it's an account */
3454 if (!TNY_IS_FOLDER (folder)) {
3455 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
3456 _("mail_in_ui_folder_delete_error"),
3458 g_object_unref (G_OBJECT (folder));
3463 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3464 tny_folder_get_name (TNY_FOLDER (folder)));
3465 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
3466 (const gchar *) message);
3469 if (response == GTK_RESPONSE_OK) {
3470 DeleteFolderInfo *info;
3471 info = g_new0(DeleteFolderInfo, 1);
3472 info->folder = folder;
3473 info->move_to_trash = move_to_trash;
3474 g_object_ref (G_OBJECT (info->folder));
3475 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder));
3476 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (main_window),
3478 TNY_FOLDER_STORE (account),
3479 on_delete_folder_cb, info);
3480 g_object_unref (account);
3482 g_object_unref (G_OBJECT (folder));
3486 modest_ui_actions_on_delete_folder (GtkAction *action,
3487 ModestMainWindow *main_window)
3489 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3491 delete_folder (main_window, FALSE);
3495 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3497 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3499 delete_folder (main_window, TRUE);
3503 typedef struct _PasswordDialogFields {
3504 GtkWidget *username;
3505 GtkWidget *password;
3507 } PasswordDialogFields;
3510 password_dialog_check_field (GtkEditable *editable,
3511 PasswordDialogFields *fields)
3514 gboolean any_value_empty = FALSE;
3516 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
3517 if ((value == NULL) || value[0] == '\0') {
3518 any_value_empty = TRUE;
3520 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
3521 if ((value == NULL) || value[0] == '\0') {
3522 any_value_empty = TRUE;
3524 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3528 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3529 const gchar* server_account_name,
3534 ModestMainWindow *main_window)
3536 g_return_if_fail(server_account_name);
3537 gboolean completed = FALSE;
3538 PasswordDialogFields *fields = NULL;
3540 /* Initalize output parameters: */
3547 #ifndef MODEST_TOOLKIT_GTK
3548 /* Maemo uses a different (awkward) button order,
3549 * It should probably just use gtk_alternative_dialog_button_order ().
3551 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3554 _("mcen_bd_dialog_ok"),
3555 GTK_RESPONSE_ACCEPT,
3556 _("mcen_bd_dialog_cancel"),
3557 GTK_RESPONSE_REJECT,
3560 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3564 GTK_RESPONSE_REJECT,
3566 GTK_RESPONSE_ACCEPT,
3568 #endif /* !MODEST_TOOLKIT_GTK */
3570 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog));
3572 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3573 modest_runtime_get_account_mgr(), server_account_name);
3574 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3575 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3581 /* This causes a warning because the logical ID has no %s in it,
3582 * though the translation does, but there is not much we can do about that: */
3583 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3584 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
3587 g_free (server_name);
3591 gchar *initial_username = modest_account_mgr_get_server_account_username (
3592 modest_runtime_get_account_mgr(), server_account_name);
3594 GtkWidget *entry_username = gtk_entry_new ();
3595 if (initial_username)
3596 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
3597 /* Dim this if a connection has ever succeeded with this username,
3598 * as per the UI spec: */
3599 /* const gboolean username_known = */
3600 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3601 /* modest_runtime_get_account_mgr(), server_account_name); */
3602 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3604 /* We drop the username sensitive code and disallow changing it here
3605 * as tinymail does not support really changing the username in the callback
3607 gtk_widget_set_sensitive (entry_username, FALSE);
3609 #ifndef MODEST_TOOLKIT_GTK
3610 /* Auto-capitalization is the default, so let's turn it off: */
3611 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3613 /* Create a size group to be used by all captions.
3614 * Note that HildonCaption does not create a default size group if we do not specify one.
3615 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3616 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3618 GtkWidget *caption = hildon_caption_new (sizegroup,
3619 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
3620 gtk_widget_show (entry_username);
3621 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3622 FALSE, FALSE, MODEST_MARGIN_HALF);
3623 gtk_widget_show (caption);
3625 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
3627 #endif /* !MODEST_TOOLKIT_GTK */
3630 GtkWidget *entry_password = gtk_entry_new ();
3631 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3632 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3634 #ifndef MODEST_TOOLKIT_GTK
3635 /* Auto-capitalization is the default, so let's turn it off: */
3636 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3637 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3639 caption = hildon_caption_new (sizegroup,
3640 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
3641 gtk_widget_show (entry_password);
3642 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3643 FALSE, FALSE, MODEST_MARGIN_HALF);
3644 gtk_widget_show (caption);
3645 g_object_unref (sizegroup);
3647 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
3649 #endif /* !MODEST_TOOLKIT_GTK */
3651 if (initial_username != NULL)
3652 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3654 /* This is not in the Maemo UI spec:
3655 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3656 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3660 fields = g_slice_new0 (PasswordDialogFields);
3661 fields->username = entry_username;
3662 fields->password = entry_password;
3663 fields->dialog = dialog;
3665 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3666 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3667 password_dialog_check_field (NULL, fields);
3669 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3671 while (!completed) {
3673 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3675 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
3677 /* Note that an empty field becomes the "" string */
3678 if (*username && strlen (*username) > 0) {
3679 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
3680 server_account_name,
3684 const gboolean username_was_changed =
3685 (strcmp (*username, initial_username) != 0);
3686 if (username_was_changed) {
3687 g_warning ("%s: tinymail does not yet support changing the "
3688 "username in the get_password() callback.\n", __FUNCTION__);
3692 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
3693 _("mcen_ib_username_pw_incorrect"));
3699 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
3701 /* We do not save the password in the configuration,
3702 * because this function is only called for passwords that should
3703 * not be remembered:
3704 modest_server_account_set_password (
3705 modest_runtime_get_account_mgr(), server_account_name,
3712 /* Set parent to NULL or the banner will disappear with its parent dialog */
3713 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
3724 /* This is not in the Maemo UI spec:
3725 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3731 gtk_widget_destroy (dialog);
3732 g_slice_free (PasswordDialogFields, fields);
3734 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3738 modest_ui_actions_on_cut (GtkAction *action,
3739 ModestWindow *window)
3741 GtkWidget *focused_widget;
3742 GtkClipboard *clipboard;
3744 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3745 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3746 if (GTK_IS_EDITABLE (focused_widget)) {
3747 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3748 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3749 gtk_clipboard_store (clipboard);
3750 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3751 GtkTextBuffer *buffer;
3753 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3754 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3755 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3756 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3757 gtk_clipboard_store (clipboard);
3759 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3760 TnyList *header_list = modest_header_view_get_selected_headers (
3761 MODEST_HEADER_VIEW (focused_widget));
3762 gboolean continue_download = FALSE;
3763 gint num_of_unc_msgs;
3765 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3767 if (num_of_unc_msgs) {
3768 TnyAccount *account = get_account_from_header_list (header_list);
3770 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3771 g_object_unref (account);
3775 if (num_of_unc_msgs == 0 || continue_download) {
3776 /* modest_platform_information_banner (
3777 NULL, NULL, _CS("mcen_ib_getting_items"));*/
3778 modest_header_view_cut_selection (
3779 MODEST_HEADER_VIEW (focused_widget));
3782 g_object_unref (header_list);
3783 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3784 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3789 modest_ui_actions_on_copy (GtkAction *action,
3790 ModestWindow *window)
3792 GtkClipboard *clipboard;
3793 GtkWidget *focused_widget;
3794 gboolean copied = TRUE;
3796 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3797 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3799 if (GTK_IS_LABEL (focused_widget)) {
3801 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
3802 gtk_clipboard_set_text (clipboard, selection, -1);
3804 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3805 gtk_clipboard_store (clipboard);
3806 } else if (GTK_IS_EDITABLE (focused_widget)) {
3807 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3808 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3809 gtk_clipboard_store (clipboard);
3810 } else if (GTK_IS_HTML (focused_widget)) {
3813 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
3814 if ((sel == NULL) || (sel[0] == '\0')) {
3817 gtk_html_copy (GTK_HTML (focused_widget));
3818 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3819 gtk_clipboard_store (clipboard);
3821 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3822 GtkTextBuffer *buffer;
3823 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3824 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3825 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3826 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3827 gtk_clipboard_store (clipboard);
3829 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3830 TnyList *header_list = modest_header_view_get_selected_headers (
3831 MODEST_HEADER_VIEW (focused_widget));
3832 gboolean continue_download = FALSE;
3833 gint num_of_unc_msgs;
3835 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3837 if (num_of_unc_msgs) {
3838 TnyAccount *account = get_account_from_header_list (header_list);
3840 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3841 g_object_unref (account);
3845 if (num_of_unc_msgs == 0 || continue_download) {
3846 modest_platform_information_banner (
3847 NULL, NULL, _CS("mcen_ib_getting_items"));
3848 modest_header_view_copy_selection (
3849 MODEST_HEADER_VIEW (focused_widget));
3853 g_object_unref (header_list);
3855 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3856 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3859 /* Show information banner if there was a copy to clipboard */
3861 modest_platform_information_banner (
3862 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3866 modest_ui_actions_on_undo (GtkAction *action,
3867 ModestWindow *window)
3869 ModestEmailClipboard *clipboard = NULL;
3871 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3872 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3873 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3874 /* Clear clipboard source */
3875 clipboard = modest_runtime_get_email_clipboard ();
3876 modest_email_clipboard_clear (clipboard);
3879 g_return_if_reached ();
3884 modest_ui_actions_on_redo (GtkAction *action,
3885 ModestWindow *window)
3887 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3888 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3891 g_return_if_reached ();
3897 destroy_information_note (ModestMailOperation *mail_op,
3900 /* destroy information note */
3901 gtk_widget_destroy (GTK_WIDGET(user_data));
3905 destroy_folder_information_note (ModestMailOperation *mail_op,
3906 TnyFolder *new_folder,
3909 /* destroy information note */
3910 gtk_widget_destroy (GTK_WIDGET(user_data));
3915 paste_as_attachment_free (gpointer data)
3917 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3919 if (helper->banner) {
3920 gtk_widget_destroy (helper->banner);
3921 g_object_unref (helper->banner);
3927 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3932 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3933 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3938 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3943 modest_ui_actions_on_paste (GtkAction *action,
3944 ModestWindow *window)
3946 GtkWidget *focused_widget = NULL;
3947 GtkWidget *inf_note = NULL;
3948 ModestMailOperation *mail_op = NULL;
3950 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3951 if (GTK_IS_EDITABLE (focused_widget)) {
3952 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3953 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3954 ModestEmailClipboard *e_clipboard = NULL;
3955 e_clipboard = modest_runtime_get_email_clipboard ();
3956 if (modest_email_clipboard_cleared (e_clipboard)) {
3957 GtkTextBuffer *buffer;
3958 GtkClipboard *clipboard;
3960 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3961 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3962 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3963 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3964 ModestMailOperation *mail_op;
3965 TnyFolder *src_folder;
3968 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3969 helper->window = MODEST_MSG_EDIT_WINDOW (window);
3970 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3971 _CS("ckct_nw_pasting"));
3972 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
3973 mail_op = modest_mail_operation_new (G_OBJECT (window));
3974 if (helper->banner != NULL) {
3975 g_object_ref (G_OBJECT (helper->banner));
3976 gtk_widget_show (GTK_WIDGET (helper->banner));
3980 modest_mail_operation_get_msgs_full (mail_op,
3982 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
3984 paste_as_attachment_free);
3987 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3988 ModestEmailClipboard *clipboard = NULL;
3989 TnyFolder *src_folder = NULL;
3990 TnyFolderStore *folder_store = NULL;
3991 TnyList *data = NULL;
3992 gboolean delete = FALSE;
3994 /* Check clipboard source */
3995 clipboard = modest_runtime_get_email_clipboard ();
3996 if (modest_email_clipboard_cleared (clipboard))
3999 /* Get elements to paste */
4000 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4002 /* Create a new mail operation */
4003 mail_op = modest_mail_operation_new (G_OBJECT(window));
4005 /* Get destination folder */
4006 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4008 /* transfer messages */
4012 /* Ask for user confirmation */
4014 modest_ui_actions_msgs_move_to_confirmation (window,
4015 TNY_FOLDER (folder_store),
4019 if (response == GTK_RESPONSE_OK) {
4020 /* Launch notification */
4021 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4022 _CS("ckct_nw_pasting"));
4023 if (inf_note != NULL) {
4024 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4025 gtk_widget_show (GTK_WIDGET(inf_note));
4028 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4029 modest_mail_operation_xfer_msgs (mail_op,
4031 TNY_FOLDER (folder_store),
4033 destroy_information_note,
4036 g_object_unref (mail_op);
4039 } else if (src_folder != NULL) {
4040 /* Launch notification */
4041 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4042 _CS("ckct_nw_pasting"));
4043 if (inf_note != NULL) {
4044 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4045 gtk_widget_show (GTK_WIDGET(inf_note));
4048 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4049 modest_mail_operation_xfer_folder (mail_op,
4053 destroy_folder_information_note,
4059 g_object_unref (data);
4060 if (src_folder != NULL)
4061 g_object_unref (src_folder);
4062 if (folder_store != NULL)
4063 g_object_unref (folder_store);
4069 modest_ui_actions_on_select_all (GtkAction *action,
4070 ModestWindow *window)
4072 GtkWidget *focused_widget;
4074 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4075 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4076 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4077 } else if (GTK_IS_LABEL (focused_widget)) {
4078 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4079 } else if (GTK_IS_EDITABLE (focused_widget)) {
4080 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4081 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4082 GtkTextBuffer *buffer;
4083 GtkTextIter start, end;
4085 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4086 gtk_text_buffer_get_start_iter (buffer, &start);
4087 gtk_text_buffer_get_end_iter (buffer, &end);
4088 gtk_text_buffer_select_range (buffer, &start, &end);
4089 } else if (GTK_IS_HTML (focused_widget)) {
4090 gtk_html_select_all (GTK_HTML (focused_widget));
4091 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4092 GtkWidget *header_view = focused_widget;
4093 GtkTreeSelection *selection = NULL;
4095 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4096 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4097 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4100 /* Disable window dimming management */
4101 modest_window_disable_dimming (MODEST_WINDOW(window));
4103 /* Select all messages */
4104 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4105 gtk_tree_selection_select_all (selection);
4107 /* Set focuse on header view */
4108 gtk_widget_grab_focus (header_view);
4110 /* Enable window dimming management */
4111 modest_window_enable_dimming (MODEST_WINDOW(window));
4112 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4113 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4119 modest_ui_actions_on_mark_as_read (GtkAction *action,
4120 ModestWindow *window)
4122 g_return_if_fail (MODEST_IS_WINDOW(window));
4124 /* Mark each header as read */
4125 do_headers_action (window, headers_action_mark_as_read, NULL);
4129 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4130 ModestWindow *window)
4132 g_return_if_fail (MODEST_IS_WINDOW(window));
4134 /* Mark each header as read */
4135 do_headers_action (window, headers_action_mark_as_unread, NULL);
4139 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4140 GtkRadioAction *selected,
4141 ModestWindow *window)
4145 value = gtk_radio_action_get_current_value (selected);
4146 if (MODEST_IS_WINDOW (window)) {
4147 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4152 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4153 GtkRadioAction *selected,
4154 ModestWindow *window)
4156 TnyHeaderFlags flags;
4157 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4159 flags = gtk_radio_action_get_current_value (selected);
4160 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4164 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4165 GtkRadioAction *selected,
4166 ModestWindow *window)
4170 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4172 file_format = gtk_radio_action_get_current_value (selected);
4173 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4178 modest_ui_actions_on_zoom_plus (GtkAction *action,
4179 ModestWindow *window)
4181 g_return_if_fail (MODEST_IS_WINDOW (window));
4183 modest_window_zoom_plus (MODEST_WINDOW (window));
4187 modest_ui_actions_on_zoom_minus (GtkAction *action,
4188 ModestWindow *window)
4190 g_return_if_fail (MODEST_IS_WINDOW (window));
4192 modest_window_zoom_minus (MODEST_WINDOW (window));
4196 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4197 ModestWindow *window)
4199 ModestWindowMgr *mgr;
4200 gboolean fullscreen, active;
4201 g_return_if_fail (MODEST_IS_WINDOW (window));
4203 mgr = modest_runtime_get_window_mgr ();
4205 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4206 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4208 if (active != fullscreen) {
4209 modest_window_mgr_set_fullscreen_mode (mgr, active);
4210 gtk_window_present (GTK_WINDOW (window));
4215 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4216 ModestWindow *window)
4218 ModestWindowMgr *mgr;
4219 gboolean fullscreen;
4221 g_return_if_fail (MODEST_IS_WINDOW (window));
4223 mgr = modest_runtime_get_window_mgr ();
4224 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4225 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4227 gtk_window_present (GTK_WINDOW (window));
4231 * Used by modest_ui_actions_on_details to call do_headers_action
4234 headers_action_show_details (TnyHeader *header,
4235 ModestWindow *window,
4242 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
4245 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog));
4246 gtk_widget_show_all (dialog);
4248 g_signal_connect_swapped (dialog, "response",
4249 G_CALLBACK (gtk_widget_destroy),
4254 * Show the folder details in a ModestDetailsDialog widget
4257 show_folder_details (TnyFolder *folder,
4263 dialog = modest_details_dialog_new_with_folder (window, folder);
4266 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4267 gtk_widget_show_all (dialog);
4268 gtk_dialog_run (GTK_DIALOG (dialog));
4270 gtk_widget_destroy (dialog);
4274 * Show the header details in a ModestDetailsDialog widget
4277 modest_ui_actions_on_details (GtkAction *action,
4280 TnyList * headers_list;
4284 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4287 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4290 g_object_unref (msg);
4292 headers_list = get_selected_headers (win);
4296 iter = tny_list_create_iterator (headers_list);
4298 header = TNY_HEADER (tny_iterator_get_current (iter));
4300 headers_action_show_details (header, win, NULL);
4301 g_object_unref (header);
4304 g_object_unref (iter);
4305 g_object_unref (headers_list);
4307 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4308 GtkWidget *folder_view, *header_view;
4310 /* Check which widget has the focus */
4311 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4312 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4313 if (gtk_widget_is_focus (folder_view)) {
4314 TnyFolderStore *folder_store
4315 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4316 if (!folder_store) {
4317 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4320 /* Show only when it's a folder */
4321 /* This function should not be called for account items,
4322 * because we dim the menu item for them. */
4323 if (TNY_IS_FOLDER (folder_store)) {
4324 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
4327 g_object_unref (folder_store);
4330 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4331 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4332 /* Show details of each header */
4333 do_headers_action (win, headers_action_show_details, header_view);
4339 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4340 ModestMsgEditWindow *window)
4342 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4344 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4348 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4349 ModestMsgEditWindow *window)
4351 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4353 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4357 modest_ui_actions_toggle_folders_view (GtkAction *action,
4358 ModestMainWindow *main_window)
4360 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4362 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4363 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4365 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4369 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4370 ModestWindow *window)
4372 gboolean active, fullscreen = FALSE;
4373 ModestWindowMgr *mgr;
4375 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4377 /* Check if we want to toggle the toolbar vuew in fullscreen
4379 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4380 "ViewShowToolbarFullScreen")) {
4384 /* Toggle toolbar */
4385 mgr = modest_runtime_get_window_mgr ();
4386 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4390 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4391 ModestMsgEditWindow *window)
4393 modest_msg_edit_window_select_font (window);
4398 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4399 const gchar *display_name,
4402 /* don't update the display name if it was already set;
4403 * updating the display name apparently is expensive */
4404 const gchar* old_name = gtk_window_get_title (window);
4406 if (display_name == NULL)
4409 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4410 return; /* don't do anything */
4412 /* This is usually used to change the title of the main window, which
4413 * is the one that holds the folder view. Note that this change can
4414 * happen even when the widget doesn't have the focus. */
4415 gtk_window_set_title (window, display_name);
4420 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4422 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4423 modest_msg_edit_window_select_contacts (window);
4427 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4429 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4430 modest_msg_edit_window_check_names (window, FALSE);
4434 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
4436 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
4437 GTK_WIDGET (user_data));
4441 * This function is used to track changes in the selection of the
4442 * folder view that is inside the "move to" dialog to enable/disable
4443 * the OK button because we do not want the user to select a disallowed
4444 * destination for a folder.
4445 * The user also not desired to be able to use NEW button on items where
4446 * folder creation is not possibel.
4449 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4450 TnyFolderStore *folder_store,
4454 GtkWidget *dialog = NULL;
4455 GtkWidget *ok_button = NULL, *new_button = NULL;
4456 GList *children = NULL;
4457 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4458 gboolean moving_folder = FALSE;
4459 gboolean is_local_account = TRUE;
4460 GtkWidget *folder_view = NULL;
4461 ModestTnyFolderRules rules;
4463 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
4468 /* Get the OK button */
4469 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
4473 children = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
4474 #ifndef MODEST_TOOLKIT_GTK
4475 ok_button = GTK_WIDGET (children->next->next->data);
4476 new_button = GTK_WIDGET (children->next->data);
4478 ok_button = GTK_WIDGET (children->data);
4479 new_button = GTK_WIDGET (children->next->next->data);
4481 g_list_free (children);
4483 /* check if folder_store is an remote account */
4484 if (TNY_IS_ACCOUNT (folder_store)) {
4485 TnyAccount *local_account = NULL;
4486 TnyAccount *mmc_account = NULL;
4487 ModestTnyAccountStore *account_store = NULL;
4489 account_store = modest_runtime_get_account_store ();
4490 local_account = modest_tny_account_store_get_local_folders_account (account_store);
4491 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
4493 if ((gpointer) local_account != (gpointer) folder_store &&
4494 (gpointer) mmc_account != (gpointer) folder_store) {
4495 ModestProtocolType proto;
4496 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
4497 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
4498 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
4500 is_local_account = FALSE;
4501 /* New button should be dimmed on remote
4503 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4505 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
4507 g_object_unref (local_account);
4508 g_object_unref (mmc_account);
4511 /* Check the target folder rules */
4512 if (TNY_IS_FOLDER (folder_store)) {
4513 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
4514 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
4515 ok_sensitive = FALSE;
4516 new_sensitive = FALSE;
4521 /* Check if we're moving a folder */
4522 if (MODEST_IS_MAIN_WINDOW (user_data)) {
4523 /* Get the widgets */
4524 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
4525 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4526 if (gtk_widget_is_focus (folder_view))
4527 moving_folder = TRUE;
4530 if (moving_folder) {
4531 TnyFolderStore *moved_folder = NULL, *parent = NULL;
4533 /* Get the folder to move */
4534 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4536 /* Check that we're not moving to the same folder */
4537 if (TNY_IS_FOLDER (moved_folder)) {
4538 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
4539 if (parent == folder_store)
4540 ok_sensitive = FALSE;
4541 g_object_unref (parent);
4544 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
4545 /* Do not allow to move to an account unless it's the
4546 local folders account */
4547 if (!is_local_account)
4548 ok_sensitive = FALSE;
4551 if (ok_sensitive && (moved_folder == folder_store)) {
4552 /* Do not allow to move to itself */
4553 ok_sensitive = FALSE;
4555 g_object_unref (moved_folder);
4557 TnyFolder *src_folder = NULL;
4559 /* Moving a message */
4560 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
4562 TnyHeader *header = NULL;
4563 header = modest_msg_view_window_get_header
4564 (MODEST_MSG_VIEW_WINDOW (user_data));
4565 if (!TNY_IS_HEADER(header))
4566 g_warning ("%s: could not get source header", __FUNCTION__);
4568 src_folder = tny_header_get_folder (header);
4571 g_object_unref (header);
4574 TNY_FOLDER (modest_folder_view_get_selected
4575 (MODEST_FOLDER_VIEW (folder_view)));
4578 if (TNY_IS_FOLDER(src_folder)) {
4579 /* Do not allow to move the msg to the same folder */
4580 /* Do not allow to move the msg to an account */
4581 if ((gpointer) src_folder == (gpointer) folder_store ||
4582 TNY_IS_ACCOUNT (folder_store))
4583 ok_sensitive = FALSE;
4584 g_object_unref (src_folder);
4586 g_warning ("%s: could not get source folder", __FUNCTION__);
4590 /* Set sensitivity of the OK button */
4591 gtk_widget_set_sensitive (ok_button, ok_sensitive);
4592 /* Set sensitivity of the NEW button */
4593 gtk_widget_set_sensitive (new_button, new_sensitive);
4597 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
4600 get_folder_view_from_move_to_dialog (GtkWidget *move_to_dialog)
4602 return GTK_WIDGET(g_object_get_data (G_OBJECT(move_to_dialog),
4603 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4607 create_move_to_dialog (GtkWindow *win,
4608 GtkWidget *folder_view,
4609 GtkWidget **tree_view)
4611 GtkWidget *dialog, *scroll;
4612 GtkWidget *new_button;
4614 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
4616 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
4619 #ifndef MODEST_TOOLKIT_GTK
4620 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
4621 /* We do this manually so GTK+ does not associate a response ID for
4623 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
4624 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
4625 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
4627 /* We do this manually so GTK+ does not associate a response ID for
4629 new_button = gtk_button_new_with_label (_("mcen_ti_new_folder"));
4630 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
4631 gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (GTK_DIALOG (dialog)->action_area), new_button, TRUE);
4632 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
4633 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
4634 gtk_container_set_border_width (GTK_CONTAINER (dialog), 12);
4635 gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 24);
4638 /* Create scrolled window */
4639 scroll = gtk_scrolled_window_new (NULL, NULL);
4640 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
4641 GTK_POLICY_AUTOMATIC,
4642 GTK_POLICY_AUTOMATIC);
4644 #ifdef MODEST_TOOLKIT_GTK
4645 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN);
4648 /* Create folder view */
4649 *tree_view = modest_platform_create_folder_view (NULL);
4651 /* Track changes in the selection to
4652 * disable the OK button whenever "Move to" is not possible
4653 * disbale NEW button whenever New is not possible */
4654 g_signal_connect (*tree_view,
4655 "folder_selection_changed",
4656 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
4659 /* Listen to clicks on New button */
4660 g_signal_connect (G_OBJECT (new_button),
4662 G_CALLBACK(create_move_to_dialog_on_new_folder),
4665 /* It could happen that we're trying to move a message from a
4666 window (msg window for example) after the main window was
4667 closed, so we can not just get the model of the folder
4669 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4670 const gchar *visible_id = NULL;
4672 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4673 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4674 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4675 MODEST_FOLDER_VIEW(*tree_view));
4678 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4680 /* Show the same account than the one that is shown in the main window */
4681 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
4684 const gchar *active_account_name = NULL;
4685 ModestAccountMgr *mgr = NULL;
4686 ModestAccountSettings *settings = NULL;
4687 ModestServerAccountSettings *store_settings = NULL;
4689 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4690 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4691 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
4692 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
4694 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4695 mgr = modest_runtime_get_account_mgr ();
4696 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4699 const gchar *store_account_name;
4700 store_settings = modest_account_settings_get_store_settings (settings);
4701 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4703 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
4704 store_account_name);
4705 g_object_unref (store_settings);
4706 g_object_unref (settings);
4710 /* we keep a pointer to the embedded folder view, so we can retrieve it with
4711 * get_folder_view_from_move_to_dialog
4712 * (see above) later (needed for focus handling)
4714 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, *tree_view);
4717 /* Hide special folders */
4718 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
4720 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
4722 /* Add scroll to dialog */
4723 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
4724 scroll, TRUE, TRUE, 0);
4726 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4727 #ifndef MODEST_TOOLKIT_GTK
4728 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
4730 gtk_window_set_default_size (GTK_WINDOW (dialog), 600, 400);
4739 * Shows a confirmation dialog to the user when we're moving messages
4740 * from a remote server to the local storage. Returns the dialog
4741 * response. If it's other kind of movement then it always returns
4744 * This one is used by the next functions:
4745 * modest_ui_actions_on_paste - commented out
4746 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4749 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4750 TnyFolder *dest_folder,
4754 gint response = GTK_RESPONSE_OK;
4755 TnyAccount *account = NULL;
4756 TnyFolder *src_folder = NULL;
4757 TnyIterator *iter = NULL;
4758 TnyHeader *header = NULL;
4760 /* return with OK if the destination is a remote folder */
4761 if (modest_tny_folder_is_remote_folder (dest_folder))
4762 return GTK_RESPONSE_OK;
4764 /* Get source folder */
4765 iter = tny_list_create_iterator (headers);
4766 header = TNY_HEADER (tny_iterator_get_current (iter));
4768 src_folder = tny_header_get_folder (header);
4769 g_object_unref (header);
4771 g_object_unref (iter);
4773 /* if no src_folder, message may be an attahcment */
4774 if (src_folder == NULL)
4775 return GTK_RESPONSE_CANCEL;
4777 /* If the source is a local or MMC folder */
4778 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4779 g_object_unref (src_folder);
4780 return GTK_RESPONSE_OK;
4783 /* Get the account */
4784 account = tny_folder_get_account (src_folder);
4786 /* now if offline we ask the user */
4787 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4788 response = GTK_RESPONSE_OK;
4790 response = GTK_RESPONSE_CANCEL;
4793 g_object_unref (src_folder);
4794 g_object_unref (account);
4800 move_to_helper_destroyer (gpointer user_data)
4802 MoveToHelper *helper = (MoveToHelper *) user_data;
4804 /* Close the "Pasting" information banner */
4805 if (helper->banner) {
4806 gtk_widget_destroy (GTK_WIDGET (helper->banner));
4807 g_object_unref (helper->banner);
4809 if (helper->reference != NULL)
4810 gtk_tree_row_reference_free (helper->reference);
4815 move_to_cb (ModestMailOperation *mail_op,
4818 MoveToHelper *helper = (MoveToHelper *) user_data;
4820 /* Note that the operation could have failed, in that case do
4822 if (modest_mail_operation_get_status (mail_op) ==
4823 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
4825 GObject *object = modest_mail_operation_get_source (mail_op);
4826 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4827 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4829 if (!modest_msg_view_window_select_next_message (self) &&
4830 !modest_msg_view_window_select_previous_message (self)) {
4831 /* No more messages to view, so close this window */
4832 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4834 } else if (MODEST_IS_MAIN_WINDOW (object) && helper->reference != NULL) {
4835 GtkWidget *header_view;
4837 GtkTreeSelection *sel;
4839 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4840 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4841 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
4842 path = gtk_tree_row_reference_get_path (helper->reference);
4843 /* We need to unselect the previous one
4844 because we could be copying instead of
4846 gtk_tree_selection_unselect_all (sel);
4847 gtk_tree_selection_select_path (sel, path);
4848 gtk_tree_path_free (path);
4850 g_object_unref (object);
4852 /* Destroy the helper */
4853 move_to_helper_destroyer (helper);
4857 folder_move_to_cb (ModestMailOperation *mail_op,
4858 TnyFolder *new_folder,
4861 GtkWidget *folder_view;
4864 object = modest_mail_operation_get_source (mail_op);
4865 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4866 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4867 g_object_ref (folder_view);
4868 g_object_unref (object);
4869 move_to_cb (mail_op, user_data);
4870 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
4871 g_object_unref (folder_view);
4875 msgs_move_to_cb (ModestMailOperation *mail_op,
4878 move_to_cb (mail_op, user_data);
4882 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
4885 ModestWindow *main_window = NULL;
4887 /* Disable next automatic folder selection */
4888 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
4889 FALSE); /* don't create */
4891 GObject *win = NULL;
4892 GtkWidget *folder_view = NULL;
4894 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
4895 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4896 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
4898 if (user_data && TNY_IS_FOLDER (user_data)) {
4899 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
4900 TNY_FOLDER (user_data), FALSE);
4903 /* Show notification dialog only if the main window exists */
4904 win = modest_mail_operation_get_source (mail_op);
4905 modest_platform_run_information_dialog ((GtkWindow *) win,
4906 _("mail_in_ui_folder_move_target_error"),
4909 g_object_unref (win);
4914 open_msg_for_purge_cb (ModestMailOperation *mail_op,
4923 gint pending_purges = 0;
4924 gboolean some_purged = FALSE;
4925 ModestWindow *win = MODEST_WINDOW (user_data);
4926 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
4928 /* If there was any error */
4929 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
4930 modest_window_mgr_unregister_header (mgr, header);
4934 /* Once the message has been retrieved for purging, we check if
4935 * it's all ok for purging */
4937 parts = tny_simple_list_new ();
4938 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
4939 iter = tny_list_create_iterator (parts);
4941 while (!tny_iterator_is_done (iter)) {
4943 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4944 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
4945 if (tny_mime_part_is_purged (part))
4952 g_object_unref (part);
4954 tny_iterator_next (iter);
4956 g_object_unref (iter);
4959 if (pending_purges>0) {
4961 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
4963 if (response == GTK_RESPONSE_OK) {
4966 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_ib_removing_attachment"));
4967 iter = tny_list_create_iterator (parts);
4968 while (!tny_iterator_is_done (iter)) {
4971 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4972 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
4973 tny_mime_part_set_purged (part);
4976 g_object_unref (part);
4978 tny_iterator_next (iter);
4980 g_object_unref (iter);
4982 tny_msg_rewrite_cache (msg);
4984 gtk_widget_destroy (info);
4988 modest_window_mgr_unregister_header (mgr, header);
4990 g_object_unref (parts);
4994 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
4995 ModestMainWindow *win)
4997 GtkWidget *header_view;
4998 TnyList *header_list;
5000 TnyHeaderFlags flags;
5001 ModestWindow *msg_view_window = NULL;
5004 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5006 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5007 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5009 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5011 g_warning ("%s: no header selected", __FUNCTION__);
5015 if (tny_list_get_length (header_list) == 1) {
5016 TnyIterator *iter = tny_list_create_iterator (header_list);
5017 header = TNY_HEADER (tny_iterator_get_current (iter));
5018 g_object_unref (iter);
5022 if (!header || !TNY_IS_HEADER(header)) {
5023 g_warning ("%s: header is not valid", __FUNCTION__);
5027 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5028 header, &msg_view_window);
5029 flags = tny_header_get_flags (header);
5030 if (!(flags & TNY_HEADER_FLAG_CACHED))
5033 if (msg_view_window != NULL)
5034 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5036 /* do nothing; uid was registered before, so window is probably on it's way */
5037 g_warning ("debug: header %p has already been registered", header);
5040 ModestMailOperation *mail_op = NULL;
5041 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5042 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5043 modest_ui_actions_disk_operations_error_handler,
5045 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5046 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5048 g_object_unref (mail_op);
5051 g_object_unref (header);
5053 g_object_unref (header_list);
5057 * Checks if we need a connection to do the transfer and if the user
5058 * wants to connect to complete it
5061 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5062 TnyFolderStore *src_folder,
5064 TnyFolder *dst_folder,
5065 gboolean delete_originals,
5066 gboolean *need_connection,
5069 TnyAccount *src_account;
5070 gint uncached_msgs = 0;
5072 uncached_msgs = header_list_count_uncached_msgs (headers);
5074 /* We don't need any further check if
5076 * 1- the source folder is local OR
5077 * 2- the device is already online
5079 if (!modest_tny_folder_store_is_remote (src_folder) ||
5080 tny_device_is_online (modest_runtime_get_device())) {
5081 *need_connection = FALSE;
5086 /* We must ask for a connection when
5088 * - the message(s) is not already cached OR
5089 * - the message(s) is cached but the leave_on_server setting
5090 * is FALSE (because we need to sync the source folder to
5091 * delete the message from the server (for IMAP we could do it
5092 * offline, it'll take place the next time we get a
5095 src_account = get_account_from_folder_store (src_folder);
5096 if (uncached_msgs > 0) {
5100 *need_connection = TRUE;
5101 num_headers = tny_list_get_length (headers);
5102 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5104 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5105 GTK_RESPONSE_CANCEL) {
5111 /* The transfer is possible and the user wants to */
5114 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5115 const gchar *account_name;
5116 gboolean leave_on_server;
5118 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5119 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5122 if (leave_on_server == TRUE) {
5123 *need_connection = FALSE;
5125 *need_connection = TRUE;
5128 *need_connection = FALSE;
5133 g_object_unref (src_account);
5137 xfer_messages_error_handler (ModestMailOperation *mail_op,
5140 ModestWindow *main_window = NULL;
5142 /* Disable next automatic folder selection */
5143 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5144 FALSE); /* don't create */
5146 GObject *win = modest_mail_operation_get_source (mail_op);
5147 modest_platform_run_information_dialog ((GtkWindow *) win,
5148 _("mail_in_ui_folder_move_target_error"),
5151 g_object_unref (win);
5153 move_to_helper_destroyer (user_data);
5157 TnyFolderStore *dst_folder;
5162 * Utility function that transfer messages from both the main window
5163 * and the msg view window when using the "Move to" dialog
5166 xfer_messages_performer (gboolean canceled,
5168 GtkWindow *parent_window,
5169 TnyAccount *account,
5172 ModestWindow *win = MODEST_WINDOW (parent_window);
5173 TnyAccount *dst_account = NULL;
5174 gboolean dst_forbids_message_add = FALSE;
5175 XferMsgsHelper *helper;
5176 MoveToHelper *movehelper;
5177 ModestMailOperation *mail_op;
5179 helper = (XferMsgsHelper *) user_data;
5181 if (canceled || err) {
5182 if (!check_memory_full_error ((GtkWidget *) parent_window, err)) {
5183 /* Show the proper error message */
5184 modest_ui_actions_on_account_connection_error (parent_window, account);
5189 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5191 /* tinymail will return NULL for local folders it seems */
5192 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5193 modest_tny_account_get_protocol_type (dst_account),
5194 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_MESSAGE_ADD);
5195 g_object_unref (dst_account);
5197 if (dst_forbids_message_add) {
5198 modest_platform_information_banner (GTK_WIDGET (win),
5200 ngettext("mail_in_ui_folder_move_target_error",
5201 "mail_in_ui_folder_move_targets_error",
5202 tny_list_get_length (helper->headers)));
5206 movehelper = g_new0 (MoveToHelper, 1);
5207 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5208 _CS("ckct_nw_pasting"));
5209 if (movehelper->banner != NULL) {
5210 g_object_ref (movehelper->banner);
5211 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5214 if (MODEST_IS_MAIN_WINDOW (win)) {
5215 GtkWidget *header_view =
5216 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5217 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5218 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5221 /* Perform the mail operation */
5222 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5223 xfer_messages_error_handler,
5225 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5228 modest_mail_operation_xfer_msgs (mail_op,
5230 TNY_FOLDER (helper->dst_folder),
5235 g_object_unref (G_OBJECT (mail_op));
5237 g_object_unref (helper->dst_folder);
5238 g_object_unref (helper->headers);
5239 g_slice_free (XferMsgsHelper, helper);
5243 TnyFolder *src_folder;
5244 TnyFolderStore *dst_folder;
5245 gboolean delete_original;
5246 GtkWidget *folder_view;
5250 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
5251 TnyAccount *account, gpointer user_data)
5253 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5254 GtkTreeSelection *sel;
5255 ModestMailOperation *mail_op = NULL;
5257 if (canceled || err || !MODEST_IS_MAIN_WINDOW (parent_window)) {
5258 g_object_unref (G_OBJECT (info->src_folder));
5259 g_object_unref (G_OBJECT (info->dst_folder));
5264 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5265 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5266 _CS("ckct_nw_pasting"));
5267 if (helper->banner != NULL) {
5268 g_object_ref (helper->banner);
5269 gtk_widget_show (GTK_WIDGET(helper->banner));
5271 /* Clean folder on header view before moving it */
5272 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5273 gtk_tree_selection_unselect_all (sel);
5275 /* Let gtk events run. We need that the folder
5276 view frees its reference to the source
5277 folder *before* issuing the mail operation
5278 so we need the signal handler of selection
5279 changed to happen before the mail
5281 while (gtk_events_pending ())
5282 gtk_main_iteration (); */
5285 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5286 modest_ui_actions_move_folder_error_handler,
5287 info->src_folder, NULL);
5288 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5291 /* Select *after* the changes */
5292 /* TODO: this function hangs UI after transfer */
5293 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
5294 /* TNY_FOLDER (src_folder), TRUE); */
5296 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5297 TNY_FOLDER (info->dst_folder), TRUE);
5298 modest_mail_operation_xfer_folder (mail_op,
5299 TNY_FOLDER (info->src_folder),
5301 info->delete_original,
5304 g_object_unref (G_OBJECT (info->src_folder));
5306 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5309 /* Unref mail operation */
5310 g_object_unref (G_OBJECT (mail_op));
5311 g_object_unref (G_OBJECT (info->dst_folder));
5316 get_account_from_folder_store (TnyFolderStore *folder_store)
5318 if (TNY_IS_ACCOUNT (folder_store))
5319 return g_object_ref (folder_store);
5321 return tny_folder_get_account (TNY_FOLDER (folder_store));
5325 * UI handler for the "Move to" action when invoked from the
5329 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5330 GtkWidget *folder_view,
5331 TnyFolderStore *dst_folder,
5332 ModestMainWindow *win)
5334 ModestHeaderView *header_view = NULL;
5335 TnyFolderStore *src_folder = NULL;
5337 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5339 /* Get the source folder */
5340 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5342 /* Get header view */
5343 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
5345 /* Get folder or messages to transfer */
5346 if (gtk_widget_is_focus (folder_view)) {
5347 gboolean do_xfer = TRUE;
5349 /* Allow only to transfer folders to the local root folder */
5350 if (TNY_IS_ACCOUNT (dst_folder) &&
5351 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5352 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5354 } else if (!TNY_IS_FOLDER (src_folder)) {
5355 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5360 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5361 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5363 info->src_folder = g_object_ref (src_folder);
5364 info->dst_folder = g_object_ref (dst_folder);
5365 info->delete_original = TRUE;
5366 info->folder_view = folder_view;
5368 connect_info->callback = on_move_folder_cb;
5369 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5370 connect_info->data = info;
5372 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5373 TNY_FOLDER_STORE (src_folder),
5376 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5379 headers = modest_header_view_get_selected_headers(header_view);
5381 /* Transfer the messages */
5382 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
5383 headers, TNY_FOLDER (dst_folder));
5385 g_object_unref (headers);
5389 g_object_unref (src_folder);
5394 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
5395 TnyFolder *src_folder,
5397 TnyFolder *dst_folder)
5399 gboolean need_connection = TRUE;
5400 gboolean do_xfer = TRUE;
5401 XferMsgsHelper *helper;
5403 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5404 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5405 g_return_if_fail (TNY_IS_LIST (headers));
5407 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5408 headers, TNY_FOLDER (dst_folder),
5409 TRUE, &need_connection,
5412 /* If we don't want to transfer just return */
5416 /* Create the helper */
5417 helper = g_slice_new (XferMsgsHelper);
5418 helper->dst_folder = g_object_ref (dst_folder);
5419 helper->headers = g_object_ref (headers);
5421 if (need_connection) {
5422 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5423 connect_info->callback = xfer_messages_performer;
5424 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5425 connect_info->data = helper;
5427 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5428 TNY_FOLDER_STORE (src_folder),
5431 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5432 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
5433 src_account, helper);
5434 g_object_unref (src_account);
5439 * UI handler for the "Move to" action when invoked from the
5440 * ModestMsgViewWindow
5443 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
5444 TnyFolderStore *dst_folder,
5445 ModestMsgViewWindow *win)
5447 TnyList *headers = NULL;
5448 TnyHeader *header = NULL;
5449 TnyFolder *src_folder = NULL;
5451 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5453 /* Create header list */
5454 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
5455 src_folder = TNY_FOLDER (tny_header_get_folder(header));
5456 headers = tny_simple_list_new ();
5457 tny_list_append (headers, G_OBJECT (header));
5459 /* Transfer the messages */
5460 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder, headers,
5461 TNY_FOLDER (dst_folder));
5464 g_object_unref (src_folder);
5465 g_object_unref (header);
5466 g_object_unref (headers);
5470 modest_ui_actions_on_move_to (GtkAction *action,
5473 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
5475 TnyFolderStore *dst_folder = NULL;
5476 ModestMainWindow *main_window;
5478 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
5479 MODEST_IS_MSG_VIEW_WINDOW (win));
5481 /* Get the main window if exists */
5482 if (MODEST_IS_MAIN_WINDOW (win))
5483 main_window = MODEST_MAIN_WINDOW (win);
5486 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5487 FALSE)); /* don't create */
5489 /* Get the folder view widget if exists */
5491 folder_view = modest_main_window_get_child_widget (main_window,
5492 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5496 /* Create and run the dialog */
5497 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
5498 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5499 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog));
5500 result = gtk_dialog_run (GTK_DIALOG(dialog));
5501 g_object_ref (tree_view);
5502 gtk_widget_destroy (dialog);
5504 if (result != GTK_RESPONSE_ACCEPT)
5507 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
5508 /* Do window specific stuff */
5509 if (MODEST_IS_MAIN_WINDOW (win)) {
5510 modest_ui_actions_on_main_window_move_to (action,
5513 MODEST_MAIN_WINDOW (win));
5515 modest_ui_actions_on_msg_view_window_move_to (action,
5517 MODEST_MSG_VIEW_WINDOW (win));
5521 g_object_unref (dst_folder);
5525 * Calls #HeadersFunc for each header already selected in the main
5526 * window or the message currently being shown in the msg view window
5529 do_headers_action (ModestWindow *win,
5533 TnyList *headers_list = NULL;
5534 TnyIterator *iter = NULL;
5535 TnyHeader *header = NULL;
5536 TnyFolder *folder = NULL;
5539 headers_list = get_selected_headers (win);
5543 /* Get the folder */
5544 iter = tny_list_create_iterator (headers_list);
5545 header = TNY_HEADER (tny_iterator_get_current (iter));
5547 folder = tny_header_get_folder (header);
5548 g_object_unref (header);
5551 /* Call the function for each header */
5552 while (!tny_iterator_is_done (iter)) {
5553 header = TNY_HEADER (tny_iterator_get_current (iter));
5554 func (header, win, user_data);
5555 g_object_unref (header);
5556 tny_iterator_next (iter);
5559 /* Trick: do a poke status in order to speed up the signaling
5561 tny_folder_poke_status (folder);
5564 g_object_unref (folder);
5565 g_object_unref (iter);
5566 g_object_unref (headers_list);
5570 modest_ui_actions_view_attachment (GtkAction *action,
5571 ModestWindow *window)
5573 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5574 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5576 /* not supported window for this action */
5577 g_return_if_reached ();
5582 modest_ui_actions_save_attachments (GtkAction *action,
5583 ModestWindow *window)
5585 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5587 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5590 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5592 /* not supported window for this action */
5593 g_return_if_reached ();
5598 modest_ui_actions_remove_attachments (GtkAction *action,
5599 ModestWindow *window)
5601 if (MODEST_IS_MAIN_WINDOW (window)) {
5602 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
5603 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5604 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5606 /* not supported window for this action */
5607 g_return_if_reached ();
5612 modest_ui_actions_on_settings (GtkAction *action,
5617 dialog = modest_platform_get_global_settings_dialog ();
5618 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
5619 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5620 gtk_widget_show_all (dialog);
5622 gtk_dialog_run (GTK_DIALOG (dialog));
5624 gtk_widget_destroy (dialog);
5628 modest_ui_actions_on_help (GtkAction *action,
5631 const gchar *help_id;
5633 g_return_if_fail (win && GTK_IS_WINDOW(win));
5635 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5638 modest_platform_show_help (GTK_WINDOW (win), help_id);
5642 modest_ui_actions_on_csm_help (GtkAction *action,
5645 const gchar* help_id = NULL;
5646 GtkWidget *folder_view;
5647 TnyFolderStore *folder_store;
5649 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
5651 /* Get selected folder */
5652 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5653 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5654 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5656 /* Switch help_id */
5657 if (folder_store && TNY_IS_FOLDER (folder_store))
5658 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
5661 g_object_unref (folder_store);
5664 modest_platform_show_help (GTK_WINDOW (win), help_id);
5666 modest_ui_actions_on_help (action, win);
5670 retrieve_contents_cb (ModestMailOperation *mail_op,
5677 /* We only need this callback to show an error in case of
5678 memory low condition */
5679 modest_ui_actions_msg_retrieval_check (mail_op, header, msg);
5683 retrieve_msg_contents_performer (gboolean canceled,
5685 GtkWindow *parent_window,
5686 TnyAccount *account,
5689 ModestMailOperation *mail_op;
5690 TnyList *headers = TNY_LIST (user_data);
5692 if (err || canceled) {
5693 check_memory_full_error ((GtkWidget *) parent_window, err);
5697 /* Create mail operation */
5698 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5699 modest_ui_actions_disk_operations_error_handler,
5701 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5702 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
5705 g_object_unref (mail_op);
5707 g_object_unref (headers);
5708 g_object_unref (account);
5712 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5713 ModestWindow *window)
5715 TnyList *headers = NULL;
5716 TnyAccount *account = NULL;
5717 TnyIterator *iter = NULL;
5718 TnyHeader *header = NULL;
5719 TnyFolder *folder = NULL;
5722 headers = get_selected_headers (window);
5726 /* Pick the account */
5727 iter = tny_list_create_iterator (headers);
5728 header = TNY_HEADER (tny_iterator_get_current (iter));
5729 folder = tny_header_get_folder (header);
5730 account = tny_folder_get_account (folder);
5731 g_object_unref (folder);
5732 g_object_unref (header);
5733 g_object_unref (iter);
5735 /* Connect and perform the message retrieval */
5736 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
5737 g_object_ref (account),
5738 retrieve_msg_contents_performer,
5739 g_object_ref (headers));
5742 g_object_unref (account);
5743 g_object_unref (headers);
5747 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
5749 g_return_if_fail (MODEST_IS_WINDOW (window));
5752 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
5756 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
5758 g_return_if_fail (MODEST_IS_WINDOW (window));
5761 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
5765 modest_ui_actions_on_email_menu_activated (GtkAction *action,
5766 ModestWindow *window)
5768 g_return_if_fail (MODEST_IS_WINDOW (window));
5771 modest_ui_actions_check_menu_dimming_rules (window);
5775 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
5776 ModestWindow *window)
5778 g_return_if_fail (MODEST_IS_WINDOW (window));
5781 modest_ui_actions_check_menu_dimming_rules (window);
5785 modest_ui_actions_on_view_menu_activated (GtkAction *action,
5786 ModestWindow *window)
5788 g_return_if_fail (MODEST_IS_WINDOW (window));
5791 modest_ui_actions_check_menu_dimming_rules (window);
5795 modest_ui_actions_on_format_menu_activated (GtkAction *action,
5796 ModestWindow *window)
5798 g_return_if_fail (MODEST_IS_WINDOW (window));
5801 modest_ui_actions_check_menu_dimming_rules (window);
5805 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
5806 ModestWindow *window)
5808 g_return_if_fail (MODEST_IS_WINDOW (window));
5811 modest_ui_actions_check_menu_dimming_rules (window);
5815 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
5816 ModestWindow *window)
5818 g_return_if_fail (MODEST_IS_WINDOW (window));
5821 modest_ui_actions_check_menu_dimming_rules (window);
5825 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
5826 ModestWindow *window)
5828 g_return_if_fail (MODEST_IS_WINDOW (window));
5831 modest_ui_actions_check_menu_dimming_rules (window);
5835 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
5836 ModestWindow *window)
5838 g_return_if_fail (MODEST_IS_WINDOW (window));
5841 modest_ui_actions_check_menu_dimming_rules (window);
5845 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
5846 ModestWindow *window)
5848 g_return_if_fail (MODEST_IS_WINDOW (window));
5851 modest_ui_actions_check_menu_dimming_rules (window);
5855 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
5857 g_return_if_fail (MODEST_IS_WINDOW (window));
5859 /* we check for low-mem; in that case, show a warning, and don't allow
5862 if (modest_platform_check_memory_low (window, TRUE))
5865 modest_platform_show_search_messages (GTK_WINDOW (window));
5869 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
5871 g_return_if_fail (MODEST_IS_WINDOW (win));
5874 /* we check for low-mem; in that case, show a warning, and don't allow
5875 * for the addressbook
5877 if (modest_platform_check_memory_low (win, TRUE))
5881 modest_platform_show_addressbook (GTK_WINDOW (win));
5886 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
5887 ModestWindow *window)
5889 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5891 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
5895 on_send_receive_finished (ModestMailOperation *mail_op,
5898 GtkWidget *header_view, *folder_view;
5899 TnyFolderStore *folder_store;
5900 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
5902 /* Set send/receive operation finished */
5903 modest_main_window_notify_send_receive_completed (main_win);
5905 /* Don't refresh the current folder if there were any errors */
5906 if (modest_mail_operation_get_status (mail_op) !=
5907 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5910 /* Refresh the current folder if we're viewing a window. We do
5911 this because the user won't be able to see the new mails in
5912 the selected folder after a Send&Receive because it only
5913 performs a poke_status, i.e, only the number of read/unread
5914 messages is updated, but the new headers are not
5916 folder_view = modest_main_window_get_child_widget (main_win,
5917 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5921 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5923 /* Do not need to refresh INBOX again because the
5924 update_account does it always automatically */
5925 if (folder_store && TNY_IS_FOLDER (folder_store) &&
5926 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
5927 ModestMailOperation *refresh_op;
5929 header_view = modest_main_window_get_child_widget (main_win,
5930 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5932 /* We do not need to set the contents style
5933 because it hasn't changed. We also do not
5934 need to save the widget status. Just force
5936 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
5937 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
5938 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
5939 folder_refreshed_cb, main_win);
5940 g_object_unref (refresh_op);
5944 g_object_unref (folder_store);
5949 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
5955 const gchar* server_name = NULL;
5956 TnyTransportAccount *server_account;
5957 gchar *message = NULL;
5959 /* Don't show anything if the user cancelled something or the
5960 * send receive request is not interactive. Authentication
5961 * errors are managed by the account store so no need to show
5962 * a dialog here again */
5963 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
5964 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
5965 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
5969 /* Get the server name: */
5971 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
5973 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
5975 g_return_if_reached ();
5977 /* Show the appropriate message text for the GError: */
5978 switch (err->code) {
5979 case TNY_SERVICE_ERROR_CONNECT:
5980 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
5982 case TNY_SERVICE_ERROR_SEND:
5983 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
5985 case TNY_SERVICE_ERROR_UNAVAILABLE:
5986 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
5989 g_warning ("%s: unexpected ERROR %d",
5990 __FUNCTION__, err->code);
5991 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
5995 modest_platform_run_information_dialog (NULL, message, FALSE);
5997 g_object_unref (server_account);
6001 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6006 ModestMainWindow *main_window = NULL;
6007 ModestWindowMgr *mgr = NULL;
6008 GtkWidget *folder_view = NULL, *header_view = NULL;
6009 TnyFolderStore *selected_folder = NULL;
6010 TnyFolderType folder_type;
6012 mgr = modest_runtime_get_window_mgr ();
6013 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr,
6014 FALSE));/* don't create */
6018 /* Check if selected folder is OUTBOX */
6019 folder_view = modest_main_window_get_child_widget (main_window,
6020 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6021 header_view = modest_main_window_get_child_widget (main_window,
6022 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6024 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6025 if (!TNY_IS_FOLDER (selected_folder))
6028 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6029 #if GTK_CHECK_VERSION(2, 8, 0)
6030 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
6031 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6032 GtkTreeViewColumn *tree_column;
6034 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6035 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6036 gtk_tree_view_column_queue_resize (tree_column);
6039 gtk_widget_queue_draw (header_view);
6042 /* Rerun dimming rules, because the message could become deletable for example */
6043 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6044 MODEST_DIMMING_RULES_TOOLBAR);
6045 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6046 MODEST_DIMMING_RULES_MENU);
6050 if (selected_folder != NULL)
6051 g_object_unref (selected_folder);
6055 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6056 TnyAccount *account)
6058 ModestProtocolType protocol_type;
6059 ModestProtocol *protocol;
6060 gchar *error_note = NULL;
6062 protocol_type = modest_tny_account_get_protocol_type (account);
6063 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6066 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6067 if (error_note == NULL) {
6068 g_warning ("%s: This should not be reached", __FUNCTION__);
6070 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6071 g_free (error_note);
6076 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6080 TnyFolderStore *folder = NULL;
6081 TnyAccount *account = NULL;
6082 ModestProtocolType proto;
6083 ModestProtocol *protocol;
6084 TnyHeader *header = NULL;
6086 if (MODEST_IS_MAIN_WINDOW (win)) {
6087 GtkWidget *header_view;
6088 TnyList* headers = NULL;
6090 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6091 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6092 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6093 if (!headers || tny_list_get_length (headers) == 0) {
6095 g_object_unref (headers);
6098 iter = tny_list_create_iterator (headers);
6099 header = TNY_HEADER (tny_iterator_get_current (iter));
6100 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6101 g_object_unref (iter);
6102 g_object_unref (headers);
6103 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6104 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6105 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6108 /* Get the account type */
6109 account = tny_folder_get_account (TNY_FOLDER (folder));
6110 proto = modest_tny_account_get_protocol_type (account);
6111 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6114 subject = tny_header_dup_subject (header);
6115 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6118 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6122 g_object_unref (account);
6123 g_object_unref (folder);
6124 g_object_unref (header);