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.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 typedef struct _GetMsgAsyncHelper {
87 ModestMailOperation *mail_op;
94 typedef enum _ReplyForwardAction {
100 typedef struct _ReplyForwardHelper {
101 guint reply_forward_type;
102 ReplyForwardAction action;
104 GtkWidget *parent_window;
105 } ReplyForwardHelper;
107 typedef struct _MoveToHelper {
108 GtkTreeRowReference *reference;
112 typedef struct _PasteAsAttachmentHelper {
113 ModestMsgEditWindow *window;
115 } PasteAsAttachmentHelper;
119 * The do_headers_action uses this kind of functions to perform some
120 * action to each member of a list of headers
122 typedef void (*HeadersFunc) (TnyHeader *header, ModestWindow *win, gpointer user_data);
124 static void do_headers_action (ModestWindow *win,
128 static void open_msg_cb (ModestMailOperation *mail_op,
135 static void reply_forward_cb (ModestMailOperation *mail_op,
142 static void reply_forward (ReplyForwardAction action, ModestWindow *win);
144 static void folder_refreshed_cb (ModestMailOperation *mail_op,
148 static void on_send_receive_finished (ModestMailOperation *mail_op,
151 static gint header_list_count_uncached_msgs (TnyList *header_list);
153 static gboolean connect_to_get_msg (ModestWindow *win,
154 gint num_of_uncached_msgs,
155 TnyAccount *account);
157 static gboolean remote_folder_is_pop (const TnyFolderStore *folder);
159 static gboolean msgs_already_deleted_from_server ( TnyList *headers,
160 const TnyFolderStore *src_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);
170 * This function checks whether a TnyFolderStore is a pop account
173 remote_folder_is_pop (const TnyFolderStore *folder)
175 const gchar *proto = NULL;
176 TnyAccount *account = NULL;
178 g_return_val_if_fail (TNY_IS_FOLDER_STORE(folder), FALSE);
180 if (TNY_IS_ACCOUNT (folder)) {
181 account = TNY_ACCOUNT(folder);
182 g_object_ref(account);
183 } else if (TNY_IS_FOLDER (folder)) {
184 account = tny_folder_get_account(TNY_FOLDER(folder));
187 if (!account && !TNY_IS_ACCOUNT(account)) {
188 g_warning ("%s: could not get account", __FUNCTION__);
192 proto = tny_account_get_proto(account);
193 g_object_unref (account);
196 (modest_protocol_info_get_transport_store_protocol (proto) == MODEST_PROTOCOL_STORE_POP);
200 * This functions checks whether if a list of messages are already
201 * deleted from the server: that is, if the server is a POP account
202 * and all messages are already cached.
205 msgs_already_deleted_from_server (TnyList *headers, const TnyFolderStore *src_folder)
207 g_return_val_if_fail (TNY_IS_FOLDER_STORE(src_folder), FALSE);
208 g_return_val_if_fail (TNY_IS_LIST(headers), FALSE);
210 gboolean src_is_pop = remote_folder_is_pop (src_folder);
211 gint uncached_msgs = header_list_count_uncached_msgs (headers);
213 return (src_is_pop && !uncached_msgs);
217 /* FIXME: this should be merged with the similar code in modest-account-view-window */
218 /* Show the account creation wizard dialog.
219 * returns: TRUE if an account was created. FALSE if the user cancelled.
222 modest_ui_actions_run_account_setup_wizard (ModestWindow *win)
224 gboolean result = FALSE;
225 GtkWindow *dialog, *wizard;
226 gint dialog_response;
228 /* Show the easy-setup wizard: */
229 dialog = modest_window_mgr_get_modal (modest_runtime_get_window_mgr());
231 /* old wizard is active already;
233 gtk_window_present (GTK_WINDOW(dialog));
238 /* there is no such wizard yet */
239 wizard = GTK_WINDOW (modest_platform_get_account_settings_wizard ());
240 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), wizard);
242 /* always present a main window in the background
243 * we do it here, so we cannot end up with two wizards (as this
244 * function might be called in modest_window_mgr_get_main_window as well */
246 win = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr(),
247 TRUE); /* create if not existent */
249 /* make sure the mainwindow is visible */
250 gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (win));
251 gtk_widget_show_all (GTK_WIDGET(win));
252 gtk_window_present (GTK_WINDOW(win));
254 dialog_response = gtk_dialog_run (GTK_DIALOG (wizard));
255 gtk_widget_destroy (GTK_WIDGET (wizard));
256 if (gtk_events_pending ())
257 gtk_main_iteration ();
259 if (dialog_response == GTK_RESPONSE_CANCEL) {
262 /* Check whether an account was created: */
263 result = modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
270 modest_ui_actions_on_about (GtkAction *action, ModestWindow *win)
273 const gchar *authors[] = {
274 "Dirk-Jan C. Binnema <dirk-jan.binnema@nokia.com>",
277 about = gtk_about_dialog_new ();
278 gtk_about_dialog_set_name (GTK_ABOUT_DIALOG(about), PACKAGE_NAME);
279 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG(about),PACKAGE_VERSION);
280 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG(about),
281 _("Copyright (c) 2006, Nokia Corporation\n"
282 "All rights reserved."));
283 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG(about),
284 _("a modest e-mail client\n\n"
285 "design and implementation: Dirk-Jan C. Binnema\n"
286 "contributions from the fine people at KC and Ig\n"
287 "uses the tinymail email framework written by Philip van Hoof"));
288 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG(about), authors);
289 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG(about), "http://modest.garage.maemo.org");
290 gtk_window_set_transient_for (GTK_WINDOW (about), GTK_WINDOW (win));
291 gtk_window_set_modal (GTK_WINDOW (about), TRUE);
293 gtk_dialog_run (GTK_DIALOG (about));
294 gtk_widget_destroy(about);
298 * Gets the list of currently selected messages. If the win is the
299 * main window, then it returns a newly allocated list of the headers
300 * selected in the header view. If win is the msg view window, then
301 * the value returned is a list with just a single header.
303 * The caller of this funcion must free the list.
306 get_selected_headers (ModestWindow *win)
308 if (MODEST_IS_MAIN_WINDOW(win)) {
309 GtkWidget *header_view;
311 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
312 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
313 return modest_header_view_get_selected_headers (MODEST_HEADER_VIEW(header_view));
315 } else if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
316 /* for MsgViewWindows, we simply return a list with one element */
318 TnyList *list = NULL;
320 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
321 if (header != NULL) {
322 list = tny_simple_list_new ();
323 tny_list_prepend (list, G_OBJECT(header));
324 g_object_unref (G_OBJECT(header));
333 static GtkTreeRowReference *
334 get_next_after_selected_headers (ModestHeaderView *header_view)
336 GtkTreeSelection *sel;
337 GList *selected_rows, *node;
339 GtkTreeRowReference *result;
342 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
343 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
344 selected_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
346 if (selected_rows == NULL)
349 node = g_list_last (selected_rows);
350 path = gtk_tree_path_copy ((GtkTreePath *) node->data);
351 gtk_tree_path_next (path);
353 result = gtk_tree_row_reference_new (model, path);
355 gtk_tree_path_free (path);
356 g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
357 g_list_free (selected_rows);
363 headers_action_mark_as_read (TnyHeader *header,
367 TnyHeaderFlags flags;
369 g_return_if_fail (TNY_IS_HEADER(header));
371 flags = tny_header_get_flags (header);
372 if (flags & TNY_HEADER_FLAG_SEEN) return;
373 tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN);
377 headers_action_mark_as_unread (TnyHeader *header,
381 TnyHeaderFlags flags;
383 g_return_if_fail (TNY_IS_HEADER(header));
385 flags = tny_header_get_flags (header);
386 if (flags & TNY_HEADER_FLAG_SEEN) {
387 tny_header_unset_flag (header, TNY_HEADER_FLAG_SEEN);
391 /** After deleing a message that is currently visible in a window,
392 * show the next message from the list, or close the window if there are no more messages.
395 modest_ui_actions_refresh_message_window_after_delete (ModestMsgViewWindow* win)
397 /* Close msg view window or select next */
398 if (modest_msg_view_window_last_message_selected (win) &&
399 modest_msg_view_window_first_message_selected (win)) {
400 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (win));
401 } else if (!modest_msg_view_window_select_next_message (win) &&
402 !modest_msg_view_window_select_previous_message (win)) {
404 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
410 modest_ui_actions_on_delete_message (GtkAction *action, ModestWindow *win)
412 TnyList *header_list = NULL;
413 TnyIterator *iter = NULL;
414 TnyHeader *header = NULL;
415 gchar *message = NULL;
418 ModestWindowMgr *mgr;
419 GtkWidget *header_view = NULL;
421 g_return_if_fail (MODEST_IS_WINDOW(win));
423 /* Check first if the header view has the focus */
424 if (MODEST_IS_MAIN_WINDOW (win)) {
426 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
427 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
428 if (!gtk_widget_is_focus (header_view))
432 /* Get the headers, either from the header view (if win is the main window),
433 * or from the message view window: */
434 header_list = get_selected_headers (win);
435 if (!header_list) return;
437 /* Check if any of the headers are already opened, or in the process of being opened */
438 if (MODEST_IS_MAIN_WINDOW (win)) {
439 gint opened_headers = 0;
441 iter = tny_list_create_iterator (header_list);
442 mgr = modest_runtime_get_window_mgr ();
443 while (!tny_iterator_is_done (iter)) {
444 header = TNY_HEADER (tny_iterator_get_current (iter));
446 if (modest_window_mgr_find_registered_header (mgr, header, NULL))
448 g_object_unref (header);
450 tny_iterator_next (iter);
452 g_object_unref (iter);
454 if (opened_headers > 0) {
457 msg = g_strdup_printf (_("mcen_nc_unable_to_delete_n_messages"),
460 modest_platform_run_information_dialog (GTK_WINDOW (win), (const gchar *) msg);
463 g_object_unref (header_list);
469 if (tny_list_get_length(header_list) == 1) {
470 iter = tny_list_create_iterator (header_list);
471 header = TNY_HEADER (tny_iterator_get_current (iter));
473 desc = g_strdup_printf ("%s", tny_header_get_subject (header));
474 g_object_unref (header);
477 g_object_unref (iter);
479 message = g_strdup_printf(ngettext("emev_nc_delete_message", "emev_nc_delete_messages",
480 tny_list_get_length(header_list)), desc);
482 /* Confirmation dialog */
483 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
487 if (response == GTK_RESPONSE_OK) {
488 ModestWindow *main_window = NULL;
489 ModestWindowMgr *mgr = NULL;
490 GtkTreeModel *model = NULL;
491 GtkTreeSelection *sel = NULL;
492 GList *sel_list = NULL, *tmp = NULL;
493 GtkTreeRowReference *next_row_reference = NULL;
494 GtkTreeRowReference *prev_row_reference = NULL;
495 GtkTreePath *next_path = NULL;
496 GtkTreePath *prev_path = NULL;
497 ModestMailOperation *mail_op = NULL;
499 /* Find last selected row */
500 if (MODEST_IS_MAIN_WINDOW (win)) {
501 model = gtk_tree_view_get_model (GTK_TREE_VIEW (header_view));
502 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
503 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
504 for (tmp=sel_list; tmp; tmp=tmp->next) {
505 if (tmp->next == NULL) {
506 prev_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
507 next_path = gtk_tree_path_copy((GtkTreePath *) tmp->data);
509 gtk_tree_path_prev (prev_path);
510 gtk_tree_path_next (next_path);
512 prev_row_reference = gtk_tree_row_reference_new (model, prev_path);
513 next_row_reference = gtk_tree_row_reference_new (model, next_path);
518 /* Disable window dimming management */
519 modest_window_disable_dimming (MODEST_WINDOW(win));
521 /* Remove each header. If it's a view window header_view == NULL */
522 mail_op = modest_mail_operation_new ((GObject *) win);
523 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
525 modest_mail_operation_remove_msgs (mail_op, header_list, FALSE);
526 g_object_unref (mail_op);
528 /* Enable window dimming management */
530 gtk_tree_selection_unselect_all (sel);
532 modest_window_enable_dimming (MODEST_WINDOW(win));
534 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
535 modest_ui_actions_refresh_message_window_after_delete (MODEST_MSG_VIEW_WINDOW (win));
537 /* Get main window */
538 mgr = modest_runtime_get_window_mgr ();
539 main_window = modest_window_mgr_get_main_window (mgr, FALSE); /* don't create */
541 /* Move cursor to next row */
544 /* Select next or previous row */
545 if (gtk_tree_row_reference_valid (next_row_reference)) {
546 /* next_path = gtk_tree_row_reference_get_path (row_reference); */
547 gtk_tree_selection_select_path (sel, next_path);
549 else if (gtk_tree_row_reference_valid (prev_row_reference)) {
550 gtk_tree_selection_select_path (sel, prev_path);
554 if (next_row_reference != NULL)
555 gtk_tree_row_reference_free (next_row_reference);
556 if (next_path != NULL)
557 gtk_tree_path_free (next_path);
558 if (prev_row_reference != NULL)
559 gtk_tree_row_reference_free (prev_row_reference);
560 if (prev_path != NULL)
561 gtk_tree_path_free (prev_path);
564 /* Update toolbar dimming state */
566 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
569 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
570 g_list_free (sel_list);
576 g_object_unref (header_list);
582 /* delete either message or folder, based on where we are */
584 modest_ui_actions_on_delete_message_or_folder (GtkAction *action, ModestWindow *win)
586 g_return_if_fail (MODEST_IS_WINDOW(win));
588 /* Check first if the header view has the focus */
589 if (MODEST_IS_MAIN_WINDOW (win)) {
591 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
592 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
593 if (gtk_widget_is_focus (w)) {
594 modest_ui_actions_on_delete_folder (action, MODEST_MAIN_WINDOW(win));
598 modest_ui_actions_on_delete_message (action, win);
604 modest_ui_actions_on_quit (GtkAction *action, ModestWindow *win)
606 ModestWindowMgr *mgr = NULL;
608 #ifdef MODEST_PLATFORM_MAEMO
609 modest_osso_save_state();
610 #endif /* MODEST_PLATFORM_MAEMO */
612 g_debug ("closing down, clearing %d item(s) from operation queue",
613 modest_mail_operation_queue_num_elements
614 (modest_runtime_get_mail_operation_queue()));
616 /* cancel all outstanding operations */
617 modest_mail_operation_queue_cancel_all
618 (modest_runtime_get_mail_operation_queue());
620 g_debug ("queue has been cleared");
623 /* Check if there are opened editing windows */
624 mgr = modest_runtime_get_window_mgr ();
625 modest_window_mgr_close_all_windows (mgr);
627 /* note: when modest-tny-account-store is finalized,
628 it will automatically set all network connections
631 /* gtk_main_quit (); */
635 modest_ui_actions_on_close_window (GtkAction *action, ModestWindow *win)
639 g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value);
641 /* if (MODEST_IS_MSG_VIEW_WINDOW (win)) { */
642 /* gtk_widget_destroy (GTK_WIDGET (win)); */
643 /* } else if (MODEST_IS_MSG_EDIT_WINDOW (win)) { */
644 /* gboolean ret_value; */
645 /* g_signal_emit_by_name (G_OBJECT (win), "delete-event", NULL, &ret_value); */
646 /* } else if (MODEST_IS_WINDOW (win)) { */
647 /* gtk_widget_destroy (GTK_WIDGET (win)); */
649 /* g_return_if_reached (); */
654 modest_ui_actions_on_add_to_contacts (GtkAction *action, ModestWindow *win)
656 GtkClipboard *clipboard = NULL;
657 gchar *selection = NULL;
659 clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
660 selection = gtk_clipboard_wait_for_text (clipboard);
662 /* Question: why is the clipboard being used here?
663 * It doesn't really make a lot of sense. */
667 modest_address_book_add_address (selection);
673 modest_ui_actions_on_accounts (GtkAction *action,
676 /* This is currently only implemented for Maemo */
677 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE)) {
678 if (!modest_ui_actions_run_account_setup_wizard (win))
679 g_debug ("%s: wizard was already running", __FUNCTION__);
683 /* Show the list of accounts */
684 GtkWindow *account_win = GTK_WINDOW (modest_account_view_window_new ());
685 gtk_window_set_transient_for (account_win, GTK_WINDOW (win));
687 /* The accounts dialog must be modal */
688 modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), account_win);
689 modest_utils_show_dialog_and_forget (GTK_WINDOW (win), GTK_DIALOG (account_win));
693 #ifdef MODEST_PLATFORM_MAEMO
695 on_smtp_servers_window_hide (GtkWindow* window, gpointer user_data)
697 /* Save any changes. */
698 modest_connection_specific_smtp_window_save_server_accounts (
699 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (window));
700 gtk_widget_destroy (GTK_WIDGET (window));
706 modest_ui_actions_on_smtp_servers (GtkAction *action, ModestWindow *win)
708 /* This is currently only implemented for Maemo,
709 * because it requires an API (libconic) to detect different connection
712 #ifdef MODEST_PLATFORM_MAEMO /* Defined in config.h */
714 /* Create the window if necessary: */
715 GtkWidget *specific_window = GTK_WIDGET (modest_connection_specific_smtp_window_new ());
716 modest_connection_specific_smtp_window_fill_with_connections (
717 MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window),
718 modest_runtime_get_account_mgr());
720 /* Show the window: */
721 gtk_window_set_transient_for (GTK_WINDOW (specific_window), GTK_WINDOW (win));
722 gtk_window_set_modal (GTK_WINDOW (specific_window), TRUE);
723 gtk_widget_show (specific_window);
725 /* Save changes when the window is hidden: */
726 g_signal_connect (specific_window, "hide",
727 G_CALLBACK (on_smtp_servers_window_hide), win);
728 #endif /* MODEST_PLATFORM_MAEMO */
732 modest_ui_actions_compose_msg(ModestWindow *win,
735 const gchar *bcc_str,
736 const gchar *subject_str,
737 const gchar *body_str,
740 gchar *account_name = NULL;
742 TnyAccount *account = NULL;
743 TnyFolder *folder = NULL;
744 gchar *from_str = NULL, *signature = NULL, *body = NULL;
745 gboolean use_signature = FALSE;
746 ModestWindow *msg_win = NULL;
747 ModestAccountMgr *mgr = modest_runtime_get_account_mgr();
748 ModestTnyAccountStore *store = modest_runtime_get_account_store();
750 account_name = modest_account_mgr_get_default_account(mgr);
752 g_printerr ("modest: no account found\n");
755 account = modest_tny_account_store_get_server_account (store, account_name, TNY_ACCOUNT_TYPE_STORE);
757 g_printerr ("modest: failed to get tnyaccount for '%s'\n", account_name);
760 folder = modest_tny_account_get_special_folder (account, TNY_FOLDER_TYPE_DRAFTS);
762 g_printerr ("modest: failed to find Drafts folder\n");
765 from_str = modest_account_mgr_get_from_string (mgr, account_name);
767 g_printerr ("modest: failed get from string for '%s'\n", account_name);
771 signature = modest_account_mgr_get_signature (mgr, account_name, &use_signature);
772 if (body_str != NULL) {
773 body = use_signature ? g_strconcat(body_str, "\n", signature, NULL) : g_strdup(body_str);
775 body = use_signature ? g_strconcat("\n", signature, NULL) : g_strdup("");
778 msg = modest_tny_msg_new (to_str, from_str, cc_str, bcc_str, subject_str, body, NULL);
780 g_printerr ("modest: failed to create new msg\n");
784 /* Create and register edit window */
785 /* This is destroyed by TODO. */
786 msg_win = modest_msg_edit_window_new (msg, account_name, FALSE);
787 while (attachments) {
788 modest_msg_edit_window_attach_file_one((ModestMsgEditWindow *)msg_win,
790 attachments = g_slist_next(attachments);
792 modest_window_mgr_register_window (modest_runtime_get_window_mgr(), msg_win);
793 gtk_widget_show_all (GTK_WIDGET (msg_win));
799 g_free (account_name);
800 if (account) g_object_unref (G_OBJECT(account));
801 if (folder) g_object_unref (G_OBJECT(folder));
802 if (msg_win) g_object_unref (G_OBJECT(msg_win));
803 if (msg) g_object_unref (G_OBJECT(msg));
807 modest_ui_actions_on_new_msg (GtkAction *action, ModestWindow *win)
809 /* if there are no accounts yet, just show the wizard */
810 if (!modest_account_mgr_has_accounts (modest_runtime_get_account_mgr(), TRUE))
811 if (!modest_ui_actions_run_account_setup_wizard (win))
814 modest_ui_actions_compose_msg(win, NULL, NULL, NULL, NULL, NULL, NULL);
818 modest_ui_actions_on_new_msg_or_folder (GtkAction *action, ModestWindow *win)
820 g_return_if_fail (MODEST_IS_WINDOW (win));
822 /* Check first if the folder view has the focus */
823 if (MODEST_IS_MAIN_WINDOW (win)) {
825 w = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
826 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
827 if (gtk_widget_is_focus (w)) {
828 modest_ui_actions_on_new_folder (action, MODEST_MAIN_WINDOW(win));
833 modest_ui_actions_on_new_msg (action, win);
838 modest_ui_actions_msg_retrieval_check (ModestMailOperation *mail_op,
842 ModestMailOperationStatus status;
844 /* If there is no message or the operation was not successful */
845 status = modest_mail_operation_get_status (mail_op);
846 if (!msg || status != MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
848 /* Remove the header from the preregistered uids */
849 modest_window_mgr_unregister_header (modest_runtime_get_window_mgr (),
859 open_msg_cb (ModestMailOperation *mail_op,
866 ModestWindowMgr *mgr = NULL;
867 ModestWindow *parent_win = NULL;
868 ModestWindow *win = NULL;
869 TnyFolderType folder_type = TNY_FOLDER_TYPE_UNKNOWN;
870 gchar *account = NULL;
872 gboolean open_in_editor = FALSE;
874 /* Do nothing if there was any problem with the mail
875 operation. The error will be shown by the error_handler of
876 the mail operation */
877 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
880 parent_win = (ModestWindow *) modest_mail_operation_get_source (mail_op);
881 folder = tny_header_get_folder (header);
883 /* Mark header as read */
884 headers_action_mark_as_read (header, MODEST_WINDOW(parent_win), NULL);
886 /* Gets folder type (OUTBOX headers will be opened in edit window */
887 if (modest_tny_folder_is_local_folder (folder)) {
888 folder_type = modest_tny_folder_get_local_or_mmc_folder_type (folder);
889 if (folder_type == TNY_FOLDER_TYPE_INVALID)
890 g_warning ("%s: BUG: TNY_FOLDER_TYPE_INVALID", __FUNCTION__);
894 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
895 TnyTransportAccount *traccount = NULL;
896 ModestTnyAccountStore *accstore = modest_runtime_get_account_store();
897 traccount = modest_tny_account_store_get_transport_account_from_outbox_header(accstore, header);
899 ModestTnySendQueue *send_queue = NULL;
900 ModestTnySendQueueStatus status;
902 account = g_strdup(modest_tny_account_get_parent_modest_account_name_for_server_account(
903 TNY_ACCOUNT(traccount)));
904 send_queue = modest_runtime_get_send_queue(traccount);
905 msg_id = modest_tny_send_queue_get_msg_id (header);
906 status = modest_tny_send_queue_get_msg_status(send_queue, msg_id);
907 /* Only open messages in outbox with the editor if they are in Failed state */
908 if (status == MODEST_TNY_SEND_QUEUE_FAILED) {
909 open_in_editor = TRUE;
912 g_object_unref(traccount);
914 g_warning("Cannot get transport account for message in outbox!!");
916 } else if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
917 open_in_editor = TRUE; /* Open in editor if the message is in the Drafts folder */
922 account = g_strdup (modest_window_get_active_account (MODEST_WINDOW (parent_win)));
924 account = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
926 if (open_in_editor) {
927 ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
928 const gchar *from_header = NULL;
930 from_header = tny_header_get_from (header);
932 /* we cannot edit without a valid account... */
933 if (!modest_account_mgr_has_accounts(mgr, TRUE)) {
934 if (!modest_ui_actions_run_account_setup_wizard(parent_win))
939 GSList *accounts = modest_account_mgr_account_names (mgr, TRUE);
941 for (node = accounts; node != NULL; node = g_slist_next (node)) {
942 gchar *from = modest_account_mgr_get_from_string (mgr, node->data);
944 if (from && (strcmp (from_header, from) == 0)) {
946 account = g_strdup (node->data);
952 g_slist_foreach (accounts, (GFunc) g_free, NULL);
953 g_slist_free (accounts);
956 win = modest_msg_edit_window_new (msg, account, TRUE);
960 modest_platform_information_banner_with_timeout
961 (NULL, NULL, _("mail_ib_opening_draft_message"), 1200);
964 gchar *uid = modest_tny_folder_get_header_unique_id (header);
966 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
967 GtkWidget *header_view;
968 GtkTreeSelection *sel;
969 GList *sel_list = NULL;
972 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(parent_win),
973 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
975 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
976 sel_list = gtk_tree_selection_get_selected_rows (sel, &model);
978 if (sel_list != NULL) {
979 GtkTreeRowReference *row_reference;
981 row_reference = gtk_tree_row_reference_new (model, (GtkTreePath *) sel_list->data);
982 g_list_foreach (sel_list, (GFunc) gtk_tree_path_free, NULL);
983 g_list_free (sel_list);
985 win = modest_msg_view_window_new_with_header_model (
986 msg, account, (const gchar*) uid,
987 model, row_reference);
988 gtk_tree_row_reference_free (row_reference);
990 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
993 win = modest_msg_view_window_new_for_attachment (msg, account, (const gchar*) uid);
998 /* Register and show new window */
1000 mgr = modest_runtime_get_window_mgr ();
1001 modest_window_mgr_register_window (mgr, win);
1002 g_object_unref (win);
1003 gtk_widget_show_all (GTK_WIDGET(win));
1006 /* Update toolbar dimming state */
1007 if (MODEST_IS_MAIN_WINDOW (parent_win)) {
1008 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (parent_win));
1014 g_object_unref (parent_win);
1015 g_object_unref (folder);
1019 modest_ui_actions_get_msgs_full_error_handler (ModestMailOperation *mail_op,
1022 const GError *error;
1023 GObject *win = NULL;
1024 const gchar *err_msg = (const gchar *) user_data;
1026 win = modest_mail_operation_get_source (mail_op);
1027 error = modest_mail_operation_get_error (mail_op);
1030 modest_platform_run_information_dialog ((GtkWindow *) win, err_msg);
1033 g_object_unref (win);
1037 * Returns the account a list of headers belongs to. It returns a
1038 * *new* reference so don't forget to unref it
1041 get_account_from_header_list (TnyList *headers)
1043 TnyAccount *account = NULL;
1045 if (tny_list_get_length (headers) > 0) {
1046 TnyIterator *iter = tny_list_create_iterator (headers);
1047 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1048 TnyFolder *folder = tny_header_get_folder (header);
1049 account = tny_folder_get_account (folder);
1050 g_object_unref (folder);
1051 g_object_unref (header);
1052 g_object_unref (iter);
1058 foreach_unregister_headers (gpointer data,
1061 ModestWindowMgr *mgr = (ModestWindowMgr *) user_data;
1062 TnyHeader *header = TNY_HEADER (data);
1064 modest_window_mgr_unregister_header (mgr, header);
1068 open_msgs_performer(gboolean canceled,
1070 GtkWindow *parent_window,
1071 TnyAccount *account,
1074 ModestMailOperation *mail_op = NULL;
1075 const gchar *proto_name;
1077 ModestTransportStoreProtocol proto;
1078 TnyList *not_opened_headers;
1079 TnyConnectionStatus status;
1081 not_opened_headers = TNY_LIST (user_data);
1083 status = tny_account_get_connection_status (account);
1084 if (err || canceled) {
1085 /* Unregister the already registered headers */
1086 tny_list_foreach (not_opened_headers, foreach_unregister_headers,
1087 modest_runtime_get_window_mgr ());
1091 /* Get the error message depending on the protocol */
1092 proto_name = tny_account_get_proto (account);
1093 if (proto_name != NULL) {
1094 proto = modest_protocol_info_get_transport_store_protocol (proto_name);
1096 proto = MODEST_PROTOCOL_STORE_MAILDIR;
1099 /* Create the error messages */
1100 if (tny_list_get_length (not_opened_headers) == 1) {
1101 if (proto == MODEST_PROTOCOL_STORE_POP) {
1102 error_msg = g_strdup (_("emev_ni_ui_pop3_msg_recv_error"));
1103 } else if (proto == MODEST_PROTOCOL_STORE_IMAP) {
1104 TnyIterator *iter = tny_list_create_iterator (not_opened_headers);
1105 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter));
1106 error_msg = g_strdup_printf (_("emev_ni_ui_imap_message_not_available_in_server"),
1107 tny_header_get_subject (header));
1108 g_object_unref (header);
1109 g_object_unref (iter);
1111 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1114 error_msg = g_strdup (_("mail_ni_ui_folder_get_msg_folder_error"));
1117 /* Create the mail operation */
1119 modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
1120 modest_ui_actions_get_msgs_full_error_handler,
1122 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
1125 modest_mail_operation_get_msgs_full (mail_op,
1134 g_object_unref (mail_op);
1135 g_object_unref (not_opened_headers);
1136 g_object_unref (account);
1140 * This function is used by both modest_ui_actions_on_open and
1141 * modest_ui_actions_on_header_activated. This way we always do the
1142 * same when trying to open messages.
1145 open_msgs_from_headers (TnyList *headers, ModestWindow *win)
1147 ModestWindowMgr *mgr = NULL;
1148 TnyIterator *iter = NULL, *iter_not_opened = NULL;
1149 TnyList *not_opened_headers = NULL;
1150 TnyHeaderFlags flags = 0;
1151 TnyAccount *account;
1152 gint uncached_msgs = 0;
1154 g_return_if_fail (headers != NULL);
1156 /* Check that only one message is selected for opening */
1157 if (tny_list_get_length (headers) != 1) {
1158 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
1159 _("mcen_ib_select_one_message"));
1163 mgr = modest_runtime_get_window_mgr ();
1164 iter = tny_list_create_iterator (headers);
1166 /* Get the account */
1167 account = get_account_from_header_list (headers);
1169 /* Look if we already have a message view for each header. If
1170 true, then remove the header from the list of headers to
1172 not_opened_headers = tny_simple_list_new ();
1173 while (!tny_iterator_is_done (iter)) {
1175 ModestWindow *window = NULL;
1176 TnyHeader *header = NULL;
1177 gboolean found = FALSE;
1179 header = TNY_HEADER (tny_iterator_get_current (iter));
1181 flags = tny_header_get_flags (header);
1184 found = modest_window_mgr_find_registered_header (mgr, header, &window);
1186 /* Do not open again the message and present the
1187 window to the user */
1190 gtk_window_present (GTK_WINDOW (window));
1192 /* the header has been registered already, we don't do
1193 * anything but wait for the window to come up*/
1194 g_debug ("header %p already registered, waiting for window", header);
1196 tny_list_append (not_opened_headers, G_OBJECT (header));
1200 g_object_unref (header);
1202 tny_iterator_next (iter);
1204 g_object_unref (iter);
1207 /* Open each message */
1208 if (tny_list_get_length (not_opened_headers) == 0)
1211 /* If some messages would have to be downloaded, ask the user to
1212 * make a connection. It's generally easier to do this here (in the mainloop)
1213 * than later in a thread:
1215 if (tny_list_get_length (not_opened_headers) > 0) {
1216 uncached_msgs = header_list_count_uncached_msgs (not_opened_headers);
1218 if (uncached_msgs > 0) {
1219 /* Allways download if we are online. */
1220 if (!tny_device_is_online (modest_runtime_get_device ())) {
1223 /* If ask for user permission to download the messages */
1224 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1225 ngettext("mcen_nc_get_msg",
1229 /* End if the user does not want to continue */
1230 if (response == GTK_RESPONSE_CANCEL)
1236 /* Register the headers before actually creating the windows: */
1237 iter_not_opened = tny_list_create_iterator (not_opened_headers);
1238 while (!tny_iterator_is_done (iter_not_opened)) {
1239 TnyHeader *header = TNY_HEADER (tny_iterator_get_current (iter_not_opened));
1241 modest_window_mgr_register_header (mgr, header, NULL);
1242 g_object_unref (header);
1244 tny_iterator_next (iter_not_opened);
1246 g_object_unref (iter_not_opened);
1247 iter_not_opened = NULL;
1249 /* Connect to the account and perform */
1250 if (uncached_msgs > 0) {
1251 modest_platform_connect_and_perform ((GtkWindow *) win, TRUE, g_object_ref (account),
1252 open_msgs_performer, g_object_ref (not_opened_headers));
1254 /* Call directly the performer, do not need to connect */
1255 open_msgs_performer (FALSE, NULL, (GtkWindow *) win, g_object_ref (account),
1256 g_object_ref (not_opened_headers));
1261 g_object_unref (account);
1262 if (not_opened_headers)
1263 g_object_unref (not_opened_headers);
1267 modest_ui_actions_on_open (GtkAction *action, ModestWindow *win)
1272 headers = get_selected_headers (win);
1277 open_msgs_from_headers (headers, win);
1279 g_object_unref(headers);
1284 free_reply_forward_helper (gpointer data)
1286 ReplyForwardHelper *helper;
1288 helper = (ReplyForwardHelper *) data;
1289 g_free (helper->account_name);
1290 g_slice_free (ReplyForwardHelper, helper);
1294 reply_forward_cb (ModestMailOperation *mail_op,
1302 ReplyForwardHelper *rf_helper;
1303 ModestWindow *msg_win = NULL;
1304 ModestEditType edit_type;
1306 TnyAccount *account = NULL;
1307 ModestWindowMgr *mgr = NULL;
1308 gchar *signature = NULL;
1309 gboolean use_signature;
1311 /* If there was any error. The mail operation could be NULL,
1312 this means that we already have the message downloaded and
1313 that we didn't do a mail operation to retrieve it */
1314 if (mail_op && !modest_ui_actions_msg_retrieval_check (mail_op, header, msg))
1317 g_return_if_fail (user_data != NULL);
1318 rf_helper = (ReplyForwardHelper *) user_data;
1320 from = modest_account_mgr_get_from_string (modest_runtime_get_account_mgr(),
1321 rf_helper->account_name);
1322 signature = modest_account_mgr_get_signature (modest_runtime_get_account_mgr(),
1323 rf_helper->account_name,
1326 /* Create reply mail */
1327 switch (rf_helper->action) {
1330 modest_tny_msg_create_reply_msg (msg, header, from, signature,
1331 rf_helper->reply_forward_type,
1332 MODEST_TNY_MSG_REPLY_MODE_SENDER);
1334 case ACTION_REPLY_TO_ALL:
1336 modest_tny_msg_create_reply_msg (msg, header, from, signature, rf_helper->reply_forward_type,
1337 MODEST_TNY_MSG_REPLY_MODE_ALL);
1338 edit_type = MODEST_EDIT_TYPE_REPLY;
1340 case ACTION_FORWARD:
1342 modest_tny_msg_create_forward_msg (msg, from, signature, rf_helper->reply_forward_type);
1343 edit_type = MODEST_EDIT_TYPE_FORWARD;
1346 g_return_if_reached ();
1353 g_printerr ("modest: failed to create message\n");
1357 account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store(),
1358 rf_helper->account_name,
1359 TNY_ACCOUNT_TYPE_STORE);
1361 g_printerr ("modest: failed to get tnyaccount for '%s'\n", rf_helper->account_name);
1365 /* Create and register the windows */
1366 msg_win = modest_msg_edit_window_new (new_msg, rf_helper->account_name, FALSE);
1367 mgr = modest_runtime_get_window_mgr ();
1368 modest_window_mgr_register_window (mgr, msg_win);
1370 if (rf_helper->parent_window != NULL) {
1371 gdouble parent_zoom;
1373 parent_zoom = modest_window_get_zoom (MODEST_WINDOW (rf_helper->parent_window));
1374 modest_window_set_zoom (msg_win, parent_zoom);
1377 /* Show edit window */
1378 gtk_widget_show_all (GTK_WIDGET (msg_win));
1382 g_object_unref (msg_win);
1384 g_object_unref (G_OBJECT (new_msg));
1386 g_object_unref (G_OBJECT (account));
1387 /* g_object_unref (msg); */
1388 free_reply_forward_helper (rf_helper);
1391 /* Checks a list of headers. If any of them are not currently
1392 * downloaded (CACHED) then returns TRUE else returns FALSE.
1395 header_list_count_uncached_msgs (TnyList *header_list)
1398 gint uncached_messages = 0;
1400 iter = tny_list_create_iterator (header_list);
1401 while (!tny_iterator_is_done (iter)) {
1404 header = TNY_HEADER (tny_iterator_get_current (iter));
1406 if (!(tny_header_get_flags (header) & TNY_HEADER_FLAG_CACHED))
1407 uncached_messages ++;
1408 g_object_unref (header);
1411 tny_iterator_next (iter);
1413 g_object_unref (iter);
1415 return uncached_messages;
1418 /* Returns FALSE if the user does not want to download the
1419 * messages. Returns TRUE if the user allowed the download.
1422 connect_to_get_msg (ModestWindow *win,
1423 gint num_of_uncached_msgs,
1424 TnyAccount *account)
1426 GtkResponseType response;
1428 /* Allways download if we are online. */
1429 if (tny_device_is_online (modest_runtime_get_device ()))
1432 /* If offline, then ask for user permission to download the messages */
1433 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
1434 ngettext("mcen_nc_get_msg",
1436 num_of_uncached_msgs));
1438 if (response == GTK_RESPONSE_CANCEL)
1441 return modest_platform_connect_and_wait((GtkWindow *) win, account);
1445 * Common code for the reply and forward actions
1448 reply_forward (ReplyForwardAction action, ModestWindow *win)
1450 ModestMailOperation *mail_op = NULL;
1451 TnyList *header_list = NULL;
1452 ReplyForwardHelper *rf_helper = NULL;
1453 guint reply_forward_type;
1454 gboolean continue_download = TRUE;
1455 gboolean do_retrieve = TRUE;
1457 g_return_if_fail (MODEST_IS_WINDOW(win));
1459 /* we need an account when editing */
1460 if (!modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE)) {
1461 if (!modest_ui_actions_run_account_setup_wizard (win))
1465 header_list = get_selected_headers (win);
1469 reply_forward_type =
1470 modest_conf_get_int (modest_runtime_get_conf (),
1471 (action == ACTION_FORWARD) ? MODEST_CONF_FORWARD_TYPE : MODEST_CONF_REPLY_TYPE,
1474 /* check if we need to download msg before asking about it */
1475 do_retrieve = (action == ACTION_FORWARD) ||
1476 (reply_forward_type != MODEST_TNY_MSG_REPLY_TYPE_CITE);
1479 gint num_of_unc_msgs;
1481 /* check that the messages have been previously downloaded */
1482 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
1483 /* If there are any uncached message ask the user
1484 * whether he/she wants to download them. */
1485 if (num_of_unc_msgs) {
1486 TnyAccount *account = get_account_from_header_list (header_list);
1487 continue_download = connect_to_get_msg (win, num_of_unc_msgs, account);
1488 g_object_unref (account);
1492 if (!continue_download) {
1493 g_object_unref (header_list);
1497 /* We assume that we can only select messages of the
1498 same folder and that we reply all of them from the
1499 same account. In fact the interface currently only
1500 allows single selection */
1503 rf_helper = g_slice_new0 (ReplyForwardHelper);
1504 rf_helper->reply_forward_type = reply_forward_type;
1505 rf_helper->action = action;
1506 rf_helper->account_name = g_strdup (modest_window_get_active_account (win));
1508 if ((win != NULL) && (MODEST_IS_WINDOW (win)))
1509 rf_helper->parent_window = GTK_WIDGET (win);
1510 if (!rf_helper->account_name)
1511 rf_helper->account_name =
1512 modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1514 if (MODEST_IS_MSG_VIEW_WINDOW(win)) {
1517 /* Get header and message. Do not free them here, the
1518 reply_forward_cb must do it */
1519 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW(win));
1520 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW(win));
1521 if (!msg || !header) {
1523 g_object_unref (msg);
1524 g_printerr ("modest: no message found\n");
1527 reply_forward_cb (NULL, header, FALSE, msg, NULL, rf_helper);
1530 g_object_unref (header);
1535 /* Only reply/forward to one message */
1536 iter = tny_list_create_iterator (header_list);
1537 header = TNY_HEADER (tny_iterator_get_current (iter));
1538 g_object_unref (iter);
1541 /* Retrieve messages */
1544 modest_mail_operation_new_with_error_handling (G_OBJECT(win),
1545 modest_ui_actions_get_msgs_full_error_handler,
1547 modest_mail_operation_queue_add (
1548 modest_runtime_get_mail_operation_queue (), mail_op);
1550 modest_mail_operation_get_msg (mail_op,
1555 g_object_unref(mail_op);
1557 /* we put a ref here to prevent double unref as the reply
1558 * forward callback unrefs the header at its end */
1559 reply_forward_cb (NULL, header, FALSE, NULL, NULL, rf_helper);
1563 g_object_unref (header);
1569 g_object_unref (header_list);
1573 modest_ui_actions_on_reply (GtkAction *action, ModestWindow *win)
1575 g_return_if_fail (MODEST_IS_WINDOW(win));
1577 reply_forward (ACTION_REPLY, win);
1581 modest_ui_actions_on_forward (GtkAction *action, ModestWindow *win)
1583 g_return_if_fail (MODEST_IS_WINDOW(win));
1585 reply_forward (ACTION_FORWARD, win);
1589 modest_ui_actions_on_reply_all (GtkAction *action, ModestWindow *win)
1591 g_return_if_fail (MODEST_IS_WINDOW(win));
1593 reply_forward (ACTION_REPLY_TO_ALL, win);
1597 modest_ui_actions_on_next (GtkAction *action,
1598 ModestWindow *window)
1600 if (MODEST_IS_MAIN_WINDOW (window)) {
1601 GtkWidget *header_view;
1603 header_view = modest_main_window_get_child_widget (
1604 MODEST_MAIN_WINDOW(window),
1605 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1609 modest_header_view_select_next (
1610 MODEST_HEADER_VIEW(header_view));
1611 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1612 modest_msg_view_window_select_next_message (
1613 MODEST_MSG_VIEW_WINDOW (window));
1615 g_return_if_reached ();
1620 modest_ui_actions_on_prev (GtkAction *action,
1621 ModestWindow *window)
1623 g_return_if_fail (MODEST_IS_WINDOW(window));
1625 if (MODEST_IS_MAIN_WINDOW (window)) {
1626 GtkWidget *header_view;
1627 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1628 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1632 modest_header_view_select_prev (MODEST_HEADER_VIEW(header_view));
1633 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
1634 modest_msg_view_window_select_previous_message (MODEST_MSG_VIEW_WINDOW (window));
1636 g_return_if_reached ();
1641 modest_ui_actions_on_sort (GtkAction *action,
1642 ModestWindow *window)
1644 g_return_if_fail (MODEST_IS_WINDOW(window));
1646 if (MODEST_IS_MAIN_WINDOW (window)) {
1647 GtkWidget *header_view;
1648 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(window),
1649 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1651 modest_platform_information_banner (NULL, NULL, _CS("ckdg_ib_nothing_to_sort"));
1656 /* Show sorting dialog */
1657 modest_platform_run_sort_dialog (GTK_WINDOW (window), MODEST_SORT_HEADERS);
1662 new_messages_arrived (ModestMailOperation *self,
1663 TnyList *new_headers,
1667 gboolean show_visual_notifications;
1669 source = modest_mail_operation_get_source (self);
1670 show_visual_notifications = (source) ? FALSE : TRUE;
1672 g_object_unref (source);
1674 /* Notify new messages have been downloaded. If the
1675 send&receive was invoked by the user then do not show any
1676 visual notification, only play a sound and activate the LED
1677 (for the Maemo version) */
1678 if (TNY_IS_LIST(new_headers) && (tny_list_get_length (new_headers)) > 0)
1679 modest_platform_on_new_headers_received (new_headers,
1680 show_visual_notifications);
1685 retrieve_all_messages_cb (GObject *source,
1687 guint retrieve_limit)
1693 window = GTK_WINDOW (source);
1694 msg = g_strdup_printf (_("mail_nc_msg_count_limit_exceeded"),
1695 num_msgs, retrieve_limit);
1697 /* Ask the user if they want to retrieve all the messages */
1699 modest_platform_run_confirmation_dialog_with_buttons (window, msg,
1700 _("mcen_bd_get_all"),
1701 _("mcen_bd_newest_only"));
1702 /* Free and return */
1704 return (response == GTK_RESPONSE_ACCEPT) ? TRUE : FALSE;
1708 TnyAccount *account;
1710 gchar *account_name;
1714 do_send_receive_performer (gboolean canceled,
1716 GtkWindow *parent_window,
1717 TnyAccount *account,
1720 ModestMailOperation *mail_op;
1721 SendReceiveInfo *info;
1723 info = (SendReceiveInfo *) user_data;
1725 if (err || canceled) {
1729 /* Set send/receive operation in progress */
1730 if (info->win && MODEST_IS_MAIN_WINDOW (info->win)) {
1731 modest_main_window_notify_send_receive_initied (MODEST_MAIN_WINDOW (info->win));
1734 mail_op = modest_mail_operation_new_with_error_handling ((info->win) ? G_OBJECT (info->win) : NULL,
1735 modest_ui_actions_send_receive_error_handler,
1738 if (info->win && MODEST_IS_MAIN_WINDOW (info->win))
1739 g_signal_connect (G_OBJECT(mail_op), "operation-finished",
1740 G_CALLBACK (on_send_receive_finished),
1743 /* Send & receive. */
1744 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
1745 modest_mail_operation_update_account (mail_op, info->account_name, (info->win) ? FALSE : TRUE,
1746 (info->win) ? retrieve_all_messages_cb : NULL,
1747 new_messages_arrived, info->win);
1748 g_object_unref (G_OBJECT (mail_op));
1752 if (info->account_name)
1753 g_free (info->account_name);
1755 g_object_unref (info->win);
1757 g_object_unref (info->account);
1758 g_slice_free (SendReceiveInfo, info);
1762 * This function performs the send & receive required actions. The
1763 * window is used to create the mail operation. Typically it should
1764 * always be the main window, but we pass it as argument in order to
1768 modest_ui_actions_do_send_receive (const gchar *account_name,
1769 gboolean force_connection,
1772 gchar *acc_name = NULL;
1773 SendReceiveInfo *info;
1774 ModestTnyAccountStore *acc_store;
1776 /* If no account name was provided then get the current account, and if
1777 there is no current account then pick the default one: */
1778 if (!account_name) {
1780 acc_name = g_strdup (modest_window_get_active_account (win));
1782 acc_name = modest_account_mgr_get_default_account (modest_runtime_get_account_mgr());
1784 g_printerr ("modest: cannot get default account\n");
1788 acc_name = g_strdup (account_name);
1791 acc_store = modest_runtime_get_account_store ();
1793 /* Create the info for the connect and perform */
1794 info = g_slice_new (SendReceiveInfo);
1795 info->account_name = acc_name;
1796 info->win = (win) ? g_object_ref (win) : NULL;
1797 info->account = modest_tny_account_store_get_server_account (acc_store, acc_name,
1798 TNY_ACCOUNT_TYPE_STORE);
1800 /* Invoke the connect and perform */
1801 modest_platform_connect_and_perform ((win) ? GTK_WINDOW (win) : NULL,
1802 force_connection, info->account,
1803 do_send_receive_performer, info);
1808 modest_ui_actions_do_cancel_send (const gchar *account_name,
1811 TnyTransportAccount *transport_account;
1812 TnySendQueue *send_queue = NULL;
1813 GError *error = NULL;
1815 /* Get transport account */
1817 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
1818 (modest_runtime_get_account_store(),
1820 TNY_ACCOUNT_TYPE_TRANSPORT));
1821 if (!transport_account) {
1822 g_printerr ("modest: no transport account found for '%s'\n", account_name);
1827 send_queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (transport_account));
1828 if (!TNY_IS_SEND_QUEUE(send_queue)) {
1829 g_set_error (&error, MODEST_MAIL_OPERATION_ERROR,
1830 MODEST_MAIL_OPERATION_ERROR_ITEM_NOT_FOUND,
1831 "modest: could not find send queue for account\n");
1833 /* Keeep messages in outbox folder */
1834 tny_send_queue_cancel (send_queue, FALSE, &error);
1838 if (transport_account != NULL)
1839 g_object_unref (G_OBJECT (transport_account));
1843 modest_ui_actions_cancel_send_all (ModestWindow *win)
1845 GSList *account_names, *iter;
1847 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1850 iter = account_names;
1852 modest_ui_actions_do_cancel_send ((const char*) iter->data, win);
1853 iter = g_slist_next (iter);
1856 modest_account_mgr_free_account_names (account_names);
1857 account_names = NULL;
1861 modest_ui_actions_cancel_send (GtkAction *action, ModestWindow *win)
1864 /* Check if accounts exist */
1865 gboolean accounts_exist =
1866 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1868 /* If not, allow the user to create an account before trying to send/receive. */
1869 if (!accounts_exist)
1870 modest_ui_actions_on_accounts (NULL, win);
1872 /* Cancel all sending operaitons */
1873 modest_ui_actions_cancel_send_all (win);
1877 * Refreshes all accounts. This function will be used by automatic
1881 modest_ui_actions_do_send_receive_all (ModestWindow *win,
1882 gboolean force_connection)
1884 GSList *account_names, *iter;
1886 account_names = modest_account_mgr_account_names (modest_runtime_get_account_mgr(),
1889 iter = account_names;
1891 modest_ui_actions_do_send_receive ((const char*) iter->data, force_connection, win);
1892 iter = g_slist_next (iter);
1895 modest_account_mgr_free_account_names (account_names);
1896 account_names = NULL;
1900 * Handler of the click on Send&Receive button in the main toolbar
1903 modest_ui_actions_on_send_receive (GtkAction *action, ModestWindow *win)
1905 /* Check if accounts exist */
1906 gboolean accounts_exist;
1909 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
1911 /* If not, allow the user to create an account before trying to send/receive. */
1912 if (!accounts_exist)
1913 modest_ui_actions_on_accounts (NULL, win);
1915 /* Refresh the current folder. The if is always TRUE it's just an extra check */
1916 if (MODEST_IS_MAIN_WINDOW (win)) {
1917 GtkWidget *folder_view;
1918 TnyFolderStore *folder_store;
1921 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
1922 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1926 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
1929 g_object_unref (folder_store);
1932 /* Refresh the active account. Force the connection if needed */
1933 modest_ui_actions_do_send_receive (NULL, TRUE, win);
1938 modest_ui_actions_toggle_header_list_view (GtkAction *action, ModestMainWindow *main_window)
1941 GtkWidget *header_view;
1943 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1945 header_view = modest_main_window_get_child_widget (main_window,
1946 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
1950 conf = modest_runtime_get_conf ();
1952 /* what is saved/restored is depending on the style; thus; we save with
1953 * old style, then update the style, and restore for this new style
1955 modest_widget_memory_save (conf, G_OBJECT(header_view), MODEST_CONF_HEADER_VIEW_KEY);
1957 if (modest_header_view_get_style
1958 (MODEST_HEADER_VIEW(header_view)) == MODEST_HEADER_VIEW_STYLE_DETAILS)
1959 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1960 MODEST_HEADER_VIEW_STYLE_TWOLINES);
1962 modest_header_view_set_style (MODEST_HEADER_VIEW(header_view),
1963 MODEST_HEADER_VIEW_STYLE_DETAILS);
1965 modest_widget_memory_restore (conf, G_OBJECT(header_view),
1966 MODEST_CONF_HEADER_VIEW_KEY);
1971 modest_ui_actions_on_header_selected (ModestHeaderView *header_view,
1973 ModestMainWindow *main_window)
1975 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
1976 g_return_if_fail (MODEST_IS_HEADER_VIEW (header_view));
1978 /* in the case the folder is empty, show the empty folder message and focus
1980 if (!header && gtk_widget_is_focus (GTK_WIDGET (header_view))) {
1981 if (modest_header_view_is_empty (header_view)) {
1982 TnyFolder *folder = modest_header_view_get_folder (header_view);
1983 GtkWidget *folder_view =
1984 modest_main_window_get_child_widget (main_window,
1985 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
1987 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view), folder, FALSE);
1988 gtk_widget_grab_focus (GTK_WIDGET (folder_view));
1992 /* If no header has been selected then exit */
1997 if (!gtk_widget_is_focus (GTK_WIDGET(header_view)))
1998 gtk_widget_grab_focus (GTK_WIDGET(header_view));
2000 /* Update toolbar dimming state */
2001 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2005 modest_ui_actions_on_header_activated (ModestHeaderView *header_view,
2007 ModestMainWindow *main_window)
2011 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2016 if (modest_header_view_count_selected_headers (header_view) > 1) {
2017 modest_platform_information_banner (NULL, NULL, _("mcen_ib_select_one_message"));
2022 /* headers = tny_simple_list_new (); */
2023 /* tny_list_prepend (headers, G_OBJECT (header)); */
2024 headers = modest_header_view_get_selected_headers (header_view);
2026 open_msgs_from_headers (headers, MODEST_WINDOW (main_window));
2028 g_object_unref (headers);
2032 set_active_account_from_tny_account (TnyAccount *account,
2033 ModestWindow *window)
2035 const gchar *server_acc_name = tny_account_get_id (account);
2037 /* We need the TnyAccount provided by the
2038 account store because that is the one that
2039 knows the name of the Modest account */
2040 TnyAccount *modest_server_account = modest_server_account =
2041 modest_tny_account_store_get_tny_account_by (modest_runtime_get_account_store (),
2042 MODEST_TNY_ACCOUNT_STORE_QUERY_ID,
2044 if (!modest_server_account) {
2045 g_warning ("%s: could not get tny account\n", __FUNCTION__);
2049 /* Update active account, but only if it's not a pseudo-account */
2050 if ((!modest_tny_account_is_virtual_local_folders(modest_server_account)) &&
2051 (!modest_tny_account_is_memory_card_account(modest_server_account))) {
2052 const gchar *modest_acc_name =
2053 modest_tny_account_get_parent_modest_account_name_for_server_account (modest_server_account);
2054 if (modest_acc_name)
2055 modest_window_set_active_account (window, modest_acc_name);
2058 g_object_unref (modest_server_account);
2063 folder_refreshed_cb (ModestMailOperation *mail_op,
2067 ModestMainWindow *win = NULL;
2068 GtkWidget *header_view;
2070 g_return_if_fail (TNY_IS_FOLDER (folder));
2072 win = MODEST_MAIN_WINDOW (user_data);
2074 modest_main_window_get_child_widget(win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2077 TnyFolder *current_folder;
2079 current_folder = modest_header_view_get_folder (MODEST_HEADER_VIEW (header_view));
2080 if (current_folder != NULL && folder != current_folder) {
2081 g_object_unref (current_folder);
2083 } else if (current_folder)
2084 g_object_unref (current_folder);
2087 /* Check if folder is empty and set headers view contents style */
2088 if (tny_folder_get_all_count (folder) == 0)
2089 modest_main_window_set_contents_style (win,
2090 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
2094 modest_ui_actions_on_folder_selection_changed (ModestFolderView *folder_view,
2095 TnyFolderStore *folder_store,
2097 ModestMainWindow *main_window)
2100 GtkWidget *header_view;
2102 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2104 header_view = modest_main_window_get_child_widget(main_window,
2105 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2109 conf = modest_runtime_get_conf ();
2111 if (TNY_IS_ACCOUNT (folder_store)) {
2113 set_active_account_from_tny_account (TNY_ACCOUNT (folder_store), MODEST_WINDOW (main_window));
2115 /* Show account details */
2116 modest_main_window_set_contents_style (main_window, MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS);
2119 if (TNY_IS_FOLDER (folder_store) && selected) {
2121 /* Update the active account */
2122 TnyAccount *account = modest_tny_folder_get_account (TNY_FOLDER (folder_store));
2124 set_active_account_from_tny_account (account, MODEST_WINDOW (main_window));
2125 g_object_unref (account);
2129 /* Set the header style by default, it could
2130 be changed later by the refresh callback to
2132 modest_main_window_set_contents_style (main_window,
2133 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
2135 /* Set folder on header view. This function
2136 will call tny_folder_refresh_async so we
2137 pass a callback that will be called when
2138 finished. We use that callback to set the
2139 empty view if there are no messages */
2140 modest_header_view_set_folder (MODEST_HEADER_VIEW(header_view),
2141 TNY_FOLDER (folder_store),
2142 folder_refreshed_cb,
2145 /* Restore configuration. We need to do this
2146 *after* the set_folder because the widget
2147 memory asks the header view about its
2149 modest_widget_memory_restore (modest_runtime_get_conf (),
2150 G_OBJECT(header_view),
2151 MODEST_CONF_HEADER_VIEW_KEY);
2153 /* Update the active account */
2154 //modest_window_set_active_account (MODEST_WINDOW (main_window), NULL);
2155 /* Save only if we're seeing headers */
2156 if (modest_main_window_get_contents_style (main_window) ==
2157 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
2158 modest_widget_memory_save (conf, G_OBJECT (header_view),
2159 MODEST_CONF_HEADER_VIEW_KEY);
2160 modest_header_view_clear (MODEST_HEADER_VIEW(header_view));
2164 /* Update toolbar dimming state */
2165 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (main_window));
2169 modest_ui_actions_on_item_not_found (ModestHeaderView *header_view,ModestItemType type,
2176 item = (type == MODEST_ITEM_TYPE_FOLDER) ? "folder" : "message";
2178 online = tny_device_is_online (modest_runtime_get_device());
2181 /* already online -- the item is simply not there... */
2182 dialog = gtk_message_dialog_new (GTK_WINDOW (win),
2184 GTK_MESSAGE_WARNING,
2186 _("The %s you selected cannot be found"),
2188 gtk_dialog_add_button (GTK_DIALOG (dialog),_("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
2189 gtk_dialog_run (GTK_DIALOG(dialog));
2191 dialog = gtk_dialog_new_with_buttons (_("Connection requested"),
2194 _("mcen_bd_dialog_cancel"),
2195 GTK_RESPONSE_REJECT,
2196 _("mcen_bd_dialog_ok"),
2197 GTK_RESPONSE_ACCEPT,
2199 txt = g_strdup_printf (_("This %s is not available in offline mode.\n"
2200 "Do you want to get online?"), item);
2201 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
2202 gtk_label_new (txt), FALSE, FALSE, 0);
2203 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
2206 gtk_window_set_default_size (GTK_WINDOW(dialog), 300, 300);
2207 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
2208 /* TODO: Comment about why is this commented out: */
2209 /* modest_platform_connect_and_wait (); */
2212 gtk_widget_destroy (dialog);
2216 modest_ui_actions_on_msg_link_hover (ModestMsgView *msgview, const gchar* link,
2219 /* g_message ("%s %s", __FUNCTION__, link); */
2224 modest_ui_actions_on_msg_link_clicked (ModestMsgView *msgview, const gchar* link,
2227 modest_platform_activate_uri (link);
2231 modest_ui_actions_on_msg_link_contextual (ModestMsgView *msgview, const gchar* link,
2234 modest_platform_show_uri_popup (link);
2238 modest_ui_actions_on_msg_attachment_clicked (ModestMsgView *msgview, TnyMimePart *mime_part,
2241 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (win), mime_part);
2245 modest_ui_actions_on_msg_recpt_activated (ModestMsgView *msgview,
2246 const gchar *address,
2249 /* g_message ("%s %s", __FUNCTION__, address); */
2253 on_save_to_drafts_cb (ModestMailOperation *mail_op,
2254 TnyMsg *saved_draft,
2257 ModestMsgEditWindow *edit_window;
2258 ModestMainWindow *win;
2260 /* FIXME. Make the header view sensitive again. This is a
2261 * temporary hack. See modest_ui_actions_on_save_to_drafts()
2263 win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2264 modest_runtime_get_window_mgr(), FALSE));
2266 GtkWidget *hdrview = modest_main_window_get_child_widget(
2267 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2268 if (hdrview) gtk_widget_set_sensitive(hdrview, TRUE);
2271 edit_window = MODEST_MSG_EDIT_WINDOW (user_data);
2273 /* It might not be a good idea to do nothing if there was an error,
2274 * so let's at least show a generic error banner. */
2275 /* TODO error while saving attachment, show "Saving draft failed" banner */
2276 if (modest_mail_operation_get_error (mail_op) != NULL) {
2277 g_warning ("%s failed: %s\n", __FUNCTION__, (modest_mail_operation_get_error (mail_op))->message);
2278 modest_platform_information_banner (NULL, NULL, _("mail_ib_file_operation_failed"));
2280 modest_msg_edit_window_set_draft (edit_window, saved_draft);
2282 g_object_unref(edit_window);
2286 modest_ui_actions_on_save_to_drafts (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2288 TnyTransportAccount *transport_account;
2289 ModestMailOperation *mail_operation;
2291 gchar *account_name, *from;
2292 ModestAccountMgr *account_mgr;
2295 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2297 data = modest_msg_edit_window_get_msg_data (edit_window);
2299 account_name = g_strdup (data->account_name);
2300 account_mgr = modest_runtime_get_account_mgr();
2302 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2304 account_name = modest_account_mgr_get_default_account (account_mgr);
2305 if (!account_name) {
2306 g_printerr ("modest: no account found\n");
2307 modest_msg_edit_window_free_msg_data (edit_window, data);
2311 if (!strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
2312 account_name = g_strdup (data->account_name);
2316 TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2317 (modest_runtime_get_account_store(),
2319 TNY_ACCOUNT_TYPE_TRANSPORT));
2320 if (!transport_account) {
2321 g_printerr ("modest: no transport account found for '%s'\n", account_name);
2322 g_free (account_name);
2323 modest_msg_edit_window_free_msg_data (edit_window, data);
2326 from = modest_account_mgr_get_from_string (account_mgr, account_name);
2328 /* Create the mail operation */
2329 mail_operation = modest_mail_operation_new (NULL);
2330 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2332 modest_mail_operation_save_to_drafts (mail_operation,
2344 data->priority_flags,
2345 on_save_to_drafts_cb,
2346 g_object_ref(edit_window));
2347 info_text = g_strdup_printf (_("mail_va_saved_to_drafts"), _("mcen_me_folder_drafts"));
2348 modest_platform_information_banner (NULL, NULL, info_text);
2353 g_free (account_name);
2354 g_object_unref (G_OBJECT (transport_account));
2355 g_object_unref (G_OBJECT (mail_operation));
2357 modest_msg_edit_window_free_msg_data (edit_window, data);
2358 modest_msg_edit_window_reset_modified (edit_window);
2361 * If the drafts folder is selected then make the header view
2362 * insensitive while the message is being saved to drafts
2363 * (it'll be sensitive again in on_save_to_drafts_cb()). This
2364 * is not very clean but it avoids letting the drafts folder
2365 * in an inconsistent state: the user could edit the message
2366 * being saved and undesirable things would happen.
2367 * In the average case the user won't notice anything at
2368 * all. In the worst case (the user is editing a really big
2369 * file from Drafts) the header view will be insensitive
2370 * during the saving process (10 or 20 seconds, depending on
2371 * the message). Anyway this is just a quick workaround: once
2372 * we find a better solution it should be removed
2373 * See NB#65125 (commend #18) for details.
2375 ModestMainWindow *win = MODEST_MAIN_WINDOW(modest_window_mgr_get_main_window(
2376 modest_runtime_get_window_mgr(), FALSE));
2378 ModestFolderView *view = MODEST_FOLDER_VIEW(modest_main_window_get_child_widget(
2379 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW));
2381 TnyFolder *folder = TNY_FOLDER(modest_folder_view_get_selected(view));
2383 if (modest_tny_folder_is_local_folder(folder)) {
2384 TnyFolderType folder_type;
2385 folder_type = modest_tny_folder_get_local_or_mmc_folder_type(folder);
2386 if (folder_type == TNY_FOLDER_TYPE_DRAFTS) {
2387 GtkWidget *hdrview = modest_main_window_get_child_widget(
2388 win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2389 if (hdrview) gtk_widget_set_sensitive(hdrview, FALSE);
2393 if (folder != NULL) g_object_unref(folder);
2398 /* For instance, when clicking the Send toolbar button when editing a message: */
2400 modest_ui_actions_on_send (GtkWidget *widget, ModestMsgEditWindow *edit_window)
2402 TnyTransportAccount *transport_account = NULL;
2404 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW(edit_window));
2406 if (!modest_msg_edit_window_check_names (edit_window, TRUE))
2409 /* FIXME: Code added just for testing. The final version will
2410 use the send queue provided by tinymail and some
2412 MsgData *data = modest_msg_edit_window_get_msg_data (edit_window);
2414 ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr();
2415 gchar *account_name = g_strdup (data->account_name);
2417 account_name = g_strdup(modest_window_get_active_account (MODEST_WINDOW(edit_window)));
2420 account_name = modest_account_mgr_get_default_account (account_mgr);
2422 if (!account_name) {
2423 modest_msg_edit_window_free_msg_data (edit_window, data);
2424 /* Run account setup wizard */
2425 if (!modest_ui_actions_run_account_setup_wizard (MODEST_WINDOW(edit_window))) {
2430 /* Get the currently-active transport account for this modest account: */
2431 if (strcmp (account_name, MODEST_LOCAL_FOLDERS_ACCOUNT_ID) != 0) {
2432 transport_account = TNY_TRANSPORT_ACCOUNT(modest_tny_account_store_get_server_account
2433 (modest_runtime_get_account_store(),
2434 account_name, TNY_ACCOUNT_TYPE_TRANSPORT));
2437 if (!transport_account) {
2438 modest_msg_edit_window_free_msg_data (edit_window, data);
2439 /* Run account setup wizard */
2440 if (!modest_ui_actions_run_account_setup_wizard(MODEST_WINDOW(edit_window)))
2444 gchar *from = modest_account_mgr_get_from_string (account_mgr, account_name);
2446 /* Create the mail operation */
2447 ModestMailOperation *mail_operation = modest_mail_operation_new (NULL);
2448 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_operation);
2450 modest_mail_operation_send_new_mail (mail_operation,
2462 data->priority_flags);
2464 if (modest_mail_operation_get_status (mail_operation) == MODEST_MAIL_OPERATION_STATUS_IN_PROGRESS)
2465 modest_platform_information_banner (NULL, NULL, _("mcen_ib_outbox_waiting_to_be_sent"));
2470 g_free (account_name);
2471 g_object_unref (G_OBJECT (transport_account));
2472 g_object_unref (G_OBJECT (mail_operation));
2474 modest_msg_edit_window_free_msg_data (edit_window, data);
2475 modest_msg_edit_window_set_sent (edit_window, TRUE);
2477 /* Save settings and close the window: */
2478 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (edit_window));
2482 modest_ui_actions_on_toggle_bold (GtkToggleAction *action,
2483 ModestMsgEditWindow *window)
2485 ModestMsgEditFormatState *format_state = NULL;
2487 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2488 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2490 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2493 format_state = modest_msg_edit_window_get_format_state (window);
2494 g_return_if_fail (format_state != NULL);
2496 format_state->bold = gtk_toggle_action_get_active (action);
2497 modest_msg_edit_window_set_format_state (window, format_state);
2498 g_free (format_state);
2503 modest_ui_actions_on_toggle_italics (GtkToggleAction *action,
2504 ModestMsgEditWindow *window)
2506 ModestMsgEditFormatState *format_state = NULL;
2508 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2509 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2511 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2514 format_state = modest_msg_edit_window_get_format_state (window);
2515 g_return_if_fail (format_state != NULL);
2517 format_state->italics = gtk_toggle_action_get_active (action);
2518 modest_msg_edit_window_set_format_state (window, format_state);
2519 g_free (format_state);
2524 modest_ui_actions_on_toggle_bullets (GtkToggleAction *action,
2525 ModestMsgEditWindow *window)
2527 ModestMsgEditFormatState *format_state = NULL;
2529 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2530 g_return_if_fail (GTK_IS_TOGGLE_ACTION (action));
2532 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW (window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2535 format_state = modest_msg_edit_window_get_format_state (window);
2536 g_return_if_fail (format_state != NULL);
2538 format_state->bullet = gtk_toggle_action_get_active (action);
2539 modest_msg_edit_window_set_format_state (window, format_state);
2540 g_free (format_state);
2545 modest_ui_actions_on_change_justify (GtkRadioAction *action,
2546 GtkRadioAction *selected,
2547 ModestMsgEditWindow *window)
2549 ModestMsgEditFormatState *format_state = NULL;
2550 GtkJustification value;
2552 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2554 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2557 value = gtk_radio_action_get_current_value (selected);
2559 format_state = modest_msg_edit_window_get_format_state (window);
2560 g_return_if_fail (format_state != NULL);
2562 format_state->justification = value;
2563 modest_msg_edit_window_set_format_state (window, format_state);
2564 g_free (format_state);
2568 modest_ui_actions_on_select_editor_color (GtkAction *action,
2569 ModestMsgEditWindow *window)
2571 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2572 g_return_if_fail (GTK_IS_ACTION (action));
2574 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2577 modest_msg_edit_window_select_color (window);
2581 modest_ui_actions_on_select_editor_background_color (GtkAction *action,
2582 ModestMsgEditWindow *window)
2584 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2585 g_return_if_fail (GTK_IS_ACTION (action));
2587 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2590 modest_msg_edit_window_select_background_color (window);
2594 modest_ui_actions_on_insert_image (GtkAction *action,
2595 ModestMsgEditWindow *window)
2597 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2598 g_return_if_fail (GTK_IS_ACTION (action));
2600 if (modest_msg_edit_window_get_format (MODEST_MSG_EDIT_WINDOW(window)) == MODEST_MSG_EDIT_FORMAT_TEXT)
2603 modest_msg_edit_window_insert_image (window);
2607 modest_ui_actions_on_attach_file (GtkAction *action,
2608 ModestMsgEditWindow *window)
2610 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2611 g_return_if_fail (GTK_IS_ACTION (action));
2613 modest_msg_edit_window_offer_attach_file (window);
2617 modest_ui_actions_on_remove_attachments (GtkAction *action,
2618 ModestMsgEditWindow *window)
2620 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
2621 g_return_if_fail (GTK_IS_ACTION (action));
2623 modest_msg_edit_window_remove_attachments (window, NULL);
2627 do_create_folder_cb (ModestMailOperation *mail_op,
2628 TnyFolderStore *parent_folder,
2629 TnyFolder *new_folder,
2632 gchar *suggested_name = (gchar *) user_data;
2633 GtkWindow *source_win = (GtkWindow *) modest_mail_operation_get_source (mail_op);
2635 if (modest_mail_operation_get_error (mail_op)) {
2637 modest_platform_information_banner (GTK_WIDGET (source_win), NULL,
2638 _("mail_in_ui_folder_create_error"));
2641 do_create_folder (source_win, parent_folder, (const gchar *) suggested_name);
2643 /* the 'source_win' is either the ModestMainWindow, or the 'Move to folder'-dialog
2644 * FIXME: any other? */
2645 GtkWidget *folder_view;
2647 if (MODEST_IS_MAIN_WINDOW(source_win))
2649 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (source_win),
2650 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2653 get_folder_view_from_move_to_dialog (GTK_WIDGET(source_win));
2655 /* Select the newly created folder */
2656 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
2658 g_object_unref (new_folder);
2660 /* Free. Note that the first time it'll be NULL so noop */
2661 g_free (suggested_name);
2662 g_object_unref (source_win);
2666 do_create_folder (GtkWindow *parent_window,
2667 TnyFolderStore *parent_folder,
2668 const gchar *suggested_name)
2671 gchar *folder_name = NULL;
2673 result = modest_platform_run_new_folder_dialog (GTK_WINDOW (parent_window),
2675 (gchar *) suggested_name,
2678 if (result == GTK_RESPONSE_ACCEPT) {
2679 ModestMailOperation *mail_op;
2681 mail_op = modest_mail_operation_new (G_OBJECT(parent_window));
2683 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2685 modest_mail_operation_create_folder (mail_op,
2687 (const gchar *) folder_name,
2688 do_create_folder_cb,
2690 g_object_unref (mail_op);
2695 create_folder_performer (gboolean canceled,
2697 GtkWindow *parent_window,
2698 TnyAccount *account,
2701 TnyFolderStore *parent_folder = TNY_FOLDER_STORE (user_data);
2703 if (canceled || err) {
2707 /* Run the new folder dialog */
2708 do_create_folder (GTK_WINDOW (parent_window), parent_folder, NULL);
2711 g_object_unref (parent_folder);
2715 modest_ui_actions_create_folder(GtkWidget *parent_window,
2716 GtkWidget *folder_view)
2718 TnyFolderStore *parent_folder;
2720 parent_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2722 if (parent_folder) {
2723 /* The parent folder will be freed in the callback */
2724 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (parent_window),
2727 create_folder_performer,
2733 modest_ui_actions_on_new_folder (GtkAction *action, ModestMainWindow *main_window)
2735 GtkWidget *folder_view;
2737 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2739 folder_view = modest_main_window_get_child_widget (main_window,
2740 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2744 modest_ui_actions_create_folder (GTK_WIDGET (main_window), folder_view);
2748 modest_ui_actions_rename_folder_error_handler (ModestMailOperation *mail_op,
2751 ModestMainWindow *window = MODEST_MAIN_WINDOW (user_data);
2752 const GError *error = NULL;
2753 const gchar *message = NULL;
2755 /* Get error message */
2756 error = modest_mail_operation_get_error (mail_op);
2758 g_return_if_reached ();
2760 switch (error->code) {
2761 case MODEST_MAIL_OPERATION_ERROR_FOLDER_EXISTS:
2762 message = _CS("ckdg_ib_folder_already_exists");
2765 g_warning ("%s: BUG: unexpected error:[%d]: %s", __FUNCTION__,
2766 error->code, error->message);
2770 modest_platform_information_banner (GTK_WIDGET (window), NULL, message);
2774 TnyFolderStore *folder;
2779 on_rename_folder_cb (ModestMailOperation *mail_op,
2780 TnyFolder *new_folder,
2784 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (user_data),
2789 on_rename_folder_performer (gboolean canceled,
2791 GtkWindow *parent_window,
2792 TnyAccount *account,
2795 ModestMailOperation *mail_op = NULL;
2796 GtkTreeSelection *sel = NULL;
2797 GtkWidget *folder_view = NULL;
2798 RenameFolderInfo *data = (RenameFolderInfo*)user_data;
2800 if (!canceled && (err == NULL) && MODEST_IS_MAIN_WINDOW(parent_window)) {
2802 folder_view = modest_main_window_get_child_widget (
2803 MODEST_MAIN_WINDOW (parent_window),
2804 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2807 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
2808 modest_ui_actions_rename_folder_error_handler,
2809 parent_window, NULL);
2811 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2814 /* Clear the headers view */
2815 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2816 gtk_tree_selection_unselect_all (sel);
2818 /* Actually rename the folder */
2819 modest_mail_operation_rename_folder (mail_op,
2820 TNY_FOLDER (data->folder),
2821 (const gchar *) (data->new_name),
2822 on_rename_folder_cb,
2826 g_object_unref (mail_op);
2827 g_free (data->new_name);
2832 modest_ui_actions_on_rename_folder (GtkAction *action,
2833 ModestMainWindow *main_window)
2835 TnyFolderStore *folder;
2836 GtkWidget *folder_view;
2837 GtkWidget *header_view;
2839 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2841 folder_view = modest_main_window_get_child_widget (main_window,
2842 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2846 header_view = modest_main_window_get_child_widget (main_window,
2847 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
2852 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW(folder_view));
2857 if (TNY_IS_FOLDER (folder)) {
2860 const gchar *current_name;
2861 TnyFolderStore *parent;
2862 gboolean do_rename = TRUE;
2864 current_name = tny_folder_get_name (TNY_FOLDER (folder));
2865 parent = tny_folder_get_folder_store (TNY_FOLDER (folder));
2866 response = modest_platform_run_rename_folder_dialog (GTK_WINDOW (main_window),
2867 parent, current_name,
2869 g_object_unref (parent);
2871 if (response != GTK_RESPONSE_ACCEPT || strlen (folder_name) == 0) {
2874 RenameFolderInfo *rename_folder_data = g_new0 (RenameFolderInfo, 1);
2875 rename_folder_data->folder = folder;
2876 rename_folder_data->new_name = folder_name;
2877 modest_platform_connect_if_remote_and_perform (GTK_WINDOW(main_window), TRUE,
2878 folder, on_rename_folder_performer, rename_folder_data);
2881 g_object_unref (folder);
2885 modest_ui_actions_delete_folder_error_handler (ModestMailOperation *mail_op,
2888 GObject *win = modest_mail_operation_get_source (mail_op);
2890 modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL,
2891 _("mail_in_ui_folder_delete_error"));
2892 g_object_unref (win);
2896 TnyFolderStore *folder;
2897 gboolean move_to_trash;
2901 on_delete_folder_cb (gboolean canceled,
2903 GtkWindow *parent_window,
2904 TnyAccount *account,
2907 DeleteFolderInfo *info = (DeleteFolderInfo*) user_data;
2908 GtkWidget *folder_view;
2909 ModestMailOperation *mail_op;
2910 GtkTreeSelection *sel;
2912 if (!MODEST_IS_MAIN_WINDOW(parent_window) || canceled || (err!=NULL)) {
2913 g_object_unref (G_OBJECT (info->folder));
2917 folder_view = modest_main_window_get_child_widget (
2918 MODEST_MAIN_WINDOW (parent_window),
2919 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2921 /* Unselect the folder before deleting it to free the headers */
2922 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (folder_view));
2923 gtk_tree_selection_unselect_all (sel);
2925 /* Create the mail operation */
2927 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
2928 modest_ui_actions_delete_folder_error_handler,
2931 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
2933 modest_mail_operation_remove_folder (mail_op, TNY_FOLDER (info->folder), info->move_to_trash);
2935 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (folder_view));
2937 g_object_unref (G_OBJECT (mail_op));
2938 g_object_unref (G_OBJECT (info->folder));
2943 delete_folder (ModestMainWindow *main_window, gboolean move_to_trash)
2945 TnyFolderStore *folder;
2946 GtkWidget *folder_view;
2950 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2952 folder_view = modest_main_window_get_child_widget (main_window,
2953 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
2957 folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
2959 /* Show an error if it's an account */
2960 if (!TNY_IS_FOLDER (folder)) {
2961 modest_platform_run_information_dialog (GTK_WINDOW (main_window),
2962 _("mail_in_ui_folder_delete_error"));
2963 g_object_unref (G_OBJECT (folder));
2968 message = g_strdup_printf (_("mcen_nc_delete_folder_text"),
2969 tny_folder_get_name (TNY_FOLDER (folder)));
2970 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (main_window),
2971 (const gchar *) message);
2974 if (response == GTK_RESPONSE_OK) {
2975 DeleteFolderInfo *info;
2976 info = g_new0(DeleteFolderInfo, 1);
2977 info->folder = folder;
2978 info->move_to_trash = move_to_trash;
2979 g_object_ref (G_OBJECT (info->folder));
2980 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (folder));
2981 modest_platform_connect_if_remote_and_perform (GTK_WINDOW (main_window),
2983 TNY_FOLDER_STORE (account),
2984 on_delete_folder_cb, info);
2985 g_object_unref (account);
2987 g_object_unref (G_OBJECT (folder));
2991 modest_ui_actions_on_delete_folder (GtkAction *action,
2992 ModestMainWindow *main_window)
2994 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
2996 delete_folder (main_window, FALSE);
3000 modest_ui_actions_on_move_folder_to_trash_folder (GtkAction *action, ModestMainWindow *main_window)
3002 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3004 delete_folder (main_window, TRUE);
3009 show_error (GtkWidget *parent_widget, const gchar* text)
3011 modest_platform_information_banner(parent_widget, NULL, text);
3014 GtkDialog *dialog = GTK_DIALOG (hildon_note_new_information (parent_window, text)); */
3016 GtkDialog *dialog = GTK_DIALOG (gtk_message_dialog_new (parent_window,
3023 gtk_dialog_run (dialog);
3024 gtk_widget_destroy (GTK_WIDGET (dialog));
3029 modest_ui_actions_on_password_requested (TnyAccountStore *account_store,
3030 const gchar* server_account_name,
3035 ModestMainWindow *main_window)
3037 g_return_if_fail(server_account_name);
3039 /* Initalize output parameters: */
3046 #ifdef MODEST_PLATFORM_MAEMO
3047 /* Maemo uses a different (awkward) button order,
3048 * It should probably just use gtk_alternative_dialog_button_order ().
3050 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3053 _("mcen_bd_dialog_ok"),
3054 GTK_RESPONSE_ACCEPT,
3055 _("mcen_bd_dialog_cancel"),
3056 GTK_RESPONSE_REJECT,
3059 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("mail_ti_password_protected"),
3063 GTK_RESPONSE_REJECT,
3065 GTK_RESPONSE_ACCEPT,
3067 #endif /* MODEST_PLATFORM_MAEMO */
3069 modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), GTK_WINDOW (dialog));
3071 gchar *server_name = modest_account_mgr_get_server_account_hostname (
3072 modest_runtime_get_account_mgr(), server_account_name);
3073 if (!server_name) {/* This happened once, though I don't know why. murrayc. */
3074 g_warning("%s: Could not get server name for server account '%s'", __FUNCTION__, server_account_name);
3080 /* This causes a warning because the logical ID has no %s in it,
3081 * though the translation does, but there is not much we can do about that: */
3082 gchar *txt = g_strdup_printf (_("mail_ia_password_info"), server_name);
3083 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), gtk_label_new(txt),
3086 g_free (server_name);
3090 gchar *initial_username = modest_account_mgr_get_server_account_username (
3091 modest_runtime_get_account_mgr(), server_account_name);
3093 GtkWidget *entry_username = gtk_entry_new ();
3094 if (initial_username)
3095 gtk_entry_set_text (GTK_ENTRY (entry_username), initial_username);
3096 /* Dim this if a connection has ever succeeded with this username,
3097 * as per the UI spec: */
3098 const gboolean username_known =
3099 modest_account_mgr_get_server_account_username_has_succeeded(
3100 modest_runtime_get_account_mgr(), server_account_name);
3101 gtk_widget_set_sensitive (entry_username, !username_known);
3103 #ifdef MODEST_PLATFORM_MAEMO
3104 /* Auto-capitalization is the default, so let's turn it off: */
3105 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_username), HILDON_GTK_INPUT_MODE_FULL);
3107 /* Create a size group to be used by all captions.
3108 * Note that HildonCaption does not create a default size group if we do not specify one.
3109 * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
3110 GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
3112 GtkWidget *caption = hildon_caption_new (sizegroup,
3113 _("mail_fi_username"), entry_username, NULL, HILDON_CAPTION_MANDATORY);
3114 gtk_widget_show (entry_username);
3115 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3116 FALSE, FALSE, MODEST_MARGIN_HALF);
3117 gtk_widget_show (caption);
3119 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_username,
3121 #endif /* MODEST_PLATFORM_MAEMO */
3124 GtkWidget *entry_password = gtk_entry_new ();
3125 gtk_entry_set_visibility (GTK_ENTRY(entry_password), FALSE);
3126 /* gtk_entry_set_invisible_char (GTK_ENTRY(entry_password), "*"); */
3128 #ifdef MODEST_PLATFORM_MAEMO
3129 /* Auto-capitalization is the default, so let's turn it off: */
3130 hildon_gtk_entry_set_input_mode (GTK_ENTRY (entry_password),
3131 HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
3133 caption = hildon_caption_new (sizegroup,
3134 _("mail_fi_password"), entry_password, NULL, HILDON_CAPTION_MANDATORY);
3135 gtk_widget_show (entry_password);
3136 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), caption,
3137 FALSE, FALSE, MODEST_MARGIN_HALF);
3138 gtk_widget_show (caption);
3139 g_object_unref (sizegroup);
3141 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), entry_password,
3143 #endif /* MODEST_PLATFORM_MAEMO */
3145 if (initial_username != NULL)
3146 gtk_widget_grab_focus (GTK_WIDGET (entry_password));
3148 /* This is not in the Maemo UI spec:
3149 remember_pass_check = gtk_check_button_new_with_label (_("Remember password"));
3150 gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox), remember_pass_check,
3154 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
3156 if (gtk_dialog_run (GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
3158 *username = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_username)));
3160 modest_account_mgr_set_server_account_username (
3161 modest_runtime_get_account_mgr(), server_account_name,
3164 const gboolean username_was_changed =
3165 (strcmp (*username, initial_username) != 0);
3166 if (username_was_changed) {
3167 g_warning ("%s: tinymail does not yet support changing the "
3168 "username in the get_password() callback.\n", __FUNCTION__);
3173 *password = g_strdup (gtk_entry_get_text (GTK_ENTRY(entry_password)));
3175 /* We do not save the password in the configuration,
3176 * because this function is only called for passwords that should
3177 * not be remembered:
3178 modest_server_account_set_password (
3179 modest_runtime_get_account_mgr(), server_account_name,
3188 show_error(GTK_WIDGET (main_window), _("mail_ib_login_cancelled"));
3200 /* This is not in the Maemo UI spec:
3201 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (remember_pass_check)))
3207 gtk_widget_destroy (dialog);
3209 /* printf ("DEBUG: %s: cancel=%d\n", __FUNCTION__, *cancel); */
3213 modest_ui_actions_on_cut (GtkAction *action,
3214 ModestWindow *window)
3216 GtkWidget *focused_widget;
3217 GtkClipboard *clipboard;
3219 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3220 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3221 if (GTK_IS_EDITABLE (focused_widget)) {
3222 gtk_editable_cut_clipboard (GTK_EDITABLE(focused_widget));
3223 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3224 gtk_clipboard_store (clipboard);
3225 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3226 GtkTextBuffer *buffer;
3228 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3229 gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
3230 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3231 gtk_clipboard_store (clipboard);
3232 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3233 TnyList *header_list = modest_header_view_get_selected_headers (
3234 MODEST_HEADER_VIEW (focused_widget));
3235 gboolean continue_download = FALSE;
3236 gint num_of_unc_msgs;
3238 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3240 if (num_of_unc_msgs) {
3241 TnyAccount *account = get_account_from_header_list (header_list);
3242 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3243 g_object_unref (account);
3246 if (num_of_unc_msgs == 0 || continue_download) {
3247 /* modest_platform_information_banner (
3248 NULL, NULL, _CS("mcen_ib_getting_items"));*/
3249 modest_header_view_cut_selection (
3250 MODEST_HEADER_VIEW (focused_widget));
3253 g_object_unref (header_list);
3254 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3255 modest_folder_view_cut_selection (MODEST_FOLDER_VIEW (focused_widget));
3260 modest_ui_actions_on_copy (GtkAction *action,
3261 ModestWindow *window)
3263 GtkClipboard *clipboard;
3264 GtkWidget *focused_widget;
3265 gboolean copied = TRUE;
3267 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3268 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3270 if (GTK_IS_LABEL (focused_widget)) {
3271 gtk_clipboard_set_text (clipboard, gtk_label_get_text (GTK_LABEL (focused_widget)), -1);
3272 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3273 gtk_clipboard_store (clipboard);
3274 } else if (GTK_IS_EDITABLE (focused_widget)) {
3275 gtk_editable_copy_clipboard (GTK_EDITABLE(focused_widget));
3276 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3277 gtk_clipboard_store (clipboard);
3278 } else if (GTK_IS_HTML (focused_widget)) {
3279 gtk_html_copy (GTK_HTML (focused_widget));
3280 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3281 gtk_clipboard_store (clipboard);
3282 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3283 GtkTextBuffer *buffer;
3284 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3285 gtk_text_buffer_copy_clipboard (buffer, clipboard);
3286 gtk_clipboard_set_can_store (clipboard, NULL, 0);
3287 gtk_clipboard_store (clipboard);
3288 } else if (MODEST_IS_HEADER_VIEW (focused_widget)) {
3289 TnyList *header_list = modest_header_view_get_selected_headers (
3290 MODEST_HEADER_VIEW (focused_widget));
3291 gboolean continue_download = FALSE;
3292 gint num_of_unc_msgs;
3294 num_of_unc_msgs = header_list_count_uncached_msgs(header_list);
3296 if (num_of_unc_msgs) {
3297 TnyAccount *account = get_account_from_header_list (header_list);
3298 continue_download = connect_to_get_msg (window, num_of_unc_msgs, account);
3299 g_object_unref (account);
3302 if (num_of_unc_msgs == 0 || continue_download) {
3303 modest_platform_information_banner (
3304 NULL, NULL, _CS("mcen_ib_getting_items"));
3305 modest_header_view_copy_selection (
3306 MODEST_HEADER_VIEW (focused_widget));
3310 g_object_unref (header_list);
3312 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3313 modest_folder_view_copy_selection (MODEST_FOLDER_VIEW (focused_widget));
3316 /* Show information banner if there was a copy to clipboard */
3318 modest_platform_information_banner (
3319 NULL, NULL, _CS("ecoc_ib_edwin_copied"));
3323 modest_ui_actions_on_undo (GtkAction *action,
3324 ModestWindow *window)
3326 ModestEmailClipboard *clipboard = NULL;
3328 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3329 modest_msg_edit_window_undo (MODEST_MSG_EDIT_WINDOW (window));
3330 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3331 /* Clear clipboard source */
3332 clipboard = modest_runtime_get_email_clipboard ();
3333 modest_email_clipboard_clear (clipboard);
3336 g_return_if_reached ();
3341 modest_ui_actions_on_redo (GtkAction *action,
3342 ModestWindow *window)
3344 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3345 modest_msg_edit_window_redo (MODEST_MSG_EDIT_WINDOW (window));
3348 g_return_if_reached ();
3354 destroy_information_note (ModestMailOperation *mail_op,
3357 /* destroy information note */
3358 gtk_widget_destroy (GTK_WIDGET(user_data));
3362 destroy_folder_information_note (ModestMailOperation *mail_op,
3363 TnyFolder *new_folder,
3366 /* destroy information note */
3367 gtk_widget_destroy (GTK_WIDGET(user_data));
3372 paste_as_attachment_free (gpointer data)
3374 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) data;
3376 gtk_widget_destroy (helper->banner);
3377 g_object_unref (helper->banner);
3382 paste_msg_as_attachment_cb (ModestMailOperation *mail_op,
3387 PasteAsAttachmentHelper *helper = (PasteAsAttachmentHelper *) userdata;
3388 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (helper->window));
3393 modest_msg_edit_window_add_part (MODEST_MSG_EDIT_WINDOW (helper->window), TNY_MIME_PART (msg));
3398 modest_ui_actions_on_paste (GtkAction *action,
3399 ModestWindow *window)
3401 GtkWidget *focused_widget = NULL;
3402 GtkWidget *inf_note = NULL;
3403 ModestMailOperation *mail_op = NULL;
3405 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3406 if (GTK_IS_EDITABLE (focused_widget)) {
3407 gtk_editable_paste_clipboard (GTK_EDITABLE(focused_widget));
3408 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3409 ModestEmailClipboard *e_clipboard = NULL;
3410 e_clipboard = modest_runtime_get_email_clipboard ();
3411 if (modest_email_clipboard_cleared (e_clipboard)) {
3412 GtkTextBuffer *buffer;
3413 GtkClipboard *clipboard;
3415 clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
3416 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3417 gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
3418 } else if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
3419 ModestMailOperation *mail_op;
3420 TnyFolder *src_folder;
3423 PasteAsAttachmentHelper *helper = g_new0 (PasteAsAttachmentHelper, 1);
3424 helper->window = MODEST_MSG_EDIT_WINDOW (window);
3425 helper->banner = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3426 _CS("ckct_nw_pasting"));
3427 modest_email_clipboard_get_data (e_clipboard, &src_folder, &data, &delete);
3428 mail_op = modest_mail_operation_new (G_OBJECT (window));
3429 if (helper->banner != NULL) {
3430 g_object_ref (G_OBJECT (helper->banner));
3431 gtk_window_set_modal (GTK_WINDOW (helper->banner), FALSE);
3432 gtk_widget_show (GTK_WIDGET (helper->banner));
3436 modest_mail_operation_get_msgs_full (mail_op,
3438 (GetMsgAsyncUserCallback) paste_msg_as_attachment_cb,
3440 paste_as_attachment_free);
3443 } else if (MODEST_IS_FOLDER_VIEW (focused_widget)) {
3444 ModestEmailClipboard *clipboard = NULL;
3445 TnyFolder *src_folder = NULL;
3446 TnyFolderStore *folder_store = NULL;
3447 TnyList *data = NULL;
3448 gboolean delete = FALSE;
3450 /* Check clipboard source */
3451 clipboard = modest_runtime_get_email_clipboard ();
3452 if (modest_email_clipboard_cleared (clipboard))
3455 /* Get elements to paste */
3456 modest_email_clipboard_get_data (clipboard, &src_folder, &data, &delete);
3458 /* Create a new mail operation */
3459 mail_op = modest_mail_operation_new (G_OBJECT(window));
3461 /* Get destination folder */
3462 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (focused_widget));
3464 /* transfer messages */
3468 /* Ask for user confirmation */
3470 modest_ui_actions_msgs_move_to_confirmation (window,
3471 TNY_FOLDER (folder_store),
3475 if (response == GTK_RESPONSE_OK) {
3476 /* Launch notification */
3477 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3478 _CS("ckct_nw_pasting"));
3479 if (inf_note != NULL) {
3480 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3481 gtk_widget_show (GTK_WIDGET(inf_note));
3484 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3485 modest_mail_operation_xfer_msgs (mail_op,
3487 TNY_FOLDER (folder_store),
3489 destroy_information_note,
3492 g_object_unref (mail_op);
3495 } else if (src_folder != NULL) {
3496 /* Launch notification */
3497 inf_note = modest_platform_animation_banner (GTK_WIDGET (window), NULL,
3498 _CS("ckct_nw_pasting"));
3499 if (inf_note != NULL) {
3500 gtk_window_set_modal (GTK_WINDOW(inf_note), FALSE);
3501 gtk_widget_show (GTK_WIDGET(inf_note));
3504 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
3505 modest_mail_operation_xfer_folder (mail_op,
3509 destroy_folder_information_note,
3515 g_object_unref (data);
3516 if (src_folder != NULL)
3517 g_object_unref (src_folder);
3518 if (folder_store != NULL)
3519 g_object_unref (folder_store);
3525 modest_ui_actions_on_select_all (GtkAction *action,
3526 ModestWindow *window)
3528 GtkWidget *focused_widget;
3530 focused_widget = gtk_window_get_focus (GTK_WINDOW (window));
3531 if (MODEST_IS_ATTACHMENTS_VIEW (focused_widget)) {
3532 modest_attachments_view_select_all (MODEST_ATTACHMENTS_VIEW (focused_widget));
3533 } else if (GTK_IS_LABEL (focused_widget)) {
3534 gtk_label_select_region (GTK_LABEL (focused_widget), 0, -1);
3535 } else if (GTK_IS_EDITABLE (focused_widget)) {
3536 gtk_editable_select_region (GTK_EDITABLE(focused_widget), 0, -1);
3537 } else if (GTK_IS_TEXT_VIEW (focused_widget)) {
3538 GtkTextBuffer *buffer;
3539 GtkTextIter start, end;
3541 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (focused_widget));
3542 gtk_text_buffer_get_start_iter (buffer, &start);
3543 gtk_text_buffer_get_end_iter (buffer, &end);
3544 gtk_text_buffer_select_range (buffer, &start, &end);
3545 } else if (GTK_IS_HTML (focused_widget)) {
3546 gtk_html_select_all (GTK_HTML (focused_widget));
3547 } else if (MODEST_IS_MAIN_WINDOW (window)) {
3548 GtkWidget *header_view = focused_widget;
3549 GtkTreeSelection *selection = NULL;
3551 if (!(MODEST_IS_HEADER_VIEW (focused_widget))) {
3552 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (window),
3553 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3556 /* Disable window dimming management */
3557 modest_window_disable_dimming (MODEST_WINDOW(window));
3559 /* Select all messages */
3560 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(header_view));
3561 gtk_tree_selection_select_all (selection);
3563 /* Set focuse on header view */
3564 gtk_widget_grab_focus (header_view);
3567 /* Enable window dimming management */
3568 modest_window_enable_dimming (MODEST_WINDOW(window));
3569 modest_ui_actions_check_toolbar_dimming_rules (MODEST_WINDOW (window));
3575 modest_ui_actions_on_mark_as_read (GtkAction *action,
3576 ModestWindow *window)
3578 g_return_if_fail (MODEST_IS_WINDOW(window));
3580 /* Mark each header as read */
3581 do_headers_action (window, headers_action_mark_as_read, NULL);
3585 modest_ui_actions_on_mark_as_unread (GtkAction *action,
3586 ModestWindow *window)
3588 g_return_if_fail (MODEST_IS_WINDOW(window));
3590 /* Mark each header as read */
3591 do_headers_action (window, headers_action_mark_as_unread, NULL);
3595 modest_ui_actions_on_change_zoom (GtkRadioAction *action,
3596 GtkRadioAction *selected,
3597 ModestWindow *window)
3601 value = gtk_radio_action_get_current_value (selected);
3602 if (MODEST_IS_WINDOW (window)) {
3603 modest_window_set_zoom (MODEST_WINDOW (window), ((gdouble)value)/100);
3608 modest_ui_actions_msg_edit_on_change_priority (GtkRadioAction *action,
3609 GtkRadioAction *selected,
3610 ModestWindow *window)
3612 TnyHeaderFlags flags;
3613 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3615 flags = gtk_radio_action_get_current_value (selected);
3616 modest_msg_edit_window_set_priority_flags (MODEST_MSG_EDIT_WINDOW (window), flags);
3620 modest_ui_actions_msg_edit_on_change_file_format (GtkRadioAction *action,
3621 GtkRadioAction *selected,
3622 ModestWindow *window)
3626 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3628 file_format = gtk_radio_action_get_current_value (selected);
3629 modest_msg_edit_window_set_file_format (MODEST_MSG_EDIT_WINDOW (window), file_format);
3634 modest_ui_actions_on_zoom_plus (GtkAction *action,
3635 ModestWindow *window)
3637 g_return_if_fail (MODEST_IS_WINDOW (window));
3639 modest_window_zoom_plus (MODEST_WINDOW (window));
3643 modest_ui_actions_on_zoom_minus (GtkAction *action,
3644 ModestWindow *window)
3646 g_return_if_fail (MODEST_IS_WINDOW (window));
3648 modest_window_zoom_minus (MODEST_WINDOW (window));
3652 modest_ui_actions_on_toggle_fullscreen (GtkToggleAction *toggle,
3653 ModestWindow *window)
3655 ModestWindowMgr *mgr;
3656 gboolean fullscreen, active;
3657 g_return_if_fail (MODEST_IS_WINDOW (window));
3659 mgr = modest_runtime_get_window_mgr ();
3661 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle)))?1:0;
3662 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3664 if (active != fullscreen) {
3665 modest_window_mgr_set_fullscreen_mode (mgr, active);
3666 gtk_window_present (GTK_WINDOW (window));
3671 modest_ui_actions_on_change_fullscreen (GtkAction *action,
3672 ModestWindow *window)
3674 ModestWindowMgr *mgr;
3675 gboolean fullscreen;
3677 g_return_if_fail (MODEST_IS_WINDOW (window));
3679 mgr = modest_runtime_get_window_mgr ();
3680 fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
3681 modest_window_mgr_set_fullscreen_mode (mgr, !fullscreen);
3683 gtk_window_present (GTK_WINDOW (window));
3687 * Used by modest_ui_actions_on_details to call do_headers_action
3690 headers_action_show_details (TnyHeader *header,
3691 ModestWindow *window,
3698 dialog = modest_details_dialog_new_with_header (GTK_WINDOW (window), header);
3701 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3702 gtk_widget_show_all (dialog);
3703 gtk_dialog_run (GTK_DIALOG (dialog));
3705 gtk_widget_destroy (dialog);
3709 * Show the folder details in a ModestDetailsDialog widget
3712 show_folder_details (TnyFolder *folder,
3718 dialog = modest_details_dialog_new_with_folder (window, folder);
3721 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
3722 gtk_widget_show_all (dialog);
3723 gtk_dialog_run (GTK_DIALOG (dialog));
3725 gtk_widget_destroy (dialog);
3729 * Show the header details in a ModestDetailsDialog widget
3732 modest_ui_actions_on_details (GtkAction *action,
3735 TnyList * headers_list;
3739 if (MODEST_IS_MSG_VIEW_WINDOW (win)) {
3742 msg = modest_msg_view_window_get_message (MODEST_MSG_VIEW_WINDOW (win));
3745 g_object_unref (msg);
3747 headers_list = get_selected_headers (win);
3751 iter = tny_list_create_iterator (headers_list);
3753 header = TNY_HEADER (tny_iterator_get_current (iter));
3755 headers_action_show_details (header, win, NULL);
3756 g_object_unref (header);
3759 g_object_unref (iter);
3760 g_object_unref (headers_list);
3762 } else if (MODEST_IS_MAIN_WINDOW (win)) {
3763 GtkWidget *folder_view, *header_view;
3765 /* Check which widget has the focus */
3766 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3767 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3768 if (gtk_widget_is_focus (folder_view)) {
3769 TnyFolderStore *folder_store
3770 = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3771 if (!folder_store) {
3772 g_warning ("%s: No item was selected.\n", __FUNCTION__);
3775 /* Show only when it's a folder */
3776 /* This function should not be called for account items,
3777 * because we dim the menu item for them. */
3778 if (TNY_IS_FOLDER (folder_store)) {
3779 show_folder_details (TNY_FOLDER (folder_store), GTK_WINDOW (win));
3782 g_object_unref (folder_store);
3785 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
3786 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
3787 /* Show details of each header */
3788 do_headers_action (win, headers_action_show_details, header_view);
3794 modest_ui_actions_on_toggle_show_cc (GtkToggleAction *toggle,
3795 ModestMsgEditWindow *window)
3797 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3799 modest_msg_edit_window_show_cc (window, gtk_toggle_action_get_active (toggle));
3803 modest_ui_actions_on_toggle_show_bcc (GtkToggleAction *toggle,
3804 ModestMsgEditWindow *window)
3806 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3808 modest_msg_edit_window_show_bcc (window, gtk_toggle_action_get_active (toggle));
3812 modest_ui_actions_toggle_folders_view (GtkAction *action,
3813 ModestMainWindow *main_window)
3815 g_return_if_fail (MODEST_IS_MAIN_WINDOW(main_window));
3817 if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)))
3818 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SPLIT);
3820 modest_main_window_set_style (main_window, MODEST_MAIN_WINDOW_STYLE_SIMPLE);
3824 modest_ui_actions_on_toggle_toolbar (GtkToggleAction *toggle,
3825 ModestWindow *window)
3827 gboolean active, fullscreen = FALSE;
3828 ModestWindowMgr *mgr;
3830 active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (toggle));
3832 /* Check if we want to toggle the toolbar vuew in fullscreen
3834 if (!strcmp (gtk_action_get_name (GTK_ACTION (toggle)),
3835 "ViewShowToolbarFullScreen")) {
3839 /* Toggle toolbar */
3840 mgr = modest_runtime_get_window_mgr ();
3841 modest_window_mgr_show_toolbars (mgr, G_TYPE_FROM_INSTANCE (window), active, fullscreen);
3845 modest_ui_actions_msg_edit_on_select_font (GtkAction *action,
3846 ModestMsgEditWindow *window)
3848 modest_msg_edit_window_select_font (window);
3853 modest_ui_actions_on_folder_display_name_changed (ModestFolderView *folder_view,
3854 const gchar *display_name,
3857 /* don't update the display name if it was already set;
3858 * updating the display name apparently is expensive */
3859 const gchar* old_name = gtk_window_get_title (window);
3861 if (display_name == NULL)
3864 if (old_name && display_name && strcmp (old_name, display_name) == 0)
3865 return; /* don't do anything */
3867 /* This is usually used to change the title of the main window, which
3868 * is the one that holds the folder view. Note that this change can
3869 * happen even when the widget doesn't have the focus. */
3870 gtk_window_set_title (window, display_name);
3875 modest_ui_actions_on_select_contacts (GtkAction *action, ModestMsgEditWindow *window)
3877 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3878 modest_msg_edit_window_select_contacts (window);
3882 modest_ui_actions_on_check_names (GtkAction *action, ModestMsgEditWindow *window)
3884 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
3885 modest_msg_edit_window_check_names (window, FALSE);
3889 create_move_to_dialog_on_new_folder(GtkWidget *button, gpointer user_data)
3891 modest_ui_actions_create_folder (gtk_widget_get_toplevel (button),
3892 GTK_WIDGET (user_data));
3896 * This function is used to track changes in the selection of the
3897 * folder view that is inside the "move to" dialog to enable/disable
3898 * the OK button because we do not want the user to select a disallowed
3899 * destination for a folder.
3900 * The user also not desired to be able to use NEW button on items where
3901 * folder creation is not possibel.
3904 on_move_to_dialog_folder_selection_changed (ModestFolderView* self,
3905 TnyFolderStore *folder_store,
3909 GtkWidget *dialog = NULL;
3910 GtkWidget *ok_button = NULL, *new_button = NULL;
3911 GList *children = NULL;
3912 gboolean ok_sensitive = TRUE, new_sensitive = TRUE;
3913 gboolean moving_folder = FALSE;
3914 gboolean is_local_account = TRUE;
3915 GtkWidget *folder_view = NULL;
3916 ModestTnyFolderRules rules;
3921 /* Get the OK button */
3922 dialog = gtk_widget_get_ancestor (GTK_WIDGET (self), GTK_TYPE_DIALOG);
3926 children = gtk_container_get_children (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area));
3927 ok_button = GTK_WIDGET (children->next->next->data);
3928 new_button = GTK_WIDGET (children->next->data);
3929 g_list_free (children);
3931 /* check if folder_store is an remote account */
3932 if (TNY_IS_ACCOUNT (folder_store)) {
3933 TnyAccount *local_account = NULL;
3934 TnyAccount *mmc_account = NULL;
3935 ModestTnyAccountStore *account_store = NULL;
3937 account_store = modest_runtime_get_account_store ();
3938 local_account = modest_tny_account_store_get_local_folders_account (account_store);
3939 mmc_account = modest_tny_account_store_get_mmc_folders_account (account_store);
3941 if ((gpointer) local_account != (gpointer) folder_store &&
3942 (gpointer) mmc_account != (gpointer) folder_store) {
3943 is_local_account = FALSE;
3944 /* New button should be dimmed on remote
3946 new_sensitive = FALSE;
3948 g_object_unref (local_account);
3951 /* Check the target folder rules */
3952 if (TNY_IS_FOLDER (folder_store)) {
3953 rules = modest_tny_folder_get_rules (TNY_FOLDER (folder_store));
3954 if (rules & MODEST_FOLDER_RULES_FOLDER_NON_WRITEABLE) {
3955 ok_sensitive = FALSE;
3956 new_sensitive = FALSE;
3961 /* Check if we're moving a folder */
3962 if (MODEST_IS_MAIN_WINDOW (user_data)) {
3963 /* Get the widgets */
3964 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (user_data),
3965 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
3966 if (gtk_widget_is_focus (folder_view))
3967 moving_folder = TRUE;
3970 if (moving_folder) {
3971 TnyFolderStore *moved_folder = NULL, *parent = NULL;
3973 /* Get the folder to move */
3974 moved_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
3976 /* Check that we're not moving to the same folder */
3977 if (TNY_IS_FOLDER (moved_folder)) {
3978 parent = tny_folder_get_folder_store (TNY_FOLDER (moved_folder));
3979 if (parent == folder_store)
3980 ok_sensitive = FALSE;
3981 g_object_unref (parent);
3984 if (ok_sensitive && TNY_IS_ACCOUNT (folder_store)) {
3985 /* Do not allow to move to an account unless it's the
3986 local folders account */
3987 if (!is_local_account)
3988 ok_sensitive = FALSE;
3991 if (ok_sensitive && (moved_folder == folder_store)) {
3992 /* Do not allow to move to itself */
3993 ok_sensitive = FALSE;
3995 g_object_unref (moved_folder);
3997 TnyHeader *header = NULL;
3998 TnyFolder *src_folder = NULL;
4000 /* Moving a message */
4001 if (MODEST_IS_MSG_VIEW_WINDOW (user_data)) {
4002 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (user_data));
4003 src_folder = tny_header_get_folder (header);
4004 g_object_unref (header);
4007 TNY_FOLDER (modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view)));
4010 /* Do not allow to move the msg to the same folder */
4011 /* Do not allow to move the msg to an account */
4012 if ((gpointer) src_folder == (gpointer) folder_store ||
4013 TNY_IS_ACCOUNT (folder_store))
4014 ok_sensitive = FALSE;
4015 g_object_unref (src_folder);
4019 /* Set sensitivity of the OK button */
4020 gtk_widget_set_sensitive (ok_button, ok_sensitive);
4021 /* Set sensitivity of the NEW button */
4022 gtk_widget_set_sensitive (new_button, new_sensitive);
4026 #define MODEST_MOVE_TO_DIALOG_FOLDER_VIEW "move-to-dialog-folder-view"
4029 get_folder_view_from_move_to_dialog (GtkWidget *move_to_dialog)
4031 return GTK_WIDGET(g_object_get_data (G_OBJECT(move_to_dialog),
4032 MODEST_MOVE_TO_DIALOG_FOLDER_VIEW));
4036 create_move_to_dialog (GtkWindow *win,
4037 GtkWidget *folder_view,
4038 GtkWidget **tree_view)
4040 GtkWidget *dialog, *scroll;
4041 GtkWidget *new_button;
4043 dialog = gtk_dialog_new_with_buttons (_("mcen_ti_moveto_folders_title"),
4045 GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR | GTK_DIALOG_DESTROY_WITH_PARENT,
4048 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT);
4049 /* We do this manually so GTK+ does not associate a response ID for
4051 new_button = gtk_button_new_from_stock (_("mcen_bd_new"));
4052 gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->action_area), new_button, FALSE, FALSE, 0);
4053 gtk_dialog_add_button (GTK_DIALOG (dialog), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT);
4055 /* Create scrolled window */
4056 scroll = gtk_scrolled_window_new (NULL, NULL);
4057 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
4058 GTK_POLICY_AUTOMATIC,
4059 GTK_POLICY_AUTOMATIC);
4061 /* Create folder view */
4062 *tree_view = modest_platform_create_folder_view (NULL);
4064 /* Track changes in the selection to
4065 * disable the OK button whenever "Move to" is not possible
4066 * disbale NEW button whenever New is not possible */
4067 g_signal_connect (*tree_view,
4068 "folder_selection_changed",
4069 G_CALLBACK (on_move_to_dialog_folder_selection_changed),
4072 /* Listen to clicks on New button */
4073 g_signal_connect (G_OBJECT (new_button),
4075 G_CALLBACK(create_move_to_dialog_on_new_folder),
4078 /* It could happen that we're trying to move a message from a
4079 window (msg window for example) after the main window was
4080 closed, so we can not just get the model of the folder
4082 if (MODEST_IS_FOLDER_VIEW (folder_view)) {
4083 const gchar *visible_id = NULL;
4085 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4086 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4087 modest_folder_view_copy_model (MODEST_FOLDER_VIEW(folder_view),
4088 MODEST_FOLDER_VIEW(*tree_view));
4091 modest_folder_view_get_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(folder_view));
4093 /* Show the same account than the one that is shown in the main window */
4094 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW(*tree_view),
4097 const gchar *active_account_name = NULL;
4098 ModestAccountMgr *mgr = NULL;
4099 ModestAccountSettings *settings = NULL;
4100 ModestServerAccountSettings *store_settings = NULL;
4102 modest_folder_view_set_style (MODEST_FOLDER_VIEW (*tree_view),
4103 MODEST_FOLDER_VIEW_STYLE_SHOW_ALL);
4104 modest_folder_view_update_model (MODEST_FOLDER_VIEW (*tree_view),
4105 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
4107 active_account_name = modest_window_get_active_account (MODEST_WINDOW (win));
4108 mgr = modest_runtime_get_account_mgr ();
4109 settings = modest_account_mgr_load_account_settings (mgr, active_account_name);
4112 const gchar *store_account_name;
4113 store_settings = modest_account_settings_get_store_settings (settings);
4114 store_account_name = modest_server_account_settings_get_account_name (store_settings);
4116 modest_folder_view_set_account_id_of_visible_server_account (MODEST_FOLDER_VIEW (*tree_view),
4117 store_account_name);
4118 g_object_unref (store_settings);
4119 g_object_unref (settings);
4123 /* we keep a pointer to the embedded folder view, so we can retrieve it with
4124 * get_folder_view_from_move_to_dialog
4125 * (see above) later (needed for focus handling)
4127 g_object_set_data (G_OBJECT(dialog), MODEST_MOVE_TO_DIALOG_FOLDER_VIEW, *tree_view);
4130 /* Hide special folders */
4131 modest_folder_view_show_non_move_folders (MODEST_FOLDER_VIEW (*tree_view), FALSE);
4133 gtk_container_add (GTK_CONTAINER (scroll), *tree_view);
4135 /* Add scroll to dialog */
4136 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
4137 scroll, TRUE, TRUE, 0);
4139 gtk_widget_show_all (GTK_WIDGET(GTK_DIALOG(dialog)->vbox));
4140 gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 300);
4146 * Returns TRUE if at least one of the headers of the list belongs to
4147 * a message that has been fully retrieved.
4149 #if 0 /* no longer in use. delete in 2007.10 */
4151 has_retrieved_msgs (TnyList *list)
4154 gboolean found = FALSE;
4156 iter = tny_list_create_iterator (list);
4157 while (!tny_iterator_is_done (iter) && !found) {
4159 TnyHeaderFlags flags = 0;
4161 header = TNY_HEADER (tny_iterator_get_current (iter));
4163 flags = tny_header_get_flags (header);
4164 if (flags & TNY_HEADER_FLAG_CACHED)
4165 /* if (!(flags & TNY_HEADER_FLAG_PARTIAL)) */
4168 g_object_unref (header);
4172 tny_iterator_next (iter);
4174 g_object_unref (iter);
4182 * Shows a confirmation dialog to the user when we're moving messages
4183 * from a remote server to the local storage. Returns the dialog
4184 * response. If it's other kind of movement then it always returns
4187 * This one is used by the next functions:
4188 * modest_ui_actions_on_paste - commented out
4189 * drag_and_drop_from_header_view (for d&d in modest_folder_view.c)
4192 modest_ui_actions_msgs_move_to_confirmation (ModestWindow *win,
4193 TnyFolder *dest_folder,
4197 gint response = GTK_RESPONSE_OK;
4198 TnyAccount *account = NULL;
4199 TnyFolder *src_folder = NULL;
4200 TnyIterator *iter = NULL;
4201 TnyHeader *header = NULL;
4203 /* return with OK if the destination is a remote folder */
4204 if (modest_tny_folder_is_remote_folder (dest_folder))
4205 return GTK_RESPONSE_OK;
4207 /* Get source folder */
4208 iter = tny_list_create_iterator (headers);
4209 header = TNY_HEADER (tny_iterator_get_current (iter));
4211 src_folder = tny_header_get_folder (header);
4212 g_object_unref (header);
4214 g_object_unref (iter);
4216 /* if no src_folder, message may be an attahcment */
4217 if (src_folder == NULL)
4218 return GTK_RESPONSE_CANCEL;
4220 /* If the source is a local or MMC folder */
4221 if (!modest_tny_folder_is_remote_folder (src_folder)) {
4222 g_object_unref (src_folder);
4223 return GTK_RESPONSE_OK;
4226 /* Get the account */
4227 account = tny_folder_get_account (src_folder);
4229 /* now if offline we ask the user */
4230 if(connect_to_get_msg (win, tny_list_get_length (headers), account))
4231 response = GTK_RESPONSE_OK;
4233 response = GTK_RESPONSE_CANCEL;
4236 g_object_unref (src_folder);
4237 g_object_unref (account);
4243 move_to_cb (ModestMailOperation *mail_op,
4246 MoveToHelper *helper = (MoveToHelper *) user_data;
4248 /* Note that the operation could have failed, in that case do
4250 if (modest_mail_operation_get_status (mail_op) ==
4251 MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
4253 GObject *object = modest_mail_operation_get_source (mail_op);
4254 if (MODEST_IS_MSG_VIEW_WINDOW (object)) {
4255 ModestMsgViewWindow *self = MODEST_MSG_VIEW_WINDOW (object);
4257 if (modest_msg_view_window_last_message_selected (self) &&
4258 modest_msg_view_window_first_message_selected (self)) {
4259 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW (self));
4260 } else if (!modest_msg_view_window_select_next_message (self) &&
4261 !modest_msg_view_window_select_previous_message (self)) {
4262 /* No more messages to view, so close this window */
4263 modest_ui_actions_on_close_window (NULL, MODEST_WINDOW(self));
4265 } else if (MODEST_IS_MAIN_WINDOW (object) && helper->reference != NULL) {
4266 GtkWidget *header_view;
4268 GtkTreeSelection *sel;
4270 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(object),
4271 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4272 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (header_view));
4273 path = gtk_tree_row_reference_get_path (helper->reference);
4274 gtk_tree_selection_select_path (sel, path);
4275 gtk_tree_path_free (path);
4277 g_object_unref (object);
4280 /* Close the "Pasting" information banner */
4281 gtk_widget_destroy (GTK_WIDGET(helper->banner));
4282 if (helper->reference != NULL)
4283 gtk_tree_row_reference_free (helper->reference);
4288 folder_move_to_cb (ModestMailOperation *mail_op,
4289 TnyFolder *new_folder,
4292 move_to_cb (mail_op, user_data);
4296 msgs_move_to_cb (ModestMailOperation *mail_op,
4299 move_to_cb (mail_op, user_data);
4303 modest_ui_actions_move_folder_error_handler (ModestMailOperation *mail_op,
4306 ModestWindow *main_window = NULL;
4307 GObject *win = NULL;
4309 /* Disable next automatic folder selection */
4310 main_window = modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
4311 FALSE); /* don't create */
4313 GtkWidget *folder_view = NULL;
4315 folder_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (main_window),
4316 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4317 modest_folder_view_disable_next_folder_selection (MODEST_FOLDER_VIEW(folder_view));
4319 if (user_data && TNY_IS_FOLDER (user_data)) {
4320 modest_folder_view_select_folder (MODEST_FOLDER_VIEW (folder_view),
4321 TNY_FOLDER (user_data), FALSE);
4325 /* Show notification dialog */
4326 win = modest_mail_operation_get_source (mail_op);
4327 modest_platform_run_information_dialog ((GtkWindow *) win, _("mail_in_ui_folder_move_target_error"));
4329 g_object_unref (win);
4333 modest_ui_actions_send_receive_error_handler (ModestMailOperation *mail_op,
4336 GObject *win = modest_mail_operation_get_source (mail_op);
4337 const GError *error = modest_mail_operation_get_error (mail_op);
4339 g_return_if_fail (error != NULL);
4340 if (error->message != NULL)
4341 g_printerr ("modest: %s\n", error->message);
4343 g_printerr ("modest: unkonw error on send&receive operation");
4345 /* Show error message */
4346 /* if (modest_mail_operation_get_id (mail_op) == MODEST_MAIL_OPERATION_TYPE_RECEIVE) */
4347 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
4348 /* _CS("sfil_ib_unable_to_receive")); */
4350 /* modest_platform_run_information_dialog ((win) ? GTK_WINDOW (win) : NULL, */
4351 /* _CS("sfil_ib_unable_to_send")); */
4352 g_object_unref (win);
4356 open_msg_for_purge_cb (ModestMailOperation *mail_op,
4365 gint pending_purges = 0;
4366 gboolean some_purged = FALSE;
4367 ModestWindow *win = MODEST_WINDOW (user_data);
4368 ModestWindowMgr *mgr = modest_runtime_get_window_mgr ();
4370 /* If there was any error */
4371 if (!modest_ui_actions_msg_retrieval_check (mail_op, header, msg)) {
4372 modest_window_mgr_unregister_header (mgr, header);
4376 /* Once the message has been retrieved for purging, we check if
4377 * it's all ok for purging */
4379 parts = tny_simple_list_new ();
4380 tny_mime_part_get_parts (TNY_MIME_PART (msg), parts);
4381 iter = tny_list_create_iterator (parts);
4383 while (!tny_iterator_is_done (iter)) {
4385 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4386 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part))) {
4387 if (tny_mime_part_is_purged (part))
4394 g_object_unref (part);
4396 tny_iterator_next (iter);
4398 g_object_unref (iter);
4401 if (pending_purges>0) {
4403 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),_("mcen_nc_purge_file_text_inbox"));
4405 if (response == GTK_RESPONSE_OK) {
4406 modest_platform_information_banner (NULL, NULL, _("mcen_ib_removing_attachment"));
4407 iter = tny_list_create_iterator (parts);
4408 while (!tny_iterator_is_done (iter)) {
4411 part = TNY_MIME_PART (tny_iterator_get_current (iter));
4412 if (part && (tny_mime_part_is_attachment (part) || TNY_IS_MSG (part)))
4413 tny_mime_part_set_purged (part);
4416 g_object_unref (part);
4418 tny_iterator_next (iter);
4421 tny_msg_rewrite_cache (msg);
4424 /* This string no longer exists, refer to NB#75415 for more info */
4425 /* modest_platform_information_banner (NULL, NULL, _("mail_ib_attachment_already_purged")); */
4427 g_object_unref (iter);
4429 modest_window_mgr_unregister_header (mgr, header);
4431 g_object_unref (parts);
4435 modest_ui_actions_on_main_window_remove_attachments (GtkAction *action,
4436 ModestMainWindow *win)
4438 GtkWidget *header_view;
4439 TnyList *header_list;
4442 TnyHeaderFlags flags;
4443 ModestWindow *msg_view_window = NULL;
4446 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4448 header_view = modest_main_window_get_child_widget (MODEST_MAIN_WINDOW (win),
4449 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4451 header_list = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (header_view));
4453 g_warning ("%s: no header selected", __FUNCTION__);
4457 if (tny_list_get_length (header_list) == 1) {
4458 iter = tny_list_create_iterator (header_list);
4459 header = TNY_HEADER (tny_iterator_get_current (iter));
4460 g_object_unref (iter);
4464 if (!header || !TNY_IS_HEADER(header)) {
4465 g_warning ("%s: header is not valid", __FUNCTION__);
4469 found = modest_window_mgr_find_registered_header (modest_runtime_get_window_mgr (),
4470 header, &msg_view_window);
4471 flags = tny_header_get_flags (header);
4472 if (!(flags & TNY_HEADER_FLAG_CACHED))
4475 if (msg_view_window != NULL)
4476 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (msg_view_window), TRUE);
4478 /* do nothing; uid was registered before, so window is probably on it's way */
4479 g_warning ("debug: header %p has already been registered", header);
4482 ModestMailOperation *mail_op = NULL;
4483 modest_window_mgr_register_header (modest_runtime_get_window_mgr (), header, NULL);
4484 mail_op = modest_mail_operation_new_with_error_handling (G_OBJECT (win),
4485 modest_ui_actions_get_msgs_full_error_handler,
4487 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
4488 modest_mail_operation_get_msg (mail_op, header, open_msg_for_purge_cb, win);
4490 g_object_unref (mail_op);
4493 g_object_unref (header);
4495 g_object_unref (header_list);
4499 * Utility function that transfer messages from both the main window
4500 * and the msg view window when using the "Move to" dialog
4503 xfer_messages_from_move_to_cb (gboolean canceled, GError *err,
4504 GtkWindow *parent_window,
4505 TnyAccount *account, gpointer user_data)
4507 TnyFolderStore *dst_folder = TNY_FOLDER_STORE (user_data);
4508 ModestWindow *win = MODEST_WINDOW (parent_window);
4509 TnyList *headers = NULL;
4510 TnyAccount *dst_account = NULL;
4511 const gchar *proto_str = NULL;
4512 gboolean dst_is_pop = FALSE;
4514 if (canceled || err) {
4515 g_object_unref (dst_folder);
4519 dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
4520 proto_str = tny_account_get_proto (dst_account);
4522 /* tinymail will return NULL for local folders it seems */
4523 dst_is_pop = proto_str &&
4524 (modest_protocol_info_get_transport_store_protocol (proto_str) ==
4525 MODEST_PROTOCOL_STORE_POP);
4527 g_object_unref (dst_account);
4529 /* Get selected headers */
4530 headers = get_selected_headers (MODEST_WINDOW (win));
4532 g_warning ("%s: no headers selected", __FUNCTION__);
4538 modest_platform_information_banner (GTK_WIDGET (win),
4540 ngettext("mail_in_ui_folder_move_target_error",
4541 "mail_in_ui_folder_move_targets_error",
4542 tny_list_get_length (headers)));
4543 g_object_unref (headers);
4547 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4548 helper->banner = modest_platform_animation_banner (GTK_WIDGET (win), NULL,
4549 _CS("ckct_nw_pasting"));
4550 if (helper->banner != NULL) {
4551 gtk_window_set_modal (GTK_WINDOW(helper->banner), FALSE);
4552 gtk_widget_show (GTK_WIDGET(helper->banner));
4555 if (MODEST_IS_MAIN_WINDOW (win)) {
4556 GtkWidget *header_view =
4557 modest_main_window_get_child_widget (MODEST_MAIN_WINDOW(win),
4558 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
4559 helper->reference = get_next_after_selected_headers (MODEST_HEADER_VIEW (header_view));
4562 ModestMailOperation *mail_op =
4563 modest_mail_operation_new_with_error_handling (G_OBJECT(win),
4564 modest_ui_actions_move_folder_error_handler,
4566 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4569 modest_mail_operation_xfer_msgs (mail_op,
4571 TNY_FOLDER (dst_folder),
4576 g_object_unref (G_OBJECT (mail_op));
4577 g_object_unref (headers);
4578 g_object_unref (dst_folder);
4582 TnyAccount *dst_account;
4583 ModestConnectedPerformer callback;
4585 } DoubleConnectionInfo;
4588 src_account_connect_performer (gboolean canceled,
4590 GtkWindow *parent_window,
4591 TnyAccount *src_account,
4594 DoubleConnectionInfo *info = (DoubleConnectionInfo *) user_data;
4596 if (canceled || err) {
4597 /* If there was any error call the user callback */
4598 info->callback (canceled, err, parent_window, src_account, info->data);
4600 /* Connect the destination account */
4601 modest_platform_connect_if_remote_and_perform (parent_window, TRUE,
4602 TNY_FOLDER_STORE (info->dst_account),
4603 info->callback, info->data);
4606 /* Free the info object */
4607 g_object_unref (info->dst_account);
4608 g_slice_free (DoubleConnectionInfo, info);
4612 TnyFolder *src_folder;
4613 TnyFolderStore *dst_folder;
4614 gboolean delete_original;
4615 GtkWidget *folder_view;
4619 on_move_folder_cb (gboolean canceled, GError *err, GtkWindow *parent_window,
4620 TnyAccount *account, gpointer user_data)
4622 MoveFolderInfo *info = (MoveFolderInfo*)user_data;
4623 GtkTreeSelection *sel;
4624 ModestMailOperation *mail_op = NULL;
4626 if (canceled || err || !MODEST_IS_MAIN_WINDOW (parent_window)) {
4627 g_object_unref (G_OBJECT (info->src_folder));
4628 g_object_unref (G_OBJECT (info->dst_folder));
4633 MoveToHelper *helper = g_new0 (MoveToHelper, 1);
4634 helper->banner = modest_platform_animation_banner (GTK_WIDGET (parent_window), NULL,
4635 _CS("ckct_nw_pasting"));
4636 if (helper->banner != NULL) {
4637 gtk_window_set_modal (GTK_WINDOW(helper->banner), FALSE);
4638 gtk_widget_show (GTK_WIDGET(helper->banner));
4640 /* Clean folder on header view before moving it */
4641 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (info->folder_view));
4642 gtk_tree_selection_unselect_all (sel);
4644 /* Let gtk events run. We need that the folder
4645 view frees its reference to the source
4646 folder *before* issuing the mail operation
4647 so we need the signal handler of selection
4648 changed to happen before the mail
4650 while (gtk_events_pending ())
4651 gtk_main_iteration (); */
4654 modest_mail_operation_new_with_error_handling (G_OBJECT(parent_window),
4655 modest_ui_actions_move_folder_error_handler,
4656 info->src_folder, NULL);
4657 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (),
4660 /* Select *after* the changes */
4661 /* TODO: this function hangs UI after transfer */
4662 /* modest_folder_view_select_folder (MODEST_FOLDER_VIEW(folder_view), */
4663 /* TNY_FOLDER (src_folder), TRUE); */
4665 modest_mail_operation_xfer_folder (mail_op,
4666 TNY_FOLDER (info->src_folder),
4668 info->delete_original,
4672 if (modest_mail_operation_get_status (mail_op) == MODEST_MAIL_OPERATION_STATUS_SUCCESS) {
4673 modest_folder_view_select_folder (MODEST_FOLDER_VIEW(info->folder_view),
4674 TNY_FOLDER (info->dst_folder), TRUE);
4677 /* Unref mail operation */
4678 g_object_unref (G_OBJECT (mail_op));
4679 g_object_unref (G_OBJECT (info->src_folder));
4680 g_object_unref (G_OBJECT (info->dst_folder));
4685 * UI handler for the "Move to" action when invoked from the
4689 modest_ui_actions_on_main_window_move_to (GtkAction *action,
4690 GtkWidget *folder_view,
4691 TnyFolderStore *dst_folder,
4692 ModestMainWindow *win)
4694 ModestHeaderView *header_view = NULL;
4695 TnyFolderStore *src_folder;
4696 gboolean online = (tny_device_is_online (modest_runtime_get_device()));
4698 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win));
4700 /* Get the source folder */
4701 src_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
4703 /* Get header view */
4704 header_view = MODEST_HEADER_VIEW(modest_main_window_get_child_widget (win, MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW));
4706 /* Get folder or messages to transfer */
4707 if (gtk_widget_is_focus (folder_view)) {
4708 gboolean do_xfer = TRUE;
4710 /* Allow only to transfer folders to the local root folder */
4711 if (TNY_IS_ACCOUNT (dst_folder) &&
4712 !MODEST_IS_TNY_LOCAL_FOLDERS_ACCOUNT (dst_folder)) {
4714 } else if (!TNY_IS_FOLDER (src_folder)) {
4715 g_warning ("%s: src_folder is not a TnyFolder.\n", __FUNCTION__);
4717 } /* else if (!online && modest_tny_folder_store_is_remote(src_folder)) {
4718 guint num_headers = tny_folder_get_all_count(TNY_FOLDER (src_folder));
4719 TnyAccount *account = tny_folder_get_account (TNY_FOLDER (src_folder));
4720 if (!connect_to_get_msg(MODEST_WINDOW (win), num_headers, account))
4722 g_object_unref (account);
4726 MoveFolderInfo *info = g_new0 (MoveFolderInfo, 1);
4727 info->src_folder = TNY_FOLDER (src_folder);
4728 info->dst_folder = dst_folder;
4729 info->delete_original = TRUE;
4730 info->folder_view = folder_view;
4731 g_object_ref (G_OBJECT (info->src_folder));
4732 g_object_ref (G_OBJECT (info->dst_folder));
4733 modest_platform_connect_if_remote_and_perform(GTK_WINDOW (win), TRUE,
4734 TNY_FOLDER_STORE (dst_folder), on_move_folder_cb, info);
4736 } else if (gtk_widget_is_focus (GTK_WIDGET(header_view))) {
4737 gboolean do_xfer = TRUE;
4739 /* Show an error when trying to move msgs to an account */
4740 if (!TNY_IS_FOLDER (dst_folder)) {
4741 modest_platform_information_banner (GTK_WIDGET (win),
4743 _CS("ckdg_ib_unable_to_move_to_current_location"));
4747 /* Ask for confirmation if the source folder is remote and we're not connected */
4748 if (!online && modest_tny_folder_store_is_remote(src_folder)) {
4749 TnyList *headers = modest_header_view_get_selected_headers(header_view);
4750 if (!msgs_already_deleted_from_server(headers, src_folder)) {
4751 guint num_headers = tny_list_get_length(headers);
4752 TnyAccount *account = get_account_from_header_list (headers);
4753 GtkResponseType response;
4755 response = modest_platform_run_confirmation_dialog (GTK_WINDOW (win),
4756 ngettext("mcen_nc_get_msg",
4759 if (response == GTK_RESPONSE_CANCEL)
4762 g_object_unref (account);
4764 g_object_unref(headers);
4766 if (do_xfer) /* Transfer messages */ {
4767 DoubleConnectionInfo *info = g_slice_new (DoubleConnectionInfo);
4768 info->callback = xfer_messages_from_move_to_cb;
4769 info->dst_account = tny_folder_get_account (TNY_FOLDER (dst_folder));
4770 info->data = g_object_ref (dst_folder);
4772 modest_platform_connect_if_remote_and_perform(GTK_WINDOW (win), TRUE,
4773 TNY_FOLDER_STORE (src_folder),
4774 src_account_connect_performer,
4781 g_object_unref (src_folder);
4786 * UI handler for the "Move to" action when invoked from the
4787 * ModestMsgViewWindow
4790 modest_ui_actions_on_msg_view_window_move_to (GtkAction *action,
4791 TnyFolderStore *dst_folder,
4792 ModestMsgViewWindow *win)
4794 TnyHeader *header = NULL;
4795 TnyFolder *src_folder = NULL;
4796 TnyAccount *account = NULL;
4797 gboolean do_xfer = FALSE;
4799 /* Create header list */
4800 header = modest_msg_view_window_get_header (MODEST_MSG_VIEW_WINDOW (win));
4801 src_folder = TNY_FOLDER (tny_header_get_folder(header));
4802 g_object_unref (header);
4804 account = tny_folder_get_account (src_folder);
4805 if (!modest_tny_folder_store_is_remote(TNY_FOLDER_STORE(src_folder))) {
4806 /* Transfer if the source folder is local */
4808 } else if (remote_folder_is_pop(TNY_FOLDER_STORE(src_folder))) {
4809 /* Transfer if the source folder is POP (as it means
4810 * that the message is already downloaded) */
4812 } else if (connect_to_get_msg(MODEST_WINDOW(win), 1, account)) {
4813 /* Transfer after asking confirmation */
4818 g_object_ref (dst_folder);
4819 modest_platform_connect_if_remote_and_perform(GTK_WINDOW (win), TRUE,
4820 TNY_FOLDER_STORE (dst_folder), xfer_messages_from_move_to_cb, dst_folder);
4822 g_object_unref (account);
4823 g_object_unref (src_folder);
4827 modest_ui_actions_on_move_to (GtkAction *action,
4830 GtkWidget *dialog = NULL, *folder_view = NULL, *tree_view = NULL;
4832 TnyFolderStore *dst_folder = NULL;
4833 ModestMainWindow *main_window;
4835 g_return_if_fail (MODEST_IS_MAIN_WINDOW (win) ||
4836 MODEST_IS_MSG_VIEW_WINDOW (win));
4838 /* Get the main window if exists */
4839 if (MODEST_IS_MAIN_WINDOW (win))
4840 main_window = MODEST_MAIN_WINDOW (win);
4843 MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr (),
4844 FALSE)); /* don't create */
4846 /* Get the folder view widget if exists */
4848 folder_view = modest_main_window_get_child_widget (main_window,
4849 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
4853 /* Create and run the dialog */
4854 dialog = create_move_to_dialog (GTK_WINDOW (win), folder_view, &tree_view);
4855 modest_folder_view_select_first_inbox_or_local (MODEST_FOLDER_VIEW (tree_view));
4856 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4857 result = gtk_dialog_run (GTK_DIALOG(dialog));
4858 g_object_ref (tree_view);
4859 gtk_widget_destroy (dialog);
4861 if (result != GTK_RESPONSE_ACCEPT)
4864 dst_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (tree_view));
4865 /* Do window specific stuff */
4866 if (MODEST_IS_MAIN_WINDOW (win)) {
4867 modest_ui_actions_on_main_window_move_to (action,
4870 MODEST_MAIN_WINDOW (win));
4872 modest_ui_actions_on_msg_view_window_move_to (action,
4874 MODEST_MSG_VIEW_WINDOW (win));
4878 g_object_unref (dst_folder);
4882 * Calls #HeadersFunc for each header already selected in the main
4883 * window or the message currently being shown in the msg view window
4886 do_headers_action (ModestWindow *win,
4890 TnyList *headers_list = NULL;
4891 TnyIterator *iter = NULL;
4892 TnyHeader *header = NULL;
4893 TnyFolder *folder = NULL;
4896 headers_list = get_selected_headers (win);
4900 /* Get the folder */
4901 iter = tny_list_create_iterator (headers_list);
4902 header = TNY_HEADER (tny_iterator_get_current (iter));
4904 folder = tny_header_get_folder (header);
4905 g_object_unref (header);
4908 /* Call the function for each header */
4909 while (!tny_iterator_is_done (iter)) {
4910 header = TNY_HEADER (tny_iterator_get_current (iter));
4911 func (header, win, user_data);
4912 g_object_unref (header);
4913 tny_iterator_next (iter);
4916 /* Trick: do a poke status in order to speed up the signaling
4918 tny_folder_poke_status (folder);
4921 g_object_unref (folder);
4922 g_object_unref (iter);
4923 g_object_unref (headers_list);
4927 modest_ui_actions_view_attachment (GtkAction *action,
4928 ModestWindow *window)
4930 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4931 modest_msg_view_window_view_attachment (MODEST_MSG_VIEW_WINDOW (window), NULL);
4933 /* not supported window for this action */
4934 g_return_if_reached ();
4939 modest_ui_actions_save_attachments (GtkAction *action,
4940 ModestWindow *window)
4942 if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4943 modest_msg_view_window_save_attachments (MODEST_MSG_VIEW_WINDOW (window), NULL);
4945 /* not supported window for this action */
4946 g_return_if_reached ();
4951 modest_ui_actions_remove_attachments (GtkAction *action,
4952 ModestWindow *window)
4954 if (MODEST_IS_MAIN_WINDOW (window)) {
4955 modest_ui_actions_on_main_window_remove_attachments (action, MODEST_MAIN_WINDOW (window));
4956 } else if (MODEST_IS_MSG_VIEW_WINDOW (window)) {
4957 modest_msg_view_window_remove_attachments (MODEST_MSG_VIEW_WINDOW (window), FALSE);
4959 /* not supported window for this action */
4960 g_return_if_reached ();
4965 modest_ui_actions_on_settings (GtkAction *action,
4970 dialog = modest_platform_get_global_settings_dialog ();
4971 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (win));
4972 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
4973 gtk_widget_show_all (dialog);
4975 gtk_dialog_run (GTK_DIALOG (dialog));
4977 gtk_widget_destroy (dialog);
4981 modest_ui_actions_on_help (GtkAction *action,
4984 const gchar *help_id;
4986 g_return_if_fail (action);
4987 g_return_if_fail (win && GTK_IS_WINDOW(win));
4989 help_id = modest_window_mgr_get_help_id (modest_runtime_get_window_mgr(), win);
4992 modest_platform_show_help (GTK_WINDOW (win), help_id);
4994 g_warning ("%s: no help for window %p", __FUNCTION__, win);
4998 retrieve_msg_contents_performer (gboolean canceled,
5000 GtkWindow *parent_window,
5001 TnyAccount *account,
5004 ModestMailOperation *mail_op;
5005 TnyList *headers = TNY_LIST (user_data);
5007 if (err || canceled) {
5011 /* Create mail operation */
5012 mail_op = modest_mail_operation_new_with_error_handling ((GObject *) parent_window,
5013 modest_ui_actions_get_msgs_full_error_handler,
5015 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), mail_op);
5016 modest_mail_operation_get_msgs_full (mail_op, headers, NULL, NULL, NULL);
5019 g_object_unref (mail_op);
5021 g_object_unref (headers);
5022 g_object_unref (account);
5026 modest_ui_actions_on_retrieve_msg_contents (GtkAction *action,
5027 ModestWindow *window)
5029 TnyList *headers = NULL;
5030 TnyAccount *account = NULL;
5031 TnyIterator *iter = NULL;
5032 TnyHeader *header = NULL;
5033 TnyFolder *folder = NULL;
5036 headers = get_selected_headers (window);
5040 /* Pick the account */
5041 iter = tny_list_create_iterator (headers);
5042 header = TNY_HEADER (tny_iterator_get_current (iter));
5043 folder = tny_header_get_folder (header);
5044 account = tny_folder_get_account (folder);
5045 g_object_unref (folder);
5046 g_object_unref (header);
5047 g_object_unref (iter);
5049 /* Connect and perform the message retrieval */
5050 modest_platform_connect_and_perform ((GtkWindow *) window, TRUE,
5051 g_object_ref (account),
5052 retrieve_msg_contents_performer,
5053 g_object_ref (headers));
5056 g_object_unref (account);
5057 g_object_unref (headers);
5061 modest_ui_actions_check_toolbar_dimming_rules (ModestWindow *window)
5063 g_return_if_fail (MODEST_IS_WINDOW (window));
5066 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_TOOLBAR);
5070 modest_ui_actions_check_menu_dimming_rules (ModestWindow *window)
5072 g_return_if_fail (MODEST_IS_WINDOW (window));
5075 modest_window_check_dimming_rules_group (window, MODEST_DIMMING_RULES_MENU);
5079 modest_ui_actions_on_email_menu_activated (GtkAction *action,
5080 ModestWindow *window)
5082 g_return_if_fail (MODEST_IS_WINDOW (window));
5085 modest_ui_actions_check_menu_dimming_rules (window);
5089 modest_ui_actions_on_edit_menu_activated (GtkAction *action,
5090 ModestWindow *window)
5092 g_return_if_fail (MODEST_IS_WINDOW (window));
5095 modest_ui_actions_check_menu_dimming_rules (window);
5099 modest_ui_actions_on_view_menu_activated (GtkAction *action,
5100 ModestWindow *window)
5102 g_return_if_fail (MODEST_IS_WINDOW (window));
5105 modest_ui_actions_check_menu_dimming_rules (window);
5109 modest_ui_actions_on_format_menu_activated (GtkAction *action,
5110 ModestWindow *window)
5112 g_return_if_fail (MODEST_IS_WINDOW (window));
5115 modest_ui_actions_check_menu_dimming_rules (window);
5119 modest_ui_actions_on_tools_menu_activated (GtkAction *action,
5120 ModestWindow *window)
5122 g_return_if_fail (MODEST_IS_WINDOW (window));
5125 modest_ui_actions_check_menu_dimming_rules (window);
5129 modest_ui_actions_on_attachment_menu_activated (GtkAction *action,
5130 ModestWindow *window)
5132 g_return_if_fail (MODEST_IS_WINDOW (window));
5135 modest_ui_actions_check_menu_dimming_rules (window);
5139 modest_ui_actions_on_toolbar_csm_menu_activated (GtkAction *action,
5140 ModestWindow *window)
5142 g_return_if_fail (MODEST_IS_WINDOW (window));
5145 modest_ui_actions_check_menu_dimming_rules (window);
5149 modest_ui_actions_on_folder_view_csm_menu_activated (GtkAction *action,
5150 ModestWindow *window)
5152 g_return_if_fail (MODEST_IS_WINDOW (window));
5155 modest_ui_actions_check_menu_dimming_rules (window);
5159 modest_ui_actions_on_header_view_csm_menu_activated (GtkAction *action,
5160 ModestWindow *window)
5162 g_return_if_fail (MODEST_IS_WINDOW (window));
5165 modest_ui_actions_check_menu_dimming_rules (window);
5169 modest_ui_actions_on_search_messages (GtkAction *action, ModestWindow *window)
5171 g_return_if_fail (MODEST_IS_WINDOW (window));
5173 modest_platform_show_search_messages (GTK_WINDOW (window));
5177 modest_ui_actions_on_open_addressbook (GtkAction *action, ModestWindow *win)
5179 g_return_if_fail (MODEST_IS_WINDOW (win));
5180 modest_platform_show_addressbook (GTK_WINDOW (win));
5185 modest_ui_actions_on_toggle_find_in_page (GtkToggleAction *action,
5186 ModestWindow *window)
5188 g_return_if_fail (MODEST_IS_MSG_EDIT_WINDOW (window));
5190 modest_msg_edit_window_toggle_find_toolbar (MODEST_MSG_EDIT_WINDOW (window), gtk_toggle_action_get_active (action));
5194 on_send_receive_finished (ModestMailOperation *mail_op,
5197 GtkWidget *header_view, *folder_view;
5198 TnyFolderStore *folder_store;
5199 ModestMainWindow *main_win = MODEST_MAIN_WINDOW (user_data);
5201 /* Set send/receive operation finished */
5202 modest_main_window_notify_send_receive_completed (main_win);
5204 /* Don't refresh the current folder if there were any errors */
5205 if (modest_mail_operation_get_status (mail_op) !=
5206 MODEST_MAIL_OPERATION_STATUS_SUCCESS)
5209 /* Refresh the current folder if we're viewing a window. We do
5210 this because the user won't be able to see the new mails in
5211 the selected folder after a Send&Receive because it only
5212 performs a poke_status, i.e, only the number of read/unread
5213 messages is updated, but the new headers are not
5215 folder_view = modest_main_window_get_child_widget (main_win,
5216 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5220 folder_store = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5222 /* Do not need to refresh INBOX again because the
5223 update_account does it always automatically */
5224 if (folder_store && TNY_IS_FOLDER (folder_store) &&
5225 tny_folder_get_folder_type (TNY_FOLDER (folder_store)) != TNY_FOLDER_TYPE_INBOX) {
5226 ModestMailOperation *refresh_op;
5228 header_view = modest_main_window_get_child_widget (main_win,
5229 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5231 /* We do not need to set the contents style
5232 because it hasn't changed. We also do not
5233 need to save the widget status. Just force
5235 refresh_op = modest_mail_operation_new (G_OBJECT (main_win));
5236 modest_mail_operation_queue_add (modest_runtime_get_mail_operation_queue (), refresh_op);
5237 modest_mail_operation_refresh_folder (refresh_op, TNY_FOLDER (folder_store),
5238 folder_refreshed_cb, main_win);
5239 g_object_unref (refresh_op);
5243 g_object_unref (folder_store);
5248 modest_ui_actions_on_send_queue_error_happened (TnySendQueue *self,
5254 const gchar* server_name = NULL;
5255 TnyTransportAccount *server_account;
5256 gchar *message = NULL;
5258 /* Don't show anything if the user cancelled something */
5259 if (err->code == TNY_SYSTEM_ERROR_CANCEL)
5262 /* Get the server name: */
5264 TNY_TRANSPORT_ACCOUNT (tny_camel_send_queue_get_transport_account (TNY_CAMEL_SEND_QUEUE (self)));
5265 if (server_account) {
5266 server_name = tny_account_get_hostname (TNY_ACCOUNT (server_account));
5268 g_object_unref (server_account);
5269 server_account = NULL;
5272 g_return_if_fail (server_name);
5274 /* Show the appropriate message text for the GError: */
5275 switch (err->code) {
5276 case TNY_SERVICE_ERROR_CONNECT:
5277 message = g_strdup_printf (_("emev_ib_ui_smtp_server_invalid"), server_name);
5279 case TNY_SERVICE_ERROR_AUTHENTICATE:
5280 message = g_strdup_printf (_("emev_ni_ui_smtp_authentication_fail_error"), server_name);
5282 case TNY_SERVICE_ERROR_SEND:
5283 message = g_strdup (_("emev_ib_ui_smtp_send_error"));
5286 g_warning ("%s: unexpected ERROR %d",
5287 __FUNCTION__, err->code);
5288 message = g_strdup (_("emev_ib_ui_smtp_send_error"));
5292 /* TODO if the username or the password where not defined we
5293 should show the Accounts Settings dialog or the Connection
5294 specific SMTP server window */
5296 modest_platform_run_information_dialog (NULL, message);
5301 modest_ui_actions_on_send_queue_status_changed (ModestTnySendQueue *send_queue,
5306 ModestMainWindow *main_window = NULL;
5307 ModestWindowMgr *mgr = NULL;
5308 GtkWidget *folder_view = NULL, *header_view = NULL;
5309 TnyFolderStore *selected_folder = NULL;
5310 TnyFolderType folder_type;
5312 mgr = modest_runtime_get_window_mgr ();
5313 main_window = MODEST_MAIN_WINDOW (modest_window_mgr_get_main_window (mgr,
5314 FALSE));/* don't create */
5318 /* Check if selected folder is OUTBOX */
5319 folder_view = modest_main_window_get_child_widget (main_window,
5320 MODEST_MAIN_WINDOW_WIDGET_TYPE_FOLDER_VIEW);
5321 header_view = modest_main_window_get_child_widget (main_window,
5322 MODEST_MAIN_WINDOW_WIDGET_TYPE_HEADER_VIEW);
5324 selected_folder = modest_folder_view_get_selected (MODEST_FOLDER_VIEW (folder_view));
5325 if (!TNY_IS_FOLDER (selected_folder))
5328 /* gtk_tree_view_column_queue_resize is only available in GTK+ 2.8 */
5329 #if GTK_CHECK_VERSION(2, 8, 0)
5330 folder_type = modest_tny_folder_guess_folder_type (TNY_FOLDER (selected_folder));
5331 if (folder_type == TNY_FOLDER_TYPE_OUTBOX) {
5332 GtkTreeViewColumn *tree_column;
5334 tree_column = gtk_tree_view_get_column (GTK_TREE_VIEW (header_view),
5335 TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN);
5336 gtk_tree_view_column_queue_resize (tree_column);
5339 gtk_widget_queue_draw (header_view);
5344 if (selected_folder != NULL)
5345 g_object_unref (selected_folder);
5349 modest_ui_actions_on_account_connection_error (GtkWindow *parent_window,
5350 TnyAccount *account)
5352 ModestTransportStoreProtocol proto;
5353 const gchar *proto_name;
5354 gchar *error_note = NULL;
5356 proto_name = tny_account_get_proto (account);
5357 proto = modest_protocol_info_get_transport_store_protocol (proto_name);
5360 case MODEST_PROTOCOL_STORE_POP:
5361 error_note = g_strdup_printf (_("emev_ni_ui_pop3_msg_connect_error"),
5362 tny_account_get_hostname (account));
5364 case MODEST_PROTOCOL_STORE_IMAP:
5365 error_note = g_strdup_printf (_("emev_ni_ui_imap_connect_server_error"),
5366 tny_account_get_hostname (account));
5368 case MODEST_PROTOCOL_STORE_MAILDIR:
5369 case MODEST_PROTOCOL_STORE_MBOX:
5370 error_note = g_strdup (_("emev_nc_mailbox_notavailable"));
5373 g_warning ("%s: This should not be reached", __FUNCTION__);
5377 modest_platform_run_information_dialog (parent_window, error_note);
5378 g_free (error_note);