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
91 #define MOVE_FOLDER_OK_BUTTON "ok-button"
92 #define MOVE_FOLDER_NEW_BUTTON "new-button"
94 typedef struct _GetMsgAsyncHelper {
96 ModestMailOperation *mail_op;
103 typedef enum _ReplyForwardAction {
107 } ReplyForwardAction;
109 typedef struct _ReplyForwardHelper {
110 guint reply_forward_type;
111 ReplyForwardAction action;
113 GtkWidget *parent_window;
115 } ReplyForwardHelper;
117 typedef struct _MoveToHelper {
118 GtkTreeRowReference *reference;
122 typedef struct _PasteAsAttachmentHelper {
123 ModestMsgEditWindow *window;
125 } PasteAsAttachmentHelper;
129 * The do_headers_action uses this kind of functions to perform some
130 * action to each member of a list of headers
132 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
134 static void do_headers_action (ModestWindow *win,
138 static void open_msg_cb (ModestMailOperation *mail_op,
145 static void reply_forward_cb (ModestMailOperation *mail_op,
152 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
154 static void folder_refreshed_cb (ModestMailOperation *mail_op,
158 static void on_send_receive_finished (ModestMailOperation *mail_op,
161 static gint header_list_count_uncached_msgs (TnyList *header_list);
163 static gboolean connect_to_get_msg (ModestWindow *win,
164 gint num_of_uncached_msgs,
165 TnyAccount *account);
167 static gboolean remote_folder_has_leave_on_server (TnyFolderStore *folder);
169 static void do_create_folder (GtkWindow *window,
170 TnyFolderStore *parent_folder,
171 const gchar *suggested_name);
173 static GtkWidget* get_folder_view_from_move_to_dialog (GtkWidget *move_to_dialog);
175 static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store);
178 * This function checks whether a TnyFolderStore is a pop account
181 remote_folder_has_leave_on_server (TnyFolderStore *folder)
186 g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
188 account = get_account_from_folder_store (folder);
189 result = (modest_protocol_registry_protocol_type_has_leave_on_server (modest_runtime_get_protocol_registry (),
190 modest_tny_account_get_protocol_type (account)));
191 g_object_unref (account);
196 /* FIXME: this should be merged with the similar code in modest-account-view-window */
197 /* Show the account creation wizard dialog.
198 * returns: TRUE if an account was created. FALSE if the user cancelled.
201 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
203 gboolean result = FALSE;
205 gint dialog_response;
207 /* there is no such wizard yet */
208 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
209 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (wizard), (GtkWindow *) win);
211 /* always present a main window in the background
212 * we do it here, so we cannot end up with two wizards (as this
213 * function might be called in modest_window_mgr_get_main_window as well */
215 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
216 TRUE); /* create if not existent */
218 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
220 /* make sure the mainwindow is visible. We need to present the
221 wizard again to give it the focus back. show_all are needed
222 in order to get the widgets properly drawn (MainWindow main
223 paned won't be in its right position and the dialog will be
225 #ifndef MODEST_TOOLKIT_HILDON2
226 gtk_widget_show_all (GTK_WIDGET (win));
227 gtk_widget_show_all (GTK_WIDGET (wizard));
228 gtk_window_present (GTK_WINDOW (win));
229 gtk_window_present (GTK_WINDOW (wizard));
232 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
233 gtk_widget_destroy (GTK_WIDGET (wizard));
234 if (gtk_events_pending ())
235 gtk_main_iteration ();
237 if (dialog_response == GTK_RESPONSE_CANCEL) {
240 /* Check whether an account was created: */
241 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
248 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
251 const gchar *authors[] = {
252 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
255 about = gtk_about_dialog_new ();
256 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
257 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
258 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
259 _("Copyright (c) 2006, Nokia Corporation\n"
260 "All rights reserved."));
261 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
262 _("a modest e-mail client\n\n"
263 "design and implementation: Dirk-Jan C. Binnema\n"
264 "contributions from the fine people at KC and Ig\n"
265 "uses the tinymail email framework written by Philip van Hoof"));
266 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
267 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
268 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
269 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
271 gtk_dialog_run (GTK_DIALOG (about));
272 gtk_widget_destroy(about);
276 * Gets the list of currently selected messages. If the win is the
277 * main window, then it returns a newly allocated list of the headers
278 * selected in the header view. If win is the msg view window, then
279 * the value returned is a list with just a single header.
281 * The caller of this funcion must free the list.
284 get_selected_headers (ModestWindow *win)
286 if (MODEST_IS_MAIN_WINDOW(win)) {
287 GtkWidget *header_view;
289 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
290 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
291 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
293 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
294 /* for MsgViewWindows, we simply return a list with one element */
296 TnyList *list = NULL;
298 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
299 if (header != NULL) {
300 list = tny_simple_list_new ();
301 tny_list_prepend (list, G_OBJECT(header));
302 g_object_unref (G_OBJECT(header));
311 static GtkTreeRowReference *
312 get_next_after_selected_headers (ModestHeaderView *header_view)
314 GtkTreeSelection *sel;
315 GList *selected_rows, *node;
317 GtkTreeRowReference *result;
320 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
321 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
322 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
324 if (selected_rows == NULL)
327 node = g_list_last (selected_rows);
328 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
329 gtk_tree_path_next (path);
331 result = gtk_tree_row_reference_new (model, path);
333 gtk_tree_path_free (path);
334 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
335 g_list_free (selected_rows);
341 headers_action_mark_as_read (TnyHeader *header,
345 TnyHeaderFlags flags;
347 g_return_if_fail (TNY_IS_HEADER(header));
349 flags = tny_header_get_flags (header);
350 if (flags & TNY_HEADER_FLAG_SEEN) return;
351 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
355 headers_action_mark_as_unread (TnyHeader *header,
359 TnyHeaderFlags flags;
361 g_return_if_fail (TNY_IS_HEADER(header));
363 flags = tny_header_get_flags (header);
364 if (flags & TNY_HEADER_FLAG_SEEN) {
365 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
369 /** After deleing a message that is currently visible in a window,
370 * show the next message from the list, or close the window if there are no more messages.
373 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
375 /* Close msg view window or select next */
376 if (!modest_msg_view_window_select_next_message (win) &&
377 !modest_msg_view_window_select_previous_message (win)) {
379 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
385 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
387 TnyList *header_list = NULL;
388 TnyIterator *iter = NULL;
389 TnyHeader *header = NULL;
390 gchar *message = NULL;
393 ModestWindowMgr *mgr;
394 GtkWidget *header_view = NULL;
396 g_return_if_fail (MODEST_IS_WINDOW(win));
398 /* Check first if the header view has the focus */
399 if (MODEST_IS_MAIN_WINDOW (win)) {
401 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
402 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
403 if (!gtk_widget_is_focus (header_view))
407 /* Get the headers, either from the header view (if win is the main window),
408 * or from the message view window: */
409 header_list = get_selected_headers (win);
410 if (!header_list) return;
412 /* Check if any of the headers are already opened, or in the process of being opened */
413 if (MODEST_IS_MAIN_WINDOW (win)) {
414 gint opened_headers = 0;
416 iter = tny_list_create_iterator (header_list);
417 mgr = modest_runtime_get_window_mgr ();
418 while (!tny_iterator_is_done (iter)) {
419 header = TNY_HEADER (tny_iterator_get_current (iter));
421 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
423 g_object_unref (header);
425 tny_iterator_next (iter);
427 g_object_unref (iter);
429 if (opened_headers > 0) {
432 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
435 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg, FALSE);
438 g_object_unref (header_list);
444 if (tny_list_get_length(header_list) == 1) {
445 iter = tny_list_create_iterator (header_list);
446 header = TNY_HEADER (tny_iterator_get_current (iter));
449 subject = tny_header_dup_subject (header);
451 subject = g_strdup (_("mail_va_no_subject"));
452 desc = g_strdup_printf ("%s", subject);
454 g_object_unref (header);
457 g_object_unref (iter);
459 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
460 tny_list_get_length(header_list)), desc);
462 /* Confirmation dialog */
463 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
467 if (response == GTK_RESPONSE_OK) {
468 ModestWindow *main_window = NULL;
469 ModestWindowMgr *mgr = NULL;
470 GtkTreeModel *model = NULL;
471 GtkTreeSelection *sel = NULL;
472 GList *sel_list = NULL, *tmp = NULL;
473 GtkTreeRowReference *next_row_reference = NULL;
474 GtkTreeRowReference *prev_row_reference = NULL;
475 GtkTreePath *next_path = NULL;
476 GtkTreePath *prev_path = NULL;
477 ModestMailOperation *mail_op = NULL;
479 /* Find last selected row */
480 if (MODEST_IS_MAIN_WINDOW (win)) {
481 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
482 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
483 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
484 for (tmp=sel_list; tmp; tmp=tmp->next) {
485 if (tmp->next == NULL) {
486 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
487 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
489 gtk_tree_path_prev (prev_path);
490 gtk_tree_path_next (next_path);
492 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
493 next_row_reference = gtk_tree_row_reference_new (model, next_path);
498 /* Disable window dimming management */
499 modest_window_disable_dimming (MODEST_WINDOW(win));
501 /* Remove each header. If it's a view window header_view == NULL */
502 mail_op = modest_mail_operation_new ((GObject *) win);
503 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
505 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
506 g_object_unref (mail_op);
508 /* Enable window dimming management */
510 gtk_tree_selection_unselect_all (sel);
512 modest_window_enable_dimming (MODEST_WINDOW(win));
514 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
515 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
517 /* Get main window */
518 mgr = modest_runtime_get_window_mgr ();
519 main_window = modest_window_mgr_get_main_window (mgr, FALSE); /* don't create */
521 /* Move cursor to next row */
524 /* Select next or previous row */
525 if (gtk_tree_row_reference_valid (next_row_reference)) {
526 gtk_tree_selection_select_path (sel, next_path);
528 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
529 gtk_tree_selection_select_path (sel, prev_path);
533 if (gtk_tree_row_reference_valid (next_row_reference))
534 gtk_tree_row_reference_free (next_row_reference);
535 if (next_path != NULL)
536 gtk_tree_path_free (next_path);
537 if (gtk_tree_row_reference_valid (prev_row_reference))
538 gtk_tree_row_reference_free (prev_row_reference);
539 if (prev_path != NULL)
540 gtk_tree_path_free (prev_path);
543 /* Update toolbar dimming state */
545 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
546 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
550 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
551 g_list_free (sel_list);
557 g_object_unref (header_list);
563 /* delete either message or folder, based on where we are */
565 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
567 g_return_if_fail (MODEST_IS_WINDOW(win));
569 /* Check first if the header view has the focus */
570 if (MODEST_IS_MAIN_WINDOW (win)) {
572 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
573 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
574 if (gtk_widget_is_focus (w)) {
575 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
579 modest_ui_actions_on_delete_message (action, win);
583 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
585 ModestWindowMgr *mgr = NULL;
587 #ifdef MODEST_PLATFORM_MAEMO
588 modest_osso_save_state();
589 #endif /* MODEST_PLATFORM_MAEMO */
591 g_debug ("closing down, clearing %d item(s) from operation queue",
592 modest_mail_operation_queue_num_elements
593 (modest_runtime_get_mail_operation_queue()));
595 /* cancel all outstanding operations */
596 modest_mail_operation_queue_cancel_all
597 (modest_runtime_get_mail_operation_queue());
599 g_debug ("queue has been cleared");
602 /* Check if there are opened editing windows */
603 mgr = modest_runtime_get_window_mgr ();
604 modest_window_mgr_close_all_windows (mgr);
606 /* note: when modest-tny-account-store is finalized,
607 it will automatically set all network connections
610 /* gtk_main_quit (); */
614 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
618 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
620 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
621 /* gtk_widget_destroy (GTK_WIDGET (win)); */
622 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
623 /* gboolean ret_value; */
624 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
625 /* } else if (MODEST_IS_WINDOW (win)) { */
626 /* gtk_widget_destroy (GTK_WIDGET (win)); */
628 /* g_return_if_reached (); */
633 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
635 GtkClipboard *clipboard = NULL;
636 gchar *selection = NULL;
638 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
639 selection = gtk_clipboard_wait_for_text (clipboard);
641 /* Question: why is the clipboard being used here?
642 * It doesn't really make a lot of sense. */
646 modest_address_book_add_address (selection);
652 modest_ui_actions_on_accounts (GtkAction *action,
655 /* This is currently only implemented for Maemo */
656 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
657 if (!modest_ui_actions_run_account_setup_wizard (win))
658 g_debug ("%s: wizard was already running", __FUNCTION__);
662 /* Show the list of accounts */
663 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
665 /* The accounts dialog must be modal */
666 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (account_win), (GtkWindow *) win);
667 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
672 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
674 /* This is currently only implemented for Maemo,
675 * because it requires an API (libconic) to detect different connection
678 #ifndef MODEST_TOOLKIT_GTK /* Defined in config.h */
680 /* Create the window if necessary: */
681 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
682 modest_connection_specific_smtp_window_fill_with_connections (
683 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
684 modest_runtime_get_account_mgr());
686 /* Show the window: */
687 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
688 GTK_WINDOW (specific_window), (GtkWindow *) win);
689 gtk_widget_show (specific_window);
690 #endif /* !MODEST_TOOLKIT_GTK */
694 modest_ui_actions_compose_msg(ModestWindow *win,
697 const gchar *bcc_str,
698 const gchar *subject_str,
699 const gchar *body_str,
701 gboolean set_as_modified)
703 gchar *account_name = NULL;
705 TnyAccount *account = NULL;
706 TnyFolder *folder = NULL;
707 gchar *from_str = NULL, *signature = NULL, *body = NULL;
708 gboolean use_signature = FALSE;
709 ModestWindow *msg_win = NULL;
710 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
711 ModestTnyAccountStore *store = modest_runtime_get_account_store();
712 GnomeVFSFileSize total_size, allowed_size;
714 /* we check for low-mem; in that case, show a warning, and don't allow
715 * composing a message with attachments
717 if (attachments && modest_platform_check_memory_low (win, TRUE))
720 #ifdef MODEST_TOOLKIT_HILDON2
721 account_name = g_strdup (modest_window_get_active_account(win));
724 account_name = modest_account_mgr_get_default_account(mgr);
727 g_printerr ("modest: no account found\n");
730 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
732 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
735 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
737 g_printerr ("modest: failed to find Drafts folder\n");
740 from_str = modest_account_mgr_get_from_string (mgr, account_name);
742 g_printerr ("modest: failed get from string for '%s'\n", account_name);
746 signature = modest_account_mgr_get_signature (mgr, account_name, &use_signature);
747 if (body_str != NULL) {
748 body = use_signature ? g_strconcat(body_str, "\n--\n", signature, NULL) : g_strdup(body_str);
750 body = use_signature ? g_strconcat("\n--\n", signature, NULL) : g_strdup("");
753 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, body, NULL, NULL, NULL);
755 g_printerr ("modest: failed to create new msg\n");
759 /* Create and register edit window */
760 /* This is destroyed by TODO. */
762 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
763 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
765 if (!modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win, NULL)) {
766 gtk_widget_destroy (GTK_WIDGET (msg_win));
769 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
770 gtk_widget_show_all (GTK_WIDGET (msg_win));
772 while (attachments) {
774 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
775 attachments->data, allowed_size);
777 if (total_size > allowed_size) {
778 g_warning ("%s: total size: %u",
779 __FUNCTION__, (unsigned int)total_size);
782 allowed_size -= total_size;
784 attachments = g_slist_next(attachments);
791 g_free (account_name);
793 g_object_unref (G_OBJECT(account));
795 g_object_unref (G_OBJECT(folder));
797 g_object_unref (G_OBJECT(msg));
801 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
803 /* if there are no accounts yet, just show the wizard */
804 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
805 if (!modest_ui_actions_run_account_setup_wizard (win))
808 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
813 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
817 ModestMailOperationStatus status;
819 /* If there is no message or the operation was not successful */
820 status = modest_mail_operation_get_status (mail_op);
821 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
824 /* If it's a memory low issue, then show a banner */
825 error = modest_mail_operation_get_error (mail_op);
826 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
827 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
828 GObject *source = modest_mail_operation_get_source (mail_op);
829 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
830 dgettext("ke-recv","memr_ib_operation_disabled"),
832 g_object_unref (source);
835 if (error && ((error->code == TNY_SERVICE_ERROR_NO_SUCH_MESSAGE) ||
836 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE)) {
837 gchar *subject, *msg;
838 subject = tny_header_dup_subject (header);
840 subject = g_strdup (_("mail_va_no_subject"));;
841 msg = g_strdup_printf (_("emev_ni_ui_imap_message_not_available_in_server"),
843 modest_platform_run_information_dialog (NULL, msg, FALSE);
848 /* Remove the header from the preregistered uids */
849 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
867 OpenMsgBannerInfo *banner_info;
868 GHashTable *row_refs_per_header;
872 open_msg_banner_idle (gpointer userdata)
874 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
876 gdk_threads_enter ();
877 banner_info->idle_handler = 0;
878 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
880 g_object_ref (banner_info->banner);
882 gdk_threads_leave ();
889 open_msg_cb (ModestMailOperation *mail_op,
896 ModestWindowMgr *mgr = NULL;
897 ModestWindow *parent_win = NULL;
898 ModestWindow *win = NULL;
899 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
900 gchar *account = NULL;
902 gboolean open_in_editor = FALSE;
903 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
905 /* Do nothing if there was any problem with the mail
906 operation. The error will be shown by the error_handler of
907 the mail operation */
908 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
911 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
912 folder = tny_header_get_folder (header);
914 /* Mark header as read */
915 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
917 /* Gets folder type (OUTBOX headers will be opened in edit window */
918 if (modest_tny_folder_is_local_folder (folder)) {
919 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
920 if (folder_type == TNY_FOLDER_TYPE_INVALID)
921 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
925 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
926 TnyTransportAccount *traccount = NULL;
927 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
928 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
930 ModestTnySendQueue *send_queue = NULL;
931 ModestTnySendQueueStatus status;
933 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
934 TNY_ACCOUNT(traccount)));
935 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
936 if (TNY_IS_SEND_QUEUE (send_queue)) {
937 msg_id = modest_tny_send_queue_get_msg_id (header);
938 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
939 /* Only open messages in outbox with the editor if they are in Failed state */
940 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
941 open_in_editor = TRUE;
945 g_object_unref(traccount);
947 g_warning("Cannot get transport account for message in outbox!!");
949 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
950 open_in_editor = TRUE; /* Open in editor if the message is in the Drafts folder */
955 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
957 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
959 if (open_in_editor) {
960 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
961 gchar *from_header = NULL, *acc_name;
963 from_header = tny_header_dup_from (header);
965 /* we cannot edit without a valid account... */
966 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
967 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
968 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
970 g_free (from_header);
975 acc_name = modest_utils_get_account_name_from_recipient (from_header);
976 g_free (from_header);
982 win = modest_msg_edit_window_new (msg, account, TRUE);
984 gchar *uid = modest_tny_folder_get_header_unique_id (header);
986 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
987 GtkTreeRowReference *row_reference;
989 row_reference = (GtkTreeRowReference *) g_hash_table_lookup (helper->row_refs_per_header, header);
991 win = modest_msg_view_window_new_with_header_model (msg, account, (const gchar*) uid,
992 helper->model, row_reference);
994 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
999 /* Register and show new window */
1001 mgr = modest_runtime_get_window_mgr ();
1002 if (!modest_window_mgr_register_window (mgr, win, NULL)) {
1003 gtk_widget_destroy (GTK_WIDGET (win));
1006 gtk_widget_show_all (GTK_WIDGET(win));
1009 /* Update toolbar dimming state */
1010 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1011 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1017 g_object_unref (parent_win);
1018 g_object_unref (folder);
1022 is_memory_full_error (GError *error)
1024 gboolean enough_free_space = TRUE;
1025 GnomeVFSURI *cache_dir_uri;
1026 const gchar *cache_dir;
1027 GnomeVFSFileSize free_space;
1029 cache_dir = tny_account_store_get_cache_dir (TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
1030 cache_dir_uri = gnome_vfs_uri_new (cache_dir);
1031 if (gnome_vfs_get_volume_free_space (cache_dir_uri, &free_space) == GNOME_VFS_OK) {
1032 if (free_space < MIN_FREE_SPACE)
1033 enough_free_space = FALSE;
1035 gnome_vfs_uri_unref (cache_dir_uri);
1037 if ((error->code == TNY_SYSTEM_ERROR_MEMORY ||
1038 /* When asking for a mail and no space left on device
1039 tinymail returns this error */
1040 error->code == TNY_SERVICE_ERROR_MESSAGE_NOT_AVAILABLE ||
1041 /* When the folder summary could not be read or
1043 error->code == TNY_IO_ERROR_WRITE ||
1044 error->code == TNY_IO_ERROR_READ) &&
1045 !enough_free_space) {
1053 check_memory_full_error (GtkWidget *parent_window, GError *err)
1058 if (is_memory_full_error (err))
1059 modest_platform_information_banner (parent_window,
1060 NULL, dgettext("ke-recv",
1061 "cerm_device_memory_full"));
1062 else if (err->code == TNY_SYSTEM_ERROR_MEMORY)
1063 /* If the account was created in memory full
1064 conditions then tinymail won't be able to
1065 connect so it'll return this error code */
1066 modest_platform_information_banner (parent_window,
1067 NULL, _("emev_ui_imap_inbox_select_error"));
1075 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1078 const GError *error;
1079 GObject *win = NULL;
1080 ModestMailOperationStatus status;
1082 win = modest_mail_operation_get_source (mail_op);
1083 error = modest_mail_operation_get_error (mail_op);
1084 status = modest_mail_operation_get_status (mail_op);
1086 /* If the mail op has been cancelled then it's not an error:
1087 don't show any message */
1088 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1089 if (is_memory_full_error ((GError *) error)) {
1090 modest_platform_information_banner ((GtkWidget *) win,
1091 NULL, dgettext("ke-recv",
1092 "cerm_device_memory_full"));
1093 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1094 modest_platform_information_banner ((GtkWidget *) win,
1095 NULL, _("emev_ui_imap_inbox_select_error"));
1096 } else if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
1097 error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1098 modest_platform_information_banner ((GtkWidget *) win,
1099 NULL, dgettext ("hildon-common-strings", "sfil_ni_unable_to_open_file_not_found"));
1100 } else if (user_data) {
1101 modest_platform_information_banner ((GtkWidget *) win,
1107 g_object_unref (win);
1111 * Returns the account a list of headers belongs to. It returns a
1112 * *new* reference so don't forget to unref it
1115 get_account_from_header_list (TnyList *headers)
1117 TnyAccount *account = NULL;
1119 if (tny_list_get_length (headers) > 0) {
1120 TnyIterator *iter = tny_list_create_iterator (headers);
1121 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1122 TnyFolder *folder = tny_header_get_folder (header);
1125 g_object_unref (header);
1127 while (!tny_iterator_is_done (iter)) {
1128 header = TNY_HEADER (tny_iterator_get_current (iter));
1129 folder = tny_header_get_folder (header);
1132 g_object_unref (header);
1134 tny_iterator_next (iter);
1139 account = tny_folder_get_account (folder);
1140 g_object_unref (folder);
1144 g_object_unref (header);
1146 g_object_unref (iter);
1152 foreach_unregister_headers (gpointer data,
1155 ModestWindowMgr *mgr = (ModestWindowMgr *) user_data;
1156 TnyHeader *header = TNY_HEADER (data);
1158 modest_window_mgr_unregister_header (mgr, header);
1162 open_msgs_helper_destroyer (gpointer user_data)
1164 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1166 if (helper->banner_info) {
1167 g_free (helper->banner_info->message);
1168 if (helper->banner_info->idle_handler > 0) {
1169 g_source_remove (helper->banner_info->idle_handler);
1170 helper->banner_info->idle_handler = 0;
1172 if (helper->banner_info->banner != NULL) {
1173 gtk_widget_destroy (helper->banner_info->banner);
1174 g_object_unref (helper->banner_info->banner);
1175 helper->banner_info->banner = NULL;
1177 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1178 helper->banner_info = NULL;
1180 g_object_unref (helper->model);
1181 g_object_unref (helper->headers);
1182 g_hash_table_destroy (helper->row_refs_per_header);
1183 g_slice_free (OpenMsgHelper, helper);
1187 open_msgs_performer(gboolean canceled,
1189 GtkWindow *parent_window,
1190 TnyAccount *account,
1193 ModestMailOperation *mail_op = NULL;
1195 ModestProtocolType proto;
1196 TnyList *not_opened_headers;
1197 TnyConnectionStatus status;
1198 gboolean show_open_draft = FALSE;
1199 OpenMsgHelper *helper = NULL;
1201 helper = (OpenMsgHelper *) user_data;
1202 not_opened_headers = helper->headers;
1204 status = tny_account_get_connection_status (account);
1205 if (err || canceled) {
1206 /* Unregister the already registered headers */
1207 tny_list_foreach (not_opened_headers, foreach_unregister_headers,
1208 modest_runtime_get_window_mgr ());
1209 /* Free the helper */
1210 open_msgs_helper_destroyer (helper);
1212 /* In memory full conditions we could get this error here */
1213 check_memory_full_error ((GtkWidget *) parent_window, err);
1218 /* Get the error message depending on the protocol */
1219 proto = modest_tny_account_get_protocol_type (account);
1220 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
1221 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
1224 /* Create the error messages */
1225 if (tny_list_get_length (not_opened_headers) == 1) {
1226 ModestProtocol *protocol;
1227 ModestProtocolRegistry *protocol_registry;
1232 protocol_registry = modest_runtime_get_protocol_registry ();
1233 iter = tny_list_create_iterator (not_opened_headers);
1234 header = TNY_HEADER (tny_iterator_get_current (iter));
1235 subject = tny_header_dup_subject (header);
1237 protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, proto);
1238 error_msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
1241 g_object_unref (header);
1242 g_object_unref (iter);
1244 if (error_msg == NULL) {
1245 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1248 if (modest_protocol_registry_protocol_type_has_tag (protocol_registry,
1250 MODEST_PROTOCOL_REGISTRY_LOCAL_STORE_PROTOCOLS)) {
1254 TnyFolderType folder_type;
1256 iter = tny_list_create_iterator (not_opened_headers);
1257 header = TNY_HEADER (tny_iterator_get_current (iter));
1258 folder = tny_header_get_folder (header);
1259 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1260 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1261 g_object_unref (folder);
1262 g_object_unref (header);
1263 g_object_unref (iter);
1266 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1269 /* Create the mail operation */
1271 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1272 modest_ui_actions_disk_operations_error_handler,
1274 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1277 if (show_open_draft) {
1278 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1279 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1280 helper->banner_info->banner = NULL;
1281 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1282 helper->banner_info);
1285 modest_mail_operation_get_msgs_full (mail_op,
1289 open_msgs_helper_destroyer);
1294 g_object_unref (mail_op);
1295 g_object_unref (account);
1299 * This function is used by both modest_ui_actions_on_open and
1300 * modest_ui_actions_on_header_activated. This way we always do the
1301 * same when trying to open messages.
1304 open_msgs_from_headers (TnyList *headers, ModestWindow *win)
1306 ModestWindowMgr *mgr = NULL;
1307 TnyIterator *iter = NULL, *iter_not_opened = NULL;
1308 TnyList *not_opened_headers = NULL;
1309 TnyHeaderFlags flags = 0;
1310 TnyAccount *account;
1311 gint uncached_msgs = 0;
1312 GtkWidget *header_view;
1313 GtkTreeModel *model;
1314 GHashTable *refs_for_headers;
1315 OpenMsgHelper *helper;
1316 GtkTreeSelection *sel;
1317 GList *sel_list = NULL, *sel_list_iter = NULL;
1319 g_return_if_fail (headers != NULL);
1321 /* Check that only one message is selected for opening */
1322 if (tny_list_get_length (headers) != 1) {
1323 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1324 NULL, _("mcen_ib_select_one_message"));
1328 mgr = modest_runtime_get_window_mgr ();
1329 iter = tny_list_create_iterator (headers);
1331 /* Get the account */
1332 account = get_account_from_header_list (headers);
1337 /* Get the selections, we need to get the references to the
1338 rows here because the treeview/model could dissapear (the
1339 user might want to select another folder)*/
1340 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1341 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1342 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
1343 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
1344 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
1345 refs_for_headers = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
1346 (GDestroyNotify) gtk_tree_row_reference_free);
1348 /* Look if we already have a message view for each header. If
1349 true, then remove the header from the list of headers to
1351 sel_list_iter = sel_list;
1352 not_opened_headers = tny_simple_list_new ();
1353 while (!tny_iterator_is_done (iter) && sel_list_iter) {
1355 ModestWindow *window = NULL;
1356 TnyHeader *header = NULL;
1357 gboolean found = FALSE;
1359 header = TNY_HEADER (tny_iterator_get_current (iter));
1361 flags = tny_header_get_flags (header);
1364 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1366 /* Do not open again the message and present the
1367 window to the user */
1370 #ifndef MODEST_TOOLKIT_HILDON2
1371 gtk_window_present (GTK_WINDOW (window));
1374 /* the header has been registered already, we don't do
1375 * anything but wait for the window to come up*/
1376 g_debug ("header %p already registered, waiting for window", header);
1379 GtkTreeRowReference *row_reference;
1381 tny_list_append (not_opened_headers, G_OBJECT (header));
1382 /* Create a new row reference and add it to the hash table */
1383 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list_iter->data);
1384 g_hash_table_insert (refs_for_headers, header, row_reference);
1388 g_object_unref (header);
1391 tny_iterator_next (iter);
1392 sel_list_iter = g_list_next (sel_list_iter);
1394 g_object_unref (iter);
1396 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
1397 g_list_free (sel_list);
1399 /* Open each message */
1400 if (tny_list_get_length (not_opened_headers) == 0) {
1401 g_hash_table_destroy (refs_for_headers);
1405 /* If some messages would have to be downloaded, ask the user to
1406 * make a connection. It's generally easier to do this here (in the mainloop)
1407 * than later in a thread:
1409 if (tny_list_get_length (not_opened_headers) > 0) {
1410 uncached_msgs = header_list_count_uncached_msgs (not_opened_headers);
1412 if (uncached_msgs > 0) {
1413 /* Allways download if we are online. */
1414 if (!tny_device_is_online (modest_runtime_get_device ())) {
1417 /* If ask for user permission to download the messages */
1418 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1419 ngettext("mcen_nc_get_msg",
1423 /* End if the user does not want to continue */
1424 if (response == GTK_RESPONSE_CANCEL) {
1425 g_hash_table_destroy (refs_for_headers);
1432 /* Register the headers before actually creating the windows: */
1433 iter_not_opened = tny_list_create_iterator (not_opened_headers);
1434 while (!tny_iterator_is_done (iter_not_opened)) {
1435 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1437 modest_window_mgr_register_header (mgr, header, NULL);
1438 g_object_unref (header);
1440 tny_iterator_next (iter_not_opened);
1442 g_object_unref (iter_not_opened);
1443 iter_not_opened = NULL;
1445 /* Create the helper. We need to get a reference to the model
1446 here because it could change while the message is readed
1447 (the user could switch between folders) */
1448 helper = g_slice_new (OpenMsgHelper);
1449 helper->model = g_object_ref (model);
1450 helper->headers = g_object_ref (not_opened_headers);
1451 helper->row_refs_per_header = refs_for_headers;
1452 helper->banner_info = NULL;
1454 /* Connect to the account and perform */
1455 if (uncached_msgs > 0) {
1456 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1457 open_msgs_performer, helper);
1459 /* Call directly the performer, do not need to connect */
1460 open_msgs_performer (FALSE, NULL, (GtkWindow *) win,
1461 g_object_ref (account), helper);
1466 g_object_unref (account);
1467 if (not_opened_headers)
1468 g_object_unref (not_opened_headers);
1472 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1476 /* we check for low-mem; in that case, show a warning, and don't allow
1479 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1483 headers = get_selected_headers (win);
1488 open_msgs_from_headers (headers, win);
1490 g_object_unref(headers);
1493 static ReplyForwardHelper*
1494 create_reply_forward_helper (ReplyForwardAction action,
1496 guint reply_forward_type,
1499 ReplyForwardHelper *rf_helper = NULL;
1500 const gchar *active_acc = modest_window_get_active_account (win);
1502 rf_helper = g_slice_new0 (ReplyForwardHelper);
1503 rf_helper->reply_forward_type = reply_forward_type;
1504 rf_helper->action = action;
1505 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1506 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1507 rf_helper->account_name = (active_acc) ?
1508 g_strdup (active_acc) :
1509 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1515 free_reply_forward_helper (gpointer data)
1517 ReplyForwardHelper *helper;
1519 helper = (ReplyForwardHelper *) data;
1520 g_free (helper->account_name);
1522 g_object_unref (helper->header);
1523 g_slice_free (ReplyForwardHelper, helper);
1527 reply_forward_cb (ModestMailOperation *mail_op,
1534 TnyMsg *new_msg = NULL;
1535 ReplyForwardHelper *rf_helper;
1536 ModestWindow *msg_win = NULL;
1537 ModestEditType edit_type;
1539 TnyAccount *account = NULL;
1540 ModestWindowMgr *mgr = NULL;
1541 gchar *signature = NULL;
1542 gboolean use_signature;
1544 /* If there was any error. The mail operation could be NULL,
1545 this means that we already have the message downloaded and
1546 that we didn't do a mail operation to retrieve it */
1547 rf_helper = (ReplyForwardHelper *) user_data;
1548 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1551 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1552 rf_helper->account_name);
1553 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr(),
1554 rf_helper->account_name,
1557 /* Create reply mail */
1558 switch (rf_helper->action) {
1561 modest_tny_msg_create_reply_msg (msg, header, from,
1562 (use_signature) ? signature : NULL,
1563 rf_helper->reply_forward_type,
1564 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1566 case ACTION_REPLY_TO_ALL:
1568 modest_tny_msg_create_reply_msg (msg, header, from,
1569 (use_signature) ? signature : NULL,
1570 rf_helper->reply_forward_type,
1571 MODEST_TNY_MSG_REPLY_MODE_ALL);
1572 edit_type = MODEST_EDIT_TYPE_REPLY;
1574 case ACTION_FORWARD:
1576 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1577 rf_helper->reply_forward_type);
1578 edit_type = MODEST_EDIT_TYPE_FORWARD;
1581 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1583 g_return_if_reached ();
1591 g_warning ("%s: failed to create message\n", __FUNCTION__);
1595 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1596 rf_helper->account_name,
1597 TNY_ACCOUNT_TYPE_STORE);
1599 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1603 /* Create and register the windows */
1604 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1605 mgr = modest_runtime_get_window_mgr ();
1606 modest_window_mgr_register_window (mgr, msg_win, (ModestWindow *) rf_helper->parent_window);
1608 if (rf_helper->parent_window != NULL) {
1609 gdouble parent_zoom;
1611 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1612 modest_window_set_zoom (msg_win, parent_zoom);
1615 /* Show edit window */
1616 gtk_widget_show_all (GTK_WIDGET (msg_win));
1619 /* We always unregister the header because the message is
1620 forwarded or replied so the original one is no longer
1622 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
1625 g_object_unref (G_OBJECT (new_msg));
1627 g_object_unref (G_OBJECT (account));
1628 free_reply_forward_helper (rf_helper);
1631 /* Checks a list of headers. If any of them are not currently
1632 * downloaded (CACHED) then returns TRUE else returns FALSE.
1635 header_list_count_uncached_msgs (TnyList *header_list)
1638 gint uncached_messages = 0;
1640 iter = tny_list_create_iterator (header_list);
1641 while (!tny_iterator_is_done (iter)) {
1644 header = TNY_HEADER (tny_iterator_get_current (iter));
1646 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1647 uncached_messages ++;
1648 g_object_unref (header);
1651 tny_iterator_next (iter);
1653 g_object_unref (iter);
1655 return uncached_messages;
1658 /* Returns FALSE if the user does not want to download the
1659 * messages. Returns TRUE if the user allowed the download.
1662 connect_to_get_msg (ModestWindow *win,
1663 gint num_of_uncached_msgs,
1664 TnyAccount *account)
1666 GtkResponseType response;
1668 /* Allways download if we are online. */
1669 if (tny_device_is_online (modest_runtime_get_device ()))
1672 /* If offline, then ask for user permission to download the messages */
1673 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1674 ngettext("mcen_nc_get_msg",
1676 num_of_uncached_msgs));
1678 if (response == GTK_RESPONSE_CANCEL)
1681 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1685 reply_forward_performer (gboolean canceled,
1687 GtkWindow *parent_window,
1688 TnyAccount *account,
1691 ReplyForwardHelper *rf_helper = NULL;
1692 ModestMailOperation *mail_op;
1694 rf_helper = (ReplyForwardHelper *) user_data;
1696 if (canceled || err) {
1697 free_reply_forward_helper (rf_helper);
1701 /* Retrieve the message */
1702 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), rf_helper->header, NULL);
1703 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1704 modest_ui_actions_disk_operations_error_handler,
1706 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1707 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1710 g_object_unref(mail_op);
1714 * Common code for the reply and forward actions
1717 reply_forward (ReplyForwardAction action, ModestWindow *win)
1719 ReplyForwardHelper *rf_helper = NULL;
1720 guint reply_forward_type;
1722 g_return_if_fail (MODEST_IS_WINDOW(win));
1724 /* we check for low-mem; in that case, show a warning, and don't allow
1725 * reply/forward (because it could potentially require a lot of memory */
1726 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1730 /* we need an account when editing */
1731 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1732 if (!modest_ui_actions_run_account_setup_wizard (win))
1736 reply_forward_type =
1737 modest_conf_get_int (modest_runtime_get_conf (),
1738 (action == ACTION_FORWARD) ?
1739 MODEST_CONF_FORWARD_TYPE :
1740 MODEST_CONF_REPLY_TYPE,
1743 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1745 TnyHeader *header = NULL;
1746 /* Get header and message. Do not free them here, the
1747 reply_forward_cb must do it */
1748 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1749 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1751 if (msg && header) {
1753 rf_helper = create_reply_forward_helper (action, win,
1754 reply_forward_type, header);
1755 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1757 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1761 g_object_unref (msg);
1763 g_object_unref (header);
1765 TnyHeader *header = NULL;
1767 gboolean do_retrieve = TRUE;
1768 TnyList *header_list = NULL;
1770 header_list = get_selected_headers (win);
1773 /* Check that only one message is selected for replying */
1774 if (tny_list_get_length (header_list) != 1) {
1775 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1776 NULL, _("mcen_ib_select_one_message"));
1777 g_object_unref (header_list);
1781 /* Only reply/forward to one message */
1782 iter = tny_list_create_iterator (header_list);
1783 header = TNY_HEADER (tny_iterator_get_current (iter));
1784 g_object_unref (iter);
1786 /* Retrieve messages */
1787 do_retrieve = (action == ACTION_FORWARD) ||
1788 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1791 TnyAccount *account = NULL;
1792 TnyFolder *folder = NULL;
1793 gdouble download = TRUE;
1794 guint uncached_msgs = 0;
1796 folder = tny_header_get_folder (header);
1798 goto do_retrieve_frees;
1799 account = tny_folder_get_account (folder);
1801 goto do_retrieve_frees;
1803 uncached_msgs = header_list_count_uncached_msgs (header_list);
1805 if (uncached_msgs > 0) {
1806 /* Allways download if we are online. */
1807 if (!tny_device_is_online (modest_runtime_get_device ())) {
1810 /* If ask for user permission to download the messages */
1811 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1812 ngettext("mcen_nc_get_msg",
1816 /* End if the user does not want to continue */
1817 if (response == GTK_RESPONSE_CANCEL)
1824 rf_helper = create_reply_forward_helper (action, win,
1825 reply_forward_type, header);
1826 if (uncached_msgs > 0) {
1827 modest_platform_connect_and_perform (GTK_WINDOW (win),
1829 reply_forward_performer,
1832 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
1833 account, rf_helper);
1838 g_object_unref (account);
1840 g_object_unref (folder);
1842 reply_forward_cb (NULL, header, FALSE, NULL, NULL, rf_helper);
1845 g_object_unref (header_list);
1846 g_object_unref (header);
1851 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1853 g_return_if_fail (MODEST_IS_WINDOW(win));
1855 reply_forward (ACTION_REPLY, win);
1859 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1861 g_return_if_fail (MODEST_IS_WINDOW(win));
1863 reply_forward (ACTION_FORWARD, win);
1867 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1869 g_return_if_fail (MODEST_IS_WINDOW(win));
1871 reply_forward (ACTION_REPLY_TO_ALL, win);
1875 modest_ui_actions_on_next (GtkAction *action,
1876 ModestWindow *window)
1878 if (MODEST_IS_MAIN_WINDOW (window)) {
1879 GtkWidget *header_view;
1881 header_view = modest_main_window_get_child_widget (
1882 MODEST_MAIN_WINDOW(window),
1883 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1887 modest_header_view_select_next (
1888 MODEST_HEADER_VIEW(header_view));
1889 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1890 modest_msg_view_window_select_next_message (
1891 MODEST_MSG_VIEW_WINDOW (window));
1893 g_return_if_reached ();
1898 modest_ui_actions_on_prev (GtkAction *action,
1899 ModestWindow *window)
1901 g_return_if_fail (MODEST_IS_WINDOW(window));
1903 if (MODEST_IS_MAIN_WINDOW (window)) {
1904 GtkWidget *header_view;
1905 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1906 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1910 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1911 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1912 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1914 g_return_if_reached ();
1919 modest_ui_actions_on_sort (GtkAction *action,
1920 ModestWindow *window)
1922 g_return_if_fail (MODEST_IS_WINDOW(window));
1924 if (MODEST_IS_MAIN_WINDOW (window)) {
1925 GtkWidget *header_view;
1926 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1927 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1929 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1934 /* Show sorting dialog */
1935 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1940 new_messages_arrived (ModestMailOperation *self,
1941 TnyList *new_headers,
1945 gboolean show_visual_notifications;
1947 source = modest_mail_operation_get_source (self);
1948 show_visual_notifications = (source) ? FALSE : TRUE;
1950 g_object_unref (source);
1952 /* Notify new messages have been downloaded. If the
1953 send&receive was invoked by the user then do not show any
1954 visual notification, only play a sound and activate the LED
1955 (for the Maemo version) */
1956 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0)
1957 modest_platform_on_new_headers_received (new_headers,
1958 show_visual_notifications);
1963 retrieve_all_messages_cb (GObject *source,
1965 guint retrieve_limit)
1971 window = GTK_WINDOW (source);
1972 msg = g_strdup_printf (_("mail_nc_msg_count_limit_exceeded"),
1973 num_msgs, retrieve_limit);
1975 /* Ask the user if they want to retrieve all the messages */
1977 modest_platform_run_confirmation_dialog_with_buttons (window, msg,
1978 _("mcen_bd_get_all"),
1979 _("mcen_bd_newest_only"));
1980 /* Free and return */
1982 return (response == GTK_RESPONSE_ACCEPT) ? TRUE : FALSE;
1986 TnyAccount *account;
1988 gchar *account_name;
1989 gboolean poke_status;
1990 gboolean interactive;
1991 ModestMailOperation *mail_op;
1995 do_send_receive_performer (gboolean canceled,
1997 GtkWindow *parent_window,
1998 TnyAccount *account,
2001 SendReceiveInfo *info;
2003 info = (SendReceiveInfo *) user_data;
2005 if (err || canceled) {
2006 /* In memory full conditions we could get this error here */
2007 check_memory_full_error ((GtkWidget *) parent_window, err);
2009 if (info->mail_op) {
2010 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
2016 /* Set send/receive operation in progress */
2017 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
2018 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
2021 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
2022 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
2023 G_CALLBACK (on_send_receive_finished),
2026 /* Send & receive. */
2027 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
2028 (info->win) ? retrieve_all_messages_cb : NULL,
2029 new_messages_arrived, info->win);
2034 g_object_unref (G_OBJECT (info->mail_op));
2035 if (info->account_name)
2036 g_free (info->account_name);
2038 g_object_unref (info->win);
2040 g_object_unref (info->account);
2041 g_slice_free (SendReceiveInfo, info);
2045 * This function performs the send & receive required actions. The
2046 * window is used to create the mail operation. Typically it should
2047 * always be the main window, but we pass it as argument in order to
2051 modest_ui_actions_do_send_receive (const gchar *account_name,
2052 gboolean force_connection,
2053 gboolean poke_status,
2054 gboolean interactive,
2057 gchar *acc_name = NULL;
2058 SendReceiveInfo *info;
2059 ModestTnyAccountStore *acc_store;
2061 /* If no account name was provided then get the current account, and if
2062 there is no current account then pick the default one: */
2063 if (!account_name) {
2065 acc_name = g_strdup (modest_window_get_active_account (win));
2067 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2069 g_printerr ("modest: cannot get default account\n");
2073 acc_name = g_strdup (account_name);
2076 acc_store = modest_runtime_get_account_store ();
2078 /* Create the info for the connect and perform */
2079 info = g_slice_new (SendReceiveInfo);
2080 info->account_name = acc_name;
2081 info->win = (win) ? g_object_ref (win) : NULL;
2082 info->poke_status = poke_status;
2083 info->interactive = interactive;
2084 info->account = modest_tny_account_store_get_server_account (acc_store, acc_name,
2085 TNY_ACCOUNT_TYPE_STORE);
2086 /* We need to create the operation here, because otherwise it
2087 could happen that the queue emits the queue-empty signal
2088 while we're trying to connect the account */
2089 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2090 modest_ui_actions_disk_operations_error_handler,
2092 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2094 /* Invoke the connect and perform */
2095 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2096 force_connection, info->account,
2097 do_send_receive_performer, info);
2102 modest_ui_actions_do_cancel_send (const gchar *account_name,
2105 TnyTransportAccount *transport_account;
2106 TnySendQueue *send_queue = NULL;
2107 GError *error = NULL;
2109 /* Get transport account */
2111 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2112 (modest_runtime_get_account_store(),
2114 TNY_ACCOUNT_TYPE_TRANSPORT));
2115 if (!transport_account) {
2116 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2121 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2122 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2123 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2124 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2125 "modest: could not find send queue for account\n");
2127 /* Cancel the current send */
2128 tny_account_cancel (TNY_ACCOUNT (transport_account));
2130 /* Suspend all pending messages */
2131 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2135 if (transport_account != NULL)
2136 g_object_unref (G_OBJECT (transport_account));
2140 modest_ui_actions_cancel_send_all (ModestWindow *win)
2142 GSList *account_names, *iter;
2144 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2147 iter = account_names;
2149 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2150 iter = g_slist_next (iter);
2153 modest_account_mgr_free_account_names (account_names);
2154 account_names = NULL;
2158 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2161 /* Check if accounts exist */
2162 gboolean accounts_exist =
2163 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2165 /* If not, allow the user to create an account before trying to send/receive. */
2166 if (!accounts_exist)
2167 modest_ui_actions_on_accounts (NULL, win);
2169 /* Cancel all sending operaitons */
2170 modest_ui_actions_cancel_send_all (win);
2174 * Refreshes all accounts. This function will be used by automatic
2178 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2179 gboolean force_connection,
2180 gboolean poke_status,
2181 gboolean interactive)
2183 GSList *account_names, *iter;
2185 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2188 iter = account_names;
2190 modest_ui_actions_do_send_receive ((const char*) iter->data,
2192 poke_status, interactive, win);
2193 iter = g_slist_next (iter);
2196 modest_account_mgr_free_account_names (account_names);
2197 account_names = NULL;
2201 * Handler of the click on Send&Receive button in the main toolbar
2204 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2206 /* Check if accounts exist */
2207 gboolean accounts_exist;
2210 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2212 /* If not, allow the user to create an account before trying to send/receive. */
2213 if (!accounts_exist)
2214 modest_ui_actions_on_accounts (NULL, win);
2216 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2217 if (MODEST_IS_MAIN_WINDOW (win)) {
2218 GtkWidget *folder_view;
2219 TnyFolderStore *folder_store;
2222 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2223 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2227 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2230 g_object_unref (folder_store);
2233 /* Refresh the active account. Force the connection if needed
2234 and poke the status of all folders */
2235 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2240 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2243 GtkWidget *header_view;
2245 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2247 header_view = modest_main_window_get_child_widget (main_window,
2248 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2252 conf = modest_runtime_get_conf ();
2254 /* what is saved/restored is depending on the style; thus; we save with
2255 * old style, then update the style, and restore for this new style
2257 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2259 if (modest_header_view_get_style
2260 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2261 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2262 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2264 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2265 MODEST_HEADER_VIEW_STYLE_DETAILS);
2267 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2268 MODEST_CONF_HEADER_VIEW_KEY);
2273 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2275 ModestMainWindow *main_window)
2277 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2278 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2280 /* in the case the folder is empty, show the empty folder message and focus
2282 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2283 if (modest_header_view_is_empty (header_view)) {
2284 TnyFolder *folder = modest_header_view_get_folder (header_view);
2285 GtkWidget *folder_view =
2286 modest_main_window_get_child_widget (main_window,
2287 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2288 if (folder != NULL) {
2289 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2290 g_object_unref (folder);
2292 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2296 /* If no header has been selected then exit */
2301 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2302 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2304 /* Update toolbar dimming state */
2305 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2306 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2310 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2312 ModestMainWindow *main_window)
2315 GtkWidget *open_widget;
2317 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2322 if (modest_header_view_count_selected_headers (header_view) > 1) {
2323 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2327 /* we check for low-mem; in that case, show a warning, and don't allow
2328 * activating headers
2330 if (modest_platform_check_memory_low (MODEST_WINDOW(main_window), TRUE))
2333 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2334 open_widget = modest_window_get_action_widget (MODEST_WINDOW (main_window), "/MenuBar/EmailMenu/EmailOpenMenu");
2335 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2338 headers = modest_header_view_get_selected_headers (header_view);
2340 open_msgs_from_headers (headers, MODEST_WINDOW (main_window));
2342 g_object_unref (headers);
2346 set_active_account_from_tny_account (TnyAccount *account,
2347 ModestWindow *window)
2349 const gchar *server_acc_name = tny_account_get_id (account);
2351 /* We need the TnyAccount provided by the
2352 account store because that is the one that
2353 knows the name of the Modest account */
2354 TnyAccount *modest_server_account = modest_server_account =
2355 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2356 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2358 if (!modest_server_account) {
2359 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2363 /* Update active account, but only if it's not a pseudo-account */
2364 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2365 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2366 const gchar *modest_acc_name =
2367 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2368 if (modest_acc_name)
2369 modest_window_set_active_account (window, modest_acc_name);
2372 g_object_unref (modest_server_account);
2377 folder_refreshed_cb (ModestMailOperation *mail_op,
2381 ModestMainWindow *win = NULL;
2382 GtkWidget *folder_view;
2383 const GError *error;
2385 g_return_if_fail (TNY_IS_FOLDER (folder));
2387 win = MODEST_MAIN_WINDOW (user_data);
2389 /* Check if the operation failed due to memory low conditions */
2390 error = modest_mail_operation_get_error (mail_op);
2391 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2392 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2393 modest_platform_run_information_dialog (GTK_WINDOW (win),
2394 dgettext("ke-recv","memr_ib_operation_disabled"),
2400 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2403 TnyFolderStore *current_folder;
2405 current_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2406 if (current_folder) {
2407 gboolean different = ((TnyFolderStore *) folder != current_folder);
2408 g_object_unref (current_folder);
2414 /* Check if folder is empty and set headers view contents style */
2415 if (tny_folder_get_all_count (folder) == 0)
2416 modest_main_window_set_contents_style (win,
2417 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2422 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2423 TnyFolderStore *folder_store,
2425 ModestMainWindow *main_window)
2428 GtkWidget *header_view;
2430 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2432 header_view = modest_main_window_get_child_widget(main_window,
2433 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2437 conf = modest_runtime_get_conf ();
2439 if (TNY_IS_ACCOUNT (folder_store)) {
2441 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2443 /* Show account details */
2444 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2447 if (TNY_IS_FOLDER (folder_store) && selected) {
2448 TnyAccount *account;
2449 const gchar *account_name = NULL;
2451 /* Update the active account */
2452 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2454 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2456 modest_tny_account_get_parent_modest_account_name_for_server_account (account);
2457 g_object_unref (account);
2461 /* Set the header style by default, it could
2462 be changed later by the refresh callback to
2464 modest_main_window_set_contents_style (main_window,
2465 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2467 /* Set folder on header view. This function
2468 will call tny_folder_refresh_async so we
2469 pass a callback that will be called when
2470 finished. We use that callback to set the
2471 empty view if there are no messages */
2472 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2473 TNY_FOLDER (folder_store),
2475 folder_refreshed_cb,
2478 /* Restore configuration. We need to do this
2479 *after* the set_folder because the widget
2480 memory asks the header view about its
2482 modest_widget_memory_restore (modest_runtime_get_conf (),
2483 G_OBJECT(header_view),
2484 MODEST_CONF_HEADER_VIEW_KEY);
2486 /* No need to save the header view
2487 configuration for Maemo because it only
2488 saves the sorting stuff and that it's
2489 already being done by the sort
2490 dialog. Remove it when the GNOME version
2491 has the same behaviour */
2492 #ifdef MODEST_TOOLKIT_GTK
2493 if (modest_main_window_get_contents_style (main_window) ==
2494 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2495 modest_widget_memory_save (conf, G_OBJECT (header_view),
2496 MODEST_CONF_HEADER_VIEW_KEY);
2498 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2502 /* Update dimming state */
2503 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2504 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2508 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2515 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2517 online = tny_device_is_online (modest_runtime_get_device());
2520 /* already online -- the item is simply not there... */
2521 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2523 GTK_MESSAGE_WARNING,
2525 _("The %s you selected cannot be found"),
2527 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2528 gtk_dialog_run (GTK_DIALOG(dialog));
2530 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2533 _("mcen_bd_dialog_cancel"),
2534 GTK_RESPONSE_REJECT,
2535 _("mcen_bd_dialog_ok"),
2536 GTK_RESPONSE_ACCEPT,
2538 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2539 "Do you want to get online?"), item);
2540 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2541 gtk_label_new (txt), FALSE, FALSE, 0);
2542 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2545 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2546 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2547 /* TODO: Comment about why is this commented out: */
2548 /* modest_platform_connect_and_wait (); */
2551 gtk_widget_destroy (dialog);
2555 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2558 /* g_message ("%s %s", __FUNCTION__, link); */
2563 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2566 modest_platform_activate_uri (link);
2570 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2573 modest_platform_show_uri_popup (link);
2577 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2580 /* we check for low-mem; in that case, show a warning, and don't allow
2581 * viewing attachments
2583 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2586 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2590 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2591 const gchar *address,
2594 /* g_message ("%s %s", __FUNCTION__, address); */
2598 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2599 TnyMsg *saved_draft,
2602 ModestMsgEditWindow *edit_window;
2603 ModestMainWindow *win;
2605 /* FIXME. Make the header view sensitive again. This is a
2606 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2608 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2609 modest_runtime_get_window_mgr(), FALSE));
2611 GtkWidget *hdrview = modest_main_window_get_child_widget(
2612 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2613 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2616 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2618 /* Set draft is there was no error */
2619 if (!modest_mail_operation_get_error (mail_op))
2620 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2622 g_object_unref(edit_window);
2626 enough_space_for_message (ModestMsgEditWindow *edit_window,
2629 TnyAccountStore *acc_store;
2630 guint64 available_disk, expected_size;
2635 acc_store = TNY_ACCOUNT_STORE (modest_runtime_get_account_store());
2636 available_disk = modest_utils_get_available_space (NULL);
2637 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2638 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2643 /* Double check: memory full condition or message too big */
2644 if (available_disk < MIN_FREE_SPACE ||
2645 expected_size > available_disk) {
2647 modest_platform_information_banner (NULL, NULL,
2649 "cerm_device_memory_full"));
2654 * djcb: if we're in low-memory state, we only allow for
2655 * saving messages smaller than
2656 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2657 * should still allow for sending anything critical...
2659 if ((expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) &&
2660 modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE))
2664 * djcb: we also make sure that the attachments are smaller than the max size
2665 * this is for the case where we'd try to forward a message with attachments
2666 * bigger than our max allowed size, or sending an message from drafts which
2667 * somehow got past our checks when attaching.
2669 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2670 modest_platform_run_information_dialog (
2671 GTK_WINDOW(edit_window),
2672 dgettext("ke-recv","memr_ib_operation_disabled"),
2681 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2683 TnyTransportAccount *transport_account;
2684 ModestMailOperation *mail_operation;
2686 gchar *account_name, *from;
2687 ModestAccountMgr *account_mgr;
2688 gboolean had_error = FALSE;
2689 ModestMainWindow *win = NULL;
2691 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2693 data = modest_msg_edit_window_get_msg_data (edit_window);
2696 if (!enough_space_for_message (edit_window, data)) {
2697 modest_msg_edit_window_free_msg_data (edit_window, data);
2701 account_name = g_strdup (data->account_name);
2702 account_mgr = modest_runtime_get_account_mgr();
2704 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2706 account_name = modest_account_mgr_get_default_account (account_mgr);
2707 if (!account_name) {
2708 g_printerr ("modest: no account found\n");
2709 modest_msg_edit_window_free_msg_data (edit_window, data);
2713 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2714 account_name = g_strdup (data->account_name);
2718 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2719 (modest_runtime_get_account_store (),
2721 TNY_ACCOUNT_TYPE_TRANSPORT));
2722 if (!transport_account) {
2723 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2724 g_free (account_name);
2725 modest_msg_edit_window_free_msg_data (edit_window, data);
2728 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2730 /* Create the mail operation */
2731 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
2733 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2735 modest_mail_operation_save_to_drafts (mail_operation,
2747 data->priority_flags,
2748 on_save_to_drafts_cb,
2749 g_object_ref(edit_window));
2751 #ifdef MODEST_TOOLKIT_HILDON2
2752 /* In hildon2 we always show the information banner on saving to drafts.
2753 * It will be a system information banner in this case.
2755 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2756 modest_platform_information_banner (NULL, NULL, text);
2759 /* Use the main window as the parent of the banner, if the
2760 main window does not exist it won't be shown, if the parent
2761 window exists then it's properly shown. We don't use the
2762 editor window because it could be closed (save to drafts
2763 could happen after closing the window */
2764 win = (ModestMainWindow *)
2765 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
2767 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2768 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
2772 modest_msg_edit_window_set_modified (edit_window, FALSE);
2776 g_free (account_name);
2777 g_object_unref (G_OBJECT (transport_account));
2778 g_object_unref (G_OBJECT (mail_operation));
2780 modest_msg_edit_window_free_msg_data (edit_window, data);
2783 * If the drafts folder is selected then make the header view
2784 * insensitive while the message is being saved to drafts
2785 * (it'll be sensitive again in on_save_to_drafts_cb()). This
2786 * is not very clean but it avoids letting the drafts folder
2787 * in an inconsistent state: the user could edit the message
2788 * being saved and undesirable things would happen.
2789 * In the average case the user won't notice anything at
2790 * all. In the worst case (the user is editing a really big
2791 * file from Drafts) the header view will be insensitive
2792 * during the saving process (10 or 20 seconds, depending on
2793 * the message). Anyway this is just a quick workaround: once
2794 * we find a better solution it should be removed
2795 * See NB#65125 (commend #18) for details.
2797 if (!had_error && win != NULL) {
2798 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
2799 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
2801 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
2803 if (modest_tny_folder_is_local_folder(folder)) {
2804 TnyFolderType folder_type;
2805 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
2806 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
2807 GtkWidget *hdrview = modest_main_window_get_child_widget(
2808 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2809 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
2813 if (folder != NULL) g_object_unref(folder);
2820 /* For instance, when clicking the Send toolbar button when editing a message: */
2822 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2824 TnyTransportAccount *transport_account = NULL;
2825 gboolean had_error = FALSE;
2827 ModestAccountMgr *account_mgr;
2828 gchar *account_name;
2830 ModestMailOperation *mail_operation;
2832 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
2834 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2837 data = modest_msg_edit_window_get_msg_data (edit_window);
2840 if (!enough_space_for_message (edit_window, data)) {
2841 modest_msg_edit_window_free_msg_data (edit_window, data);
2845 account_mgr = modest_runtime_get_account_mgr();
2846 account_name = g_strdup (data->account_name);
2848 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2851 account_name = modest_account_mgr_get_default_account (account_mgr);
2853 if (!account_name) {
2854 modest_msg_edit_window_free_msg_data (edit_window, data);
2855 /* Run account setup wizard */
2856 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
2861 /* Get the currently-active transport account for this modest account: */
2862 if (strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
2864 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2865 (modest_runtime_get_account_store (),
2866 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
2869 if (!transport_account) {
2870 modest_msg_edit_window_free_msg_data (edit_window, data);
2871 /* Run account setup wizard */
2872 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2877 /* Create the mail operation */
2878 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2879 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
2880 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2882 modest_mail_operation_send_new_mail (mail_operation,
2894 data->priority_flags);
2896 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
2897 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2900 if (modest_mail_operation_get_error (mail_operation) != NULL) {
2901 const GError *error = modest_mail_operation_get_error (mail_operation);
2902 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
2903 error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
2904 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
2905 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
2912 g_free (account_name);
2913 g_object_unref (G_OBJECT (transport_account));
2914 g_object_unref (G_OBJECT (mail_operation));
2916 modest_msg_edit_window_free_msg_data (edit_window, data);
2919 modest_msg_edit_window_set_sent (edit_window, TRUE);
2921 /* Save settings and close the window: */
2922 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2929 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2930 ModestMsgEditWindow *window)
2932 ModestMsgEditFormatState *format_state = NULL;
2934 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2935 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2937 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2940 format_state = modest_msg_edit_window_get_format_state (window);
2941 g_return_if_fail (format_state != NULL);
2943 format_state->bold = gtk_toggle_action_get_active (action);
2944 modest_msg_edit_window_set_format_state (window, format_state);
2945 g_free (format_state);
2950 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2951 ModestMsgEditWindow *window)
2953 ModestMsgEditFormatState *format_state = NULL;
2955 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2956 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2958 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2961 format_state = modest_msg_edit_window_get_format_state (window);
2962 g_return_if_fail (format_state != NULL);
2964 format_state->italics = gtk_toggle_action_get_active (action);
2965 modest_msg_edit_window_set_format_state (window, format_state);
2966 g_free (format_state);
2971 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2972 ModestMsgEditWindow *window)
2974 ModestMsgEditFormatState *format_state = NULL;
2976 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2977 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2979 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2982 format_state = modest_msg_edit_window_get_format_state (window);
2983 g_return_if_fail (format_state != NULL);
2985 format_state->bullet = gtk_toggle_action_get_active (action);
2986 modest_msg_edit_window_set_format_state (window, format_state);
2987 g_free (format_state);
2992 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2993 GtkRadioAction *selected,
2994 ModestMsgEditWindow *window)
2996 ModestMsgEditFormatState *format_state = NULL;
2997 GtkJustification value;
2999 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3001 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3004 value = gtk_radio_action_get_current_value (selected);
3006 format_state = modest_msg_edit_window_get_format_state (window);
3007 g_return_if_fail (format_state != NULL);
3009 format_state->justification = value;
3010 modest_msg_edit_window_set_format_state (window, format_state);
3011 g_free (format_state);
3015 modest_ui_actions_on_select_editor_color (GtkAction *action,
3016 ModestMsgEditWindow *window)
3018 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3019 g_return_if_fail (GTK_IS_ACTION (action));
3021 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3024 modest_msg_edit_window_select_color (window);
3028 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3029 ModestMsgEditWindow *window)
3031 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3032 g_return_if_fail (GTK_IS_ACTION (action));
3034 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3037 modest_msg_edit_window_select_background_color (window);
3041 modest_ui_actions_on_insert_image (GtkAction *action,
3042 ModestMsgEditWindow *window)
3044 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3045 g_return_if_fail (GTK_IS_ACTION (action));
3048 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3051 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3054 modest_msg_edit_window_insert_image (window);
3058 modest_ui_actions_on_attach_file (GtkAction *action,
3059 ModestMsgEditWindow *window)
3061 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3062 g_return_if_fail (GTK_IS_ACTION (action));
3064 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3067 modest_msg_edit_window_offer_attach_file (window);
3071 modest_ui_actions_on_remove_attachments (GtkAction *action,
3072 ModestMsgEditWindow *window)
3074 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3075 g_return_if_fail (GTK_IS_ACTION (action));
3077 modest_msg_edit_window_remove_attachments (window, NULL);
3081 #ifndef MODEST_TOOLKIT_GTK
3086 TnyFolderStore *folder;
3087 } CreateFolderHelper;
3090 show_create_folder_in_timeout (gpointer data)
3092 CreateFolderHelper *helper = (CreateFolderHelper *) data;
3094 /* Remove the timeout ASAP, we can not wait until the dialog
3095 is shown because it could take a lot of time and so the
3096 timeout could be called twice or more times */
3097 g_source_remove (helper->handler);
3099 gdk_threads_enter ();
3100 do_create_folder (helper->win, helper->folder, helper->name);
3101 gdk_threads_leave ();
3103 g_object_unref (helper->win);
3104 g_object_unref (helper->folder);
3105 g_free (helper->name);
3106 g_slice_free (CreateFolderHelper, helper);
3113 do_create_folder_cb (ModestMailOperation *mail_op,
3114 TnyFolderStore *parent_folder,
3115 TnyFolder *new_folder,
3118 gchar *suggested_name = (gchar *) user_data;
3119 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3121 if (modest_mail_operation_get_error (mail_op)) {
3123 /* Show an error. If there was some problem writing to
3124 disk, show it, otherwise show the generic folder
3125 create error. We do it here and not in an error
3126 handler because the call to do_create_folder will
3127 stop the main loop in a gtk_dialog_run and then,
3128 the message won't be shown until that dialog is
3130 modest_ui_actions_disk_operations_error_handler (mail_op,
3131 _("mail_in_ui_folder_create_error"));
3133 /* Try again. Do *NOT* show any error because the mail
3134 operations system will do it for us because we
3135 created the mail_op with new_with_error_handler */
3136 #ifndef MODEST_TOOLKIT_GTK
3137 CreateFolderHelper *helper;
3138 helper = g_slice_new0 (CreateFolderHelper);
3139 helper->name = g_strdup (suggested_name);
3140 helper->folder = g_object_ref (parent_folder);
3141 helper->win = g_object_ref (source_win);
3143 /* Ugly but neccesary stuff. The problem is that the
3144 dialog when is shown calls a function that destroys
3145 all the temporary windows, so the banner is
3147 helper->handler = g_timeout_add (2000, show_create_folder_in_timeout, helper);
3149 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3152 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3153 * FIXME: any other? */
3154 GtkWidget *folder_view;
3156 if (MODEST_IS_MAIN_WINDOW(source_win))
3158 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3159 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3162 get_folder_view_from_move_to_dialog (GTK_WIDGET(source_win));
3164 /* Select the newly created folder. It could happen
3165 that the widget is no longer there (i.e. the window
3166 has been destroyed, so we need to check this */
3168 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3170 g_object_unref (new_folder);
3172 /* Free. Note that the first time it'll be NULL so noop */
3173 g_free (suggested_name);
3174 g_object_unref (source_win);
3178 do_create_folder (GtkWindow *parent_window,
3179 TnyFolderStore *parent_folder,
3180 const gchar *suggested_name)
3183 gchar *folder_name = NULL;
3185 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3187 (gchar *) suggested_name,
3190 if (result == GTK_RESPONSE_ACCEPT) {
3191 ModestMailOperation *mail_op;
3193 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3194 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3196 modest_mail_operation_create_folder (mail_op,
3198 (const gchar *) folder_name,
3199 do_create_folder_cb,
3201 g_object_unref (mail_op);
3206 create_folder_performer (gboolean canceled,
3208 GtkWindow *parent_window,
3209 TnyAccount *account,
3212 TnyFolderStore *parent_folder = TNY_FOLDER_STORE (user_data);
3214 if (canceled || err) {
3215 /* In memory full conditions we could get this error here */
3216 check_memory_full_error ((GtkWidget *) parent_window, err);
3220 /* Run the new folder dialog */
3221 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3224 g_object_unref (parent_folder);
3228 modest_ui_actions_create_folder(GtkWidget *parent_window,
3229 GtkWidget *folder_view)
3231 TnyFolderStore *parent_folder;
3233 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3235 if (parent_folder) {
3236 /* The parent folder will be freed in the callback */
3237 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3240 create_folder_performer,
3246 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
3248 GtkWidget *folder_view;
3250 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3252 folder_view = modest_main_window_get_child_widget (main_window,
3253 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3257 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
3261 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3264 const GError *error = NULL;
3265 const gchar *message = NULL;
3267 /* Get error message */
3268 error = modest_mail_operation_get_error (mail_op);
3270 g_return_if_reached ();
3272 if (error->domain == MODEST_MAIL_OPERATION_ERROR &&
3273 error->code == MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS) {
3274 message = _CS("ckdg_ib_folder_already_exists");
3275 } else if (error->domain == TNY_ERROR_DOMAIN &&
3276 error->code == TNY_SERVICE_ERROR_STATE) {
3277 /* This means that the folder is already in use (a
3278 message is opened for example */
3279 message = _("emev_ni_internal_error");
3281 message = _("emev_ib_ui_imap_unable_to_rename");
3284 /* We don't set a parent for the dialog because the dialog
3285 will be destroyed so the banner won't appear */
3286 modest_platform_information_banner (NULL, NULL, message);
3290 TnyFolderStore *folder;
3295 on_rename_folder_cb (ModestMailOperation *mail_op,
3296 TnyFolder *new_folder,
3299 ModestFolderView *folder_view;
3301 /* If the window was closed when renaming a folder this could
3303 if (!MODEST_IS_FOLDER_VIEW (user_data))
3306 folder_view = MODEST_FOLDER_VIEW (user_data);
3307 /* Note that if the rename fails new_folder will be NULL */
3309 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3311 modest_folder_view_select_first_inbox_or_local (folder_view);
3313 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3317 on_rename_folder_performer (gboolean canceled,
3319 GtkWindow *parent_window,
3320 TnyAccount *account,
3323 ModestMailOperation *mail_op = NULL;
3324 GtkTreeSelection *sel = NULL;
3325 GtkWidget *folder_view = NULL;
3326 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3328 if (canceled || err) {
3329 /* In memory full conditions we could get this error here */
3330 check_memory_full_error ((GtkWidget *) parent_window, err);
3331 } else if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3333 folder_view = modest_main_window_get_child_widget (
3334 MODEST_MAIN_WINDOW (parent_window),
3335 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3338 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3339 modest_ui_actions_rename_folder_error_handler,
3340 parent_window, NULL);
3342 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3345 /* Clear the headers view */
3346 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3347 gtk_tree_selection_unselect_all (sel);
3349 /* Actually rename the folder */
3350 modest_mail_operation_rename_folder (mail_op,
3351 TNY_FOLDER (data->folder),
3352 (const gchar *) (data->new_name),
3353 on_rename_folder_cb,
3355 g_object_unref (data->folder);
3356 g_object_unref (mail_op);
3359 g_free (data->new_name);
3364 modest_ui_actions_on_rename_folder (GtkAction *action,
3365 ModestMainWindow *main_window)
3367 TnyFolderStore *folder;
3368 GtkWidget *folder_view;
3369 GtkWidget *header_view;
3371 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3373 folder_view = modest_main_window_get_child_widget (main_window,
3374 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3378 header_view = modest_main_window_get_child_widget (main_window,
3379 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3384 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3389 if (TNY_IS_FOLDER (folder)) {
3392 const gchar *current_name;
3393 TnyFolderStore *parent;
3394 gboolean do_rename = TRUE;
3396 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3397 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3398 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
3399 parent, current_name,
3401 g_object_unref (parent);
3403 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3406 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3407 rename_folder_data->folder = g_object_ref (folder);
3408 rename_folder_data->new_name = folder_name;
3409 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(main_window), TRUE,
3410 folder, on_rename_folder_performer, rename_folder_data);
3413 g_object_unref (folder);
3417 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3420 GObject *win = modest_mail_operation_get_source (mail_op);
3422 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3423 _("mail_in_ui_folder_delete_error"),
3425 g_object_unref (win);
3429 TnyFolderStore *folder;
3430 gboolean move_to_trash;
3434 on_delete_folder_cb (gboolean canceled,
3436 GtkWindow *parent_window,
3437 TnyAccount *account,
3440 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3441 GtkWidget *folder_view;
3442 ModestMailOperation *mail_op;
3443 GtkTreeSelection *sel;
3445 if (!MODEST_IS_MAIN_WINDOW(parent_window) || canceled || (err!=NULL)) {
3446 g_object_unref (G_OBJECT (info->folder));
3451 folder_view = modest_main_window_get_child_widget (
3452 MODEST_MAIN_WINDOW (parent_window),
3453 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3455 /* Unselect the folder before deleting it to free the headers */
3456 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3457 gtk_tree_selection_unselect_all (sel);
3459 /* Create the mail operation */
3461 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3462 modest_ui_actions_delete_folder_error_handler,
3465 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3467 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3469 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3471 g_object_unref (G_OBJECT (mail_op));
3472 g_object_unref (G_OBJECT (info->folder));
3477 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
3479 TnyFolderStore *folder;
3480 GtkWidget *folder_view;
3484 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3486 folder_view = modest_main_window_get_child_widget (main_window,
3487 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3491 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3493 /* Show an error if it's an account */
3494 if (!TNY_IS_FOLDER (folder)) {
3495 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
3496 _("mail_in_ui_folder_delete_error"),
3498 g_object_unref (G_OBJECT (folder));
3503 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3504 tny_folder_get_name (TNY_FOLDER (folder)));
3505 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
3506 (const gchar *) message);
3509 if (response == GTK_RESPONSE_OK) {
3510 DeleteFolderInfo *info;
3511 info = g_new0(DeleteFolderInfo, 1);
3512 info->folder = folder;
3513 info->move_to_trash = move_to_trash;
3514 g_object_ref (G_OBJECT (info->folder));
3515 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder));
3516 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (main_window),
3518 TNY_FOLDER_STORE (account),
3519 on_delete_folder_cb, info);
3520 g_object_unref (account);
3522 g_object_unref (G_OBJECT (folder));
3526 modest_ui_actions_on_delete_folder (GtkAction *action,
3527 ModestMainWindow *main_window)
3529 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3531 delete_folder (main_window, FALSE);
3535 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3537 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3539 delete_folder (main_window, TRUE);
3543 typedef struct _PasswordDialogFields {
3544 GtkWidget *username;
3545 GtkWidget *password;
3547 } PasswordDialogFields;
3550 password_dialog_check_field (GtkEditable *editable,
3551 PasswordDialogFields *fields)
3554 gboolean any_value_empty = FALSE;
3556 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
3557 if ((value == NULL) || value[0] == '\0') {
3558 any_value_empty = TRUE;
3560 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
3561 if ((value == NULL) || value[0] == '\0') {
3562 any_value_empty = TRUE;
3564 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3568 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3569 const gchar* server_account_name,
3574 ModestMainWindow *main_window)
3576 g_return_if_fail(server_account_name);
3577 gboolean completed = FALSE;
3578 PasswordDialogFields *fields = NULL;
3580 /* Initalize output parameters: */
3587 #ifndef MODEST_TOOLKIT_GTK
3588 /* Maemo uses a different (awkward) button order,
3589 * It should probably just use gtk_alternative_dialog_button_order ().
3591 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3594 _("mcen_bd_dialog_ok"),
3595 GTK_RESPONSE_ACCEPT,
3596 _("mcen_bd_dialog_cancel"),
3597 GTK_RESPONSE_REJECT,
3600 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3604 GTK_RESPONSE_REJECT,
3606 GTK_RESPONSE_ACCEPT,
3608 #endif /* !MODEST_TOOLKIT_GTK */
3610 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog), NULL);
3612 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3613 modest_runtime_get_account_mgr(), server_account_name);
3614 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3615 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3621 /* This causes a warning because the logical ID has no %s in it,
3622 * though the translation does, but there is not much we can do about that: */
3623 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3624 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
3627 g_free (server_name);
3631 gchar *initial_username = modest_account_mgr_get_server_account_username (
3632 modest_runtime_get_account_mgr(), server_account_name);
3634 GtkWidget *entry_username = gtk_entry_new ();
3635 if (initial_username)
3636 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
3637 /* Dim this if a connection has ever succeeded with this username,
3638 * as per the UI spec: */
3639 /* const gboolean username_known = */
3640 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3641 /* modest_runtime_get_account_mgr(), server_account_name); */
3642 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3644 /* We drop the username sensitive code and disallow changing it here
3645 * as tinymail does not support really changing the username in the callback
3647 gtk_widget_set_sensitive (entry_username, FALSE);
3649 #ifndef MODEST_TOOLKIT_GTK
3650 /* Auto-capitalization is the default, so let's turn it off: */
3651 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3653 /* Create a size group to be used by all captions.
3654 * Note that HildonCaption does not create a default size group if we do not specify one.
3655 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3656 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3658 GtkWidget *caption = hildon_caption_new (sizegroup,
3659 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
3660 gtk_widget_show (entry_username);
3661 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3662 FALSE, FALSE, MODEST_MARGIN_HALF);
3663 gtk_widget_show (caption);
3665 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
3667 #endif /* !MODEST_TOOLKIT_GTK */
3670 GtkWidget *entry_password = gtk_entry_new ();
3671 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3672 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3674 #ifndef MODEST_TOOLKIT_GTK
3675 /* Auto-capitalization is the default, so let's turn it off: */
3676 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3677 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3679 caption = hildon_caption_new (sizegroup,
3680 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
3681 gtk_widget_show (entry_password);
3682 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3683 FALSE, FALSE, MODEST_MARGIN_HALF);
3684 gtk_widget_show (caption);
3685 g_object_unref (sizegroup);
3687 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
3689 #endif /* !MODEST_TOOLKIT_GTK */
3691 if (initial_username != NULL)
3692 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3694 /* This is not in the Maemo UI spec:
3695 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3696 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3700 fields = g_slice_new0 (PasswordDialogFields);
3701 fields->username = entry_username;
3702 fields->password = entry_password;
3703 fields->dialog = dialog;
3705 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3706 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3707 password_dialog_check_field (NULL, fields);
3709 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3711 while (!completed) {
3713 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3715 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
3717 /* Note that an empty field becomes the "" string */
3718 if (*username && strlen (*username) > 0) {
3719 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
3720 server_account_name,
3724 const gboolean username_was_changed =
3725 (strcmp (*username, initial_username) != 0);
3726 if (username_was_changed) {
3727 g_warning ("%s: tinymail does not yet support changing the "
3728 "username in the get_password() callback.\n", __FUNCTION__);
3732 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
3733 _("mcen_ib_username_pw_incorrect"));
3739 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
3741 /* We do not save the password in the configuration,
3742 * because this function is only called for passwords that should
3743 * not be remembered:
3744 modest_server_account_set_password (
3745 modest_runtime_get_account_mgr(), server_account_name,
3752 /* Set parent to NULL or the banner will disappear with its parent dialog */
3753 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
3764 /* This is not in the Maemo UI spec:
3765 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3771 gtk_widget_destroy (dialog);
3772 g_slice_free (PasswordDialogFields, fields);
3774 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3778 modest_ui_actions_on_cut (GtkAction *action,
3779 ModestWindow *window)
3781 GtkWidget *focused_widget;
3782 GtkClipboard *clipboard;
3784 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3785 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3786 if (GTK_IS_EDITABLE (focused_widget)) {
3787 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3788 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3789 gtk_clipboard_store (clipboard);
3790 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3791 GtkTextBuffer *buffer;
3793 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3794 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3795 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3796 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3797 gtk_clipboard_store (clipboard);
3799 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3800 TnyList *header_list = modest_header_view_get_selected_headers (
3801 MODEST_HEADER_VIEW (focused_widget));
3802 gboolean continue_download = FALSE;
3803 gint num_of_unc_msgs;
3805 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3807 if (num_of_unc_msgs) {
3808 TnyAccount *account = get_account_from_header_list (header_list);
3810 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3811 g_object_unref (account);
3815 if (num_of_unc_msgs == 0 || continue_download) {
3816 /* modest_platform_information_banner (
3817 NULL, NULL, _CS("mcen_ib_getting_items"));*/
3818 modest_header_view_cut_selection (
3819 MODEST_HEADER_VIEW (focused_widget));
3822 g_object_unref (header_list);
3823 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3824 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3829 modest_ui_actions_on_copy (GtkAction *action,
3830 ModestWindow *window)
3832 GtkClipboard *clipboard;
3833 GtkWidget *focused_widget;
3834 gboolean copied = TRUE;
3836 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3837 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3839 if (GTK_IS_LABEL (focused_widget)) {
3841 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
3842 gtk_clipboard_set_text (clipboard, selection, -1);
3844 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3845 gtk_clipboard_store (clipboard);
3846 } else if (GTK_IS_EDITABLE (focused_widget)) {
3847 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3848 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3849 gtk_clipboard_store (clipboard);
3850 } else if (GTK_IS_HTML (focused_widget)) {
3853 sel = gtk_html_get_selection_html (GTK_HTML (focused_widget), &len);
3854 if ((sel == NULL) || (sel[0] == '\0')) {
3857 gtk_html_copy (GTK_HTML (focused_widget));
3858 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3859 gtk_clipboard_store (clipboard);
3861 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3862 GtkTextBuffer *buffer;
3863 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3864 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3865 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3866 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3867 gtk_clipboard_store (clipboard);
3869 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3870 TnyList *header_list = modest_header_view_get_selected_headers (
3871 MODEST_HEADER_VIEW (focused_widget));
3872 gboolean continue_download = FALSE;
3873 gint num_of_unc_msgs;
3875 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3877 if (num_of_unc_msgs) {
3878 TnyAccount *account = get_account_from_header_list (header_list);
3880 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3881 g_object_unref (account);
3885 if (num_of_unc_msgs == 0 || continue_download) {
3886 modest_platform_information_banner (
3887 NULL, NULL, _CS("mcen_ib_getting_items"));
3888 modest_header_view_copy_selection (
3889 MODEST_HEADER_VIEW (focused_widget));
3893 g_object_unref (header_list);
3895 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3896 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3899 /* Show information banner if there was a copy to clipboard */
3901 modest_platform_information_banner (
3902 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3906 modest_ui_actions_on_undo (GtkAction *action,
3907 ModestWindow *window)
3909 ModestEmailClipboard *clipboard = NULL;
3911 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3912 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3913 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3914 /* Clear clipboard source */
3915 clipboard = modest_runtime_get_email_clipboard ();
3916 modest_email_clipboard_clear (clipboard);
3919 g_return_if_reached ();
3924 modest_ui_actions_on_redo (GtkAction *action,
3925 ModestWindow *window)
3927 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3928 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3931 g_return_if_reached ();
3937 destroy_information_note (ModestMailOperation *mail_op,
3940 /* destroy information note */
3941 gtk_widget_destroy (GTK_WIDGET(user_data));
3945 destroy_folder_information_note (ModestMailOperation *mail_op,
3946 TnyFolder *new_folder,
3949 /* destroy information note */
3950 gtk_widget_destroy (GTK_WIDGET(user_data));
3955 paste_as_attachment_free (gpointer data)
3957 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3959 if (helper->banner) {
3960 gtk_widget_destroy (helper->banner);
3961 g_object_unref (helper->banner);
3967 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3972 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3973 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3978 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3983 modest_ui_actions_on_paste (GtkAction *action,
3984 ModestWindow *window)
3986 GtkWidget *focused_widget = NULL;
3987 GtkWidget *inf_note = NULL;
3988 ModestMailOperation *mail_op = NULL;
3990 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3991 if (GTK_IS_EDITABLE (focused_widget)) {
3992 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3993 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3994 ModestEmailClipboard *e_clipboard = NULL;
3995 e_clipboard = modest_runtime_get_email_clipboard ();
3996 if (modest_email_clipboard_cleared (e_clipboard)) {
3997 GtkTextBuffer *buffer;
3998 GtkClipboard *clipboard;
4000 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
4001 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4002 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
4003 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
4004 ModestMailOperation *mail_op;
4005 TnyFolder *src_folder;
4008 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
4009 helper->window = MODEST_MSG_EDIT_WINDOW (window);
4010 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4011 _CS("ckct_nw_pasting"));
4012 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
4013 mail_op = modest_mail_operation_new (G_OBJECT (window));
4014 if (helper->banner != NULL) {
4015 g_object_ref (G_OBJECT (helper->banner));
4016 gtk_widget_show (GTK_WIDGET (helper->banner));
4020 modest_mail_operation_get_msgs_full (mail_op,
4022 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
4024 paste_as_attachment_free);
4027 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
4028 ModestEmailClipboard *clipboard = NULL;
4029 TnyFolder *src_folder = NULL;
4030 TnyFolderStore *folder_store = NULL;
4031 TnyList *data = NULL;
4032 gboolean delete = FALSE;
4034 /* Check clipboard source */
4035 clipboard = modest_runtime_get_email_clipboard ();
4036 if (modest_email_clipboard_cleared (clipboard))
4039 /* Get elements to paste */
4040 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
4042 /* Create a new mail operation */
4043 mail_op = modest_mail_operation_new (G_OBJECT(window));
4045 /* Get destination folder */
4046 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
4048 /* transfer messages */
4052 /* Ask for user confirmation */
4054 modest_ui_actions_msgs_move_to_confirmation (window,
4055 TNY_FOLDER (folder_store),
4059 if (response == GTK_RESPONSE_OK) {
4060 /* Launch notification */
4061 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4062 _CS("ckct_nw_pasting"));
4063 if (inf_note != NULL) {
4064 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4065 gtk_widget_show (GTK_WIDGET(inf_note));
4068 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4069 modest_mail_operation_xfer_msgs (mail_op,
4071 TNY_FOLDER (folder_store),
4073 destroy_information_note,
4076 g_object_unref (mail_op);
4079 } else if (src_folder != NULL) {
4080 /* Launch notification */
4081 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4082 _CS("ckct_nw_pasting"));
4083 if (inf_note != NULL) {
4084 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4085 gtk_widget_show (GTK_WIDGET(inf_note));
4088 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4089 modest_mail_operation_xfer_folder (mail_op,
4093 destroy_folder_information_note,
4099 g_object_unref (data);
4100 if (src_folder != NULL)
4101 g_object_unref (src_folder);
4102 if (folder_store != NULL)
4103 g_object_unref (folder_store);
4109 modest_ui_actions_on_select_all (GtkAction *action,
4110 ModestWindow *window)
4112 GtkWidget *focused_widget;
4114 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4115 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4116 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4117 } else if (GTK_IS_LABEL (focused_widget)) {
4118 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4119 } else if (GTK_IS_EDITABLE (focused_widget)) {
4120 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4121 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4122 GtkTextBuffer *buffer;
4123 GtkTextIter start, end;
4125 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4126 gtk_text_buffer_get_start_iter (buffer, &start);
4127 gtk_text_buffer_get_end_iter (buffer, &end);
4128 gtk_text_buffer_select_range (buffer, &start, &end);
4129 } else if (GTK_IS_HTML (focused_widget)) {
4130 gtk_html_select_all (GTK_HTML (focused_widget));
4131 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4132 GtkWidget *header_view = focused_widget;
4133 GtkTreeSelection *selection = NULL;
4135 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4136 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4137 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4140 /* Disable window dimming management */
4141 modest_window_disable_dimming (MODEST_WINDOW(window));
4143 /* Select all messages */
4144 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4145 gtk_tree_selection_select_all (selection);
4147 /* Set focuse on header view */
4148 gtk_widget_grab_focus (header_view);
4150 /* Enable window dimming management */
4151 modest_window_enable_dimming (MODEST_WINDOW(window));
4152 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (window));
4153 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4159 modest_ui_actions_on_mark_as_read (GtkAction *action,
4160 ModestWindow *window)
4162 g_return_if_fail (MODEST_IS_WINDOW(window));
4164 /* Mark each header as read */
4165 do_headers_action (window, headers_action_mark_as_read, NULL);
4169 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4170 ModestWindow *window)
4172 g_return_if_fail (MODEST_IS_WINDOW(window));
4174 /* Mark each header as read */
4175 do_headers_action (window, headers_action_mark_as_unread, NULL);
4179 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4180 GtkRadioAction *selected,
4181 ModestWindow *window)
4185 value = gtk_radio_action_get_current_value (selected);
4186 if (MODEST_IS_WINDOW (window)) {
4187 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4192 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4193 GtkRadioAction *selected,
4194 ModestWindow *window)
4196 TnyHeaderFlags flags;
4197 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4199 flags = gtk_radio_action_get_current_value (selected);
4200 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4204 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4205 GtkRadioAction *selected,
4206 ModestWindow *window)
4210 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4212 file_format = gtk_radio_action_get_current_value (selected);
4213 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4218 modest_ui_actions_on_zoom_plus (GtkAction *action,
4219 ModestWindow *window)
4221 g_return_if_fail (MODEST_IS_WINDOW (window));
4223 modest_window_zoom_plus (MODEST_WINDOW (window));
4227 modest_ui_actions_on_zoom_minus (GtkAction *action,
4228 ModestWindow *window)
4230 g_return_if_fail (MODEST_IS_WINDOW (window));
4232 modest_window_zoom_minus (MODEST_WINDOW (window));
4236 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4237 ModestWindow *window)
4239 ModestWindowMgr *mgr;
4240 gboolean fullscreen, active;
4241 g_return_if_fail (MODEST_IS_WINDOW (window));
4243 mgr = modest_runtime_get_window_mgr ();
4245 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4246 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4248 if (active != fullscreen) {
4249 modest_window_mgr_set_fullscreen_mode (mgr, active);
4250 #ifndef MODEST_TOOLKIT_HILDON2
4251 gtk_window_present (GTK_WINDOW (window));
4257 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4258 ModestWindow *window)
4260 ModestWindowMgr *mgr;
4261 gboolean fullscreen;
4263 g_return_if_fail (MODEST_IS_WINDOW (window));
4265 mgr = modest_runtime_get_window_mgr ();
4266 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4267 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4269 #ifndef MODEST_TOOLKIT_HILDON2
4270 gtk_window_present (GTK_WINDOW (window));
4275 * Used by modest_ui_actions_on_details to call do_headers_action
4278 headers_action_show_details (TnyHeader *header,
4279 ModestWindow *window,
4283 modest_platform_run_header_details_dialog (GTK_WINDOW (window), header);
4287 * Show the header details in a ModestDetailsDialog widget
4290 modest_ui_actions_on_details (GtkAction *action,
4293 TnyList * headers_list;
4297 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4300 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4303 g_object_unref (msg);
4305 headers_list = get_selected_headers (win);
4309 iter = tny_list_create_iterator (headers_list);
4311 header = TNY_HEADER (tny_iterator_get_current (iter));
4313 headers_action_show_details (header, win, NULL);
4314 g_object_unref (header);
4317 g_object_unref (iter);
4318 g_object_unref (headers_list);
4320 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4321 GtkWidget *folder_view, *header_view;
4323 /* Check which widget has the focus */
4324 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4325 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4326 if (gtk_widget_is_focus (folder_view)) {
4327 TnyFolderStore *folder_store
4328 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4329 if (!folder_store) {
4330 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4333 /* Show only when it's a folder */
4334 /* This function should not be called for account items,
4335 * because we dim the menu item for them. */
4336 if (TNY_IS_FOLDER (folder_store)) {
4337 modest_platform_run_folder_details_dialog (GTK_WINDOW (win),
4338 TNY_FOLDER (folder_store));
4341 g_object_unref (folder_store);
4344 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4345 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4346 /* Show details of each header */
4347 do_headers_action (win, headers_action_show_details, header_view);
4353 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4354 ModestMsgEditWindow *window)
4356 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4358 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4362 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4363 ModestMsgEditWindow *window)
4365 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4367 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4371 modest_ui_actions_toggle_folders_view (GtkAction *action,
4372 ModestMainWindow *main_window)
4374 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4376 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4377 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4379 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4383 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4384 ModestWindow *window)
4386 gboolean active, fullscreen = FALSE;
4387 ModestWindowMgr *mgr;
4389 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4391 /* Check if we want to toggle the toolbar vuew in fullscreen
4393 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4394 "ViewShowToolbarFullScreen")) {
4398 /* Toggle toolbar */
4399 mgr = modest_runtime_get_window_mgr ();
4400 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4404 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4405 ModestMsgEditWindow *window)
4407 modest_msg_edit_window_select_font (window);
4412 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4413 const gchar *display_name,
4416 /* don't update the display name if it was already set;
4417 * updating the display name apparently is expensive */
4418 const gchar* old_name = gtk_window_get_title (window);
4420 if (display_name == NULL)
4423 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4424 return; /* don't do anything */
4426 /* This is usually used to change the title of the main window, which
4427 * is the one that holds the folder view. Note that this change can
4428 * happen even when the widget doesn't have the focus. */
4429 gtk_window_set_title (window, display_name);
4434 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4436 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4437 modest_msg_edit_window_select_contacts (window);
4441 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4443 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4444 modest_msg_edit_window_check_names (window, FALSE);
4448 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
4450 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
4451 GTK_WIDGET (user_data));
4455 * This function is used to track changes in the selection of the
4456 * folder view that is inside the "move to" dialog to enable/disable
4457 * the OK button because we do not want the user to select a disallowed
4458 * destination for a folder.
4459 * The user also not desired to be able to use NEW button on items where
4460 * folder creation is not possibel.
4463 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4464 TnyFolderStore *folder_store,
4468 GtkWidget *dialog = NULL;
4469 GtkWidget *ok_button = NULL, *new_button = NULL;
4470 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4471 gboolean moving_folder = FALSE;
4472 gboolean is_local_account = TRUE;
4473 GtkWidget *folder_view = NULL;
4474 ModestTnyFolderRules rules;
4476 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
4481 /* Get the OK button */
4482 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
4486 ok_button = g_object_get_data (G_OBJECT (dialog), MOVE_FOLDER_OK_BUTTON);
4487 new_button = g_object_get_data (G_OBJECT (dialog), MOVE_FOLDER_NEW_BUTTON);
4489 /* check if folder_store is an remote account */
4490 if (TNY_IS_ACCOUNT (folder_store)) {
4491 TnyAccount *local_account = NULL;
4492 TnyAccount *mmc_account = NULL;
4493 ModestTnyAccountStore *account_store = NULL;
4495 account_store = modest_runtime_get_account_store ();
4496 local_account = modest_tny_account_store_get_local_folders_account (account_store);
4497 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
4499 if ((gpointer) local_account != (gpointer) folder_store &&
4500 (gpointer) mmc_account != (gpointer) folder_store) {
4501 ModestProtocolType proto;
4502 proto = modest_tny_account_get_protocol_type (TNY_ACCOUNT (folder_store));
4503 if (proto == MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
4504 proto = MODEST_PROTOCOLS_STORE_MAILDIR;
4506 is_local_account = FALSE;
4507 /* New button should be dimmed on remote
4509 new_sensitive = (modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
4511 MODEST_PROTOCOL_REGISTRY_STORE_HAS_FOLDERS));
4513 g_object_unref (local_account);
4515 /* It could not exist */
4517 g_object_unref (mmc_account);
4520 /* Check the target folder rules */
4521 if (TNY_IS_FOLDER (folder_store)) {
4522 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
4523 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
4524 ok_sensitive = FALSE;
4525 new_sensitive = FALSE;
4530 /* Check if we're moving a folder */
4531 if (MODEST_IS_MAIN_WINDOW (user_data)) {
4532 /* Get the widgets */
4533 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
4534 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4535 if (gtk_widget_is_focus (folder_view))
4536 moving_folder = TRUE;
4539 if (moving_folder) {
4540 TnyFolderStore *moved_folder = NULL, *parent = NULL;
4542 /* Get the folder to move */
4543 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4545 /* Check that we're not moving to the same folder */
4546 if (TNY_IS_FOLDER (moved_folder)) {
4547 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
4548 if (parent == folder_store)
4549 ok_sensitive = FALSE;
4550 g_object_unref (parent);
4553 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
4554 /* Do not allow to move to an account unless it's the
4555 local folders account */
4556 if (!is_local_account)
4557 ok_sensitive = FALSE;
4560 if (ok_sensitive && (moved_folder == folder_store)) {
4561 /* Do not allow to move to itself */
4562 ok_sensitive = FALSE;
4564 g_object_unref (moved_folder);
4566 TnyFolder *src_folder = NULL;
4568 /* Moving a message */
4569 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
4571 TnyHeader *header = NULL;
4572 header = modest_msg_view_window_get_header
4573 (MODEST_MSG_VIEW_WINDOW (user_data));
4574 if (!TNY_IS_HEADER(header))
4575 g_warning ("%s: could not get source header", __FUNCTION__);
4577 src_folder = tny_header_get_folder (header);
4580 g_object_unref (header);
4583 TNY_FOLDER (modest_folder_view_get_selected
4584 (MODEST_FOLDER_VIEW (folder_view)));
4587 if (TNY_IS_FOLDER(src_folder)) {
4588 /* Do not allow to move the msg to the same folder */
4589 /* Do not allow to move the msg to an account */
4590 if ((gpointer) src_folder == (gpointer) folder_store ||
4591 TNY_IS_ACCOUNT (folder_store))
4592 ok_sensitive = FALSE;
4593 g_object_unref (src_folder);
4595 g_warning ("%s: could not get source folder", __FUNCTION__);
4599 /* Set sensitivity of the OK button */
4600 gtk_widget_set_sensitive (ok_button, ok_sensitive);
4601 /* Set sensitivity of the NEW button */
4602 gtk_widget_set_sensitive (new_button, new_sensitive);
4606 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
4609 get_folder_view_from_move_to_dialog (GtkWidget *move_to_dialog)
4611 return GTK_WIDGET(g_object_get_data (G_OBJECT(move_to_dialog),
4612 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4616 create_move_to_dialog (GtkWindow *win,
4617 GtkWidget *folder_view,
4618 GtkWidget **tree_view)
4620 GtkWidget *dialog, *scroll;
4621 GtkWidget *new_button, *ok_button;
4623 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
4625 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
4628 #ifndef MODEST_TOOLKIT_GTK
4629 ok_button = gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
4630 /* We do this manually so GTK+ does not associate a response ID for
4632 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
4633 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
4634 gtk_widget_show (new_button);
4635 #ifndef MODEST_TOOLKIT_HILDON2
4636 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
4639 /* We do this manually so GTK+ does not associate a response ID for
4641 new_button = gtk_button_new_with_label (_("mcen_ti_new_folder"));
4642 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
4643 gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (GTK_DIALOG (dialog)->action_area), new_button, TRUE);
4644 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
4645 ok_button = gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
4646 gtk_container_set_border_width (GTK_CONTAINER (dialog), 12);
4647 gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 24);
4649 g_object_set_data (G_OBJECT (dialog), MOVE_FOLDER_OK_BUTTON, ok_button);
4650 g_object_set_data (G_OBJECT (dialog), MOVE_FOLDER_NEW_BUTTON, new_button);
4652 /* Create scrolled window */
4653 scroll = gtk_scrolled_window_new (NULL, NULL);
4654 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
4655 GTK_POLICY_AUTOMATIC,
4656 GTK_POLICY_AUTOMATIC);
4658 #ifdef MODEST_TOOLKIT_GTK
4659 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN);
4662 /* Create folder view */
4663 *tree_view = modest_platform_create_folder_view (NULL);
4665 /* Track changes in the selection to
4666 * disable the OK button whenever "Move to" is not possible
4667 * disbale NEW button whenever New is not possible */
4668 g_signal_connect (*tree_view,
4669 "folder_selection_changed",
4670 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
4673 /* Listen to clicks on New button */
4674 g_signal_connect (G_OBJECT (new_button),
4676 G_CALLBACK(create_move_to_dialog_on_new_folder),
4679 /* It could happen that we're trying to move a message from a
4680 window (msg window for example) after the main window was
4681 closed, so we can not just get the model of the folder
4683 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4684 const gchar *visible_id = NULL;
4686 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4687 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4688 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4689 MODEST_FOLDER_VIEW(*tree_view));
4692 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4694 /* Show the same account than the one that is shown in the main window */
4695 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
4698 const gchar *active_account_name = NULL;
4699 ModestAccountMgr *mgr = NULL;
4700 ModestAccountSettings *settings = NULL;
4701 ModestServerAccountSettings *store_settings = NULL;
4703 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4704 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4705 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
4706 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
4708 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4709 mgr = modest_runtime_get_account_mgr ();
4710 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4713 const gchar *store_account_name;
4714 store_settings = modest_account_settings_get_store_settings (settings);
4715 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4717 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
4718 store_account_name);
4719 g_object_unref (store_settings);
4720 g_object_unref (settings);
4724 /* we keep a pointer to the embedded folder view, so we can retrieve it with
4725 * get_folder_view_from_move_to_dialog
4726 * (see above) later (needed for focus handling)
4728 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, *tree_view);
4731 /* Hide special folders */
4732 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
4734 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
4736 /* Add scroll to dialog */
4737 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
4738 scroll, TRUE, TRUE, 0);
4740 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4741 #ifndef MODEST_TOOLKIT_GTK
4742 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
4744 gtk_window_set_default_size (GTK_WINDOW (dialog), 600, 400);
4753 * Shows a confirmation dialog to the user when we're moving messages
4754 * from a remote server to the local storage. Returns the dialog
4755 * response. If it's other kind of movement then it always returns
4758 * This one is used by the next functions:
4759 * modest_ui_actions_on_paste - commented out
4760 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4763 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4764 TnyFolder *dest_folder,
4768 gint response = GTK_RESPONSE_OK;
4769 TnyAccount *account = NULL;
4770 TnyFolder *src_folder = NULL;
4771 TnyIterator *iter = NULL;
4772 TnyHeader *header = NULL;
4774 /* return with OK if the destination is a remote folder */
4775 if (modest_tny_folder_is_remote_folder (dest_folder))
4776 return GTK_RESPONSE_OK;
4778 /* Get source folder */
4779 iter = tny_list_create_iterator (headers);
4780 header = TNY_HEADER (tny_iterator_get_current (iter));
4782 src_folder = tny_header_get_folder (header);
4783 g_object_unref (header);
4785 g_object_unref (iter);
4787 /* if no src_folder, message may be an attahcment */
4788 if (src_folder == NULL)
4789 return GTK_RESPONSE_CANCEL;
4791 /* If the source is a local or MMC folder */
4792 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4793 g_object_unref (src_folder);
4794 return GTK_RESPONSE_OK;
4797 /* Get the account */
4798 account = tny_folder_get_account (src_folder);
4800 /* now if offline we ask the user */
4801 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4802 response = GTK_RESPONSE_OK;
4804 response = GTK_RESPONSE_CANCEL;
4807 g_object_unref (src_folder);
4808 g_object_unref (account);
4814 move_to_helper_destroyer (gpointer user_data)
4816 MoveToHelper *helper = (MoveToHelper *) user_data;
4818 /* Close the "Pasting" information banner */
4819 if (helper->banner) {
4820 gtk_widget_destroy (GTK_WIDGET (helper->banner));
4821 g_object_unref (helper->banner);
4823 if (gtk_tree_row_reference_valid (helper->reference)) {
4824 gtk_tree_row_reference_free (helper->reference);
4825 helper->reference = NULL;
4831 move_to_cb (ModestMailOperation *mail_op,
4834 MoveToHelper *helper = (MoveToHelper *) user_data;
4836 /* Note that the operation could have failed, in that case do
4838 if (modest_mail_operation_get_status (mail_op) ==
4839 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
4841 GObject *object = modest_mail_operation_get_source (mail_op);
4842 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4843 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4845 if (!modest_msg_view_window_select_next_message (self) &&
4846 !modest_msg_view_window_select_previous_message (self)) {
4847 /* No more messages to view, so close this window */
4848 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4850 } else if (MODEST_IS_MAIN_WINDOW (object) &&
4851 gtk_tree_row_reference_valid (helper->reference)) {
4852 GtkWidget *header_view;
4854 GtkTreeSelection *sel;
4856 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4857 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4858 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
4859 path = gtk_tree_row_reference_get_path (helper->reference);
4860 /* We need to unselect the previous one
4861 because we could be copying instead of
4863 gtk_tree_selection_unselect_all (sel);
4864 gtk_tree_selection_select_path (sel, path);
4865 gtk_tree_path_free (path);
4867 g_object_unref (object);
4869 /* Destroy the helper */
4870 move_to_helper_destroyer (helper);
4874 folder_move_to_cb (ModestMailOperation *mail_op,
4875 TnyFolder *new_folder,
4878 GtkWidget *folder_view;
4881 object = modest_mail_operation_get_source (mail_op);
4882 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4883 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4884 g_object_ref (folder_view);
4885 g_object_unref (object);
4886 move_to_cb (mail_op, user_data);
4887 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
4888 g_object_unref (folder_view);
4892 msgs_move_to_cb (ModestMailOperation *mail_op,
4895 move_to_cb (mail_op, user_data);
4899 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
4902 ModestWindow *main_window = NULL;
4904 /* Disable next automatic folder selection */
4905 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
4906 FALSE); /* don't create */
4908 GObject *win = NULL;
4909 GtkWidget *folder_view = NULL;
4911 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
4912 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4913 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
4915 if (user_data && TNY_IS_FOLDER (user_data)) {
4916 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
4917 TNY_FOLDER (user_data), FALSE);
4920 /* Show notification dialog only if the main window exists */
4921 win = modest_mail_operation_get_source (mail_op);
4922 modest_platform_run_information_dialog ((GtkWindow *) win,
4923 _("mail_in_ui_folder_move_target_error"),
4926 g_object_unref (win);
4931 open_msg_for_purge_cb (ModestMailOperation *mail_op,
4940 gint pending_purges = 0;
4941 gboolean some_purged = FALSE;
4942 ModestWindow *win = MODEST_WINDOW (user_data);
4943 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
4945 /* If there was any error */
4946 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
4947 modest_window_mgr_unregister_header (mgr, header);
4951 /* Once the message has been retrieved for purging, we check if
4952 * it's all ok for purging */
4954 parts = tny_simple_list_new ();
4955 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
4956 iter = tny_list_create_iterator (parts);
4958 while (!tny_iterator_is_done (iter)) {
4960 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4961 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
4962 if (tny_mime_part_is_purged (part))
4969 g_object_unref (part);
4971 tny_iterator_next (iter);
4973 g_object_unref (iter);
4976 if (pending_purges>0) {
4978 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
4980 if (response == GTK_RESPONSE_OK) {
4983 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_ib_removing_attachment"));
4984 iter = tny_list_create_iterator (parts);
4985 while (!tny_iterator_is_done (iter)) {
4988 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4989 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
4990 tny_mime_part_set_purged (part);
4993 g_object_unref (part);
4995 tny_iterator_next (iter);
4997 g_object_unref (iter);
4999 tny_msg_rewrite_cache (msg);
5001 gtk_widget_destroy (info);
5005 modest_window_mgr_unregister_header (mgr, header);
5007 g_object_unref (parts);
5011 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
5012 ModestMainWindow *win)
5014 GtkWidget *header_view;
5015 TnyList *header_list;
5017 TnyHeaderFlags flags;
5018 ModestWindow *msg_view_window = NULL;
5021 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5023 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5024 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5026 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
5028 g_warning ("%s: no header selected", __FUNCTION__);
5032 if (tny_list_get_length (header_list) == 1) {
5033 TnyIterator *iter = tny_list_create_iterator (header_list);
5034 header = TNY_HEADER (tny_iterator_get_current (iter));
5035 g_object_unref (iter);
5039 if (!header || !TNY_IS_HEADER(header)) {
5040 g_warning ("%s: header is not valid", __FUNCTION__);
5044 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
5045 header, &msg_view_window);
5046 flags = tny_header_get_flags (header);
5047 if (!(flags & TNY_HEADER_FLAG_CACHED))
5050 if (msg_view_window != NULL)
5051 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
5053 /* do nothing; uid was registered before, so window is probably on it's way */
5054 g_warning ("debug: header %p has already been registered", header);
5057 ModestMailOperation *mail_op = NULL;
5058 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
5059 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5060 modest_ui_actions_disk_operations_error_handler,
5062 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5063 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5065 g_object_unref (mail_op);
5068 g_object_unref (header);
5070 g_object_unref (header_list);
5074 * Checks if we need a connection to do the transfer and if the user
5075 * wants to connect to complete it
5078 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5079 TnyFolderStore *src_folder,
5081 TnyFolder *dst_folder,
5082 gboolean delete_originals,
5083 gboolean *need_connection,
5086 TnyAccount *src_account;
5087 gint uncached_msgs = 0;
5089 uncached_msgs = header_list_count_uncached_msgs (headers);
5091 /* We don't need any further check if
5093 * 1- the source folder is local OR
5094 * 2- the device is already online
5096 if (!modest_tny_folder_store_is_remote (src_folder) ||
5097 tny_device_is_online (modest_runtime_get_device())) {
5098 *need_connection = FALSE;
5103 /* We must ask for a connection when
5105 * - the message(s) is not already cached OR
5106 * - the message(s) is cached but the leave_on_server setting
5107 * is FALSE (because we need to sync the source folder to
5108 * delete the message from the server (for IMAP we could do it
5109 * offline, it'll take place the next time we get a
5112 src_account = get_account_from_folder_store (src_folder);
5113 if (uncached_msgs > 0) {
5117 *need_connection = TRUE;
5118 num_headers = tny_list_get_length (headers);
5119 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5121 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5122 GTK_RESPONSE_CANCEL) {
5128 /* The transfer is possible and the user wants to */
5131 if (remote_folder_has_leave_on_server (src_folder) && delete_originals) {
5132 const gchar *account_name;
5133 gboolean leave_on_server;
5135 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5136 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5139 if (leave_on_server == TRUE) {
5140 *need_connection = FALSE;
5142 *need_connection = TRUE;
5145 *need_connection = FALSE;
5150 g_object_unref (src_account);
5154 xfer_messages_error_handler (ModestMailOperation *mail_op,
5157 ModestWindow *main_window = NULL;
5159 /* Disable next automatic folder selection */
5160 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5161 FALSE); /* don't create */
5163 GObject *win = modest_mail_operation_get_source (mail_op);
5164 modest_platform_run_information_dialog ((GtkWindow *) win,
5165 _("mail_in_ui_folder_move_target_error"),
5168 g_object_unref (win);
5170 move_to_helper_destroyer (user_data);
5174 TnyFolderStore *dst_folder;
5179 * Utility function that transfer messages from both the main window
5180 * and the msg view window when using the "Move to" dialog
5183 xfer_messages_performer (gboolean canceled,
5185 GtkWindow *parent_window,
5186 TnyAccount *account,
5189 ModestWindow *win = MODEST_WINDOW (parent_window);
5190 TnyAccount *dst_account = NULL;
5191 gboolean dst_forbids_message_add = FALSE;
5192 XferMsgsHelper *helper;
5193 MoveToHelper *movehelper;
5194 ModestMailOperation *mail_op;
5196 helper = (XferMsgsHelper *) user_data;
5198 if (canceled || err) {
5199 if (!check_memory_full_error ((GtkWidget *) parent_window, err)) {
5200 /* Show the proper error message */
5201 modest_ui_actions_on_account_connection_error (parent_window, account);
5206 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5208 /* tinymail will return NULL for local folders it seems */
5209 dst_forbids_message_add = modest_protocol_registry_protocol_type_has_tag (modest_runtime_get_protocol_registry (),
5210 modest_tny_account_get_protocol_type (dst_account),
5211 MODEST_PROTOCOL_REGISTRY_STORE_FORBID_MESSAGE_ADD);
5212 g_object_unref (dst_account);
5214 if (dst_forbids_message_add) {
5215 modest_platform_information_banner (GTK_WIDGET (win),
5217 ngettext("mail_in_ui_folder_move_target_error",
5218 "mail_in_ui_folder_move_targets_error",
5219 tny_list_get_length (helper->headers)));
5223 movehelper = g_new0 (MoveToHelper, 1);
5224 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5225 _CS("ckct_nw_pasting"));
5226 if (movehelper->banner != NULL) {
5227 g_object_ref (movehelper->banner);
5228 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5231 if (MODEST_IS_MAIN_WINDOW (win)) {
5232 GtkWidget *header_view =
5233 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5234 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5235 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5238 /* Perform the mail operation */
5239 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5240 xfer_messages_error_handler,
5242 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5245 modest_mail_operation_xfer_msgs (mail_op,
5247 TNY_FOLDER (helper->dst_folder),
5252 g_object_unref (G_OBJECT (mail_op));
5254 g_object_unref (helper->dst_folder);
5255 g_object_unref (helper->headers);
5256 g_slice_free (XferMsgsHelper, helper);
5260 TnyFolder *src_folder;
5261 TnyFolderStore *dst_folder;
5262 gboolean delete_original;
5263 GtkWidget *folder_view;
5267 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
5268 TnyAccount *account, gpointer user_data)
5270 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5271 GtkTreeSelection *sel;
5272 ModestMailOperation *mail_op = NULL;
5274 if (canceled || err || !MODEST_IS_MAIN_WINDOW (parent_window)) {
5275 g_object_unref (G_OBJECT (info->src_folder));
5276 g_object_unref (G_OBJECT (info->dst_folder));
5281 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5282 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5283 _CS("ckct_nw_pasting"));
5284 if (helper->banner != NULL) {
5285 g_object_ref (helper->banner);
5286 gtk_widget_show (GTK_WIDGET(helper->banner));
5288 /* Clean folder on header view before moving it */
5289 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5290 gtk_tree_selection_unselect_all (sel);
5292 /* Let gtk events run. We need that the folder
5293 view frees its reference to the source
5294 folder *before* issuing the mail operation
5295 so we need the signal handler of selection
5296 changed to happen before the mail
5298 while (gtk_events_pending ())
5299 gtk_main_iteration (); */
5302 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5303 modest_ui_actions_move_folder_error_handler,
5304 info->src_folder, NULL);
5305 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5308 /* Select *after* the changes */
5309 /* TODO: this function hangs UI after transfer */
5310 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
5311 /* TNY_FOLDER (src_folder), TRUE); */
5313 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5314 TNY_FOLDER (info->dst_folder), TRUE);
5315 modest_mail_operation_xfer_folder (mail_op,
5316 TNY_FOLDER (info->src_folder),
5318 info->delete_original,
5321 g_object_unref (G_OBJECT (info->src_folder));
5323 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5326 /* Unref mail operation */
5327 g_object_unref (G_OBJECT (mail_op));
5328 g_object_unref (G_OBJECT (info->dst_folder));
5333 get_account_from_folder_store (TnyFolderStore *folder_store)
5335 if (TNY_IS_ACCOUNT (folder_store))
5336 return g_object_ref (folder_store);
5338 return tny_folder_get_account (TNY_FOLDER (folder_store));
5342 * UI handler for the "Move to" action when invoked from the
5346 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5347 GtkWidget *folder_view,
5348 TnyFolderStore *dst_folder,
5349 ModestMainWindow *win)
5351 ModestHeaderView *header_view = NULL;
5352 TnyFolderStore *src_folder = NULL;
5354 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5356 /* Get the source folder */
5357 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5359 /* Get header view */
5360 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
5362 /* Get folder or messages to transfer */
5363 if (gtk_widget_is_focus (folder_view)) {
5364 gboolean do_xfer = TRUE;
5366 /* Allow only to transfer folders to the local root folder */
5367 if (TNY_IS_ACCOUNT (dst_folder) &&
5368 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5369 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5371 } else if (!TNY_IS_FOLDER (src_folder)) {
5372 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5377 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5378 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5380 info->src_folder = g_object_ref (src_folder);
5381 info->dst_folder = g_object_ref (dst_folder);
5382 info->delete_original = TRUE;
5383 info->folder_view = folder_view;
5385 connect_info->callback = on_move_folder_cb;
5386 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5387 connect_info->data = info;
5389 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5390 TNY_FOLDER_STORE (src_folder),
5393 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5396 headers = modest_header_view_get_selected_headers(header_view);
5398 /* Transfer the messages */
5399 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
5400 headers, TNY_FOLDER (dst_folder));
5402 g_object_unref (headers);
5406 g_object_unref (src_folder);
5411 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
5412 TnyFolder *src_folder,
5414 TnyFolder *dst_folder)
5416 gboolean need_connection = TRUE;
5417 gboolean do_xfer = TRUE;
5418 XferMsgsHelper *helper;
5420 g_return_if_fail (TNY_IS_FOLDER (src_folder));
5421 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5422 g_return_if_fail (TNY_IS_LIST (headers));
5424 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5425 headers, TNY_FOLDER (dst_folder),
5426 TRUE, &need_connection,
5429 /* If we don't want to transfer just return */
5433 /* Create the helper */
5434 helper = g_slice_new (XferMsgsHelper);
5435 helper->dst_folder = g_object_ref (dst_folder);
5436 helper->headers = g_object_ref (headers);
5438 if (need_connection) {
5439 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5440 connect_info->callback = xfer_messages_performer;
5441 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5442 connect_info->data = helper;
5444 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5445 TNY_FOLDER_STORE (src_folder),
5448 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5449 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
5450 src_account, helper);
5451 g_object_unref (src_account);
5456 * UI handler for the "Move to" action when invoked from the
5457 * ModestMsgViewWindow
5460 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
5461 TnyFolderStore *dst_folder,
5462 ModestMsgViewWindow *win)
5464 TnyList *headers = NULL;
5465 TnyHeader *header = NULL;
5466 TnyFolder *src_folder = NULL;
5468 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5470 /* Create header list */
5471 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
5472 src_folder = TNY_FOLDER (tny_header_get_folder(header));
5473 headers = tny_simple_list_new ();
5474 tny_list_append (headers, G_OBJECT (header));
5476 /* Transfer the messages */
5477 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder, headers,
5478 TNY_FOLDER (dst_folder));
5481 g_object_unref (src_folder);
5482 g_object_unref (header);
5483 g_object_unref (headers);
5487 modest_ui_actions_on_move_to (GtkAction *action,
5490 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
5492 TnyFolderStore *dst_folder = NULL;
5493 ModestMainWindow *main_window;
5495 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
5496 MODEST_IS_MSG_VIEW_WINDOW (win));
5498 /* Get the main window if exists */
5499 if (MODEST_IS_MAIN_WINDOW (win))
5500 main_window = MODEST_MAIN_WINDOW (win);
5503 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5504 FALSE)); /* don't create */
5506 /* Get the folder view widget if exists */
5508 folder_view = modest_main_window_get_child_widget (main_window,
5509 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5513 /* Create and run the dialog */
5514 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
5515 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5516 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog), (GtkWindow *) win);
5517 result = gtk_dialog_run (GTK_DIALOG(dialog));
5518 g_object_ref (tree_view);
5519 gtk_widget_destroy (dialog);
5521 if (result != GTK_RESPONSE_ACCEPT)
5524 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
5525 /* Do window specific stuff */
5526 if (MODEST_IS_MAIN_WINDOW (win)) {
5527 modest_ui_actions_on_main_window_move_to (action,
5530 MODEST_MAIN_WINDOW (win));
5532 modest_ui_actions_on_msg_view_window_move_to (action,
5534 MODEST_MSG_VIEW_WINDOW (win));
5538 g_object_unref (dst_folder);
5542 * Calls #HeadersFunc for each header already selected in the main
5543 * window or the message currently being shown in the msg view window
5546 do_headers_action (ModestWindow *win,
5550 TnyList *headers_list = NULL;
5551 TnyIterator *iter = NULL;
5552 TnyHeader *header = NULL;
5553 TnyFolder *folder = NULL;
5556 headers_list = get_selected_headers (win);
5560 /* Get the folder */
5561 iter = tny_list_create_iterator (headers_list);
5562 header = TNY_HEADER (tny_iterator_get_current (iter));
5564 folder = tny_header_get_folder (header);
5565 g_object_unref (header);
5568 /* Call the function for each header */
5569 while (!tny_iterator_is_done (iter)) {
5570 header = TNY_HEADER (tny_iterator_get_current (iter));
5571 func (header, win, user_data);
5572 g_object_unref (header);
5573 tny_iterator_next (iter);
5576 /* Trick: do a poke status in order to speed up the signaling
5578 tny_folder_poke_status (folder);
5581 g_object_unref (folder);
5582 g_object_unref (iter);
5583 g_object_unref (headers_list);
5587 modest_ui_actions_view_attachment (GtkAction *action,
5588 ModestWindow *window)
5590 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5591 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5593 /* not supported window for this action */
5594 g_return_if_reached ();
5599 modest_ui_actions_save_attachments (GtkAction *action,
5600 ModestWindow *window)
5602 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5604 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5607 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5609 /* not supported window for this action */
5610 g_return_if_reached ();
5615 modest_ui_actions_remove_attachments (GtkAction *action,
5616 ModestWindow *window)
5618 if (MODEST_IS_MAIN_WINDOW (window)) {
5619 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
5620 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5621 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5623 /* not supported window for this action */
5624 g_return_if_reached ();
5629 modest_ui_actions_on_settings (GtkAction *action,
5634 dialog = modest_platform_get_global_settings_dialog ();
5635 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
5636 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5637 gtk_widget_show_all (dialog);
5639 gtk_dialog_run (GTK_DIALOG (dialog));
5641 gtk_widget_destroy (dialog);
5645 modest_ui_actions_on_help (GtkAction *action,
5648 const gchar *help_id;
5650 g_return_if_fail (win && GTK_IS_WINDOW(win));
5652 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5655 modest_platform_show_help (GTK_WINDOW (win), help_id);
5659 modest_ui_actions_on_csm_help (GtkAction *action,
5662 const gchar* help_id = NULL;
5663 GtkWidget *folder_view;
5664 TnyFolderStore *folder_store;
5666 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
5668 /* Get selected folder */
5669 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5670 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5671 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5673 /* Switch help_id */
5674 if (folder_store && TNY_IS_FOLDER (folder_store))
5675 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
5678 g_object_unref (folder_store);
5681 modest_platform_show_help (GTK_WINDOW (win), help_id);
5683 modest_ui_actions_on_help (action, win);
5687 retrieve_contents_cb (ModestMailOperation *mail_op,
5694 /* We only need this callback to show an error in case of
5695 memory low condition */
5696 modest_ui_actions_msg_retrieval_check (mail_op, header, msg);
5700 retrieve_msg_contents_performer (gboolean canceled,
5702 GtkWindow *parent_window,
5703 TnyAccount *account,
5706 ModestMailOperation *mail_op;
5707 TnyList *headers = TNY_LIST (user_data);
5709 if (err || canceled) {
5710 check_memory_full_error ((GtkWidget *) parent_window, err);
5714 /* Create mail operation */
5715 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5716 modest_ui_actions_disk_operations_error_handler,
5718 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5719 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
5722 g_object_unref (mail_op);
5724 g_object_unref (headers);
5725 g_object_unref (account);
5729 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5730 ModestWindow *window)
5732 TnyList *headers = NULL;
5733 TnyAccount *account = NULL;
5734 TnyIterator *iter = NULL;
5735 TnyHeader *header = NULL;
5736 TnyFolder *folder = NULL;
5739 headers = get_selected_headers (window);
5743 /* Pick the account */
5744 iter = tny_list_create_iterator (headers);
5745 header = TNY_HEADER (tny_iterator_get_current (iter));
5746 folder = tny_header_get_folder (header);
5747 account = tny_folder_get_account (folder);
5748 g_object_unref (folder);
5749 g_object_unref (header);
5750 g_object_unref (iter);
5752 /* Connect and perform the message retrieval */
5753 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
5754 g_object_ref (account),
5755 retrieve_msg_contents_performer,
5756 g_object_ref (headers));
5759 g_object_unref (account);
5760 g_object_unref (headers);
5764 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
5766 g_return_if_fail (MODEST_IS_WINDOW (window));
5769 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
5773 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
5775 g_return_if_fail (MODEST_IS_WINDOW (window));
5778 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
5782 modest_ui_actions_on_email_menu_activated (GtkAction *action,
5783 ModestWindow *window)
5785 g_return_if_fail (MODEST_IS_WINDOW (window));
5788 modest_ui_actions_check_menu_dimming_rules (window);
5792 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
5793 ModestWindow *window)
5795 g_return_if_fail (MODEST_IS_WINDOW (window));
5798 modest_ui_actions_check_menu_dimming_rules (window);
5802 modest_ui_actions_on_view_menu_activated (GtkAction *action,
5803 ModestWindow *window)
5805 g_return_if_fail (MODEST_IS_WINDOW (window));
5808 modest_ui_actions_check_menu_dimming_rules (window);
5812 modest_ui_actions_on_format_menu_activated (GtkAction *action,
5813 ModestWindow *window)
5815 g_return_if_fail (MODEST_IS_WINDOW (window));
5818 modest_ui_actions_check_menu_dimming_rules (window);
5822 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
5823 ModestWindow *window)
5825 g_return_if_fail (MODEST_IS_WINDOW (window));
5828 modest_ui_actions_check_menu_dimming_rules (window);
5832 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
5833 ModestWindow *window)
5835 g_return_if_fail (MODEST_IS_WINDOW (window));
5838 modest_ui_actions_check_menu_dimming_rules (window);
5842 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
5843 ModestWindow *window)
5845 g_return_if_fail (MODEST_IS_WINDOW (window));
5848 modest_ui_actions_check_menu_dimming_rules (window);
5852 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
5853 ModestWindow *window)
5855 g_return_if_fail (MODEST_IS_WINDOW (window));
5858 modest_ui_actions_check_menu_dimming_rules (window);
5862 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
5863 ModestWindow *window)
5865 g_return_if_fail (MODEST_IS_WINDOW (window));
5868 modest_ui_actions_check_menu_dimming_rules (window);
5872 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
5874 g_return_if_fail (MODEST_IS_WINDOW (window));
5876 /* we check for low-mem; in that case, show a warning, and don't allow
5879 if (modest_platform_check_memory_low (window, TRUE))
5882 modest_platform_show_search_messages (GTK_WINDOW (window));
5886 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
5888 g_return_if_fail (MODEST_IS_WINDOW (win));
5891 /* we check for low-mem; in that case, show a warning, and don't allow
5892 * for the addressbook
5894 if (modest_platform_check_memory_low (win, TRUE))
5898 modest_platform_show_addressbook (GTK_WINDOW (win));
5903 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
5904 ModestWindow *window)
5906 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5908 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
5912 on_send_receive_finished (ModestMailOperation *mail_op,
5915 GtkWidget *header_view, *folder_view;
5916 TnyFolderStore *folder_store;
5917 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
5919 /* Set send/receive operation finished */
5920 modest_main_window_notify_send_receive_completed (main_win);
5922 /* Don't refresh the current folder if there were any errors */
5923 if (modest_mail_operation_get_status (mail_op) !=
5924 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5927 /* Refresh the current folder if we're viewing a window. We do
5928 this because the user won't be able to see the new mails in
5929 the selected folder after a Send&Receive because it only
5930 performs a poke_status, i.e, only the number of read/unread
5931 messages is updated, but the new headers are not
5933 folder_view = modest_main_window_get_child_widget (main_win,
5934 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5938 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5940 /* Do not need to refresh INBOX again because the
5941 update_account does it always automatically */
5942 if (folder_store && TNY_IS_FOLDER (folder_store) &&
5943 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
5944 ModestMailOperation *refresh_op;
5946 header_view = modest_main_window_get_child_widget (main_win,
5947 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5949 /* We do not need to set the contents style
5950 because it hasn't changed. We also do not
5951 need to save the widget status. Just force
5953 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
5954 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
5955 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
5956 folder_refreshed_cb, main_win);
5957 g_object_unref (refresh_op);
5961 g_object_unref (folder_store);
5966 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
5972 const gchar* server_name = NULL;
5973 TnyTransportAccount *server_account;
5974 gchar *message = NULL;
5976 /* Don't show anything if the user cancelled something or the
5977 * send receive request is not interactive. Authentication
5978 * errors are managed by the account store so no need to show
5979 * a dialog here again */
5980 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
5981 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
5982 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
5986 /* Get the server name: */
5988 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
5990 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
5992 g_return_if_reached ();
5994 /* Show the appropriate message text for the GError: */
5995 switch (err->code) {
5996 case TNY_SERVICE_ERROR_CONNECT:
5997 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
5999 case TNY_SERVICE_ERROR_SEND:
6000 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
6002 case TNY_SERVICE_ERROR_UNAVAILABLE:
6003 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
6006 g_warning ("%s: unexpected ERROR %d",
6007 __FUNCTION__, err->code);
6008 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
6012 modest_platform_run_information_dialog (NULL, message, FALSE);
6014 g_object_unref (server_account);
6018 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
6023 ModestMainWindow *main_window = NULL;
6024 ModestWindowMgr *mgr = NULL;
6025 GtkWidget *folder_view = NULL, *header_view = NULL;
6026 TnyFolderStore *selected_folder = NULL;
6027 TnyFolderType folder_type;
6029 mgr = modest_runtime_get_window_mgr ();
6030 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr,
6031 FALSE));/* don't create */
6035 /* Check if selected folder is OUTBOX */
6036 folder_view = modest_main_window_get_child_widget (main_window,
6037 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
6038 header_view = modest_main_window_get_child_widget (main_window,
6039 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6041 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
6042 if (!TNY_IS_FOLDER (selected_folder))
6045 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
6046 #if GTK_CHECK_VERSION(2, 8, 0)
6047 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
6048 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
6049 GtkTreeViewColumn *tree_column;
6051 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
6052 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
6054 gtk_tree_view_column_queue_resize (tree_column);
6057 gtk_widget_queue_draw (header_view);
6060 /* Rerun dimming rules, because the message could become deletable for example */
6061 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6062 MODEST_DIMMING_RULES_TOOLBAR);
6063 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
6064 MODEST_DIMMING_RULES_MENU);
6068 if (selected_folder != NULL)
6069 g_object_unref (selected_folder);
6073 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6074 TnyAccount *account)
6076 ModestProtocolType protocol_type;
6077 ModestProtocol *protocol;
6078 gchar *error_note = NULL;
6080 protocol_type = modest_tny_account_get_protocol_type (account);
6081 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6084 error_note = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_ACCOUNT_CONNECTION_ERROR, tny_account_get_hostname (account));
6085 if (error_note == NULL) {
6086 g_warning ("%s: This should not be reached", __FUNCTION__);
6088 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6089 g_free (error_note);
6094 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6098 TnyFolderStore *folder = NULL;
6099 TnyAccount *account = NULL;
6100 ModestProtocolType proto;
6101 ModestProtocol *protocol;
6102 TnyHeader *header = NULL;
6104 if (MODEST_IS_MAIN_WINDOW (win)) {
6105 GtkWidget *header_view;
6106 TnyList* headers = NULL;
6108 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6109 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6110 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6111 if (!headers || tny_list_get_length (headers) == 0) {
6113 g_object_unref (headers);
6116 iter = tny_list_create_iterator (headers);
6117 header = TNY_HEADER (tny_iterator_get_current (iter));
6118 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6119 g_object_unref (iter);
6120 g_object_unref (headers);
6121 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6122 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6123 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6126 /* Get the account type */
6127 account = tny_folder_get_account (TNY_FOLDER (folder));
6128 proto = modest_tny_account_get_protocol_type (account);
6129 protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
6132 subject = tny_header_dup_subject (header);
6133 msg = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_MSG_NOT_AVAILABLE, subject);
6137 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6141 g_object_unref (account);
6142 g_object_unref (folder);
6143 g_object_unref (header);