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-protocol-info.h"
45 #include "modest-tny-platform-factory.h"
46 #include "modest-platform.h"
47 #include "modest-debug.h"
48 #include <tny-mime-part.h>
49 #include <tny-camel-folder.h>
50 #include <tny-camel-imap-folder.h>
51 #include <tny-camel-pop-folder.h>
53 #ifdef MODEST_PLATFORM_MAEMO
54 #include "maemo/modest-osso-state-saving.h"
55 #include "maemo/modest-hildon-includes.h"
56 #include "maemo/modest-connection-specific-smtp-window.h"
57 #endif /* MODEST_PLATFORM_MAEMO */
58 #include <modest-utils.h>
60 #include "widgets/modest-ui-constants.h"
61 #include <widgets/modest-main-window.h>
62 #include <widgets/modest-msg-view-window.h>
63 #include <widgets/modest-account-view-window.h>
64 #include <widgets/modest-details-dialog.h>
65 #include <widgets/modest-attachments-view.h>
66 #include "widgets/modest-folder-view.h"
67 #include "widgets/modest-global-settings-dialog.h"
68 #include "modest-account-mgr-helpers.h"
69 #include "modest-mail-operation.h"
70 #include "modest-text-utils.h"
72 #ifdef MODEST_HAVE_EASYSETUP
73 #include "easysetup/modest-easysetup-wizard-dialog.h"
74 #endif /* MODEST_HAVE_EASYSETUP */
76 #include <modest-widget-memory.h>
77 #include <tny-error.h>
78 #include <tny-simple-list.h>
79 #include <tny-msg-view.h>
80 #include <tny-device.h>
81 #include <tny-merge-folder.h>
83 #include <gtkhtml/gtkhtml.h>
85 #define MIN_FREE_SPACE 5 * 1024 * 1024
87 typedef struct _GetMsgAsyncHelper {
89 ModestMailOperation *mail_op;
96 typedef enum _ReplyForwardAction {
100 } ReplyForwardAction;
102 typedef struct _ReplyForwardHelper {
103 guint reply_forward_type;
104 ReplyForwardAction action;
106 GtkWidget *parent_window;
108 } ReplyForwardHelper;
110 typedef struct _MoveToHelper {
111 GtkTreeRowReference *reference;
115 typedef struct _PasteAsAttachmentHelper {
116 ModestMsgEditWindow *window;
118 } PasteAsAttachmentHelper;
122 * The do_headers_action uses this kind of functions to perform some
123 * action to each member of a list of headers
125 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
127 static void do_headers_action (ModestWindow *win,
131 static void open_msg_cb (ModestMailOperation *mail_op,
138 static void reply_forward_cb (ModestMailOperation *mail_op,
145 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
147 static void folder_refreshed_cb (ModestMailOperation *mail_op,
151 static void on_send_receive_finished (ModestMailOperation *mail_op,
154 static gint header_list_count_uncached_msgs (TnyList *header_list);
156 static gboolean connect_to_get_msg (ModestWindow *win,
157 gint num_of_uncached_msgs,
158 TnyAccount *account);
160 static gboolean remote_folder_is_pop (TnyFolderStore *folder);
162 static void do_create_folder (GtkWindow *window,
163 TnyFolderStore *parent_folder,
164 const gchar *suggested_name);
166 static GtkWidget* get_folder_view_from_move_to_dialog (GtkWidget *move_to_dialog);
168 static TnyAccount *get_account_from_folder_store (TnyFolderStore *folder_store);
171 * This function checks whether a TnyFolderStore is a pop account
174 remote_folder_is_pop (TnyFolderStore *folder)
176 const gchar *proto = NULL;
177 TnyAccount *account = NULL;
179 g_return_val_if_fail (TNY_IS_FOLDER_STORE (folder), FALSE);
181 account = get_account_from_folder_store (folder);
182 proto = tny_account_get_proto (account);
183 g_object_unref (account);
185 return (modest_protocol_info_get_transport_store_protocol (proto) == MODEST_PROTOCOL_STORE_POP);
188 /* FIXME: this should be merged with the similar code in modest-account-view-window */
189 /* Show the account creation wizard dialog.
190 * returns: TRUE if an account was created. FALSE if the user cancelled.
193 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
195 gboolean result = FALSE;
196 GtkWindow *dialog, *wizard;
197 gint dialog_response;
199 /* Show the easy-setup wizard: */
200 dialog = modest_window_mgr_get_modal (modest_runtime_get_window_mgr());
202 /* old wizard is active already;
204 gtk_window_present (GTK_WINDOW(dialog));
209 /* there is no such wizard yet */
210 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
211 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), wizard);
213 /* always present a main window in the background
214 * we do it here, so we cannot end up with two wizards (as this
215 * function might be called in modest_window_mgr_get_main_window as well */
217 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
218 TRUE); /* create if not existent */
220 /* make sure the mainwindow is visible */
221 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
222 gtk_widget_show_all (GTK_WIDGET(win));
223 gtk_window_present (GTK_WINDOW(win));
225 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
226 gtk_widget_destroy (GTK_WIDGET (wizard));
227 if (gtk_events_pending ())
228 gtk_main_iteration ();
230 if (dialog_response == GTK_RESPONSE_CANCEL) {
233 /* Check whether an account was created: */
234 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
241 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
244 const gchar *authors[] = {
245 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
248 about = gtk_about_dialog_new ();
249 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
250 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
251 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
252 _("Copyright (c) 2006, Nokia Corporation\n"
253 "All rights reserved."));
254 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
255 _("a modest e-mail client\n\n"
256 "design and implementation: Dirk-Jan C. Binnema\n"
257 "contributions from the fine people at KC and Ig\n"
258 "uses the tinymail email framework written by Philip van Hoof"));
259 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
260 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
261 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
262 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
264 gtk_dialog_run (GTK_DIALOG (about));
265 gtk_widget_destroy(about);
269 * Gets the list of currently selected messages. If the win is the
270 * main window, then it returns a newly allocated list of the headers
271 * selected in the header view. If win is the msg view window, then
272 * the value returned is a list with just a single header.
274 * The caller of this funcion must free the list.
277 get_selected_headers (ModestWindow *win)
279 if (MODEST_IS_MAIN_WINDOW(win)) {
280 GtkWidget *header_view;
282 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
283 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
284 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
286 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
287 /* for MsgViewWindows, we simply return a list with one element */
289 TnyList *list = NULL;
291 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
292 if (header != NULL) {
293 list = tny_simple_list_new ();
294 tny_list_prepend (list, G_OBJECT(header));
295 g_object_unref (G_OBJECT(header));
304 static GtkTreeRowReference *
305 get_next_after_selected_headers (ModestHeaderView *header_view)
307 GtkTreeSelection *sel;
308 GList *selected_rows, *node;
310 GtkTreeRowReference *result;
313 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
314 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
315 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
317 if (selected_rows == NULL)
320 node = g_list_last (selected_rows);
321 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
322 gtk_tree_path_next (path);
324 result = gtk_tree_row_reference_new (model, path);
326 gtk_tree_path_free (path);
327 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
328 g_list_free (selected_rows);
334 headers_action_mark_as_read (TnyHeader *header,
338 TnyHeaderFlags flags;
340 g_return_if_fail (TNY_IS_HEADER(header));
342 flags = tny_header_get_flags (header);
343 if (flags & TNY_HEADER_FLAG_SEEN) return;
344 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
348 headers_action_mark_as_unread (TnyHeader *header,
352 TnyHeaderFlags flags;
354 g_return_if_fail (TNY_IS_HEADER(header));
356 flags = tny_header_get_flags (header);
357 if (flags & TNY_HEADER_FLAG_SEEN) {
358 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
362 /** After deleing a message that is currently visible in a window,
363 * show the next message from the list, or close the window if there are no more messages.
366 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
368 /* Close msg view window or select next */
369 if (!modest_msg_view_window_select_next_message (win) &&
370 !modest_msg_view_window_select_previous_message (win)) {
372 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
378 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
380 TnyList *header_list = NULL;
381 TnyIterator *iter = NULL;
382 TnyHeader *header = NULL;
383 gchar *message = NULL;
386 ModestWindowMgr *mgr;
387 GtkWidget *header_view = NULL;
389 g_return_if_fail (MODEST_IS_WINDOW(win));
391 /* Check first if the header view has the focus */
392 if (MODEST_IS_MAIN_WINDOW (win)) {
394 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
395 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
396 if (!gtk_widget_is_focus (header_view))
400 /* Get the headers, either from the header view (if win is the main window),
401 * or from the message view window: */
402 header_list = get_selected_headers (win);
403 if (!header_list) return;
405 /* Check if any of the headers are already opened, or in the process of being opened */
406 if (MODEST_IS_MAIN_WINDOW (win)) {
407 gint opened_headers = 0;
409 iter = tny_list_create_iterator (header_list);
410 mgr = modest_runtime_get_window_mgr ();
411 while (!tny_iterator_is_done (iter)) {
412 header = TNY_HEADER (tny_iterator_get_current (iter));
414 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
416 g_object_unref (header);
418 tny_iterator_next (iter);
420 g_object_unref (iter);
422 if (opened_headers > 0) {
425 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
428 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg, FALSE);
431 g_object_unref (header_list);
437 if (tny_list_get_length(header_list) == 1) {
438 iter = tny_list_create_iterator (header_list);
439 header = TNY_HEADER (tny_iterator_get_current (iter));
442 subject = tny_header_dup_subject (header);
443 desc = g_strdup_printf ("%s", subject);
445 g_object_unref (header);
448 g_object_unref (iter);
450 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
451 tny_list_get_length(header_list)), desc);
453 /* Confirmation dialog */
454 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
458 if (response == GTK_RESPONSE_OK) {
459 ModestWindow *main_window = NULL;
460 ModestWindowMgr *mgr = NULL;
461 GtkTreeModel *model = NULL;
462 GtkTreeSelection *sel = NULL;
463 GList *sel_list = NULL, *tmp = NULL;
464 GtkTreeRowReference *next_row_reference = NULL;
465 GtkTreeRowReference *prev_row_reference = NULL;
466 GtkTreePath *next_path = NULL;
467 GtkTreePath *prev_path = NULL;
468 ModestMailOperation *mail_op = NULL;
470 /* Find last selected row */
471 if (MODEST_IS_MAIN_WINDOW (win)) {
472 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
473 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
474 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
475 for (tmp=sel_list; tmp; tmp=tmp->next) {
476 if (tmp->next == NULL) {
477 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
478 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
480 gtk_tree_path_prev (prev_path);
481 gtk_tree_path_next (next_path);
483 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
484 next_row_reference = gtk_tree_row_reference_new (model, next_path);
489 /* Disable window dimming management */
490 modest_window_disable_dimming (MODEST_WINDOW(win));
492 /* Remove each header. If it's a view window header_view == NULL */
493 mail_op = modest_mail_operation_new ((GObject *) win);
494 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
496 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
497 g_object_unref (mail_op);
499 /* Enable window dimming management */
501 gtk_tree_selection_unselect_all (sel);
503 modest_window_enable_dimming (MODEST_WINDOW(win));
505 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
506 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
508 /* Get main window */
509 mgr = modest_runtime_get_window_mgr ();
510 main_window = modest_window_mgr_get_main_window (mgr, FALSE); /* don't create */
512 /* Move cursor to next row */
515 /* Select next or previous row */
516 if (gtk_tree_row_reference_valid (next_row_reference)) {
517 /* next_path = gtk_tree_row_reference_get_path (row_reference); */
518 gtk_tree_selection_select_path (sel, next_path);
520 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
521 gtk_tree_selection_select_path (sel, prev_path);
525 if (next_row_reference != NULL)
526 gtk_tree_row_reference_free (next_row_reference);
527 if (next_path != NULL)
528 gtk_tree_path_free (next_path);
529 if (prev_row_reference != NULL)
530 gtk_tree_row_reference_free (prev_row_reference);
531 if (prev_path != NULL)
532 gtk_tree_path_free (prev_path);
535 /* Update toolbar dimming state */
537 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
540 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
541 g_list_free (sel_list);
547 g_object_unref (header_list);
553 /* delete either message or folder, based on where we are */
555 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
557 g_return_if_fail (MODEST_IS_WINDOW(win));
559 /* Check first if the header view has the focus */
560 if (MODEST_IS_MAIN_WINDOW (win)) {
562 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
563 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
564 if (gtk_widget_is_focus (w)) {
565 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
569 modest_ui_actions_on_delete_message (action, win);
573 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
575 ModestWindowMgr *mgr = NULL;
577 #ifdef MODEST_PLATFORM_MAEMO
578 modest_osso_save_state();
579 #endif /* MODEST_PLATFORM_MAEMO */
581 g_debug ("closing down, clearing %d item(s) from operation queue",
582 modest_mail_operation_queue_num_elements
583 (modest_runtime_get_mail_operation_queue()));
585 /* cancel all outstanding operations */
586 modest_mail_operation_queue_cancel_all
587 (modest_runtime_get_mail_operation_queue());
589 g_debug ("queue has been cleared");
592 /* Check if there are opened editing windows */
593 mgr = modest_runtime_get_window_mgr ();
594 modest_window_mgr_close_all_windows (mgr);
596 /* note: when modest-tny-account-store is finalized,
597 it will automatically set all network connections
600 /* gtk_main_quit (); */
604 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
608 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
610 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
611 /* gtk_widget_destroy (GTK_WIDGET (win)); */
612 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
613 /* gboolean ret_value; */
614 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
615 /* } else if (MODEST_IS_WINDOW (win)) { */
616 /* gtk_widget_destroy (GTK_WIDGET (win)); */
618 /* g_return_if_reached (); */
623 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
625 GtkClipboard *clipboard = NULL;
626 gchar *selection = NULL;
628 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
629 selection = gtk_clipboard_wait_for_text (clipboard);
631 /* Question: why is the clipboard being used here?
632 * It doesn't really make a lot of sense. */
636 modest_address_book_add_address (selection);
642 modest_ui_actions_on_accounts (GtkAction *action,
645 /* This is currently only implemented for Maemo */
646 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
647 if (!modest_ui_actions_run_account_setup_wizard (win))
648 g_debug ("%s: wizard was already running", __FUNCTION__);
652 /* Show the list of accounts */
653 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
655 /* The accounts dialog must be modal */
656 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), account_win);
657 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
662 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
664 /* This is currently only implemented for Maemo,
665 * because it requires an API (libconic) to detect different connection
668 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
670 /* Create the window if necessary: */
671 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
672 modest_connection_specific_smtp_window_fill_with_connections (
673 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
674 modest_runtime_get_account_mgr());
676 /* Show the window: */
677 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
678 GTK_WINDOW (specific_window));
679 gtk_widget_show (specific_window);
680 #endif /* MODEST_PLATFORM_MAEMO */
684 modest_ui_actions_compose_msg(ModestWindow *win,
687 const gchar *bcc_str,
688 const gchar *subject_str,
689 const gchar *body_str,
691 gboolean set_as_modified)
693 gchar *account_name = NULL;
695 TnyAccount *account = NULL;
696 TnyFolder *folder = NULL;
697 gchar *from_str = NULL, *signature = NULL, *body = NULL;
698 gboolean use_signature = FALSE;
699 ModestWindow *msg_win = NULL;
700 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
701 ModestTnyAccountStore *store = modest_runtime_get_account_store();
702 GnomeVFSFileSize total_size, allowed_size;
704 /* we check for low-mem; in that case, show a warning, and don't allow
705 * composing a message with attachments
707 if (attachments && modest_platform_check_memory_low (win, TRUE))
710 account_name = modest_account_mgr_get_default_account(mgr);
712 g_printerr ("modest: no account found\n");
715 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
717 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
720 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
722 g_printerr ("modest: failed to find Drafts folder\n");
725 from_str = modest_account_mgr_get_from_string (mgr, account_name);
727 g_printerr ("modest: failed get from string for '%s'\n", account_name);
731 signature = modest_account_mgr_get_signature (mgr, account_name, &use_signature);
732 if (body_str != NULL) {
733 body = use_signature ? g_strconcat(body_str, "\n", signature, NULL) : g_strdup(body_str);
735 body = use_signature ? g_strconcat("\n", signature, NULL) : g_strdup("");
738 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, body, NULL, NULL, NULL);
740 g_printerr ("modest: failed to create new msg\n");
744 /* Create and register edit window */
745 /* This is destroyed by TODO. */
747 allowed_size = MODEST_MAX_ATTACHMENT_SIZE;
748 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
749 while (attachments) {
751 modest_msg_edit_window_attach_file_one(
752 (ModestMsgEditWindow *)msg_win,
753 attachments->data, allowed_size);
755 if (total_size > allowed_size) {
756 g_warning ("%s: total size: %u",
757 __FUNCTION__, (unsigned int)total_size);
760 allowed_size -= total_size;
762 attachments = g_slist_next(attachments);
764 modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win);
765 modest_msg_edit_window_set_modified (MODEST_MSG_EDIT_WINDOW (msg_win), set_as_modified);
767 gtk_widget_show_all (GTK_WIDGET (msg_win));
773 g_free (account_name);
775 g_object_unref (G_OBJECT(account));
777 g_object_unref (G_OBJECT(folder));
779 g_object_unref (G_OBJECT(msg_win));
781 g_object_unref (G_OBJECT(msg));
785 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
787 /* if there are no accounts yet, just show the wizard */
788 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
789 if (!modest_ui_actions_run_account_setup_wizard (win))
792 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL, FALSE);
797 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
801 ModestMailOperationStatus status;
803 /* If there is no message or the operation was not successful */
804 status = modest_mail_operation_get_status (mail_op);
805 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
808 /* If it's a memory low issue, then show a banner */
809 error = modest_mail_operation_get_error (mail_op);
810 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
811 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
812 GObject *source = modest_mail_operation_get_source (mail_op);
813 modest_platform_run_information_dialog (GTK_IS_WINDOW (source) ? GTK_WINDOW (source) : NULL,
814 dgettext("ke-recv","memr_ib_operation_disabled"),
816 g_object_unref (source);
819 /* Remove the header from the preregistered uids */
820 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
838 OpenMsgBannerInfo *banner_info;
839 GHashTable *row_refs_per_header;
843 open_msg_banner_idle (gpointer userdata)
845 OpenMsgBannerInfo *banner_info = (OpenMsgBannerInfo *) userdata;
847 gdk_threads_enter ();
848 banner_info->idle_handler = 0;
849 banner_info->banner = modest_platform_animation_banner (NULL, NULL, banner_info->message);
851 g_object_ref (banner_info->banner);
853 gdk_threads_leave ();
860 open_msg_cb (ModestMailOperation *mail_op,
867 ModestWindowMgr *mgr = NULL;
868 ModestWindow *parent_win = NULL;
869 ModestWindow *win = NULL;
870 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
871 gchar *account = NULL;
873 gboolean open_in_editor = FALSE;
874 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
876 /* Do nothing if there was any problem with the mail
877 operation. The error will be shown by the error_handler of
878 the mail operation */
879 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
882 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
883 folder = tny_header_get_folder (header);
885 /* Mark header as read */
886 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
888 /* Gets folder type (OUTBOX headers will be opened in edit window */
889 if (modest_tny_folder_is_local_folder (folder)) {
890 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
891 if (folder_type == TNY_FOLDER_TYPE_INVALID)
892 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
896 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
897 TnyTransportAccount *traccount = NULL;
898 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
899 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
901 ModestTnySendQueue *send_queue = NULL;
902 ModestTnySendQueueStatus status;
904 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
905 TNY_ACCOUNT(traccount)));
906 send_queue = modest_runtime_get_send_queue(traccount, TRUE);
907 if (TNY_IS_SEND_QUEUE (send_queue)) {
908 msg_id = modest_tny_send_queue_get_msg_id (header);
909 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
910 /* Only open messages in outbox with the editor if they are in Failed state */
911 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
912 open_in_editor = TRUE;
916 g_object_unref(traccount);
918 g_warning("Cannot get transport account for message in outbox!!");
920 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
921 open_in_editor = TRUE; /* Open in editor if the message is in the Drafts folder */
926 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
928 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
930 if (open_in_editor) {
931 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
932 gchar *from_header = NULL;
934 from_header = tny_header_dup_from (header);
936 /* we cannot edit without a valid account... */
937 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
938 if (!modest_ui_actions_run_account_setup_wizard(parent_win)) {
939 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
941 g_free (from_header);
947 GSList *accounts = modest_account_mgr_account_names (mgr, TRUE);
950 for (node = accounts; node != NULL; node = g_slist_next (node)) {
951 gchar *from = modest_account_mgr_get_from_string (mgr, node->data);
953 if (from && (strcmp (from_header, from) == 0)) {
955 account = g_strdup (node->data);
962 g_free (from_header);
963 g_slist_foreach (accounts, (GFunc) g_free, NULL);
964 g_slist_free (accounts);
967 win = modest_msg_edit_window_new (msg, account, TRUE);
972 gchar *uid = modest_tny_folder_get_header_unique_id (header);
974 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
975 GtkTreeRowReference *row_reference;
977 row_reference = (GtkTreeRowReference *) g_hash_table_lookup (helper->row_refs_per_header, header);
979 win = modest_msg_view_window_new_with_header_model (msg, account, (const gchar*) uid,
980 helper->model, row_reference);
982 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
987 /* Register and show new window */
989 mgr = modest_runtime_get_window_mgr ();
990 modest_window_mgr_register_window (mgr, win);
991 g_object_unref (win);
992 gtk_widget_show_all (GTK_WIDGET(win));
995 /* Update toolbar dimming state */
996 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
997 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1003 g_object_unref (parent_win);
1004 g_object_unref (folder);
1008 is_memory_full_error (GError *error)
1010 gboolean enough_free_space = TRUE;
1011 GnomeVFSURI *cache_dir_uri;
1012 const gchar *cache_dir;
1013 GnomeVFSFileSize free_space;
1015 cache_dir = tny_account_store_get_cache_dir (TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
1016 cache_dir_uri = gnome_vfs_uri_new (cache_dir);
1017 if (gnome_vfs_get_volume_free_space (cache_dir_uri, &free_space) == GNOME_VFS_OK) {
1018 if (free_space < MIN_FREE_SPACE)
1019 enough_free_space = FALSE;
1021 gnome_vfs_uri_unref (cache_dir_uri);
1023 if ((error->code == TNY_SYSTEM_ERROR_MEMORY ||
1024 error->code == TNY_IO_ERROR_WRITE ||
1025 error->code == TNY_IO_ERROR_READ) &&
1026 !enough_free_space) {
1034 check_memory_full_error (GtkWidget *parent_window, GError *err)
1039 if (is_memory_full_error (err))
1040 modest_platform_information_banner (parent_window,
1041 NULL, dgettext("ke-recv",
1042 "cerm_device_memory_full"));
1043 else if (err->code == TNY_SYSTEM_ERROR_MEMORY)
1044 /* If the account was created in memory full
1045 conditions then tinymail won't be able to
1046 connect so it'll return this error code */
1047 modest_platform_information_banner (parent_window,
1048 NULL, _("emev_ui_imap_inbox_select_error"));
1056 modest_ui_actions_disk_operations_error_handler (ModestMailOperation *mail_op,
1059 const GError *error;
1060 GObject *win = NULL;
1061 ModestMailOperationStatus status;
1063 win = modest_mail_operation_get_source (mail_op);
1064 error = modest_mail_operation_get_error (mail_op);
1065 status = modest_mail_operation_get_status (mail_op);
1067 /* If the mail op has been cancelled then it's not an error:
1068 don't show any message */
1069 if (status != MODEST_MAIL_OPERATION_STATUS_CANCELED) {
1070 if (is_memory_full_error ((GError *) error)) {
1071 modest_platform_information_banner ((GtkWidget *) win,
1072 NULL, dgettext("ke-recv",
1073 "cerm_device_memory_full"));
1074 } else if (error->code == TNY_SYSTEM_ERROR_MEMORY) {
1075 modest_platform_information_banner ((GtkWidget *) win,
1076 NULL, _("emev_ui_imap_inbox_select_error"));
1077 } else if (error->code == MODEST_MAIL_OPERATION_ERROR_FILE_IO) {
1078 modest_platform_information_banner ((GtkWidget *) win,
1079 NULL, dgettext ("hildon-common-strings", "sfil_ni_unable_to_open_file_not_found"));
1080 } else if (user_data) {
1081 modest_platform_information_banner ((GtkWidget *) win,
1087 g_object_unref (win);
1091 * Returns the account a list of headers belongs to. It returns a
1092 * *new* reference so don't forget to unref it
1095 get_account_from_header_list (TnyList *headers)
1097 TnyAccount *account = NULL;
1099 if (tny_list_get_length (headers) > 0) {
1100 TnyIterator *iter = tny_list_create_iterator (headers);
1101 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1102 TnyFolder *folder = tny_header_get_folder (header);
1105 g_object_unref (header);
1107 while (!tny_iterator_is_done (iter)) {
1108 header = TNY_HEADER (tny_iterator_get_current (iter));
1109 folder = tny_header_get_folder (header);
1112 g_object_unref (header);
1114 tny_iterator_next (iter);
1119 account = tny_folder_get_account (folder);
1120 g_object_unref (folder);
1124 g_object_unref (header);
1126 g_object_unref (iter);
1132 foreach_unregister_headers (gpointer data,
1135 ModestWindowMgr *mgr = (ModestWindowMgr *) user_data;
1136 TnyHeader *header = TNY_HEADER (data);
1138 modest_window_mgr_unregister_header (mgr, header);
1142 open_msgs_helper_destroyer (gpointer user_data)
1144 OpenMsgHelper *helper = (OpenMsgHelper *) user_data;
1146 if (helper->banner_info) {
1147 g_free (helper->banner_info->message);
1148 if (helper->banner_info->idle_handler > 0) {
1149 g_source_remove (helper->banner_info->idle_handler);
1150 helper->banner_info->idle_handler = 0;
1152 if (helper->banner_info->banner != NULL) {
1153 gtk_widget_destroy (helper->banner_info->banner);
1154 g_object_unref (helper->banner_info->banner);
1155 helper->banner_info->banner = NULL;
1157 g_slice_free (OpenMsgBannerInfo, helper->banner_info);
1158 helper->banner_info = NULL;
1160 g_object_unref (helper->model);
1161 g_object_unref (helper->headers);
1162 g_hash_table_destroy (helper->row_refs_per_header);
1163 g_slice_free (OpenMsgHelper, helper);
1167 open_msgs_performer(gboolean canceled,
1169 GtkWindow *parent_window,
1170 TnyAccount *account,
1173 ModestMailOperation *mail_op = NULL;
1174 const gchar *proto_name;
1176 ModestTransportStoreProtocol proto;
1177 TnyList *not_opened_headers;
1178 TnyConnectionStatus status;
1179 gboolean show_open_draft = FALSE;
1180 OpenMsgHelper *helper = NULL;
1182 helper = (OpenMsgHelper *) user_data;
1183 not_opened_headers = helper->headers;
1185 status = tny_account_get_connection_status (account);
1186 if (err || canceled) {
1187 /* Unregister the already registered headers */
1188 tny_list_foreach (not_opened_headers, foreach_unregister_headers,
1189 modest_runtime_get_window_mgr ());
1190 /* Free the helper */
1191 open_msgs_helper_destroyer (helper);
1193 /* In memory full conditions we could get this error here */
1194 check_memory_full_error ((GtkWidget *) parent_window, err);
1199 /* Get the error message depending on the protocol */
1200 proto_name = tny_account_get_proto (account);
1201 if (proto_name != NULL) {
1202 proto = modest_protocol_info_get_transport_store_protocol (proto_name);
1204 proto = MODEST_PROTOCOL_STORE_MAILDIR;
1207 /* Create the error messages */
1208 if (tny_list_get_length (not_opened_headers) == 1) {
1209 if (proto == MODEST_PROTOCOL_STORE_POP) {
1210 error_msg = g_strdup (_("emev_ni_ui_pop3_msg_recv_error"));
1211 } else if (proto == MODEST_PROTOCOL_STORE_IMAP) {
1212 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1213 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1214 gchar *subject = tny_header_dup_subject (header);
1215 error_msg = g_strdup_printf (_("emev_ni_ui_imap_message_not_available_in_server"),
1218 g_object_unref (header);
1219 g_object_unref (iter);
1224 TnyFolderType folder_type;
1226 iter = tny_list_create_iterator (not_opened_headers);
1227 header = TNY_HEADER (tny_iterator_get_current (iter));
1228 folder = tny_header_get_folder (header);
1229 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
1230 show_open_draft = (folder_type == TNY_FOLDER_TYPE_DRAFTS);
1231 g_object_unref (folder);
1232 g_object_unref (header);
1233 g_object_unref (iter);
1234 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1237 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1240 /* Create the mail operation */
1242 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1243 modest_ui_actions_disk_operations_error_handler,
1245 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1248 if (show_open_draft) {
1249 helper->banner_info = g_slice_new (OpenMsgBannerInfo);
1250 helper->banner_info->message = g_strdup (_("mail_ib_opening_draft_message"));
1251 helper->banner_info->banner = NULL;
1252 helper->banner_info->idle_handler = g_timeout_add (500, open_msg_banner_idle,
1253 helper->banner_info);
1256 modest_mail_operation_get_msgs_full (mail_op,
1260 open_msgs_helper_destroyer);
1265 g_object_unref (mail_op);
1266 g_object_unref (account);
1270 * This function is used by both modest_ui_actions_on_open and
1271 * modest_ui_actions_on_header_activated. This way we always do the
1272 * same when trying to open messages.
1275 open_msgs_from_headers (TnyList *headers, ModestWindow *win)
1277 ModestWindowMgr *mgr = NULL;
1278 TnyIterator *iter = NULL, *iter_not_opened = NULL;
1279 TnyList *not_opened_headers = NULL;
1280 TnyHeaderFlags flags = 0;
1281 TnyAccount *account;
1282 gint uncached_msgs = 0;
1283 GtkWidget *header_view;
1284 GtkTreeModel *model;
1285 GHashTable *refs_for_headers;
1286 OpenMsgHelper *helper;
1287 GtkTreeSelection *sel;
1288 GList *sel_list = NULL, *sel_list_iter = NULL;
1290 g_return_if_fail (headers != NULL);
1292 /* Check that only one message is selected for opening */
1293 if (tny_list_get_length (headers) != 1) {
1294 modest_platform_information_banner ((win) ? GTK_WIDGET (win) : NULL,
1295 NULL, _("mcen_ib_select_one_message"));
1299 mgr = modest_runtime_get_window_mgr ();
1300 iter = tny_list_create_iterator (headers);
1302 /* Get the account */
1303 account = get_account_from_header_list (headers);
1308 /* Get the selections, we need to get the references to the
1309 rows here because the treeview/model could dissapear (the
1310 user might want to select another folder)*/
1311 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1312 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1313 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
1314 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
1315 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
1316 refs_for_headers = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
1317 (GDestroyNotify) gtk_tree_row_reference_free);
1319 /* Look if we already have a message view for each header. If
1320 true, then remove the header from the list of headers to
1322 sel_list_iter = sel_list;
1323 not_opened_headers = tny_simple_list_new ();
1324 while (!tny_iterator_is_done (iter) && sel_list_iter) {
1326 ModestWindow *window = NULL;
1327 TnyHeader *header = NULL;
1328 gboolean found = FALSE;
1330 header = TNY_HEADER (tny_iterator_get_current (iter));
1332 flags = tny_header_get_flags (header);
1335 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1337 /* Do not open again the message and present the
1338 window to the user */
1341 gtk_window_present (GTK_WINDOW (window));
1343 /* the header has been registered already, we don't do
1344 * anything but wait for the window to come up*/
1345 g_debug ("header %p already registered, waiting for window", header);
1348 GtkTreeRowReference *row_reference;
1350 tny_list_append (not_opened_headers, G_OBJECT (header));
1351 /* Create a new row reference and add it to the hash table */
1352 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list_iter->data);
1353 g_hash_table_insert (refs_for_headers, header, row_reference);
1357 g_object_unref (header);
1360 tny_iterator_next (iter);
1361 sel_list_iter = g_list_next (sel_list_iter);
1363 g_object_unref (iter);
1365 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
1366 g_list_free (sel_list);
1368 /* Open each message */
1369 if (tny_list_get_length (not_opened_headers) == 0) {
1370 g_hash_table_destroy (refs_for_headers);
1374 /* If some messages would have to be downloaded, ask the user to
1375 * make a connection. It's generally easier to do this here (in the mainloop)
1376 * than later in a thread:
1378 if (tny_list_get_length (not_opened_headers) > 0) {
1379 uncached_msgs = header_list_count_uncached_msgs (not_opened_headers);
1381 if (uncached_msgs > 0) {
1382 /* Allways download if we are online. */
1383 if (!tny_device_is_online (modest_runtime_get_device ())) {
1386 /* If ask for user permission to download the messages */
1387 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1388 ngettext("mcen_nc_get_msg",
1392 /* End if the user does not want to continue */
1393 if (response == GTK_RESPONSE_CANCEL) {
1394 g_hash_table_destroy (refs_for_headers);
1401 /* Register the headers before actually creating the windows: */
1402 iter_not_opened = tny_list_create_iterator (not_opened_headers);
1403 while (!tny_iterator_is_done (iter_not_opened)) {
1404 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1406 modest_window_mgr_register_header (mgr, header, NULL);
1407 g_object_unref (header);
1409 tny_iterator_next (iter_not_opened);
1411 g_object_unref (iter_not_opened);
1412 iter_not_opened = NULL;
1414 /* Create the helper. We need to get a reference to the model
1415 here because it could change while the message is readed
1416 (the user could switch between folders) */
1417 helper = g_slice_new (OpenMsgHelper);
1418 helper->model = g_object_ref (model);
1419 helper->headers = g_object_ref (not_opened_headers);
1420 helper->row_refs_per_header = refs_for_headers;
1421 helper->banner_info = NULL;
1423 /* Connect to the account and perform */
1424 if (uncached_msgs > 0) {
1425 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1426 open_msgs_performer, helper);
1428 /* Call directly the performer, do not need to connect */
1429 open_msgs_performer (FALSE, NULL, (GtkWindow *) win,
1430 g_object_ref (account), helper);
1435 g_object_unref (account);
1436 if (not_opened_headers)
1437 g_object_unref (not_opened_headers);
1441 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1445 /* we check for low-mem; in that case, show a warning, and don't allow
1448 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1452 headers = get_selected_headers (win);
1457 open_msgs_from_headers (headers, win);
1459 g_object_unref(headers);
1462 static ReplyForwardHelper*
1463 create_reply_forward_helper (ReplyForwardAction action,
1465 guint reply_forward_type,
1468 ReplyForwardHelper *rf_helper = NULL;
1469 const gchar *active_acc = modest_window_get_active_account (win);
1471 rf_helper = g_slice_new0 (ReplyForwardHelper);
1472 rf_helper->reply_forward_type = reply_forward_type;
1473 rf_helper->action = action;
1474 rf_helper->parent_window = (MODEST_IS_WINDOW (win)) ? GTK_WIDGET (win) : NULL;
1475 rf_helper->header = (header) ? g_object_ref (header) : NULL;
1476 rf_helper->account_name = (active_acc) ?
1477 g_strdup (active_acc) :
1478 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1484 free_reply_forward_helper (gpointer data)
1486 ReplyForwardHelper *helper;
1488 helper = (ReplyForwardHelper *) data;
1489 g_free (helper->account_name);
1491 g_object_unref (helper->header);
1492 g_slice_free (ReplyForwardHelper, helper);
1496 reply_forward_cb (ModestMailOperation *mail_op,
1503 TnyMsg *new_msg = NULL;
1504 ReplyForwardHelper *rf_helper;
1505 ModestWindow *msg_win = NULL;
1506 ModestEditType edit_type;
1508 TnyAccount *account = NULL;
1509 ModestWindowMgr *mgr = NULL;
1510 gchar *signature = NULL;
1511 gboolean use_signature;
1513 /* If there was any error. The mail operation could be NULL,
1514 this means that we already have the message downloaded and
1515 that we didn't do a mail operation to retrieve it */
1516 rf_helper = (ReplyForwardHelper *) user_data;
1517 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1520 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1521 rf_helper->account_name);
1522 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr(),
1523 rf_helper->account_name,
1526 /* Create reply mail */
1527 switch (rf_helper->action) {
1530 modest_tny_msg_create_reply_msg (msg, header, from,
1531 (use_signature) ? signature : NULL,
1532 rf_helper->reply_forward_type,
1533 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1535 case ACTION_REPLY_TO_ALL:
1537 modest_tny_msg_create_reply_msg (msg, header, from,
1538 (use_signature) ? signature : NULL,
1539 rf_helper->reply_forward_type,
1540 MODEST_TNY_MSG_REPLY_MODE_ALL);
1541 edit_type = MODEST_EDIT_TYPE_REPLY;
1543 case ACTION_FORWARD:
1545 modest_tny_msg_create_forward_msg (msg, from, (use_signature) ? signature : NULL,
1546 rf_helper->reply_forward_type);
1547 edit_type = MODEST_EDIT_TYPE_FORWARD;
1550 g_return_if_reached ();
1558 g_warning ("%s: failed to create message\n", __FUNCTION__);
1562 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1563 rf_helper->account_name,
1564 TNY_ACCOUNT_TYPE_STORE);
1566 g_warning ("%s: failed to get tnyaccount for '%s'\n", __FUNCTION__, rf_helper->account_name);
1570 /* Create and register the windows */
1571 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1572 mgr = modest_runtime_get_window_mgr ();
1573 modest_window_mgr_register_window (mgr, msg_win);
1575 if (rf_helper->parent_window != NULL) {
1576 gdouble parent_zoom;
1578 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1579 modest_window_set_zoom (msg_win, parent_zoom);
1582 /* Show edit window */
1583 gtk_widget_show_all (GTK_WIDGET (msg_win));
1587 g_object_unref (msg_win);
1589 g_object_unref (G_OBJECT (new_msg));
1591 g_object_unref (G_OBJECT (account));
1592 free_reply_forward_helper (rf_helper);
1595 /* Checks a list of headers. If any of them are not currently
1596 * downloaded (CACHED) then returns TRUE else returns FALSE.
1599 header_list_count_uncached_msgs (TnyList *header_list)
1602 gint uncached_messages = 0;
1604 iter = tny_list_create_iterator (header_list);
1605 while (!tny_iterator_is_done (iter)) {
1608 header = TNY_HEADER (tny_iterator_get_current (iter));
1610 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1611 uncached_messages ++;
1612 g_object_unref (header);
1615 tny_iterator_next (iter);
1617 g_object_unref (iter);
1619 return uncached_messages;
1622 /* Returns FALSE if the user does not want to download the
1623 * messages. Returns TRUE if the user allowed the download.
1626 connect_to_get_msg (ModestWindow *win,
1627 gint num_of_uncached_msgs,
1628 TnyAccount *account)
1630 GtkResponseType response;
1632 /* Allways download if we are online. */
1633 if (tny_device_is_online (modest_runtime_get_device ()))
1636 /* If offline, then ask for user permission to download the messages */
1637 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1638 ngettext("mcen_nc_get_msg",
1640 num_of_uncached_msgs));
1642 if (response == GTK_RESPONSE_CANCEL)
1645 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1649 reply_forward_performer (gboolean canceled,
1651 GtkWindow *parent_window,
1652 TnyAccount *account,
1655 ReplyForwardHelper *rf_helper = NULL;
1656 ModestMailOperation *mail_op;
1658 rf_helper = (ReplyForwardHelper *) user_data;
1660 if (canceled || err) {
1661 free_reply_forward_helper (rf_helper);
1665 /* Retrieve the message */
1666 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (parent_window),
1667 modest_ui_actions_disk_operations_error_handler,
1669 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1670 modest_mail_operation_get_msg (mail_op, rf_helper->header, TRUE, reply_forward_cb, rf_helper);
1673 g_object_unref(mail_op);
1677 * Common code for the reply and forward actions
1680 reply_forward (ReplyForwardAction action, ModestWindow *win)
1682 ReplyForwardHelper *rf_helper = NULL;
1683 guint reply_forward_type;
1685 g_return_if_fail (MODEST_IS_WINDOW(win));
1687 /* we check for low-mem; in that case, show a warning, and don't allow
1688 * reply/forward (because it could potentially require a lot of memory */
1689 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
1693 /* we need an account when editing */
1694 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1695 if (!modest_ui_actions_run_account_setup_wizard (win))
1699 reply_forward_type =
1700 modest_conf_get_int (modest_runtime_get_conf (),
1701 (action == ACTION_FORWARD) ?
1702 MODEST_CONF_FORWARD_TYPE :
1703 MODEST_CONF_REPLY_TYPE,
1706 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
1708 TnyHeader *header = NULL;
1709 /* Get header and message. Do not free them here, the
1710 reply_forward_cb must do it */
1711 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1712 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
1714 if (msg && header) {
1716 rf_helper = create_reply_forward_helper (action, win,
1717 reply_forward_type, header);
1718 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1720 g_warning("%s: no message or header found in viewer\n", __FUNCTION__);
1724 g_object_unref (msg);
1726 g_object_unref (header);
1728 TnyHeader *header = NULL;
1730 gboolean do_retrieve = TRUE;
1731 TnyList *header_list = NULL;
1733 header_list = get_selected_headers (win);
1736 if (tny_list_get_length (header_list) == 0) {
1737 g_object_unref (header_list);
1741 /* Only reply/forward to one message */
1742 iter = tny_list_create_iterator (header_list);
1743 header = TNY_HEADER (tny_iterator_get_current (iter));
1744 g_object_unref (iter);
1746 /* Retrieve messages */
1747 do_retrieve = (action == ACTION_FORWARD) ||
1748 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1751 TnyAccount *account = NULL;
1752 TnyFolder *folder = NULL;
1753 gdouble download = TRUE;
1754 guint uncached_msgs = 0;
1756 folder = tny_header_get_folder (header);
1758 goto do_retrieve_frees;
1759 account = tny_folder_get_account (folder);
1761 goto do_retrieve_frees;
1763 uncached_msgs = header_list_count_uncached_msgs (header_list);
1765 if (uncached_msgs > 0) {
1766 /* Allways download if we are online. */
1767 if (!tny_device_is_online (modest_runtime_get_device ())) {
1770 /* If ask for user permission to download the messages */
1771 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1772 ngettext("mcen_nc_get_msg",
1776 /* End if the user does not want to continue */
1777 if (response == GTK_RESPONSE_CANCEL)
1784 rf_helper = create_reply_forward_helper (action, win,
1785 reply_forward_type, header);
1786 if (uncached_msgs > 0) {
1787 modest_platform_connect_and_perform (GTK_WINDOW (win),
1789 reply_forward_performer,
1792 reply_forward_performer (FALSE, NULL, GTK_WINDOW (win),
1793 account, rf_helper);
1798 g_object_unref (account);
1800 g_object_unref (folder);
1802 reply_forward_cb (NULL, header, FALSE, NULL, NULL, rf_helper);
1805 g_object_unref (header_list);
1806 g_object_unref (header);
1811 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1813 g_return_if_fail (MODEST_IS_WINDOW(win));
1815 reply_forward (ACTION_REPLY, win);
1819 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1821 g_return_if_fail (MODEST_IS_WINDOW(win));
1823 reply_forward (ACTION_FORWARD, win);
1827 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1829 g_return_if_fail (MODEST_IS_WINDOW(win));
1831 reply_forward (ACTION_REPLY_TO_ALL, win);
1835 modest_ui_actions_on_next (GtkAction *action,
1836 ModestWindow *window)
1838 if (MODEST_IS_MAIN_WINDOW (window)) {
1839 GtkWidget *header_view;
1841 header_view = modest_main_window_get_child_widget (
1842 MODEST_MAIN_WINDOW(window),
1843 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1847 modest_header_view_select_next (
1848 MODEST_HEADER_VIEW(header_view));
1849 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1850 modest_msg_view_window_select_next_message (
1851 MODEST_MSG_VIEW_WINDOW (window));
1853 g_return_if_reached ();
1858 modest_ui_actions_on_prev (GtkAction *action,
1859 ModestWindow *window)
1861 g_return_if_fail (MODEST_IS_WINDOW(window));
1863 if (MODEST_IS_MAIN_WINDOW (window)) {
1864 GtkWidget *header_view;
1865 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1866 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1870 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1871 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1872 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1874 g_return_if_reached ();
1879 modest_ui_actions_on_sort (GtkAction *action,
1880 ModestWindow *window)
1882 g_return_if_fail (MODEST_IS_WINDOW(window));
1884 if (MODEST_IS_MAIN_WINDOW (window)) {
1885 GtkWidget *header_view;
1886 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1887 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1889 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1894 /* Show sorting dialog */
1895 modest_utils_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1900 new_messages_arrived (ModestMailOperation *self,
1901 TnyList *new_headers,
1905 gboolean show_visual_notifications;
1907 source = modest_mail_operation_get_source (self);
1908 show_visual_notifications = (source) ? FALSE : TRUE;
1910 g_object_unref (source);
1912 /* Notify new messages have been downloaded. If the
1913 send&receive was invoked by the user then do not show any
1914 visual notification, only play a sound and activate the LED
1915 (for the Maemo version) */
1916 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0)
1917 modest_platform_on_new_headers_received (new_headers,
1918 show_visual_notifications);
1923 retrieve_all_messages_cb (GObject *source,
1925 guint retrieve_limit)
1931 window = GTK_WINDOW (source);
1932 msg = g_strdup_printf (_("mail_nc_msg_count_limit_exceeded"),
1933 num_msgs, retrieve_limit);
1935 /* Ask the user if they want to retrieve all the messages */
1937 modest_platform_run_confirmation_dialog_with_buttons (window, msg,
1938 _("mcen_bd_get_all"),
1939 _("mcen_bd_newest_only"));
1940 /* Free and return */
1942 return (response == GTK_RESPONSE_ACCEPT) ? TRUE : FALSE;
1946 TnyAccount *account;
1948 gchar *account_name;
1949 gboolean poke_status;
1950 gboolean interactive;
1951 ModestMailOperation *mail_op;
1955 do_send_receive_performer (gboolean canceled,
1957 GtkWindow *parent_window,
1958 TnyAccount *account,
1961 SendReceiveInfo *info;
1963 info = (SendReceiveInfo *) user_data;
1965 if (err || canceled) {
1966 /* In memory full conditions we could get this error here */
1967 check_memory_full_error ((GtkWidget *) parent_window, err);
1969 if (info->mail_op) {
1970 modest_mail_operation_queue_remove (modest_runtime_get_mail_operation_queue (),
1976 /* Set send/receive operation in progress */
1977 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
1978 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
1981 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
1982 g_signal_connect (G_OBJECT (info->mail_op), "operation-finished",
1983 G_CALLBACK (on_send_receive_finished),
1986 /* Send & receive. */
1987 modest_mail_operation_update_account (info->mail_op, info->account_name, info->poke_status, info->interactive,
1988 (info->win) ? retrieve_all_messages_cb : NULL,
1989 new_messages_arrived, info->win);
1994 g_object_unref (G_OBJECT (info->mail_op));
1995 if (info->account_name)
1996 g_free (info->account_name);
1998 g_object_unref (info->win);
2000 g_object_unref (info->account);
2001 g_slice_free (SendReceiveInfo, info);
2005 * This function performs the send & receive required actions. The
2006 * window is used to create the mail operation. Typically it should
2007 * always be the main window, but we pass it as argument in order to
2011 modest_ui_actions_do_send_receive (const gchar *account_name,
2012 gboolean force_connection,
2013 gboolean poke_status,
2014 gboolean interactive,
2017 gchar *acc_name = NULL;
2018 SendReceiveInfo *info;
2019 ModestTnyAccountStore *acc_store;
2021 /* If no account name was provided then get the current account, and if
2022 there is no current account then pick the default one: */
2023 if (!account_name) {
2025 acc_name = g_strdup (modest_window_get_active_account (win));
2027 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
2029 g_printerr ("modest: cannot get default account\n");
2033 acc_name = g_strdup (account_name);
2036 acc_store = modest_runtime_get_account_store ();
2038 /* Create the info for the connect and perform */
2039 info = g_slice_new (SendReceiveInfo);
2040 info->account_name = acc_name;
2041 info->win = (win) ? g_object_ref (win) : NULL;
2042 info->poke_status = poke_status;
2043 info->interactive = interactive;
2044 info->account = modest_tny_account_store_get_server_account (acc_store, acc_name,
2045 TNY_ACCOUNT_TYPE_STORE);
2046 /* We need to create the operation here, because otherwise it
2047 could happen that the queue emits the queue-empty signal
2048 while we're trying to connect the account */
2049 info->mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
2050 modest_ui_actions_disk_operations_error_handler,
2052 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), info->mail_op);
2054 /* Invoke the connect and perform */
2055 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
2056 force_connection, info->account,
2057 do_send_receive_performer, info);
2062 modest_ui_actions_do_cancel_send (const gchar *account_name,
2065 TnyTransportAccount *transport_account;
2066 TnySendQueue *send_queue = NULL;
2067 GError *error = NULL;
2069 /* Get transport account */
2071 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2072 (modest_runtime_get_account_store(),
2074 TNY_ACCOUNT_TYPE_TRANSPORT));
2075 if (!transport_account) {
2076 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2081 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account, TRUE));
2082 if (!TNY_IS_SEND_QUEUE(send_queue)) {
2083 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
2084 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
2085 "modest: could not find send queue for account\n");
2087 /* Cancel the current send */
2088 tny_account_cancel (TNY_ACCOUNT (transport_account));
2090 /* Suspend all pending messages */
2091 tny_send_queue_cancel (send_queue, TNY_SEND_QUEUE_CANCEL_ACTION_SUSPEND, &error);
2095 if (transport_account != NULL)
2096 g_object_unref (G_OBJECT (transport_account));
2100 modest_ui_actions_cancel_send_all (ModestWindow *win)
2102 GSList *account_names, *iter;
2104 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2107 iter = account_names;
2109 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
2110 iter = g_slist_next (iter);
2113 modest_account_mgr_free_account_names (account_names);
2114 account_names = NULL;
2118 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
2121 /* Check if accounts exist */
2122 gboolean accounts_exist =
2123 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2125 /* If not, allow the user to create an account before trying to send/receive. */
2126 if (!accounts_exist)
2127 modest_ui_actions_on_accounts (NULL, win);
2129 /* Cancel all sending operaitons */
2130 modest_ui_actions_cancel_send_all (win);
2134 * Refreshes all accounts. This function will be used by automatic
2138 modest_ui_actions_do_send_receive_all (ModestWindow *win,
2139 gboolean force_connection,
2140 gboolean poke_status,
2141 gboolean interactive)
2143 GSList *account_names, *iter;
2145 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
2148 iter = account_names;
2150 modest_ui_actions_do_send_receive ((const char*) iter->data,
2152 poke_status, interactive, win);
2153 iter = g_slist_next (iter);
2156 modest_account_mgr_free_account_names (account_names);
2157 account_names = NULL;
2161 * Handler of the click on Send&Receive button in the main toolbar
2164 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
2166 /* Check if accounts exist */
2167 gboolean accounts_exist;
2170 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
2172 /* If not, allow the user to create an account before trying to send/receive. */
2173 if (!accounts_exist)
2174 modest_ui_actions_on_accounts (NULL, win);
2176 /* Refresh the current folder. The if is always TRUE it's just an extra check */
2177 if (MODEST_IS_MAIN_WINDOW (win)) {
2178 GtkWidget *folder_view;
2179 TnyFolderStore *folder_store;
2182 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
2183 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2187 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2190 g_object_unref (folder_store);
2193 /* Refresh the active account. Force the connection if needed
2194 and poke the status of all folders */
2195 modest_ui_actions_do_send_receive (NULL, TRUE, TRUE, TRUE, win);
2200 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
2203 GtkWidget *header_view;
2205 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2207 header_view = modest_main_window_get_child_widget (main_window,
2208 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2212 conf = modest_runtime_get_conf ();
2214 /* what is saved/restored is depending on the style; thus; we save with
2215 * old style, then update the style, and restore for this new style
2217 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
2219 if (modest_header_view_get_style
2220 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
2221 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2222 MODEST_HEADER_VIEW_STYLE_TWOLINES);
2224 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
2225 MODEST_HEADER_VIEW_STYLE_DETAILS);
2227 modest_widget_memory_restore (conf, G_OBJECT(header_view),
2228 MODEST_CONF_HEADER_VIEW_KEY);
2233 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
2235 ModestMainWindow *main_window)
2237 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2238 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
2240 /* in the case the folder is empty, show the empty folder message and focus
2242 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
2243 if (modest_header_view_is_empty (header_view)) {
2244 TnyFolder *folder = modest_header_view_get_folder (header_view);
2245 GtkWidget *folder_view =
2246 modest_main_window_get_child_widget (main_window,
2247 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2248 if (folder != NULL) {
2249 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
2250 g_object_unref (folder);
2252 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
2256 /* If no header has been selected then exit */
2261 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
2262 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2264 /* Update toolbar dimming state */
2265 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2266 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2270 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2272 ModestMainWindow *main_window)
2275 GtkWidget *open_widget;
2277 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2282 if (modest_header_view_count_selected_headers (header_view) > 1) {
2283 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2287 /* we check for low-mem; in that case, show a warning, and don't allow
2288 * activating headers
2290 if (modest_platform_check_memory_low (MODEST_WINDOW(main_window), TRUE))
2293 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2294 open_widget = modest_window_get_action_widget (MODEST_WINDOW (main_window), "/MenuBar/EmailMenu/EmailOpenMenu");
2295 if (!GTK_WIDGET_IS_SENSITIVE (open_widget))
2298 headers = modest_header_view_get_selected_headers (header_view);
2300 open_msgs_from_headers (headers, MODEST_WINDOW (main_window));
2302 g_object_unref (headers);
2306 set_active_account_from_tny_account (TnyAccount *account,
2307 ModestWindow *window)
2309 const gchar *server_acc_name = tny_account_get_id (account);
2311 /* We need the TnyAccount provided by the
2312 account store because that is the one that
2313 knows the name of the Modest account */
2314 TnyAccount *modest_server_account = modest_server_account =
2315 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2316 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2318 if (!modest_server_account) {
2319 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2323 /* Update active account, but only if it's not a pseudo-account */
2324 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2325 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2326 const gchar *modest_acc_name =
2327 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2328 if (modest_acc_name)
2329 modest_window_set_active_account (window, modest_acc_name);
2332 g_object_unref (modest_server_account);
2337 folder_refreshed_cb (ModestMailOperation *mail_op,
2341 ModestMainWindow *win = NULL;
2342 GtkWidget *header_view;
2343 const GError *error;
2345 g_return_if_fail (TNY_IS_FOLDER (folder));
2347 win = MODEST_MAIN_WINDOW (user_data);
2349 /* Check if the operation failed due to memory low conditions */
2350 error = modest_mail_operation_get_error (mail_op);
2351 if (error && error->domain == MODEST_MAIL_OPERATION_ERROR &&
2352 error->code == MODEST_MAIL_OPERATION_ERROR_LOW_MEMORY) {
2353 modest_platform_run_information_dialog (GTK_WINDOW (win),
2354 dgettext("ke-recv","memr_ib_operation_disabled"),
2360 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2363 TnyFolder *current_folder;
2365 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
2366 if (current_folder != NULL && folder != current_folder) {
2367 g_object_unref (current_folder);
2369 } else if (current_folder)
2370 g_object_unref (current_folder);
2373 /* Check if folder is empty and set headers view contents style */
2374 if (tny_folder_get_all_count (folder) == 0)
2375 modest_main_window_set_contents_style (win,
2376 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2381 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2382 TnyFolderStore *folder_store,
2384 ModestMainWindow *main_window)
2387 GtkWidget *header_view;
2389 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2391 header_view = modest_main_window_get_child_widget(main_window,
2392 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2396 conf = modest_runtime_get_conf ();
2398 if (TNY_IS_ACCOUNT (folder_store)) {
2400 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2402 /* Show account details */
2403 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2406 if (TNY_IS_FOLDER (folder_store) && selected) {
2407 TnyAccount *account;
2408 const gchar *account_name = NULL;
2411 /* Update the active account */
2412 account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2414 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2416 modest_tny_account_get_parent_modest_account_name_for_server_account (account);
2417 g_object_unref (account);
2421 /* Set the header style by default, it could
2422 be changed later by the refresh callback to
2424 modest_main_window_set_contents_style (main_window,
2425 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2427 refresh = !modest_account_mgr_account_is_busy (modest_runtime_get_account_mgr (), account_name);
2429 /* Set folder on header view. This function
2430 will call tny_folder_refresh_async so we
2431 pass a callback that will be called when
2432 finished. We use that callback to set the
2433 empty view if there are no messages */
2434 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2435 TNY_FOLDER (folder_store),
2437 folder_refreshed_cb,
2440 /* Restore configuration. We need to do this
2441 *after* the set_folder because the widget
2442 memory asks the header view about its
2444 modest_widget_memory_restore (modest_runtime_get_conf (),
2445 G_OBJECT(header_view),
2446 MODEST_CONF_HEADER_VIEW_KEY);
2448 /* No need to save the header view
2449 configuration for Maemo because it only
2450 saves the sorting stuff and that it's
2451 already being done by the sort
2452 dialog. Remove it when the GNOME version
2453 has the same behaviour */
2454 #ifdef MODEST_PLATFORM_GNOME
2455 if (modest_main_window_get_contents_style (main_window) ==
2456 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2457 modest_widget_memory_save (conf, G_OBJECT (header_view),
2458 MODEST_CONF_HEADER_VIEW_KEY);
2460 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2464 /* Update dimming state */
2465 modest_ui_actions_check_menu_dimming_rules (MODEST_WINDOW (main_window));
2466 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2470 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2477 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2479 online = tny_device_is_online (modest_runtime_get_device());
2482 /* already online -- the item is simply not there... */
2483 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2485 GTK_MESSAGE_WARNING,
2487 _("The %s you selected cannot be found"),
2489 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2490 gtk_dialog_run (GTK_DIALOG(dialog));
2492 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2495 _("mcen_bd_dialog_cancel"),
2496 GTK_RESPONSE_REJECT,
2497 _("mcen_bd_dialog_ok"),
2498 GTK_RESPONSE_ACCEPT,
2500 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2501 "Do you want to get online?"), item);
2502 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2503 gtk_label_new (txt), FALSE, FALSE, 0);
2504 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2507 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2508 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2509 /* TODO: Comment about why is this commented out: */
2510 /* modest_platform_connect_and_wait (); */
2513 gtk_widget_destroy (dialog);
2517 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2520 /* g_message ("%s %s", __FUNCTION__, link); */
2525 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2528 modest_platform_activate_uri (link);
2532 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2535 modest_platform_show_uri_popup (link);
2539 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2542 /* we check for low-mem; in that case, show a warning, and don't allow
2543 * viewing attachments
2545 if (modest_platform_check_memory_low (MODEST_WINDOW(win), TRUE))
2548 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2552 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2553 const gchar *address,
2556 /* g_message ("%s %s", __FUNCTION__, address); */
2560 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2561 TnyMsg *saved_draft,
2564 ModestMsgEditWindow *edit_window;
2565 ModestMainWindow *win;
2567 /* FIXME. Make the header view sensitive again. This is a
2568 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2570 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2571 modest_runtime_get_window_mgr(), FALSE));
2573 GtkWidget *hdrview = modest_main_window_get_child_widget(
2574 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2575 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2578 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2580 /* Set draft is there was no error */
2581 if (!modest_mail_operation_get_error (mail_op))
2582 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2584 g_object_unref(edit_window);
2588 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2590 TnyTransportAccount *transport_account;
2591 ModestMailOperation *mail_operation;
2593 gchar *account_name, *from;
2594 ModestAccountMgr *account_mgr;
2595 /* char *info_text; */
2596 gboolean had_error = FALSE;
2597 guint64 available_disk, expected_size;
2600 ModestMainWindow *win;
2602 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), FALSE);
2604 data = modest_msg_edit_window_get_msg_data (edit_window);
2607 available_disk = modest_folder_available_space (NULL);
2608 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2609 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2614 if ((available_disk != -1) && expected_size > available_disk) {
2615 modest_msg_edit_window_free_msg_data (edit_window, data);
2617 modest_platform_information_banner (NULL, NULL, dgettext("ke-recv", "cerm_device_memory_full"));
2622 * djcb: if we're in low-memory state, we only allow for
2623 * saving messages smaller than
2624 * MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h) this
2625 * should still allow for sending anything critical...
2627 if (expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) {
2629 if (modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE)) {
2630 modest_msg_edit_window_free_msg_data (edit_window, data);
2636 * djcb: we also make sure that the attachments are smaller than the max size
2637 * this is for the case where we'd try to forward a message with attachments
2638 * bigger than our max allowed size, or sending an message from drafts which
2639 * somehow got past our checks when attaching.
2641 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2642 modest_platform_run_information_dialog (
2643 GTK_WINDOW(edit_window),
2644 dgettext("ke-recv","memr_ib_operation_disabled"),
2646 modest_msg_edit_window_free_msg_data (edit_window, data);
2650 account_name = g_strdup (data->account_name);
2651 account_mgr = modest_runtime_get_account_mgr();
2653 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2655 account_name = modest_account_mgr_get_default_account (account_mgr);
2656 if (!account_name) {
2657 g_printerr ("modest: no account found\n");
2658 modest_msg_edit_window_free_msg_data (edit_window, data);
2662 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2663 account_name = g_strdup (data->account_name);
2667 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2668 (modest_runtime_get_account_store(),
2670 TNY_ACCOUNT_TYPE_TRANSPORT));
2671 if (!transport_account) {
2672 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2673 g_free (account_name);
2674 modest_msg_edit_window_free_msg_data (edit_window, data);
2677 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2679 /* Create the mail operation */
2680 mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler,
2682 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2684 modest_mail_operation_save_to_drafts (mail_operation,
2696 data->priority_flags,
2697 on_save_to_drafts_cb,
2698 g_object_ref(edit_window));
2700 /* Use the main window as the parent of the banner, if the
2701 main window does not exist it won't be shown, if the parent
2702 window exists then it's properly shown. We don't use the
2703 editor window because it could be closed (save to drafts
2704 could happen after closing the window */
2705 win = (ModestMainWindow *)
2706 modest_window_mgr_get_main_window( modest_runtime_get_window_mgr(), FALSE);
2708 gchar *text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2709 modest_platform_information_banner (GTK_WIDGET (win), NULL, text);
2712 modest_msg_edit_window_set_modified (edit_window, FALSE);
2716 g_free (account_name);
2717 g_object_unref (G_OBJECT (transport_account));
2718 g_object_unref (G_OBJECT (mail_operation));
2720 modest_msg_edit_window_free_msg_data (edit_window, data);
2723 * If the drafts folder is selected then make the header view
2724 * insensitive while the message is being saved to drafts
2725 * (it'll be sensitive again in on_save_to_drafts_cb()). This
2726 * is not very clean but it avoids letting the drafts folder
2727 * in an inconsistent state: the user could edit the message
2728 * being saved and undesirable things would happen.
2729 * In the average case the user won't notice anything at
2730 * all. In the worst case (the user is editing a really big
2731 * file from Drafts) the header view will be insensitive
2732 * during the saving process (10 or 20 seconds, depending on
2733 * the message). Anyway this is just a quick workaround: once
2734 * we find a better solution it should be removed
2735 * See NB#65125 (commend #18) for details.
2737 if (!had_error && win != NULL) {
2738 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
2739 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
2741 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
2743 if (modest_tny_folder_is_local_folder(folder)) {
2744 TnyFolderType folder_type;
2745 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
2746 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
2747 GtkWidget *hdrview = modest_main_window_get_child_widget(
2748 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2749 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
2753 if (folder != NULL) g_object_unref(folder);
2760 /* For instance, when clicking the Send toolbar button when editing a message: */
2762 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2764 TnyTransportAccount *transport_account = NULL;
2765 gboolean had_error = FALSE;
2766 guint64 available_disk, expected_size;
2770 g_return_val_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window), TRUE);
2772 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2775 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2778 available_disk = modest_folder_available_space (NULL);
2779 modest_msg_edit_window_get_parts_size (edit_window, &parts_count, &parts_size);
2780 expected_size = modest_tny_msg_estimate_size (data->plain_body,
2785 if ((available_disk != -1) && expected_size > available_disk) {
2786 modest_msg_edit_window_free_msg_data (edit_window, data);
2788 modest_platform_information_banner (NULL, NULL, dgettext("ke-recv", "cerm_device_memory_full"));
2794 * djcb: if we're in low-memory state, we only allow for sending messages
2795 * smaller than MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE (see modest-defs.h)
2796 * this should still allow for sending anything critical...
2798 if (expected_size > MODEST_MAX_LOW_MEMORY_MESSAGE_SIZE) {
2799 if (modest_platform_check_memory_low (MODEST_WINDOW(edit_window), TRUE)) {
2800 modest_msg_edit_window_free_msg_data (edit_window, data);
2806 * djcb: we also make sure that the attachments are smaller than the max size
2807 * this is for the case where we'd try to forward a message with attachments
2808 * bigger than our max allowed size, or sending an message from drafts which
2809 * somehow got past our checks when attaching.
2811 if (expected_size > MODEST_MAX_ATTACHMENT_SIZE) {
2812 modest_platform_run_information_dialog (
2813 GTK_WINDOW(edit_window),
2814 dgettext("ke-recv","memr_ib_operation_disabled"),
2816 modest_msg_edit_window_free_msg_data (edit_window, data);
2820 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2821 gchar *account_name = g_strdup (data->account_name);
2823 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2826 account_name = modest_account_mgr_get_default_account (account_mgr);
2828 if (!account_name) {
2829 modest_msg_edit_window_free_msg_data (edit_window, data);
2830 /* Run account setup wizard */
2831 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
2836 /* Get the currently-active transport account for this modest account: */
2837 if (strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
2838 transport_account = TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2839 (modest_runtime_get_account_store(),
2840 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
2843 if (!transport_account) {
2844 modest_msg_edit_window_free_msg_data (edit_window, data);
2845 /* Run account setup wizard */
2846 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2850 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2852 /* Create the mail operation */
2853 ModestMailOperation *mail_operation = modest_mail_operation_new_with_error_handling (NULL, modest_ui_actions_disk_operations_error_handler, NULL, NULL);
2854 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2856 modest_mail_operation_send_new_mail (mail_operation,
2868 data->priority_flags);
2870 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
2871 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2874 if (modest_mail_operation_get_error (mail_operation) != NULL) {
2875 const GError *error = modest_mail_operation_get_error (mail_operation);
2876 if (error->code == MODEST_MAIL_OPERATION_ERROR_INSTANCE_CREATION_FAILED) {
2877 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_operation))->message);
2878 modest_platform_information_banner (NULL, NULL, _CS("sfil_ni_not_enough_memory"));
2885 g_free (account_name);
2886 g_object_unref (G_OBJECT (transport_account));
2887 g_object_unref (G_OBJECT (mail_operation));
2889 modest_msg_edit_window_free_msg_data (edit_window, data);
2892 modest_msg_edit_window_set_sent (edit_window, TRUE);
2894 /* Save settings and close the window: */
2895 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2902 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2903 ModestMsgEditWindow *window)
2905 ModestMsgEditFormatState *format_state = NULL;
2907 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2908 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2910 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2913 format_state = modest_msg_edit_window_get_format_state (window);
2914 g_return_if_fail (format_state != NULL);
2916 format_state->bold = gtk_toggle_action_get_active (action);
2917 modest_msg_edit_window_set_format_state (window, format_state);
2918 g_free (format_state);
2923 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2924 ModestMsgEditWindow *window)
2926 ModestMsgEditFormatState *format_state = NULL;
2928 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2929 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2931 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2934 format_state = modest_msg_edit_window_get_format_state (window);
2935 g_return_if_fail (format_state != NULL);
2937 format_state->italics = gtk_toggle_action_get_active (action);
2938 modest_msg_edit_window_set_format_state (window, format_state);
2939 g_free (format_state);
2944 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2945 ModestMsgEditWindow *window)
2947 ModestMsgEditFormatState *format_state = NULL;
2949 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2950 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2952 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2955 format_state = modest_msg_edit_window_get_format_state (window);
2956 g_return_if_fail (format_state != NULL);
2958 format_state->bullet = gtk_toggle_action_get_active (action);
2959 modest_msg_edit_window_set_format_state (window, format_state);
2960 g_free (format_state);
2965 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2966 GtkRadioAction *selected,
2967 ModestMsgEditWindow *window)
2969 ModestMsgEditFormatState *format_state = NULL;
2970 GtkJustification value;
2972 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2974 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2977 value = gtk_radio_action_get_current_value (selected);
2979 format_state = modest_msg_edit_window_get_format_state (window);
2980 g_return_if_fail (format_state != NULL);
2982 format_state->justification = value;
2983 modest_msg_edit_window_set_format_state (window, format_state);
2984 g_free (format_state);
2988 modest_ui_actions_on_select_editor_color (GtkAction *action,
2989 ModestMsgEditWindow *window)
2991 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2992 g_return_if_fail (GTK_IS_ACTION (action));
2994 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2997 modest_msg_edit_window_select_color (window);
3001 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
3002 ModestMsgEditWindow *window)
3004 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3005 g_return_if_fail (GTK_IS_ACTION (action));
3007 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3010 modest_msg_edit_window_select_background_color (window);
3014 modest_ui_actions_on_insert_image (GtkAction *action,
3015 ModestMsgEditWindow *window)
3017 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3018 g_return_if_fail (GTK_IS_ACTION (action));
3021 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3024 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
3027 modest_msg_edit_window_insert_image (window);
3031 modest_ui_actions_on_attach_file (GtkAction *action,
3032 ModestMsgEditWindow *window)
3034 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3035 g_return_if_fail (GTK_IS_ACTION (action));
3037 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
3040 modest_msg_edit_window_offer_attach_file (window);
3044 modest_ui_actions_on_remove_attachments (GtkAction *action,
3045 ModestMsgEditWindow *window)
3047 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3048 g_return_if_fail (GTK_IS_ACTION (action));
3050 modest_msg_edit_window_remove_attachments (window, NULL);
3054 do_create_folder_cb (ModestMailOperation *mail_op,
3055 TnyFolderStore *parent_folder,
3056 TnyFolder *new_folder,
3059 gchar *suggested_name = (gchar *) user_data;
3060 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
3062 if (modest_mail_operation_get_error (mail_op)) {
3064 /* Show an error. If there was some problem writing to
3065 disk, show it, otherwise show the generic folder
3066 create error. We do it here and not in an error
3067 handler because the call to do_create_folder will
3068 stop the main loop in a gtk_dialog_run and then,
3069 the message won't be shown until that dialog is
3071 modest_ui_actions_disk_operations_error_handler (mail_op,
3072 _("mail_in_ui_folder_create_error"));
3074 /* Try again. Do *NOT* show any error because the mail
3075 operations system will do it for us because we
3076 created the mail_op with new_with_error_handler */
3077 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
3079 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
3080 * FIXME: any other? */
3081 GtkWidget *folder_view;
3083 if (MODEST_IS_MAIN_WINDOW(source_win))
3085 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
3086 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3089 get_folder_view_from_move_to_dialog (GTK_WIDGET(source_win));
3091 /* Select the newly created folder. It could happen
3092 that the widget is no longer there (i.e. the window
3093 has been destroyed, so we need to check this */
3095 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
3097 g_object_unref (new_folder);
3099 /* Free. Note that the first time it'll be NULL so noop */
3100 g_free (suggested_name);
3101 g_object_unref (source_win);
3105 do_create_folder (GtkWindow *parent_window,
3106 TnyFolderStore *parent_folder,
3107 const gchar *suggested_name)
3110 gchar *folder_name = NULL;
3112 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
3114 (gchar *) suggested_name,
3117 if (result == GTK_RESPONSE_ACCEPT) {
3118 ModestMailOperation *mail_op;
3120 mail_op = modest_mail_operation_new ((GObject *) parent_window);
3121 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3123 modest_mail_operation_create_folder (mail_op,
3125 (const gchar *) folder_name,
3126 do_create_folder_cb,
3128 g_object_unref (mail_op);
3133 create_folder_performer (gboolean canceled,
3135 GtkWindow *parent_window,
3136 TnyAccount *account,
3139 TnyFolderStore *parent_folder = TNY_FOLDER_STORE (user_data);
3141 if (canceled || err) {
3142 /* In memory full conditions we could get this error here */
3143 check_memory_full_error ((GtkWidget *) parent_window, err);
3147 /* Run the new folder dialog */
3148 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
3151 g_object_unref (parent_folder);
3155 modest_ui_actions_create_folder(GtkWidget *parent_window,
3156 GtkWidget *folder_view)
3158 TnyFolderStore *parent_folder;
3160 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3162 if (parent_folder) {
3163 /* The parent folder will be freed in the callback */
3164 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
3167 create_folder_performer,
3173 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
3175 GtkWidget *folder_view;
3177 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3179 folder_view = modest_main_window_get_child_widget (main_window,
3180 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3184 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
3188 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
3191 const GError *error = NULL;
3192 const gchar *message = NULL;
3194 /* Get error message */
3195 error = modest_mail_operation_get_error (mail_op);
3197 g_return_if_reached ();
3199 switch (error->code) {
3200 case MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS:
3201 message = _CS("ckdg_ib_folder_already_exists");
3203 case TNY_SERVICE_ERROR_STATE:
3204 /* This means that the folder is already in use (a
3205 message is opened for example */
3206 message = _("emev_ni_internal_error");
3209 message = _("emev_ib_ui_imap_unable_to_rename");
3212 /* We don't set a parent for the dialog because the dialog
3213 will be destroyed so the banner won't appear */
3214 modest_platform_information_banner (NULL, NULL, message);
3218 TnyFolderStore *folder;
3223 on_rename_folder_cb (ModestMailOperation *mail_op,
3224 TnyFolder *new_folder,
3227 ModestFolderView *folder_view;
3229 /* If the window was closed when renaming a folder this could
3231 if (!MODEST_IS_FOLDER_VIEW (user_data))
3234 folder_view = MODEST_FOLDER_VIEW (user_data);
3235 /* Note that if the rename fails new_folder will be NULL */
3237 modest_folder_view_select_folder (folder_view, new_folder, FALSE);
3239 modest_folder_view_select_first_inbox_or_local (folder_view);
3241 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
3245 on_rename_folder_performer (gboolean canceled,
3247 GtkWindow *parent_window,
3248 TnyAccount *account,
3251 ModestMailOperation *mail_op = NULL;
3252 GtkTreeSelection *sel = NULL;
3253 GtkWidget *folder_view = NULL;
3254 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
3256 if (canceled || err) {
3257 /* In memory full conditions we could get this error here */
3258 check_memory_full_error ((GtkWidget *) parent_window, err);
3259 } else if (MODEST_IS_MAIN_WINDOW(parent_window)) {
3261 folder_view = modest_main_window_get_child_widget (
3262 MODEST_MAIN_WINDOW (parent_window),
3263 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3266 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3267 modest_ui_actions_rename_folder_error_handler,
3268 parent_window, NULL);
3270 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3273 /* Clear the headers view */
3274 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3275 gtk_tree_selection_unselect_all (sel);
3277 /* Actually rename the folder */
3278 modest_mail_operation_rename_folder (mail_op,
3279 TNY_FOLDER (data->folder),
3280 (const gchar *) (data->new_name),
3281 on_rename_folder_cb,
3283 g_object_unref (mail_op);
3286 g_free (data->new_name);
3291 modest_ui_actions_on_rename_folder (GtkAction *action,
3292 ModestMainWindow *main_window)
3294 TnyFolderStore *folder;
3295 GtkWidget *folder_view;
3296 GtkWidget *header_view;
3298 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3300 folder_view = modest_main_window_get_child_widget (main_window,
3301 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3305 header_view = modest_main_window_get_child_widget (main_window,
3306 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3311 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
3316 if (TNY_IS_FOLDER (folder)) {
3319 const gchar *current_name;
3320 TnyFolderStore *parent;
3321 gboolean do_rename = TRUE;
3323 current_name = tny_folder_get_name (TNY_FOLDER (folder));
3324 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
3325 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
3326 parent, current_name,
3328 g_object_unref (parent);
3330 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
3333 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
3334 rename_folder_data->folder = folder;
3335 rename_folder_data->new_name = folder_name;
3336 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(main_window), TRUE,
3337 folder, on_rename_folder_performer, rename_folder_data);
3340 g_object_unref (folder);
3344 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
3347 GObject *win = modest_mail_operation_get_source (mail_op);
3349 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
3350 _("mail_in_ui_folder_delete_error"),
3352 g_object_unref (win);
3356 TnyFolderStore *folder;
3357 gboolean move_to_trash;
3361 on_delete_folder_cb (gboolean canceled,
3363 GtkWindow *parent_window,
3364 TnyAccount *account,
3367 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
3368 GtkWidget *folder_view;
3369 ModestMailOperation *mail_op;
3370 GtkTreeSelection *sel;
3372 if (!MODEST_IS_MAIN_WINDOW(parent_window) || canceled || (err!=NULL)) {
3373 g_object_unref (G_OBJECT (info->folder));
3378 folder_view = modest_main_window_get_child_widget (
3379 MODEST_MAIN_WINDOW (parent_window),
3380 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3382 /* Unselect the folder before deleting it to free the headers */
3383 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
3384 gtk_tree_selection_unselect_all (sel);
3386 /* Create the mail operation */
3388 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
3389 modest_ui_actions_delete_folder_error_handler,
3392 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
3394 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
3396 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
3398 g_object_unref (G_OBJECT (mail_op));
3399 g_object_unref (G_OBJECT (info->folder));
3404 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
3406 TnyFolderStore *folder;
3407 GtkWidget *folder_view;
3411 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3413 folder_view = modest_main_window_get_child_widget (main_window,
3414 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3418 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3420 /* Show an error if it's an account */
3421 if (!TNY_IS_FOLDER (folder)) {
3422 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
3423 _("mail_in_ui_folder_delete_error"),
3425 g_object_unref (G_OBJECT (folder));
3430 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
3431 tny_folder_get_name (TNY_FOLDER (folder)));
3432 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
3433 (const gchar *) message);
3436 if (response == GTK_RESPONSE_OK) {
3437 DeleteFolderInfo *info;
3438 info = g_new0(DeleteFolderInfo, 1);
3439 info->folder = folder;
3440 info->move_to_trash = move_to_trash;
3441 g_object_ref (G_OBJECT (info->folder));
3442 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder));
3443 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (main_window),
3445 TNY_FOLDER_STORE (account),
3446 on_delete_folder_cb, info);
3447 g_object_unref (account);
3449 g_object_unref (G_OBJECT (folder));
3453 modest_ui_actions_on_delete_folder (GtkAction *action,
3454 ModestMainWindow *main_window)
3456 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3458 delete_folder (main_window, FALSE);
3462 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3464 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3466 delete_folder (main_window, TRUE);
3470 typedef struct _PasswordDialogFields {
3471 GtkWidget *username;
3472 GtkWidget *password;
3474 } PasswordDialogFields;
3477 password_dialog_check_field (GtkEditable *editable,
3478 PasswordDialogFields *fields)
3481 gboolean any_value_empty = FALSE;
3483 value = gtk_entry_get_text (GTK_ENTRY (fields->username));
3484 if ((value == NULL) || value[0] == '\0') {
3485 any_value_empty = TRUE;
3487 value = gtk_entry_get_text (GTK_ENTRY (fields->password));
3488 if ((value == NULL) || value[0] == '\0') {
3489 any_value_empty = TRUE;
3491 gtk_dialog_set_response_sensitive (GTK_DIALOG (fields->dialog), GTK_RESPONSE_ACCEPT, !any_value_empty);
3495 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3496 const gchar* server_account_name,
3501 ModestMainWindow *main_window)
3503 g_return_if_fail(server_account_name);
3504 gboolean completed = FALSE;
3505 PasswordDialogFields *fields = NULL;
3507 /* Initalize output parameters: */
3514 #ifdef MODEST_PLATFORM_MAEMO
3515 /* Maemo uses a different (awkward) button order,
3516 * It should probably just use gtk_alternative_dialog_button_order ().
3518 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3521 _("mcen_bd_dialog_ok"),
3522 GTK_RESPONSE_ACCEPT,
3523 _("mcen_bd_dialog_cancel"),
3524 GTK_RESPONSE_REJECT,
3527 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3531 GTK_RESPONSE_REJECT,
3533 GTK_RESPONSE_ACCEPT,
3535 #endif /* MODEST_PLATFORM_MAEMO */
3537 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog));
3539 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3540 modest_runtime_get_account_mgr(), server_account_name);
3541 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3542 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3548 /* This causes a warning because the logical ID has no %s in it,
3549 * though the translation does, but there is not much we can do about that: */
3550 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3551 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
3554 g_free (server_name);
3558 gchar *initial_username = modest_account_mgr_get_server_account_username (
3559 modest_runtime_get_account_mgr(), server_account_name);
3561 GtkWidget *entry_username = gtk_entry_new ();
3562 if (initial_username)
3563 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
3564 /* Dim this if a connection has ever succeeded with this username,
3565 * as per the UI spec: */
3566 /* const gboolean username_known = */
3567 /* modest_account_mgr_get_server_account_username_has_succeeded( */
3568 /* modest_runtime_get_account_mgr(), server_account_name); */
3569 /* gtk_widget_set_sensitive (entry_username, !username_known); */
3571 /* We drop the username sensitive code and disallow changing it here
3572 * as tinymail does not support really changing the username in the callback
3574 gtk_widget_set_sensitive (entry_username, FALSE);
3576 #ifdef MODEST_PLATFORM_MAEMO
3577 /* Auto-capitalization is the default, so let's turn it off: */
3578 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3580 /* Create a size group to be used by all captions.
3581 * Note that HildonCaption does not create a default size group if we do not specify one.
3582 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3583 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3585 GtkWidget *caption = hildon_caption_new (sizegroup,
3586 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
3587 gtk_widget_show (entry_username);
3588 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3589 FALSE, FALSE, MODEST_MARGIN_HALF);
3590 gtk_widget_show (caption);
3592 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
3594 #endif /* MODEST_PLATFORM_MAEMO */
3597 GtkWidget *entry_password = gtk_entry_new ();
3598 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3599 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3601 #ifdef MODEST_PLATFORM_MAEMO
3602 /* Auto-capitalization is the default, so let's turn it off: */
3603 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3604 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3606 caption = hildon_caption_new (sizegroup,
3607 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
3608 gtk_widget_show (entry_password);
3609 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3610 FALSE, FALSE, MODEST_MARGIN_HALF);
3611 gtk_widget_show (caption);
3612 g_object_unref (sizegroup);
3614 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
3616 #endif /* MODEST_PLATFORM_MAEMO */
3618 if (initial_username != NULL)
3619 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3621 /* This is not in the Maemo UI spec:
3622 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3623 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3627 fields = g_slice_new0 (PasswordDialogFields);
3628 fields->username = entry_username;
3629 fields->password = entry_password;
3630 fields->dialog = dialog;
3632 g_signal_connect (entry_username, "changed", G_CALLBACK (password_dialog_check_field), fields);
3633 g_signal_connect (entry_password, "changed", G_CALLBACK (password_dialog_check_field), fields);
3634 password_dialog_check_field (NULL, fields);
3636 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3638 while (!completed) {
3640 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3642 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
3644 /* Note that an empty field becomes the "" string */
3645 if (*username && strlen (*username) > 0) {
3646 modest_account_mgr_set_server_account_username (modest_runtime_get_account_mgr(),
3647 server_account_name,
3651 const gboolean username_was_changed =
3652 (strcmp (*username, initial_username) != 0);
3653 if (username_was_changed) {
3654 g_warning ("%s: tinymail does not yet support changing the "
3655 "username in the get_password() callback.\n", __FUNCTION__);
3659 modest_platform_information_banner (GTK_WIDGET (dialog), NULL,
3660 _("mcen_ib_username_pw_incorrect"));
3666 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
3668 /* We do not save the password in the configuration,
3669 * because this function is only called for passwords that should
3670 * not be remembered:
3671 modest_server_account_set_password (
3672 modest_runtime_get_account_mgr(), server_account_name,
3679 /* Set parent to NULL or the banner will disappear with its parent dialog */
3680 modest_platform_information_banner(NULL, NULL, _("mail_ib_login_cancelled"));
3691 /* This is not in the Maemo UI spec:
3692 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3698 gtk_widget_destroy (dialog);
3699 g_slice_free (PasswordDialogFields, fields);
3701 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3705 modest_ui_actions_on_cut (GtkAction *action,
3706 ModestWindow *window)
3708 GtkWidget *focused_widget;
3709 GtkClipboard *clipboard;
3711 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3712 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3713 if (GTK_IS_EDITABLE (focused_widget)) {
3714 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3715 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3716 gtk_clipboard_store (clipboard);
3717 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3718 GtkTextBuffer *buffer;
3720 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3721 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3722 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3723 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3724 gtk_clipboard_store (clipboard);
3726 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3727 TnyList *header_list = modest_header_view_get_selected_headers (
3728 MODEST_HEADER_VIEW (focused_widget));
3729 gboolean continue_download = FALSE;
3730 gint num_of_unc_msgs;
3732 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3734 if (num_of_unc_msgs) {
3735 TnyAccount *account = get_account_from_header_list (header_list);
3737 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3738 g_object_unref (account);
3742 if (num_of_unc_msgs == 0 || continue_download) {
3743 /* modest_platform_information_banner (
3744 NULL, NULL, _CS("mcen_ib_getting_items"));*/
3745 modest_header_view_cut_selection (
3746 MODEST_HEADER_VIEW (focused_widget));
3749 g_object_unref (header_list);
3750 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3751 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3756 modest_ui_actions_on_copy (GtkAction *action,
3757 ModestWindow *window)
3759 GtkClipboard *clipboard;
3760 GtkWidget *focused_widget;
3761 gboolean copied = TRUE;
3763 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3764 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3766 if (GTK_IS_LABEL (focused_widget)) {
3768 selection = modest_text_utils_label_get_selection (GTK_LABEL (focused_widget));
3769 gtk_clipboard_set_text (clipboard, selection, -1);
3771 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3772 gtk_clipboard_store (clipboard);
3773 } else if (GTK_IS_EDITABLE (focused_widget)) {
3774 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3775 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3776 gtk_clipboard_store (clipboard);
3777 } else if (GTK_IS_HTML (focused_widget)) {
3778 gtk_html_copy (GTK_HTML (focused_widget));
3779 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3780 gtk_clipboard_store (clipboard);
3781 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3782 GtkTextBuffer *buffer;
3783 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3784 if (modest_text_utils_buffer_selection_is_valid (buffer)) {
3785 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3786 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3787 gtk_clipboard_store (clipboard);
3789 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3790 TnyList *header_list = modest_header_view_get_selected_headers (
3791 MODEST_HEADER_VIEW (focused_widget));
3792 gboolean continue_download = FALSE;
3793 gint num_of_unc_msgs;
3795 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3797 if (num_of_unc_msgs) {
3798 TnyAccount *account = get_account_from_header_list (header_list);
3800 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3801 g_object_unref (account);
3805 if (num_of_unc_msgs == 0 || continue_download) {
3806 modest_platform_information_banner (
3807 NULL, NULL, _CS("mcen_ib_getting_items"));
3808 modest_header_view_copy_selection (
3809 MODEST_HEADER_VIEW (focused_widget));
3813 g_object_unref (header_list);
3815 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3816 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3819 /* Show information banner if there was a copy to clipboard */
3821 modest_platform_information_banner (
3822 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3826 modest_ui_actions_on_undo (GtkAction *action,
3827 ModestWindow *window)
3829 ModestEmailClipboard *clipboard = NULL;
3831 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3832 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3833 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3834 /* Clear clipboard source */
3835 clipboard = modest_runtime_get_email_clipboard ();
3836 modest_email_clipboard_clear (clipboard);
3839 g_return_if_reached ();
3844 modest_ui_actions_on_redo (GtkAction *action,
3845 ModestWindow *window)
3847 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3848 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3851 g_return_if_reached ();
3857 destroy_information_note (ModestMailOperation *mail_op,
3860 /* destroy information note */
3861 gtk_widget_destroy (GTK_WIDGET(user_data));
3865 destroy_folder_information_note (ModestMailOperation *mail_op,
3866 TnyFolder *new_folder,
3869 /* destroy information note */
3870 gtk_widget_destroy (GTK_WIDGET(user_data));
3875 paste_as_attachment_free (gpointer data)
3877 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3879 if (helper->banner) {
3880 gtk_widget_destroy (helper->banner);
3881 g_object_unref (helper->banner);
3887 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3892 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3893 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3898 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3903 modest_ui_actions_on_paste (GtkAction *action,
3904 ModestWindow *window)
3906 GtkWidget *focused_widget = NULL;
3907 GtkWidget *inf_note = NULL;
3908 ModestMailOperation *mail_op = NULL;
3910 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3911 if (GTK_IS_EDITABLE (focused_widget)) {
3912 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3913 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3914 ModestEmailClipboard *e_clipboard = NULL;
3915 e_clipboard = modest_runtime_get_email_clipboard ();
3916 if (modest_email_clipboard_cleared (e_clipboard)) {
3917 GtkTextBuffer *buffer;
3918 GtkClipboard *clipboard;
3920 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3921 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3922 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3923 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3924 ModestMailOperation *mail_op;
3925 TnyFolder *src_folder;
3928 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3929 helper->window = MODEST_MSG_EDIT_WINDOW (window);
3930 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3931 _CS("ckct_nw_pasting"));
3932 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
3933 mail_op = modest_mail_operation_new (G_OBJECT (window));
3934 if (helper->banner != NULL) {
3935 g_object_ref (G_OBJECT (helper->banner));
3936 gtk_widget_show (GTK_WIDGET (helper->banner));
3940 modest_mail_operation_get_msgs_full (mail_op,
3942 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
3944 paste_as_attachment_free);
3947 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3948 ModestEmailClipboard *clipboard = NULL;
3949 TnyFolder *src_folder = NULL;
3950 TnyFolderStore *folder_store = NULL;
3951 TnyList *data = NULL;
3952 gboolean delete = FALSE;
3954 /* Check clipboard source */
3955 clipboard = modest_runtime_get_email_clipboard ();
3956 if (modest_email_clipboard_cleared (clipboard))
3959 /* Get elements to paste */
3960 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
3962 /* Create a new mail operation */
3963 mail_op = modest_mail_operation_new (G_OBJECT(window));
3965 /* Get destination folder */
3966 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
3968 /* transfer messages */
3972 /* Ask for user confirmation */
3974 modest_ui_actions_msgs_move_to_confirmation (window,
3975 TNY_FOLDER (folder_store),
3979 if (response == GTK_RESPONSE_OK) {
3980 /* Launch notification */
3981 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3982 _CS("ckct_nw_pasting"));
3983 if (inf_note != NULL) {
3984 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3985 gtk_widget_show (GTK_WIDGET(inf_note));
3988 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3989 modest_mail_operation_xfer_msgs (mail_op,
3991 TNY_FOLDER (folder_store),
3993 destroy_information_note,
3996 g_object_unref (mail_op);
3999 } else if (src_folder != NULL) {
4000 /* Launch notification */
4001 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
4002 _CS("ckct_nw_pasting"));
4003 if (inf_note != NULL) {
4004 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
4005 gtk_widget_show (GTK_WIDGET(inf_note));
4008 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4009 modest_mail_operation_xfer_folder (mail_op,
4013 destroy_folder_information_note,
4019 g_object_unref (data);
4020 if (src_folder != NULL)
4021 g_object_unref (src_folder);
4022 if (folder_store != NULL)
4023 g_object_unref (folder_store);
4029 modest_ui_actions_on_select_all (GtkAction *action,
4030 ModestWindow *window)
4032 GtkWidget *focused_widget;
4034 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
4035 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
4036 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
4037 } else if (GTK_IS_LABEL (focused_widget)) {
4038 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
4039 } else if (GTK_IS_EDITABLE (focused_widget)) {
4040 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
4041 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
4042 GtkTextBuffer *buffer;
4043 GtkTextIter start, end;
4045 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
4046 gtk_text_buffer_get_start_iter (buffer, &start);
4047 gtk_text_buffer_get_end_iter (buffer, &end);
4048 gtk_text_buffer_select_range (buffer, &start, &end);
4049 } else if (GTK_IS_HTML (focused_widget)) {
4050 gtk_html_select_all (GTK_HTML (focused_widget));
4051 } else if (MODEST_IS_MAIN_WINDOW (window)) {
4052 GtkWidget *header_view = focused_widget;
4053 GtkTreeSelection *selection = NULL;
4055 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
4056 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
4057 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4060 /* Disable window dimming management */
4061 modest_window_disable_dimming (MODEST_WINDOW(window));
4063 /* Select all messages */
4064 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
4065 gtk_tree_selection_select_all (selection);
4067 /* Set focuse on header view */
4068 gtk_widget_grab_focus (header_view);
4071 /* Enable window dimming management */
4072 modest_window_enable_dimming (MODEST_WINDOW(window));
4073 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
4079 modest_ui_actions_on_mark_as_read (GtkAction *action,
4080 ModestWindow *window)
4082 g_return_if_fail (MODEST_IS_WINDOW(window));
4084 /* Mark each header as read */
4085 do_headers_action (window, headers_action_mark_as_read, NULL);
4089 modest_ui_actions_on_mark_as_unread (GtkAction *action,
4090 ModestWindow *window)
4092 g_return_if_fail (MODEST_IS_WINDOW(window));
4094 /* Mark each header as read */
4095 do_headers_action (window, headers_action_mark_as_unread, NULL);
4099 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
4100 GtkRadioAction *selected,
4101 ModestWindow *window)
4105 value = gtk_radio_action_get_current_value (selected);
4106 if (MODEST_IS_WINDOW (window)) {
4107 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
4112 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
4113 GtkRadioAction *selected,
4114 ModestWindow *window)
4116 TnyHeaderFlags flags;
4117 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4119 flags = gtk_radio_action_get_current_value (selected);
4120 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
4124 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
4125 GtkRadioAction *selected,
4126 ModestWindow *window)
4130 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4132 file_format = gtk_radio_action_get_current_value (selected);
4133 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
4138 modest_ui_actions_on_zoom_plus (GtkAction *action,
4139 ModestWindow *window)
4141 g_return_if_fail (MODEST_IS_WINDOW (window));
4143 modest_window_zoom_plus (MODEST_WINDOW (window));
4147 modest_ui_actions_on_zoom_minus (GtkAction *action,
4148 ModestWindow *window)
4150 g_return_if_fail (MODEST_IS_WINDOW (window));
4152 modest_window_zoom_minus (MODEST_WINDOW (window));
4156 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
4157 ModestWindow *window)
4159 ModestWindowMgr *mgr;
4160 gboolean fullscreen, active;
4161 g_return_if_fail (MODEST_IS_WINDOW (window));
4163 mgr = modest_runtime_get_window_mgr ();
4165 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
4166 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4168 if (active != fullscreen) {
4169 modest_window_mgr_set_fullscreen_mode (mgr, active);
4170 gtk_window_present (GTK_WINDOW (window));
4175 modest_ui_actions_on_change_fullscreen (GtkAction *action,
4176 ModestWindow *window)
4178 ModestWindowMgr *mgr;
4179 gboolean fullscreen;
4181 g_return_if_fail (MODEST_IS_WINDOW (window));
4183 mgr = modest_runtime_get_window_mgr ();
4184 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
4185 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
4187 gtk_window_present (GTK_WINDOW (window));
4191 * Used by modest_ui_actions_on_details to call do_headers_action
4194 headers_action_show_details (TnyHeader *header,
4195 ModestWindow *window,
4202 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
4205 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4206 gtk_widget_show_all (dialog);
4207 gtk_dialog_run (GTK_DIALOG (dialog));
4209 gtk_widget_destroy (dialog);
4213 * Show the folder details in a ModestDetailsDialog widget
4216 show_folder_details (TnyFolder *folder,
4222 dialog = modest_details_dialog_new_with_folder (window, folder);
4225 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4226 gtk_widget_show_all (dialog);
4227 gtk_dialog_run (GTK_DIALOG (dialog));
4229 gtk_widget_destroy (dialog);
4233 * Show the header details in a ModestDetailsDialog widget
4236 modest_ui_actions_on_details (GtkAction *action,
4239 TnyList * headers_list;
4243 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
4246 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
4249 g_object_unref (msg);
4251 headers_list = get_selected_headers (win);
4255 iter = tny_list_create_iterator (headers_list);
4257 header = TNY_HEADER (tny_iterator_get_current (iter));
4259 headers_action_show_details (header, win, NULL);
4260 g_object_unref (header);
4263 g_object_unref (iter);
4264 g_object_unref (headers_list);
4266 } else if (MODEST_IS_MAIN_WINDOW (win)) {
4267 GtkWidget *folder_view, *header_view;
4269 /* Check which widget has the focus */
4270 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4271 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4272 if (gtk_widget_is_focus (folder_view)) {
4273 TnyFolderStore *folder_store
4274 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4275 if (!folder_store) {
4276 g_warning ("%s: No item was selected.\n", __FUNCTION__);
4279 /* Show only when it's a folder */
4280 /* This function should not be called for account items,
4281 * because we dim the menu item for them. */
4282 if (TNY_IS_FOLDER (folder_store)) {
4283 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
4286 g_object_unref (folder_store);
4289 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4290 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4291 /* Show details of each header */
4292 do_headers_action (win, headers_action_show_details, header_view);
4298 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
4299 ModestMsgEditWindow *window)
4301 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4303 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
4307 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
4308 ModestMsgEditWindow *window)
4310 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4312 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
4316 modest_ui_actions_toggle_folders_view (GtkAction *action,
4317 ModestMainWindow *main_window)
4319 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
4321 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
4322 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
4324 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
4328 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
4329 ModestWindow *window)
4331 gboolean active, fullscreen = FALSE;
4332 ModestWindowMgr *mgr;
4334 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
4336 /* Check if we want to toggle the toolbar vuew in fullscreen
4338 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
4339 "ViewShowToolbarFullScreen")) {
4343 /* Toggle toolbar */
4344 mgr = modest_runtime_get_window_mgr ();
4345 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
4349 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
4350 ModestMsgEditWindow *window)
4352 modest_msg_edit_window_select_font (window);
4357 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
4358 const gchar *display_name,
4361 /* don't update the display name if it was already set;
4362 * updating the display name apparently is expensive */
4363 const gchar* old_name = gtk_window_get_title (window);
4365 if (display_name == NULL)
4368 if (old_name && display_name && strcmp (old_name, display_name) == 0)
4369 return; /* don't do anything */
4371 /* This is usually used to change the title of the main window, which
4372 * is the one that holds the folder view. Note that this change can
4373 * happen even when the widget doesn't have the focus. */
4374 gtk_window_set_title (window, display_name);
4379 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
4381 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4382 modest_msg_edit_window_select_contacts (window);
4386 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
4388 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
4389 modest_msg_edit_window_check_names (window, FALSE);
4393 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
4395 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
4396 GTK_WIDGET (user_data));
4400 * This function is used to track changes in the selection of the
4401 * folder view that is inside the "move to" dialog to enable/disable
4402 * the OK button because we do not want the user to select a disallowed
4403 * destination for a folder.
4404 * The user also not desired to be able to use NEW button on items where
4405 * folder creation is not possibel.
4408 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
4409 TnyFolderStore *folder_store,
4413 GtkWidget *dialog = NULL;
4414 GtkWidget *ok_button = NULL, *new_button = NULL;
4415 GList *children = NULL;
4416 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
4417 gboolean moving_folder = FALSE;
4418 gboolean is_local_account = TRUE;
4419 GtkWidget *folder_view = NULL;
4420 ModestTnyFolderRules rules;
4422 g_return_if_fail (MODEST_IS_FOLDER_VIEW(self));
4427 /* Get the OK button */
4428 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
4432 children = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
4433 #ifdef MODEST_PLATFORM_MAEMO
4434 ok_button = GTK_WIDGET (children->next->next->data);
4435 new_button = GTK_WIDGET (children->next->data);
4437 ok_button = GTK_WIDGET (children->data);
4438 new_button = GTK_WIDGET (children->next->next->data);
4440 g_list_free (children);
4442 /* check if folder_store is an remote account */
4443 if (TNY_IS_ACCOUNT (folder_store)) {
4444 TnyAccount *local_account = NULL;
4445 TnyAccount *mmc_account = NULL;
4446 ModestTnyAccountStore *account_store = NULL;
4448 account_store = modest_runtime_get_account_store ();
4449 local_account = modest_tny_account_store_get_local_folders_account (account_store);
4450 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
4452 if ((gpointer) local_account != (gpointer) folder_store &&
4453 (gpointer) mmc_account != (gpointer) folder_store) {
4454 const char *proto_name = tny_account_get_proto (TNY_ACCOUNT (folder_store));
4455 ModestTransportStoreProtocol proto = MODEST_PROTOCOL_STORE_MAILDIR;
4456 if (proto_name != NULL) {
4457 proto = modest_protocol_info_get_transport_store_protocol (proto_name);
4459 is_local_account = FALSE;
4460 /* New button should be dimmed on remote
4462 new_sensitive = (proto != MODEST_PROTOCOL_STORE_POP);
4464 g_object_unref (local_account);
4465 g_object_unref (mmc_account);
4468 /* Check the target folder rules */
4469 if (TNY_IS_FOLDER (folder_store)) {
4470 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
4471 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
4472 ok_sensitive = FALSE;
4473 new_sensitive = FALSE;
4478 /* Check if we're moving a folder */
4479 if (MODEST_IS_MAIN_WINDOW (user_data)) {
4480 /* Get the widgets */
4481 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
4482 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4483 if (gtk_widget_is_focus (folder_view))
4484 moving_folder = TRUE;
4487 if (moving_folder) {
4488 TnyFolderStore *moved_folder = NULL, *parent = NULL;
4490 /* Get the folder to move */
4491 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4493 /* Check that we're not moving to the same folder */
4494 if (TNY_IS_FOLDER (moved_folder)) {
4495 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
4496 if (parent == folder_store)
4497 ok_sensitive = FALSE;
4498 g_object_unref (parent);
4501 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
4502 /* Do not allow to move to an account unless it's the
4503 local folders account */
4504 if (!is_local_account)
4505 ok_sensitive = FALSE;
4508 if (ok_sensitive && (moved_folder == folder_store)) {
4509 /* Do not allow to move to itself */
4510 ok_sensitive = FALSE;
4512 g_object_unref (moved_folder);
4514 TnyFolder *src_folder = NULL;
4516 /* Moving a message */
4517 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
4519 TnyHeader *header = NULL;
4520 header = modest_msg_view_window_get_header
4521 (MODEST_MSG_VIEW_WINDOW (user_data));
4522 if (!TNY_IS_HEADER(header))
4523 g_warning ("%s: could not get source header", __FUNCTION__);
4525 src_folder = tny_header_get_folder (header);
4528 g_object_unref (header);
4531 TNY_FOLDER (modest_folder_view_get_selected
4532 (MODEST_FOLDER_VIEW (folder_view)));
4535 if (TNY_IS_FOLDER(src_folder)) {
4536 /* Do not allow to move the msg to the same folder */
4537 /* Do not allow to move the msg to an account */
4538 if ((gpointer) src_folder == (gpointer) folder_store ||
4539 TNY_IS_ACCOUNT (folder_store))
4540 ok_sensitive = FALSE;
4541 g_object_unref (src_folder);
4543 g_warning ("%s: could not get source folder", __FUNCTION__);
4547 /* Set sensitivity of the OK button */
4548 gtk_widget_set_sensitive (ok_button, ok_sensitive);
4549 /* Set sensitivity of the NEW button */
4550 gtk_widget_set_sensitive (new_button, new_sensitive);
4554 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
4557 get_folder_view_from_move_to_dialog (GtkWidget *move_to_dialog)
4559 return GTK_WIDGET(g_object_get_data (G_OBJECT(move_to_dialog),
4560 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4564 create_move_to_dialog (GtkWindow *win,
4565 GtkWidget *folder_view,
4566 GtkWidget **tree_view)
4568 GtkWidget *dialog, *scroll;
4569 GtkWidget *new_button;
4571 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
4573 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
4576 #ifdef MODEST_PLATFORM_MAEMO
4577 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
4578 /* We do this manually so GTK+ does not associate a response ID for
4580 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
4581 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
4582 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
4584 /* We do this manually so GTK+ does not associate a response ID for
4586 new_button = gtk_button_new_with_label (_("mcen_ti_new_folder"));
4587 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
4588 gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (GTK_DIALOG (dialog)->action_area), new_button, TRUE);
4589 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
4590 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT);
4591 gtk_container_set_border_width (GTK_CONTAINER (dialog), 12);
4592 gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 24);
4595 /* Create scrolled window */
4596 scroll = gtk_scrolled_window_new (NULL, NULL);
4597 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
4598 GTK_POLICY_AUTOMATIC,
4599 GTK_POLICY_AUTOMATIC);
4601 #ifndef MODEST_PLATFORM_MAEMO
4602 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN);
4605 /* Create folder view */
4606 *tree_view = modest_platform_create_folder_view (NULL);
4608 /* Track changes in the selection to
4609 * disable the OK button whenever "Move to" is not possible
4610 * disbale NEW button whenever New is not possible */
4611 g_signal_connect (*tree_view,
4612 "folder_selection_changed",
4613 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
4616 /* Listen to clicks on New button */
4617 g_signal_connect (G_OBJECT (new_button),
4619 G_CALLBACK(create_move_to_dialog_on_new_folder),
4622 /* It could happen that we're trying to move a message from a
4623 window (msg window for example) after the main window was
4624 closed, so we can not just get the model of the folder
4626 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4627 const gchar *visible_id = NULL;
4629 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4630 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4631 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4632 MODEST_FOLDER_VIEW(*tree_view));
4635 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4637 /* Show the same account than the one that is shown in the main window */
4638 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
4641 const gchar *active_account_name = NULL;
4642 ModestAccountMgr *mgr = NULL;
4643 ModestAccountSettings *settings = NULL;
4644 ModestServerAccountSettings *store_settings = NULL;
4646 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4647 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4648 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
4649 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
4651 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4652 mgr = modest_runtime_get_account_mgr ();
4653 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4656 const gchar *store_account_name;
4657 store_settings = modest_account_settings_get_store_settings (settings);
4658 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4660 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
4661 store_account_name);
4662 g_object_unref (store_settings);
4663 g_object_unref (settings);
4667 /* we keep a pointer to the embedded folder view, so we can retrieve it with
4668 * get_folder_view_from_move_to_dialog
4669 * (see above) later (needed for focus handling)
4671 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, *tree_view);
4674 /* Hide special folders */
4675 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
4677 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
4679 /* Add scroll to dialog */
4680 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
4681 scroll, TRUE, TRUE, 0);
4683 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4684 #ifdef MODEST_PLATFORM_MAEMO
4685 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
4687 gtk_window_set_default_size (GTK_WINDOW (dialog), 600, 400);
4696 * Shows a confirmation dialog to the user when we're moving messages
4697 * from a remote server to the local storage. Returns the dialog
4698 * response. If it's other kind of movement then it always returns
4701 * This one is used by the next functions:
4702 * modest_ui_actions_on_paste - commented out
4703 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4706 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4707 TnyFolder *dest_folder,
4711 gint response = GTK_RESPONSE_OK;
4712 TnyAccount *account = NULL;
4713 TnyFolder *src_folder = NULL;
4714 TnyIterator *iter = NULL;
4715 TnyHeader *header = NULL;
4717 /* return with OK if the destination is a remote folder */
4718 if (modest_tny_folder_is_remote_folder (dest_folder))
4719 return GTK_RESPONSE_OK;
4721 /* Get source folder */
4722 iter = tny_list_create_iterator (headers);
4723 header = TNY_HEADER (tny_iterator_get_current (iter));
4725 src_folder = tny_header_get_folder (header);
4726 g_object_unref (header);
4728 g_object_unref (iter);
4730 /* if no src_folder, message may be an attahcment */
4731 if (src_folder == NULL)
4732 return GTK_RESPONSE_CANCEL;
4734 /* If the source is a local or MMC folder */
4735 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4736 g_object_unref (src_folder);
4737 return GTK_RESPONSE_OK;
4740 /* Get the account */
4741 account = tny_folder_get_account (src_folder);
4743 /* now if offline we ask the user */
4744 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4745 response = GTK_RESPONSE_OK;
4747 response = GTK_RESPONSE_CANCEL;
4750 g_object_unref (src_folder);
4751 g_object_unref (account);
4757 move_to_helper_destroyer (gpointer user_data)
4759 MoveToHelper *helper = (MoveToHelper *) user_data;
4761 /* Close the "Pasting" information banner */
4762 if (helper->banner) {
4763 gtk_widget_destroy (GTK_WIDGET (helper->banner));
4764 g_object_unref (helper->banner);
4766 if (helper->reference != NULL)
4767 gtk_tree_row_reference_free (helper->reference);
4772 move_to_cb (ModestMailOperation *mail_op,
4775 MoveToHelper *helper = (MoveToHelper *) user_data;
4777 /* Note that the operation could have failed, in that case do
4779 if (modest_mail_operation_get_status (mail_op) ==
4780 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
4782 GObject *object = modest_mail_operation_get_source (mail_op);
4783 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4784 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4786 if (!modest_msg_view_window_select_next_message (self) &&
4787 !modest_msg_view_window_select_previous_message (self)) {
4788 /* No more messages to view, so close this window */
4789 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4791 } else if (MODEST_IS_MAIN_WINDOW (object) && helper->reference != NULL) {
4792 GtkWidget *header_view;
4794 GtkTreeSelection *sel;
4796 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4797 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4798 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
4799 path = gtk_tree_row_reference_get_path (helper->reference);
4800 /* We need to unselect the previous one
4801 because we could be copying instead of
4803 gtk_tree_selection_unselect_all (sel);
4804 gtk_tree_selection_select_path (sel, path);
4805 gtk_tree_path_free (path);
4807 g_object_unref (object);
4809 /* Destroy the helper */
4810 move_to_helper_destroyer (helper);
4814 folder_move_to_cb (ModestMailOperation *mail_op,
4815 TnyFolder *new_folder,
4818 GtkWidget *folder_view;
4821 object = modest_mail_operation_get_source (mail_op);
4822 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4823 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4824 g_object_ref (folder_view);
4825 g_object_unref (object);
4826 move_to_cb (mail_op, user_data);
4827 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), new_folder, FALSE);
4828 g_object_unref (folder_view);
4832 msgs_move_to_cb (ModestMailOperation *mail_op,
4835 move_to_cb (mail_op, user_data);
4839 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
4842 ModestWindow *main_window = NULL;
4844 /* Disable next automatic folder selection */
4845 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
4846 FALSE); /* don't create */
4848 GObject *win = NULL;
4849 GtkWidget *folder_view = NULL;
4851 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
4852 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4853 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
4855 if (user_data && TNY_IS_FOLDER (user_data)) {
4856 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
4857 TNY_FOLDER (user_data), FALSE);
4860 /* Show notification dialog only if the main window exists */
4861 win = modest_mail_operation_get_source (mail_op);
4862 modest_platform_run_information_dialog ((GtkWindow *) win,
4863 _("mail_in_ui_folder_move_target_error"),
4866 g_object_unref (win);
4871 open_msg_for_purge_cb (ModestMailOperation *mail_op,
4880 gint pending_purges = 0;
4881 gboolean some_purged = FALSE;
4882 ModestWindow *win = MODEST_WINDOW (user_data);
4883 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
4885 /* If there was any error */
4886 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
4887 modest_window_mgr_unregister_header (mgr, header);
4891 /* Once the message has been retrieved for purging, we check if
4892 * it's all ok for purging */
4894 parts = tny_simple_list_new ();
4895 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
4896 iter = tny_list_create_iterator (parts);
4898 while (!tny_iterator_is_done (iter)) {
4900 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4901 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
4902 if (tny_mime_part_is_purged (part))
4909 g_object_unref (part);
4911 tny_iterator_next (iter);
4913 g_object_unref (iter);
4916 if (pending_purges>0) {
4918 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
4920 if (response == GTK_RESPONSE_OK) {
4923 modest_platform_animation_banner (GTK_WIDGET (win), NULL, _("mcen_ib_removing_attachment"));
4924 iter = tny_list_create_iterator (parts);
4925 while (!tny_iterator_is_done (iter)) {
4928 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4929 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
4930 tny_mime_part_set_purged (part);
4933 g_object_unref (part);
4935 tny_iterator_next (iter);
4937 g_object_unref (iter);
4939 tny_msg_rewrite_cache (msg);
4941 gtk_widget_destroy (info);
4945 modest_window_mgr_unregister_header (mgr, header);
4947 g_object_unref (parts);
4951 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
4952 ModestMainWindow *win)
4954 GtkWidget *header_view;
4955 TnyList *header_list;
4957 TnyHeaderFlags flags;
4958 ModestWindow *msg_view_window = NULL;
4961 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4963 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4964 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4966 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
4968 g_warning ("%s: no header selected", __FUNCTION__);
4972 if (tny_list_get_length (header_list) == 1) {
4973 TnyIterator *iter = tny_list_create_iterator (header_list);
4974 header = TNY_HEADER (tny_iterator_get_current (iter));
4975 g_object_unref (iter);
4979 if (!header || !TNY_IS_HEADER(header)) {
4980 g_warning ("%s: header is not valid", __FUNCTION__);
4984 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
4985 header, &msg_view_window);
4986 flags = tny_header_get_flags (header);
4987 if (!(flags & TNY_HEADER_FLAG_CACHED))
4990 if (msg_view_window != NULL)
4991 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
4993 /* do nothing; uid was registered before, so window is probably on it's way */
4994 g_warning ("debug: header %p has already been registered", header);
4997 ModestMailOperation *mail_op = NULL;
4998 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
4999 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
5000 modest_ui_actions_disk_operations_error_handler,
5002 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5003 modest_mail_operation_get_msg (mail_op, header, FALSE, open_msg_for_purge_cb, win);
5005 g_object_unref (mail_op);
5008 g_object_unref (header);
5010 g_object_unref (header_list);
5014 * Checks if we need a connection to do the transfer and if the user
5015 * wants to connect to complete it
5018 modest_ui_actions_xfer_messages_check (GtkWindow *parent_window,
5019 TnyFolderStore *src_folder,
5021 TnyFolder *dst_folder,
5022 gboolean delete_originals,
5023 gboolean *need_connection,
5026 TnyAccount *src_account;
5027 gint uncached_msgs = 0;
5029 uncached_msgs = header_list_count_uncached_msgs (headers);
5031 /* We don't need any further check if
5033 * 1- the source folder is local OR
5034 * 2- the device is already online
5036 if (!modest_tny_folder_store_is_remote (src_folder) ||
5037 tny_device_is_online (modest_runtime_get_device())) {
5038 *need_connection = FALSE;
5043 /* We must ask for a connection when
5045 * - the message(s) is not already cached OR
5046 * - the message(s) is cached but the leave_on_server setting
5047 * is FALSE (because we need to sync the source folder to
5048 * delete the message from the server (for IMAP we could do it
5049 * offline, it'll take place the next time we get a
5052 src_account = get_account_from_folder_store (src_folder);
5053 if (uncached_msgs > 0) {
5057 *need_connection = TRUE;
5058 num_headers = tny_list_get_length (headers);
5059 msg = ngettext ("mcen_nc_get_msg", "mcen_nc_get_msgs", num_headers);
5061 if (modest_platform_run_confirmation_dialog (parent_window, msg) ==
5062 GTK_RESPONSE_CANCEL) {
5068 /* The transfer is possible and the user wants to */
5071 if (remote_folder_is_pop (src_folder) && delete_originals) {
5072 const gchar *account_name;
5073 gboolean leave_on_server;
5075 account_name = modest_tny_account_get_parent_modest_account_name_for_server_account (src_account);
5076 leave_on_server = modest_account_mgr_get_leave_on_server (modest_runtime_get_account_mgr (),
5079 if (leave_on_server == TRUE) {
5080 *need_connection = FALSE;
5082 *need_connection = TRUE;
5085 *need_connection = FALSE;
5090 g_object_unref (src_account);
5094 xfer_messages_error_handler (ModestMailOperation *mail_op,
5097 ModestWindow *main_window = NULL;
5099 /* Disable next automatic folder selection */
5100 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5101 FALSE); /* don't create */
5103 GObject *win = modest_mail_operation_get_source (mail_op);
5104 modest_platform_run_information_dialog ((GtkWindow *) win,
5105 _("mail_in_ui_folder_move_target_error"),
5108 g_object_unref (win);
5110 move_to_helper_destroyer (user_data);
5114 TnyFolderStore *dst_folder;
5119 * Utility function that transfer messages from both the main window
5120 * and the msg view window when using the "Move to" dialog
5123 xfer_messages_performer (gboolean canceled,
5125 GtkWindow *parent_window,
5126 TnyAccount *account,
5129 ModestWindow *win = MODEST_WINDOW (parent_window);
5130 TnyAccount *dst_account = NULL;
5131 const gchar *proto_str = NULL;
5132 gboolean dst_is_pop = FALSE;
5133 XferMsgsHelper *helper;
5134 MoveToHelper *movehelper;
5135 ModestMailOperation *mail_op;
5137 helper = (XferMsgsHelper *) user_data;
5139 if (canceled || err) {
5140 if (!check_memory_full_error ((GtkWidget *) parent_window, err)) {
5141 /* Show the proper error message */
5142 modest_ui_actions_on_account_connection_error (parent_window, account);
5147 dst_account = tny_folder_get_account (TNY_FOLDER (helper->dst_folder));
5148 proto_str = tny_account_get_proto (dst_account);
5150 /* tinymail will return NULL for local folders it seems */
5151 dst_is_pop = proto_str &&
5152 (modest_protocol_info_get_transport_store_protocol (proto_str) ==
5153 MODEST_PROTOCOL_STORE_POP);
5155 g_object_unref (dst_account);
5158 modest_platform_information_banner (GTK_WIDGET (win),
5160 ngettext("mail_in_ui_folder_move_target_error",
5161 "mail_in_ui_folder_move_targets_error",
5162 tny_list_get_length (helper->headers)));
5166 movehelper = g_new0 (MoveToHelper, 1);
5167 movehelper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
5168 _CS("ckct_nw_pasting"));
5169 if (movehelper->banner != NULL) {
5170 g_object_ref (movehelper->banner);
5171 gtk_widget_show (GTK_WIDGET (movehelper->banner));
5174 if (MODEST_IS_MAIN_WINDOW (win)) {
5175 GtkWidget *header_view =
5176 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
5177 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5178 movehelper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
5181 /* Perform the mail operation */
5182 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT(win),
5183 xfer_messages_error_handler,
5185 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5188 modest_mail_operation_xfer_msgs (mail_op,
5190 TNY_FOLDER (helper->dst_folder),
5195 g_object_unref (G_OBJECT (mail_op));
5197 g_object_unref (helper->dst_folder);
5198 g_object_unref (helper->headers);
5199 g_slice_free (XferMsgsHelper, helper);
5203 TnyFolder *src_folder;
5204 TnyFolderStore *dst_folder;
5205 gboolean delete_original;
5206 GtkWidget *folder_view;
5210 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
5211 TnyAccount *account, gpointer user_data)
5213 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
5214 GtkTreeSelection *sel;
5215 ModestMailOperation *mail_op = NULL;
5217 if (canceled || err || !MODEST_IS_MAIN_WINDOW (parent_window)) {
5218 g_object_unref (G_OBJECT (info->src_folder));
5219 g_object_unref (G_OBJECT (info->dst_folder));
5224 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
5225 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
5226 _CS("ckct_nw_pasting"));
5227 if (helper->banner != NULL) {
5228 g_object_ref (helper->banner);
5229 gtk_widget_show (GTK_WIDGET(helper->banner));
5231 /* Clean folder on header view before moving it */
5232 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
5233 gtk_tree_selection_unselect_all (sel);
5235 /* Let gtk events run. We need that the folder
5236 view frees its reference to the source
5237 folder *before* issuing the mail operation
5238 so we need the signal handler of selection
5239 changed to happen before the mail
5241 while (gtk_events_pending ())
5242 gtk_main_iteration (); */
5245 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
5246 modest_ui_actions_move_folder_error_handler,
5247 info->src_folder, NULL);
5248 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
5251 /* Select *after* the changes */
5252 /* TODO: this function hangs UI after transfer */
5253 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
5254 /* TNY_FOLDER (src_folder), TRUE); */
5256 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
5257 TNY_FOLDER (info->dst_folder), TRUE);
5258 modest_mail_operation_xfer_folder (mail_op,
5259 TNY_FOLDER (info->src_folder),
5261 info->delete_original,
5264 g_object_unref (G_OBJECT (info->src_folder));
5266 /* if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) { */
5269 /* Unref mail operation */
5270 g_object_unref (G_OBJECT (mail_op));
5271 g_object_unref (G_OBJECT (info->dst_folder));
5276 get_account_from_folder_store (TnyFolderStore *folder_store)
5278 if (TNY_IS_ACCOUNT (folder_store))
5279 return g_object_ref (folder_store);
5281 return tny_folder_get_account (TNY_FOLDER (folder_store));
5285 * UI handler for the "Move to" action when invoked from the
5289 modest_ui_actions_on_main_window_move_to (GtkAction *action,
5290 GtkWidget *folder_view,
5291 TnyFolderStore *dst_folder,
5292 ModestMainWindow *win)
5294 ModestHeaderView *header_view = NULL;
5295 TnyFolderStore *src_folder = NULL;
5297 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
5299 /* Get the source folder */
5300 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5302 /* Get header view */
5303 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
5305 /* Get folder or messages to transfer */
5306 if (gtk_widget_is_focus (folder_view)) {
5307 gboolean do_xfer = TRUE;
5309 /* Allow only to transfer folders to the local root folder */
5310 if (TNY_IS_ACCOUNT (dst_folder) &&
5311 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder) &&
5312 !modest_tny_account_is_memory_card_account (TNY_ACCOUNT (dst_folder))) {
5314 } else if (!TNY_IS_FOLDER (src_folder)) {
5315 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
5320 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
5321 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5323 info->src_folder = g_object_ref (src_folder);
5324 info->dst_folder = g_object_ref (dst_folder);
5325 info->delete_original = TRUE;
5326 info->folder_view = folder_view;
5328 connect_info->callback = on_move_folder_cb;
5329 connect_info->dst_account = get_account_from_folder_store (TNY_FOLDER_STORE (dst_folder));
5330 connect_info->data = info;
5332 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5333 TNY_FOLDER_STORE (src_folder),
5336 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
5339 headers = modest_header_view_get_selected_headers(header_view);
5341 /* Transfer the messages */
5342 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), TNY_FOLDER (src_folder),
5343 headers, TNY_FOLDER (dst_folder));
5345 g_object_unref (headers);
5349 g_object_unref (src_folder);
5354 modest_ui_actions_transfer_messages_helper (GtkWindow *win,
5355 TnyFolder *src_folder,
5357 TnyFolder *dst_folder)
5359 gboolean need_connection = TRUE;
5360 gboolean do_xfer = TRUE;
5361 XferMsgsHelper *helper;
5363 modest_ui_actions_xfer_messages_check (win, TNY_FOLDER_STORE (src_folder),
5364 headers, TNY_FOLDER (dst_folder),
5365 TRUE, &need_connection,
5368 /* If we don't want to transfer just return */
5372 /* Create the helper */
5373 helper = g_slice_new (XferMsgsHelper);
5374 helper->dst_folder = g_object_ref (dst_folder);
5375 helper->headers = g_object_ref (headers);
5377 if (need_connection) {
5378 DoubleConnectionInfo *connect_info = g_slice_new (DoubleConnectionInfo);
5379 connect_info->callback = xfer_messages_performer;
5380 connect_info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
5381 connect_info->data = helper;
5383 modest_platform_double_connect_and_perform(GTK_WINDOW (win), TRUE,
5384 TNY_FOLDER_STORE (src_folder),
5387 TnyAccount *src_account = get_account_from_folder_store (TNY_FOLDER_STORE (src_folder));
5388 xfer_messages_performer (FALSE, NULL, GTK_WINDOW (win),
5389 src_account, helper);
5390 g_object_unref (src_account);
5395 * UI handler for the "Move to" action when invoked from the
5396 * ModestMsgViewWindow
5399 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
5400 TnyFolderStore *dst_folder,
5401 ModestMsgViewWindow *win)
5403 TnyList *headers = NULL;
5404 TnyHeader *header = NULL;
5405 TnyFolder *src_folder = NULL;
5407 g_return_if_fail (TNY_IS_FOLDER (dst_folder));
5409 /* Create header list */
5410 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
5411 src_folder = TNY_FOLDER (tny_header_get_folder(header));
5412 headers = tny_simple_list_new ();
5413 tny_list_append (headers, G_OBJECT (header));
5415 /* Transfer the messages */
5416 modest_ui_actions_transfer_messages_helper (GTK_WINDOW (win), src_folder, headers,
5417 TNY_FOLDER (dst_folder));
5420 g_object_unref (header);
5421 g_object_unref (headers);
5425 modest_ui_actions_on_move_to (GtkAction *action,
5428 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
5430 TnyFolderStore *dst_folder = NULL;
5431 ModestMainWindow *main_window;
5433 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
5434 MODEST_IS_MSG_VIEW_WINDOW (win));
5436 /* Get the main window if exists */
5437 if (MODEST_IS_MAIN_WINDOW (win))
5438 main_window = MODEST_MAIN_WINDOW (win);
5441 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
5442 FALSE)); /* don't create */
5444 /* Get the folder view widget if exists */
5446 folder_view = modest_main_window_get_child_widget (main_window,
5447 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5451 /* Create and run the dialog */
5452 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
5453 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
5454 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5455 result = gtk_dialog_run (GTK_DIALOG(dialog));
5456 g_object_ref (tree_view);
5457 gtk_widget_destroy (dialog);
5459 if (result != GTK_RESPONSE_ACCEPT)
5462 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
5463 /* Do window specific stuff */
5464 if (MODEST_IS_MAIN_WINDOW (win)) {
5465 modest_ui_actions_on_main_window_move_to (action,
5468 MODEST_MAIN_WINDOW (win));
5470 modest_ui_actions_on_msg_view_window_move_to (action,
5472 MODEST_MSG_VIEW_WINDOW (win));
5476 g_object_unref (dst_folder);
5480 * Calls #HeadersFunc for each header already selected in the main
5481 * window or the message currently being shown in the msg view window
5484 do_headers_action (ModestWindow *win,
5488 TnyList *headers_list = NULL;
5489 TnyIterator *iter = NULL;
5490 TnyHeader *header = NULL;
5491 TnyFolder *folder = NULL;
5494 headers_list = get_selected_headers (win);
5498 /* Get the folder */
5499 iter = tny_list_create_iterator (headers_list);
5500 header = TNY_HEADER (tny_iterator_get_current (iter));
5502 folder = tny_header_get_folder (header);
5503 g_object_unref (header);
5506 /* Call the function for each header */
5507 while (!tny_iterator_is_done (iter)) {
5508 header = TNY_HEADER (tny_iterator_get_current (iter));
5509 func (header, win, user_data);
5510 g_object_unref (header);
5511 tny_iterator_next (iter);
5514 /* Trick: do a poke status in order to speed up the signaling
5516 tny_folder_poke_status (folder);
5519 g_object_unref (folder);
5520 g_object_unref (iter);
5521 g_object_unref (headers_list);
5525 modest_ui_actions_view_attachment (GtkAction *action,
5526 ModestWindow *window)
5528 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5529 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
5531 /* not supported window for this action */
5532 g_return_if_reached ();
5537 modest_ui_actions_save_attachments (GtkAction *action,
5538 ModestWindow *window)
5540 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5542 if (modest_platform_check_memory_low (MODEST_WINDOW(window), TRUE))
5545 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
5547 /* not supported window for this action */
5548 g_return_if_reached ();
5553 modest_ui_actions_remove_attachments (GtkAction *action,
5554 ModestWindow *window)
5556 if (MODEST_IS_MAIN_WINDOW (window)) {
5557 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
5558 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
5559 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
5561 /* not supported window for this action */
5562 g_return_if_reached ();
5567 modest_ui_actions_on_settings (GtkAction *action,
5572 dialog = modest_platform_get_global_settings_dialog ();
5573 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
5574 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
5575 gtk_widget_show_all (dialog);
5577 gtk_dialog_run (GTK_DIALOG (dialog));
5579 gtk_widget_destroy (dialog);
5583 modest_ui_actions_on_help (GtkAction *action,
5586 const gchar *help_id;
5588 g_return_if_fail (win && GTK_IS_WINDOW(win));
5590 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
5593 modest_platform_show_help (GTK_WINDOW (win), help_id);
5597 modest_ui_actions_on_csm_help (GtkAction *action,
5600 const gchar* help_id = NULL;
5601 GtkWidget *folder_view;
5602 TnyFolderStore *folder_store;
5604 g_return_if_fail (win && MODEST_IS_MAIN_WINDOW (win));
5606 /* Get selected folder */
5607 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
5608 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5609 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5611 /* Switch help_id */
5612 if (folder_store && TNY_IS_FOLDER (folder_store))
5613 help_id = modest_tny_folder_get_help_id (TNY_FOLDER (folder_store));
5616 g_object_unref (folder_store);
5619 modest_platform_show_help (GTK_WINDOW (win), help_id);
5621 modest_ui_actions_on_help (action, win);
5625 retrieve_contents_cb (ModestMailOperation *mail_op,
5632 /* We only need this callback to show an error in case of
5633 memory low condition */
5634 modest_ui_actions_msg_retrieval_check (mail_op, header, msg);
5638 retrieve_msg_contents_performer (gboolean canceled,
5640 GtkWindow *parent_window,
5641 TnyAccount *account,
5644 ModestMailOperation *mail_op;
5645 TnyList *headers = TNY_LIST (user_data);
5647 if (err || canceled) {
5648 check_memory_full_error ((GtkWidget *) parent_window, err);
5652 /* Create mail operation */
5653 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5654 modest_ui_actions_disk_operations_error_handler,
5656 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5657 modest_mail_operation_get_msgs_full (mail_op, headers, retrieve_contents_cb, NULL, NULL);
5660 g_object_unref (mail_op);
5662 g_object_unref (headers);
5663 g_object_unref (account);
5667 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5668 ModestWindow *window)
5670 TnyList *headers = NULL;
5671 TnyAccount *account = NULL;
5672 TnyIterator *iter = NULL;
5673 TnyHeader *header = NULL;
5674 TnyFolder *folder = NULL;
5677 headers = get_selected_headers (window);
5681 /* Pick the account */
5682 iter = tny_list_create_iterator (headers);
5683 header = TNY_HEADER (tny_iterator_get_current (iter));
5684 folder = tny_header_get_folder (header);
5685 account = tny_folder_get_account (folder);
5686 g_object_unref (folder);
5687 g_object_unref (header);
5688 g_object_unref (iter);
5690 /* Connect and perform the message retrieval */
5691 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
5692 g_object_ref (account),
5693 retrieve_msg_contents_performer,
5694 g_object_ref (headers));
5697 g_object_unref (account);
5698 g_object_unref (headers);
5702 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
5704 g_return_if_fail (MODEST_IS_WINDOW (window));
5707 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
5711 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
5713 g_return_if_fail (MODEST_IS_WINDOW (window));
5716 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
5720 modest_ui_actions_on_email_menu_activated (GtkAction *action,
5721 ModestWindow *window)
5723 g_return_if_fail (MODEST_IS_WINDOW (window));
5726 modest_ui_actions_check_menu_dimming_rules (window);
5730 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
5731 ModestWindow *window)
5733 g_return_if_fail (MODEST_IS_WINDOW (window));
5736 modest_ui_actions_check_menu_dimming_rules (window);
5740 modest_ui_actions_on_view_menu_activated (GtkAction *action,
5741 ModestWindow *window)
5743 g_return_if_fail (MODEST_IS_WINDOW (window));
5746 modest_ui_actions_check_menu_dimming_rules (window);
5750 modest_ui_actions_on_format_menu_activated (GtkAction *action,
5751 ModestWindow *window)
5753 g_return_if_fail (MODEST_IS_WINDOW (window));
5756 modest_ui_actions_check_menu_dimming_rules (window);
5760 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
5761 ModestWindow *window)
5763 g_return_if_fail (MODEST_IS_WINDOW (window));
5766 modest_ui_actions_check_menu_dimming_rules (window);
5770 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
5771 ModestWindow *window)
5773 g_return_if_fail (MODEST_IS_WINDOW (window));
5776 modest_ui_actions_check_menu_dimming_rules (window);
5780 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
5781 ModestWindow *window)
5783 g_return_if_fail (MODEST_IS_WINDOW (window));
5786 modest_ui_actions_check_menu_dimming_rules (window);
5790 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
5791 ModestWindow *window)
5793 g_return_if_fail (MODEST_IS_WINDOW (window));
5796 modest_ui_actions_check_menu_dimming_rules (window);
5800 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
5801 ModestWindow *window)
5803 g_return_if_fail (MODEST_IS_WINDOW (window));
5806 modest_ui_actions_check_menu_dimming_rules (window);
5810 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
5812 g_return_if_fail (MODEST_IS_WINDOW (window));
5814 /* we check for low-mem; in that case, show a warning, and don't allow
5817 if (modest_platform_check_memory_low (window, TRUE))
5820 modest_platform_show_search_messages (GTK_WINDOW (window));
5824 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
5826 g_return_if_fail (MODEST_IS_WINDOW (win));
5829 /* we check for low-mem; in that case, show a warning, and don't allow
5830 * for the addressbook
5832 if (modest_platform_check_memory_low (win, TRUE))
5836 modest_platform_show_addressbook (GTK_WINDOW (win));
5841 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
5842 ModestWindow *window)
5844 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5846 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
5850 on_send_receive_finished (ModestMailOperation *mail_op,
5853 GtkWidget *header_view, *folder_view;
5854 TnyFolderStore *folder_store;
5855 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
5857 /* Set send/receive operation finished */
5858 modest_main_window_notify_send_receive_completed (main_win);
5860 /* Don't refresh the current folder if there were any errors */
5861 if (modest_mail_operation_get_status (mail_op) !=
5862 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5865 /* Refresh the current folder if we're viewing a window. We do
5866 this because the user won't be able to see the new mails in
5867 the selected folder after a Send&Receive because it only
5868 performs a poke_status, i.e, only the number of read/unread
5869 messages is updated, but the new headers are not
5871 folder_view = modest_main_window_get_child_widget (main_win,
5872 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5876 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5878 /* Do not need to refresh INBOX again because the
5879 update_account does it always automatically */
5880 if (folder_store && TNY_IS_FOLDER (folder_store) &&
5881 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
5882 ModestMailOperation *refresh_op;
5884 header_view = modest_main_window_get_child_widget (main_win,
5885 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5887 /* We do not need to set the contents style
5888 because it hasn't changed. We also do not
5889 need to save the widget status. Just force
5891 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
5892 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
5893 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
5894 folder_refreshed_cb, main_win);
5895 g_object_unref (refresh_op);
5899 g_object_unref (folder_store);
5904 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
5910 const gchar* server_name = NULL;
5911 TnyTransportAccount *server_account;
5912 gchar *message = NULL;
5914 /* Don't show anything if the user cancelled something or the
5915 * send receive request is not interactive. Authentication
5916 * errors are managed by the account store so no need to show
5917 * a dialog here again */
5918 if (err->code == TNY_SYSTEM_ERROR_CANCEL ||
5919 err->code == TNY_SERVICE_ERROR_AUTHENTICATE ||
5920 !modest_tny_send_queue_get_requested_send_receive (MODEST_TNY_SEND_QUEUE (self)))
5924 /* Get the server name: */
5926 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
5928 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
5930 g_return_if_reached ();
5932 /* Show the appropriate message text for the GError: */
5933 switch (err->code) {
5934 case TNY_SERVICE_ERROR_CONNECT:
5935 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
5937 case TNY_SERVICE_ERROR_SEND:
5938 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
5940 case TNY_SERVICE_ERROR_UNAVAILABLE:
5941 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
5944 g_warning ("%s: unexpected ERROR %d",
5945 __FUNCTION__, err->code);
5946 message = g_strdup (dgettext("hildon-common-strings", "sfil_ib_unable_to_send"));
5950 modest_platform_run_information_dialog (NULL, message, FALSE);
5952 g_object_unref (server_account);
5956 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
5961 ModestMainWindow *main_window = NULL;
5962 ModestWindowMgr *mgr = NULL;
5963 GtkWidget *folder_view = NULL, *header_view = NULL;
5964 TnyFolderStore *selected_folder = NULL;
5965 TnyFolderType folder_type;
5967 mgr = modest_runtime_get_window_mgr ();
5968 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr,
5969 FALSE));/* don't create */
5973 /* Check if selected folder is OUTBOX */
5974 folder_view = modest_main_window_get_child_widget (main_window,
5975 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5976 header_view = modest_main_window_get_child_widget (main_window,
5977 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5979 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5980 if (!TNY_IS_FOLDER (selected_folder))
5983 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
5984 #if GTK_CHECK_VERSION(2, 8, 0)
5985 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
5986 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
5987 GtkTreeViewColumn *tree_column;
5989 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
5990 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
5991 gtk_tree_view_column_queue_resize (tree_column);
5994 gtk_widget_queue_draw (header_view);
5997 /* Rerun dimming rules, because the message could become deletable for example */
5998 modest_window_check_dimming_rules_group (MODEST_WINDOW (main_window),
5999 MODEST_DIMMING_RULES_TOOLBAR);
6003 if (selected_folder != NULL)
6004 g_object_unref (selected_folder);
6008 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
6009 TnyAccount *account)
6011 ModestTransportStoreProtocol proto;
6012 const gchar *proto_name;
6013 gchar *error_note = NULL;
6015 proto_name = tny_account_get_proto (account);
6016 proto = modest_protocol_info_get_transport_store_protocol (proto_name);
6019 case MODEST_PROTOCOL_STORE_POP:
6020 error_note = g_strdup_printf (_("emev_ni_ui_pop3_msg_connect_error"),
6021 tny_account_get_hostname (account));
6023 case MODEST_PROTOCOL_STORE_IMAP:
6024 error_note = g_strdup_printf (_("emev_ni_ui_imap_connect_server_error"),
6025 tny_account_get_hostname (account));
6027 case MODEST_PROTOCOL_STORE_MAILDIR:
6028 case MODEST_PROTOCOL_STORE_MBOX:
6029 error_note = g_strdup (_("emev_nc_mailbox_notavailable"));
6032 g_warning ("%s: This should not be reached", __FUNCTION__);
6036 modest_platform_run_information_dialog (parent_window, error_note, FALSE);
6037 g_free (error_note);
6042 modest_ui_actions_get_msg_already_deleted_error_msg (ModestWindow *win)
6045 TnyFolderStore *folder = NULL;
6046 TnyAccount *account = NULL;
6047 ModestTransportStoreProtocol proto;
6048 TnyHeader *header = NULL;
6050 if (MODEST_IS_MAIN_WINDOW (win)) {
6051 GtkWidget *header_view;
6052 TnyList* headers = NULL;
6054 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
6055 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
6056 headers = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
6057 if (!headers || tny_list_get_length (headers) == 0) {
6059 g_object_unref (headers);
6062 iter = tny_list_create_iterator (headers);
6063 header = TNY_HEADER (tny_iterator_get_current (iter));
6064 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6065 g_object_unref (iter);
6066 g_object_unref (headers);
6067 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
6068 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
6069 folder = TNY_FOLDER_STORE (tny_header_get_folder (header));
6072 /* Get the account type */
6073 account = tny_folder_get_account (TNY_FOLDER (folder));
6074 proto = modest_protocol_info_get_transport_store_protocol (tny_account_get_proto (account));
6075 if (proto == MODEST_PROTOCOL_STORE_POP) {
6076 msg = g_strdup (_("emev_ni_ui_pop3_msg_recv_error"));
6077 } else if (proto == MODEST_PROTOCOL_STORE_IMAP) {
6079 subject = tny_header_dup_subject (header);
6080 msg = g_strdup_printf (_("emev_ni_ui_imap_message_not_available_in_server"),
6084 msg = g_strdup_printf (_("mail_ni_ui_folder_get_msg_folder_error"));
6088 g_object_unref (account);
6089 g_object_unref (folder);
6090 g_object_unref (header);